TODO for tests include: * Send error/cancel from agent in single and multiple transfers; * Cancel transfer as it was from client, in different steps of the ongoing operation; --- tests/Makefile.am | 2 + tests/file-transfer.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 tests/file-transfer.c diff --git a/tests/Makefile.am b/tests/Makefile.am index c1d95c1..90b31f4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -4,6 +4,7 @@ noinst_PROGRAMS = TESTS = coroutine \ util \ session \ + file_transfer \ $(NULL) if WITH_PHODAV @@ -35,6 +36,7 @@ util_SOURCES = util.c coroutine_SOURCES = coroutine.c session_SOURCES = session.c pipe_SOURCES = pipe.c +file_transfer_SOURCES = file-transfer.c usb_acl_helper_SOURCES = usb-acl-helper.c usb_acl_helper_CFLAGS = -DTESTDIR=\"$(abs_builddir)\" mock_acl_helper_SOURCES = mock-acl-helper.c diff --git a/tests/file-transfer.c b/tests/file-transfer.c new file mode 100644 index 0000000..d7b5f01 --- /dev/null +++ b/tests/file-transfer.c @@ -0,0 +1,153 @@ +#include <gio/gio.h> + +#include "spice-file-transfer-task-priv.h" + +typedef struct _Fixture { + GFile **files; + guint num_files; + GCancellable *cancellable; + GMainLoop *loop; +} Fixture; + +typedef struct _AgentAsync { + SpiceFileTransferTask *xfer_task; + VDAgentFileXferStatusMessage msg; +} AgentAsync; + +#define SINGLE_FILE 1 +#define MULTIPLE_FILES 10 + +#define T10ns (G_TIME_SPAN_MILLISECOND / 100) + +const gchar content[] = "0123456789_spice-file-transfer-task"; + +static void +f_setup(Fixture *f, gconstpointer user_data) +{ + gint i; + GError *err = NULL; + + f->loop = g_main_loop_new(NULL, FALSE); + f->num_files = GPOINTER_TO_UINT(user_data); + f->files = g_new0(GFile *, f->num_files); + f->cancellable = g_cancellable_new(); + for (i = 0; i < f->num_files; i++) { + gboolean success; + GFileIOStream *iostream; + + f->files[i] = g_file_new_tmp("spice-file-transfer-XXXXXX", &iostream, &err); + g_assert_no_error(err); + g_assert_nonnull(iostream); + g_clear_object(&iostream); + + success = g_file_replace_contents (f->files[i], content, strlen(content), NULL, FALSE, + G_FILE_CREATE_NONE, NULL, f->cancellable, &err); + g_assert_no_error(err); + g_assert_true(success); + } +} + +static void +f_teardown(Fixture *f, gconstpointer user_data) +{ + gint i; + GError *err = NULL; + + g_main_loop_unref(f->loop); + g_clear_object(&f->cancellable); + + for (i = 0; i < f->num_files; i++) { + g_file_delete(f->files[i], NULL, &err); + g_assert_no_error(err); + g_object_unref(f->files[i]); + } + g_free(f->files); +} + +static gboolean +agent_send_msg(gpointer user_data) +{ + AgentAsync *aa = user_data; + spice_file_transfer_task_handle_status(aa->xfer_task, &aa->msg); + g_free(aa); +} + +static void +agent_send_msg_async(SpiceFileTransferTask *xfer_task, guint32 result) +{ + AgentAsync *aa = g_new0(AgentAsync, 1); + aa->xfer_task = xfer_task; + aa->msg.result = result; + g_object_get(xfer_task, "id", &aa->msg.id, NULL); + g_timeout_add_full(G_PRIORITY_LOW, T10ns, agent_send_msg, aa, NULL); +} + +#define agent_send_success_async(t) agent_send_msg_async(t, VD_AGENT_FILE_XFER_STATUS_SUCCESS) +#define agent_send_more_data_async(t) agent_send_msg_async(t, VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA) +#define agent_send_cancel_async(t) agent_send_msg_async(t, VD_AGENT_FILE_XFER_STATUS_CANCELLED) +#define agent_send_error_async(t) agent_send_msg_async(t, VD_AGENT_FILE_XFER_STATUS_ERROR) + +static void +transfer_small_done(GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + Fixture *f = user_data; + g_main_loop_quit(f->loop); +} + +static void +transfer_flush_callback(SpiceFileTransferTask *xfer_task, + void *buffer, + gssize count, + gpointer user_data) +{ + spice_file_transfer_task_flush_done(xfer_task, NULL); + agent_send_success_async(xfer_task); +} + +static void +transfer_task_on_file_info(SpiceFileTransferTask *xfer_task, + GFileInfo *info, + gpointer data) +{ + guint32 id; + g_object_get (xfer_task, "id", &id, NULL); + agent_send_more_data_async(xfer_task); +} + +static void +test_transfer_small(Fixture *f, gconstpointer user_datat) +{ + GList *tasks, *it; + + tasks = spice_file_transfer_task_create_tasks(NULL, + f->files, + G_FILE_COPY_NONE, + f->cancellable, + transfer_flush_callback, + NULL, + transfer_small_done, + f); + for (it = tasks; it != NULL; it = it->next) { + SpiceFileTransferTask *xfer_task = SPICE_FILE_TRANSFER_TASK(it->data); + g_signal_connect(xfer_task, "file-info", G_CALLBACK(transfer_task_on_file_info), f); + spice_file_transfer_task_start_task(xfer_task); + } + g_main_loop_run (f->loop); +} + +int main(int argc, char* argv[]) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add("/spice-file-transfer-task/single/transfer-small", + Fixture, GUINT_TO_POINTER(SINGLE_FILE), + f_setup, test_transfer_small, f_teardown); + + g_test_add("/spice-file-transfer-task/multiple/transfer-small", + Fixture, GUINT_TO_POINTER(MULTIPLE_FILES), + f_setup, test_transfer_small, f_teardown); + + return g_test_run(); +} -- 2.5.5 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel