#include "support.h" #include "engine_support.h" #include #include #include #include #include #include #include "../mock-plugin/mock_sync.h" #include "../mock-plugin/mock_format.h" START_TEST (engine_new) { char *testbed = setup_testbed(NULL); OSyncError *error = NULL; OSyncGroup *group = osync_group_new(&error); fail_unless(group != NULL, NULL); fail_unless(error == NULL, NULL); OSyncMember *member = osync_member_new(&error); fail_unless(member != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(group, member); member = osync_member_new(&error); fail_unless(member != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(group, member); OSyncEngine *engine = osync_engine_new(group, &error); fail_unless(engine != NULL, NULL); fail_unless(error == NULL, NULL); osync_engine_ref(engine); osync_engine_unref(engine); osync_engine_unref(engine); destroy_testbed(testbed); } END_TEST START_TEST (engine_init) { char *path = NULL; char *testbed = setup_testbed("sync_setup"); OSyncError *error = NULL; OSyncGroup *group = osync_group_new(&error); fail_unless(group != NULL, NULL); fail_unless(error == NULL, NULL); OSyncMember *member = osync_member_new(&error); fail_unless(member != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(group, member); osync_member_add_objtype(member, "mockobjtype1"); osync_member_set_pluginname(member, "mock-sync"); path = g_strdup_printf("%s/configs/group/1", testbed); osync_member_set_configdir(member, path); g_free(path); member = osync_member_new(&error); fail_unless(member != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(group, member); osync_member_add_objtype(member, "mockobjtype1"); osync_member_set_pluginname(member, "mock-sync"); path = g_strdup_printf("%s/configs/group/1", testbed); osync_member_set_configdir(member, path); g_free(path); OSyncEngine *engine = osync_engine_new(group, &error); fail_unless(engine != NULL, NULL); fail_unless(error == NULL, NULL); osync_engine_set_plugindir(engine, testbed); fail_unless(osync_engine_initialize(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_finalize(engine, &error), NULL); fail_unless(error == NULL, NULL); osync_engine_unref(engine); destroy_testbed(testbed); } END_TEST static void connect(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 0); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 0); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_atomic_int_inc(&(env->num_connect)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void disconnect(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 1); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 1); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_atomic_int_inc(&(env->num_disconnect)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void get_changes(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 1); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 0); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_atomic_int_inc(&(env->num_get_changes)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void *initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, info, error); mock_env *env = osync_try_malloc0(sizeof(mock_env), error); if (!env) goto error; OSyncObjTypeSink *sink = osync_objtype_sink_new("file", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "file"); OSyncObjTypeSinkFunctions functions; memset(&functions, 0, sizeof(functions)); functions.connect = connect; functions.disconnect = disconnect; functions.get_changes = get_changes; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); osync_trace(TRACE_EXIT, "%s: %p", __func__, env); return (void *)env; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; } static void finalize(void *data) { mock_env *env = data; osync_assert(env->num_connect == 1); osync_assert(env->num_disconnect == 1); osync_assert(env->num_get_changes == 1); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_free(env); } static OSyncDebugGroup *_create_group(char *testbed) { OSyncDebugGroup *debug = g_malloc0(sizeof(OSyncDebugGroup)); OSyncError *error = NULL; debug->group = osync_group_new(&error); fail_unless(debug->group != NULL, NULL); fail_unless(error == NULL, NULL); debug->member1 = osync_member_new(&error); fail_unless(debug->member1 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member1); osync_member_set_pluginname(debug->member1, "mock-sync"); char *path = g_strdup_printf("%s/configs/group/1", testbed); osync_member_set_configdir(debug->member1, path); g_free(path); osync_member_set_start_type(debug->member1, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member1, "file"); debug->member2 = osync_member_new(&error); fail_unless(debug->member2 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member2); osync_member_set_pluginname(debug->member2, "mock-sync"); path = g_strdup_printf("%s/configs/group/2", testbed); osync_member_set_configdir(debug->member2, path); g_free(path); osync_member_set_start_type(debug->member2, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member2, "file"); debug->plugin = osync_plugin_new(&error); fail_unless(debug->plugin != NULL, NULL); fail_unless(error == NULL, NULL); osync_plugin_set_name(debug->plugin, "mock-sync"); osync_plugin_set_longname(debug->plugin, "Mock Sync Plugin"); osync_plugin_set_description(debug->plugin, "This is a pseudo plugin"); osync_plugin_set_initialize(debug->plugin, initialize); osync_plugin_set_finalize(debug->plugin, finalize); debug->client1 = osync_client_new(&error); fail_unless(debug->client1 != NULL, NULL); fail_unless(error == NULL, NULL); char *pipe_path = g_strdup_printf("%s/configs/group/1/pluginpipe", testbed); osync_client_run_external(debug->client1, pipe_path, debug->plugin, &error); g_free(pipe_path); debug->client2 = osync_client_new(&error); fail_unless(debug->client2 != NULL, NULL); fail_unless(error == NULL, NULL); pipe_path = g_strdup_printf("%s/configs/group/2/pluginpipe", testbed); osync_client_run_external(debug->client2, pipe_path, debug->plugin, &error); g_free(pipe_path); return debug; } static void _free_group(OSyncDebugGroup *debug) { osync_client_unref(debug->client1); osync_client_unref(debug->client2); osync_plugin_unref(debug->plugin); osync_member_unref(debug->member1); osync_member_unref(debug->member2); osync_group_unref(debug->group); g_free(debug); } START_TEST (engine_sync) { char *testbed = setup_testbed("sync_setup"); OSyncError *error = NULL; OSyncDebugGroup *debug = _create_group(testbed); OSyncEngine *engine = osync_engine_new(debug->group, &error); fail_unless(engine != NULL, NULL); fail_unless(error == NULL, NULL); osync_engine_set_plugindir(engine, testbed); fail_unless(osync_engine_initialize(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_synchronize_and_block(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_finalize(engine, &error), NULL); fail_unless(error == NULL, NULL); _free_group(debug); osync_engine_unref(engine); destroy_testbed(testbed); } END_TEST static void connect2(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect < 3); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 0); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_atomic_int_inc(&(env->num_connect)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void disconnect2(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect < 3); osync_assert(env->num_get_changes == 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 1); g_atomic_int_inc(&(env->num_disconnect)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void get_changes2(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes < 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_atomic_int_inc(&(env->num_get_changes)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void main_connect2(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 0); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_atomic_int_inc(&(env->main_connect)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void main_disconnect2(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 3); osync_assert(env->num_get_changes == 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 1); g_atomic_int_inc(&(env->main_disconnect)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void main_get_changes2(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_atomic_int_inc(&(env->main_get_changes)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void *initialize_multi(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, info, error); mock_env *env = osync_try_malloc0(sizeof(mock_env), error); if (!env) goto error; OSyncObjTypeSink *sink = osync_objtype_sink_new("file", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "file"); OSyncObjTypeSinkFunctions functions; memset(&functions, 0, sizeof(functions)); functions.connect = connect2; functions.disconnect = disconnect2; functions.get_changes = get_changes2; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); sink = osync_objtype_sink_new("contact", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "vcard"); memset(&functions, 0, sizeof(functions)); functions.connect = connect2; functions.disconnect = disconnect2; functions.get_changes = get_changes2; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); sink = osync_objtype_sink_new("note", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "plain"); memset(&functions, 0, sizeof(functions)); functions.connect = connect2; functions.disconnect = disconnect2; functions.get_changes = get_changes2; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); /* The main sink */ sink = osync_objtype_sink_new(NULL, error); if (!sink) goto error; memset(&functions, 0, sizeof(functions)); functions.connect = main_connect2; functions.disconnect = main_disconnect2; functions.get_changes = main_get_changes2; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_set_main_sink(info, sink); osync_objtype_sink_unref(sink); osync_trace(TRACE_EXIT, "%s: %p", __func__, env); return (void *)env; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; } static void finalize_multi(void *data) { mock_env *env = data; osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 3); osync_assert(env->num_get_changes == 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 1); osync_assert(env->main_get_changes == 1); g_free(env); } static OSyncDebugGroup *_create_group2(char *testbed) { osync_trace(TRACE_ENTRY, "%s(%s)", __func__, testbed); OSyncDebugGroup *debug = g_malloc0(sizeof(OSyncDebugGroup)); OSyncError *error = NULL; debug->group = osync_group_new(&error); fail_unless(debug->group != NULL, NULL); fail_unless(error == NULL, NULL); debug->member1 = osync_member_new(&error); fail_unless(debug->member1 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member1); osync_member_set_pluginname(debug->member1, "mock-sync"); char *path = g_strdup_printf("%s/configs/group/1", testbed); osync_member_set_configdir(debug->member1, path); g_free(path); osync_member_set_start_type(debug->member1, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member1, "file"); osync_member_add_objtype(debug->member1, "contact"); osync_member_add_objtype(debug->member1, "note"); debug->member2 = osync_member_new(&error); fail_unless(debug->member2 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member2); osync_member_set_pluginname(debug->member2, "mock-sync"); path = g_strdup_printf("%s/configs/group/2", testbed); osync_member_set_configdir(debug->member2, path); g_free(path); osync_member_set_start_type(debug->member2, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member2, "file"); osync_member_add_objtype(debug->member2, "contact"); osync_member_add_objtype(debug->member2, "note"); debug->plugin = osync_plugin_new(&error); fail_unless(debug->plugin != NULL, NULL); fail_unless(error == NULL, NULL); osync_plugin_set_name(debug->plugin, "mock-sync"); osync_plugin_set_longname(debug->plugin, "Mock Sync Plugin"); osync_plugin_set_description(debug->plugin, "This is a pseudo plugin"); osync_plugin_set_initialize(debug->plugin, initialize_multi); osync_plugin_set_finalize(debug->plugin, finalize_multi); debug->client1 = osync_client_new(&error); fail_unless(debug->client1 != NULL, NULL); fail_unless(error == NULL, NULL); char *pipe_path = g_strdup_printf("%s/configs/group/1/pluginpipe", testbed); osync_client_run_external(debug->client1, pipe_path, debug->plugin, &error); g_free(pipe_path); debug->client2 = osync_client_new(&error); fail_unless(debug->client2 != NULL, NULL); fail_unless(error == NULL, NULL); pipe_path = g_strdup_printf("%s/configs/group/2/pluginpipe", testbed); osync_client_run_external(debug->client2, pipe_path, debug->plugin, &error); g_free(pipe_path); osync_trace(TRACE_EXIT, "%s: %p", __func__, debug); return debug; } START_TEST (engine_sync_multi_obj) { char *testbed = setup_testbed("sync_setup"); OSyncError *error = NULL; OSyncDebugGroup *debug = _create_group2(testbed); OSyncEngine *engine = osync_engine_new(debug->group, &error); fail_unless(engine != NULL, NULL); fail_unless(error == NULL, NULL); osync_engine_set_plugindir(engine, testbed); fail_unless(osync_engine_initialize(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_synchronize_and_block(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_finalize(engine, &error), NULL); fail_unless(error == NULL, NULL); _free_group(debug); osync_engine_unref(engine); destroy_testbed(testbed); } END_TEST static void connect3(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect < 3); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 0); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); env->ctx[env->num_connect] = ctx; osync_context_ref(ctx); g_atomic_int_inc(&(env->num_connect)); osync_trace(TRACE_EXIT, "%s", __func__); } static void disconnect3(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect < 3); osync_assert(env->num_get_changes == 3); osync_assert(env->num_sync_done == 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 1); osync_assert(env->main_sync_done == 1); env->ctx[env->num_disconnect] = ctx; osync_context_ref(ctx); g_atomic_int_inc(&(env->num_disconnect)); osync_trace(TRACE_EXIT, "%s", __func__); } static void get_changes3(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes < 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); env->ctx[env->num_get_changes] = ctx; osync_context_ref(ctx); g_atomic_int_inc(&(env->num_get_changes)); osync_trace(TRACE_EXIT, "%s", __func__); } static void sync_done3(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 3); osync_assert(env->num_sync_done < 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 1); osync_assert(env->main_sync_done == 0); env->ctx[env->num_sync_done] = ctx; osync_context_ref(ctx); g_atomic_int_inc(&(env->num_sync_done)); osync_trace(TRACE_EXIT, "%s", __func__); } static void main_connect3(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 0); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_atomic_int_inc(&(env->main_connect)); osync_context_report_success(ctx); osync_context_report_success(env->ctx[0]); osync_context_report_success(env->ctx[1]); osync_context_report_success(env->ctx[2]); osync_context_unref(env->ctx[0]); osync_context_unref(env->ctx[1]); osync_context_unref(env->ctx[2]); osync_trace(TRACE_EXIT, "%s", __func__); } static void main_disconnect3(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 3); osync_assert(env->num_get_changes == 3); osync_assert(env->num_sync_done == 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 1); osync_assert(env->main_sync_done == 1); g_atomic_int_inc(&(env->main_disconnect)); osync_context_report_success(env->ctx[0]); osync_context_report_success(env->ctx[2]); osync_context_report_success(ctx); osync_context_report_success(env->ctx[1]); osync_context_unref(env->ctx[0]); osync_context_unref(env->ctx[1]); osync_context_unref(env->ctx[2]); osync_trace(TRACE_EXIT, "%s", __func__); } static void main_get_changes3(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_atomic_int_inc(&(env->main_get_changes)); osync_context_report_success(ctx); osync_context_report_success(env->ctx[2]); osync_context_report_success(env->ctx[1]); osync_context_report_success(env->ctx[0]); osync_context_unref(env->ctx[0]); osync_context_unref(env->ctx[1]); osync_context_unref(env->ctx[2]); osync_trace(TRACE_EXIT, "%s", __func__); } static void main_sync_done3(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 0); osync_assert(env->num_get_changes == 3); osync_assert(env->num_sync_done == 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 1); osync_assert(env->main_sync_done == 0); g_atomic_int_inc(&(env->main_sync_done)); osync_context_report_success(ctx); osync_context_report_success(env->ctx[2]); osync_context_report_success(env->ctx[1]); osync_context_report_success(env->ctx[0]); osync_context_unref(env->ctx[0]); osync_context_unref(env->ctx[1]); osync_context_unref(env->ctx[2]); osync_trace(TRACE_EXIT, "%s", __func__); } static void *initialize_order(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, info, error); mock_env *env = osync_try_malloc0(sizeof(mock_env), error); if (!env) goto error; OSyncObjTypeSink *sink = osync_objtype_sink_new("file", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "file"); OSyncObjTypeSinkFunctions functions; memset(&functions, 0, sizeof(functions)); functions.connect = connect3; functions.disconnect = disconnect3; functions.get_changes = get_changes3; functions.sync_done = sync_done3; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); sink = osync_objtype_sink_new("contact", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "vcard"); memset(&functions, 0, sizeof(functions)); functions.connect = connect3; functions.disconnect = disconnect3; functions.get_changes = get_changes3; functions.sync_done = sync_done3; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); sink = osync_objtype_sink_new("note", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "plain"); memset(&functions, 0, sizeof(functions)); functions.connect = connect3; functions.disconnect = disconnect3; functions.get_changes = get_changes3; functions.sync_done = sync_done3; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); /* The main sink */ sink = osync_objtype_sink_new(NULL, error); if (!sink) goto error; memset(&functions, 0, sizeof(functions)); functions.connect = main_connect3; functions.disconnect = main_disconnect3; functions.get_changes = main_get_changes3; functions.sync_done = main_sync_done3; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_set_main_sink(info, sink); osync_objtype_sink_unref(sink); osync_trace(TRACE_EXIT, "%s: %p", __func__, env); return (void *)env; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; } static void finalize_order(void *data) { mock_env *env = data; osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 3); osync_assert(env->num_get_changes == 3); osync_assert(env->num_sync_done == 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 1); osync_assert(env->main_get_changes == 1); osync_assert(env->main_sync_done == 1); g_free(env); } static OSyncDebugGroup *_create_group3(char *testbed) { osync_trace(TRACE_ENTRY, "%s(%s)", __func__, testbed); OSyncDebugGroup *debug = g_malloc0(sizeof(OSyncDebugGroup)); OSyncError *error = NULL; debug->group = osync_group_new(&error); fail_unless(debug->group != NULL, NULL); fail_unless(error == NULL, NULL); debug->member1 = osync_member_new(&error); fail_unless(debug->member1 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member1); osync_member_set_pluginname(debug->member1, "mock-sync"); char *path = g_strdup_printf("%s/configs/group/1", testbed); osync_member_set_configdir(debug->member1, path); g_free(path); osync_member_set_start_type(debug->member1, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member1, "file"); osync_member_add_objtype(debug->member1, "contact"); osync_member_add_objtype(debug->member1, "note"); debug->member2 = osync_member_new(&error); fail_unless(debug->member2 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member2); osync_member_set_pluginname(debug->member2, "mock-sync"); path = g_strdup_printf("%s/configs/group/2", testbed); osync_member_set_configdir(debug->member2, path); g_free(path); osync_member_set_start_type(debug->member2, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member2, "file"); osync_member_add_objtype(debug->member2, "contact"); osync_member_add_objtype(debug->member2, "note"); debug->plugin = osync_plugin_new(&error); fail_unless(debug->plugin != NULL, NULL); fail_unless(error == NULL, NULL); osync_plugin_set_name(debug->plugin, "mock-sync"); osync_plugin_set_longname(debug->plugin, "Mock Sync Plugin"); osync_plugin_set_description(debug->plugin, "This is a pseudo plugin"); osync_plugin_set_initialize(debug->plugin, initialize_order); osync_plugin_set_finalize(debug->plugin, finalize_order); debug->client1 = osync_client_new(&error); fail_unless(debug->client1 != NULL, NULL); fail_unless(error == NULL, NULL); char *pipe_path = g_strdup_printf("%s/configs/group/1/pluginpipe", testbed); osync_client_run_external(debug->client1, pipe_path, debug->plugin, &error); g_free(pipe_path); debug->client2 = osync_client_new(&error); fail_unless(debug->client2 != NULL, NULL); fail_unless(error == NULL, NULL); pipe_path = g_strdup_printf("%s/configs/group/2/pluginpipe", testbed); osync_client_run_external(debug->client2, pipe_path, debug->plugin, &error); g_free(pipe_path); osync_trace(TRACE_EXIT, "%s: %p", __func__, debug); return debug; } START_TEST (engine_sync_out_of_order) { char *testbed = setup_testbed("sync_setup"); OSyncError *error = NULL; OSyncDebugGroup *debug = _create_group3(testbed); OSyncEngine *engine = osync_engine_new(debug->group, &error); fail_unless(engine != NULL, NULL); fail_unless(error == NULL, NULL); osync_engine_set_plugindir(engine, testbed); fail_unless(osync_engine_initialize(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_synchronize_and_block(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_finalize(engine, &error), NULL); fail_unless(error == NULL, NULL); _free_group(debug); osync_engine_unref(engine); destroy_testbed(testbed); } END_TEST static void main_disconnect4(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); osync_assert(env->num_connect == 3); osync_assert(env->num_disconnect == 3); osync_assert(env->num_get_changes == 3); osync_assert(env->main_connect == 1); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 1); g_atomic_int_inc(&(env->main_disconnect)); osync_context_report_success(env->ctx[0]); osync_context_report_success(env->ctx[2]); osync_context_report_success(ctx); osync_context_report_success(env->ctx[1]); osync_context_unref(env->ctx[0]); osync_context_unref(env->ctx[1]); osync_context_unref(env->ctx[2]); env->num_connect = 0; env->num_disconnect = 0; env->num_get_changes = 0; env->num_sync_done = 0; env->main_connect = 0; env->main_disconnect = 0; env->main_get_changes = 0; env->main_sync_done = 0; osync_trace(TRACE_EXIT, "%s", __func__); } static void *initialize_reuse(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, info, error); mock_env *env = osync_try_malloc0(sizeof(mock_env), error); if (!env) goto error; OSyncObjTypeSink *sink = osync_objtype_sink_new("file", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "file"); OSyncObjTypeSinkFunctions functions; memset(&functions, 0, sizeof(functions)); functions.connect = connect3; functions.disconnect = disconnect3; functions.get_changes = get_changes3; functions.sync_done = sync_done3; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); sink = osync_objtype_sink_new("contact", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "vcard"); memset(&functions, 0, sizeof(functions)); functions.connect = connect3; functions.disconnect = disconnect3; functions.get_changes = get_changes3; functions.sync_done = sync_done3; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); sink = osync_objtype_sink_new("note", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "plain"); memset(&functions, 0, sizeof(functions)); functions.connect = connect3; functions.disconnect = disconnect3; functions.get_changes = get_changes3; functions.sync_done = sync_done3; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); /* The main sink */ sink = osync_objtype_sink_new(NULL, error); if (!sink) goto error; memset(&functions, 0, sizeof(functions)); functions.connect = main_connect3; functions.disconnect = main_disconnect4; functions.get_changes = main_get_changes3; functions.sync_done = main_sync_done3; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_set_main_sink(info, sink); osync_objtype_sink_unref(sink); osync_trace(TRACE_EXIT, "%s: %p", __func__, env); return (void *)env; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; } static void finalize_reuse(void *data) { mock_env *env = data; g_free(env); } static OSyncDebugGroup *_create_group4(char *testbed) { osync_trace(TRACE_ENTRY, "%s(%s)", __func__, testbed); OSyncDebugGroup *debug = g_malloc0(sizeof(OSyncDebugGroup)); OSyncError *error = NULL; debug->group = osync_group_new(&error); fail_unless(debug->group != NULL, NULL); fail_unless(error == NULL, NULL); debug->member1 = osync_member_new(&error); fail_unless(debug->member1 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member1); osync_member_set_pluginname(debug->member1, "mock-sync"); char *path = g_strdup_printf("%s/configs/group/1", testbed); osync_member_set_configdir(debug->member1, path); g_free(path); osync_member_set_start_type(debug->member1, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member1, "file"); osync_member_add_objtype(debug->member1, "contact"); osync_member_add_objtype(debug->member1, "note"); debug->member2 = osync_member_new(&error); fail_unless(debug->member2 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member2); osync_member_set_pluginname(debug->member2, "mock-sync"); path = g_strdup_printf("%s/configs/group/2", testbed); osync_member_set_configdir(debug->member2, path); g_free(path); osync_member_set_start_type(debug->member2, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member2, "file"); osync_member_add_objtype(debug->member2, "contact"); osync_member_add_objtype(debug->member2, "note"); debug->plugin = osync_plugin_new(&error); fail_unless(debug->plugin != NULL, NULL); fail_unless(error == NULL, NULL); osync_plugin_set_name(debug->plugin, "mock-sync"); osync_plugin_set_longname(debug->plugin, "Mock Sync Plugin"); osync_plugin_set_description(debug->plugin, "This is a pseudo plugin"); osync_plugin_set_initialize(debug->plugin, initialize_reuse); osync_plugin_set_finalize(debug->plugin, finalize_reuse); debug->client1 = osync_client_new(&error); fail_unless(debug->client1 != NULL, NULL); fail_unless(error == NULL, NULL); char *pipe_path = g_strdup_printf("%s/configs/group/1/pluginpipe", testbed); osync_client_run_external(debug->client1, pipe_path, debug->plugin, &error); g_free(pipe_path); debug->client2 = osync_client_new(&error); fail_unless(debug->client2 != NULL, NULL); fail_unless(error == NULL, NULL); pipe_path = g_strdup_printf("%s/configs/group/2/pluginpipe", testbed); osync_client_run_external(debug->client2, pipe_path, debug->plugin, &error); g_free(pipe_path); osync_trace(TRACE_EXIT, "%s: %p", __func__, debug); return debug; } START_TEST (engine_sync_reuse) { char *testbed = setup_testbed("sync_setup"); OSyncError *error = NULL; OSyncDebugGroup *debug = _create_group4(testbed); OSyncEngine *engine = osync_engine_new(debug->group, &error); fail_unless(engine != NULL, NULL); fail_unless(error == NULL, NULL); osync_engine_set_plugindir(engine, testbed); fail_unless(osync_engine_initialize(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_synchronize_and_block(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_synchronize_and_block(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_synchronize_and_block(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_finalize(engine, &error), NULL); fail_unless(error == NULL, NULL); _free_group(debug); osync_engine_unref(engine); destroy_testbed(testbed); } END_TEST START_TEST (engine_sync_stress) { int n = 1000; int i = 0; char *testbed = setup_testbed("sync_setup"); OSyncError *error = NULL; OSyncDebugGroup *debug = _create_group4(testbed); OSyncEngine *engine = osync_engine_new(debug->group, &error); fail_unless(engine != NULL, NULL); fail_unless(error == NULL, NULL); osync_engine_set_plugindir(engine, testbed); fail_unless(osync_engine_initialize(engine, &error), NULL); fail_unless(error == NULL, NULL); for (i = 0; i < n; i++) { fail_unless(osync_engine_synchronize_and_block(engine, &error), NULL); fail_unless(error == NULL, NULL); } fail_unless(osync_engine_finalize(engine, &error), NULL); fail_unless(error == NULL, NULL); _free_group(debug); osync_engine_unref(engine); destroy_testbed(testbed); } END_TEST static void connect5(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); g_atomic_int_inc(&(env->num_connect)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void disconnect5(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); g_atomic_int_inc(&(env->num_disconnect)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void get_changes5(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info); osync_assert(formatenv != NULL); OSyncObjFormat *format = osync_format_env_find_objformat(formatenv, "mockformat1"); osync_assert(format != NULL); OSyncError *error = NULL; OSyncChange *change = osync_change_new(&error); osync_assert(change != NULL); osync_assert(error == NULL); osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_ADDED); osync_change_set_uid(change, "uid"); OSyncFileFormat *file = osync_try_malloc0(sizeof(OSyncFileFormat), &error); osync_assert(file != NULL); file->path = g_strdup(osync_change_get_uid(change)); file->data = g_strdup_printf("%p", change); file->size = strlen(file->data); OSyncData *changedata = osync_data_new((char *)file, sizeof(OSyncFileFormat), format, &error); osync_data_set_objtype(changedata, "file"); osync_assert(changedata != NULL); osync_assert(error == NULL); osync_change_set_data(change, changedata); osync_data_unref(changedata); osync_context_report_change(ctx, change); g_atomic_int_inc(&(env->num_get_changes)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void commit_change5(void *data, OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *change) { mock_env *env = data; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, data, info, ctx, change); g_atomic_int_inc(&(env->num_commit_changes)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void *initialize5(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, info, error); mock_env *env = osync_try_malloc0(sizeof(mock_env), error); if (!env) goto error; OSyncObjTypeSink *sink = osync_objtype_sink_new("file", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "mockformat1"); OSyncObjTypeSinkFunctions functions; memset(&functions, 0, sizeof(functions)); functions.connect = connect5; functions.disconnect = disconnect5; functions.get_changes = get_changes5; functions.commit = commit_change5; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); osync_trace(TRACE_EXIT, "%s: %p", __func__, env); return (void *)env; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; } static void finalize5(void *data) { mock_env *env = data; osync_assert(env->num_connect == 1); osync_assert(env->num_disconnect == 1); osync_assert(env->num_get_changes == 1); osync_assert(env->num_commit_changes == 1); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_free(env); } static OSyncDebugGroup *_create_group5(char *testbed) { osync_trace(TRACE_ENTRY, "%s(%s)", __func__, testbed); OSyncDebugGroup *debug = g_malloc0(sizeof(OSyncDebugGroup)); OSyncError *error = NULL; debug->group = osync_group_new(&error); fail_unless(debug->group != NULL, NULL); fail_unless(error == NULL, NULL); debug->member1 = osync_member_new(&error); fail_unless(debug->member1 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member1); osync_member_set_pluginname(debug->member1, "mock-sync"); char *path = g_strdup_printf("%s/configs/group/1", testbed); osync_member_set_configdir(debug->member1, path); g_free(path); osync_member_set_start_type(debug->member1, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member1, "file"); debug->member2 = osync_member_new(&error); fail_unless(debug->member2 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member2); osync_member_set_pluginname(debug->member2, "mock-sync"); path = g_strdup_printf("%s/configs/group/2", testbed); osync_member_set_configdir(debug->member2, path); g_free(path); osync_member_set_start_type(debug->member2, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member2, "file"); osync_member_add_objtype(debug->member2, "contact"); osync_member_add_objtype(debug->member2, "note"); debug->plugin = osync_plugin_new(&error); fail_unless(debug->plugin != NULL, NULL); fail_unless(error == NULL, NULL); osync_plugin_set_name(debug->plugin, "mock-sync"); osync_plugin_set_longname(debug->plugin, "Mock Sync Plugin"); osync_plugin_set_description(debug->plugin, "This is a pseudo plugin"); osync_plugin_set_initialize(debug->plugin, initialize5); osync_plugin_set_finalize(debug->plugin, finalize5); debug->client1 = osync_client_new(&error); fail_unless(debug->client1 != NULL, NULL); fail_unless(error == NULL, NULL); char *pipe_path = g_strdup_printf("%s/configs/group/1/pluginpipe", testbed); osync_client_run_external(debug->client1, pipe_path, debug->plugin, &error); g_free(pipe_path); debug->client2 = osync_client_new(&error); fail_unless(debug->client2 != NULL, NULL); fail_unless(error == NULL, NULL); pipe_path = g_strdup_printf("%s/configs/group/2/pluginpipe", testbed); osync_client_run_external(debug->client2, pipe_path, debug->plugin, &error); g_free(pipe_path); osync_trace(TRACE_EXIT, "%s: %p", __func__, debug); return debug; } START_TEST (engine_sync_read_write) { char *testbed = setup_testbed("sync_setup"); OSyncError *error = NULL; OSyncDebugGroup *debug = _create_group5(testbed); OSyncEngine *engine = osync_engine_new(debug->group, &error); fail_unless(engine != NULL, NULL); fail_unless(error == NULL, NULL); osync_engine_set_plugindir(engine, testbed); osync_engine_set_formatdir(engine, testbed); fail_unless(osync_engine_initialize(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_synchronize_and_block(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_finalize(engine, &error), NULL); fail_unless(error == NULL, NULL); _free_group(debug); osync_engine_unref(engine); destroy_testbed(testbed); } END_TEST static void get_changes6(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; int i; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info); osync_assert(formatenv != NULL); OSyncObjFormat *format = osync_format_env_find_objformat(formatenv, "mockformat1"); osync_assert(format != NULL); OSyncError *error = NULL; for (i = 0; i < 1000; i++) { OSyncChange *change = osync_change_new(&error); osync_assert(change != NULL); osync_assert(error == NULL); osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_ADDED); char *uid = g_strdup_printf("uid%i", i); osync_change_set_uid(change, uid); g_free(uid); OSyncFileFormat *file = osync_try_malloc0(sizeof(OSyncFileFormat), &error); osync_assert(file != NULL); file->path = g_strdup(osync_change_get_uid(change)); file->data = g_strdup_printf("%p", change); file->size = strlen(file->data); OSyncData *changedata = osync_data_new((char *)file, sizeof(OSyncFileFormat), format, &error); osync_assert(changedata != NULL); osync_data_set_objtype(changedata, "file"); osync_assert(changedata != NULL); osync_assert(error == NULL); osync_change_set_data(change, changedata); osync_data_unref(changedata); osync_context_report_change(ctx, change); } g_atomic_int_inc(&(env->num_get_changes)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void *initialize6(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, info, error); mock_env *env = osync_try_malloc0(sizeof(mock_env), error); if (!env) goto error; OSyncObjTypeSink *sink = osync_objtype_sink_new("file", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "mockformat1"); OSyncObjTypeSinkFunctions functions; memset(&functions, 0, sizeof(functions)); functions.connect = connect5; functions.disconnect = disconnect5; functions.get_changes = get_changes6; functions.commit = commit_change5; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); osync_trace(TRACE_EXIT, "%s: %p", __func__, env); return (void *)env; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; } static void finalize6(void *data) { mock_env *env = data; osync_assert(env->num_connect == 1); osync_assert(env->num_disconnect == 1); osync_assert(env->num_get_changes == 1); osync_assert(env->num_commit_changes == 1000); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_free(env); } static OSyncDebugGroup *_create_group6(char *testbed) { osync_trace(TRACE_ENTRY, "%s(%s)", __func__, testbed); OSyncDebugGroup *debug = g_malloc0(sizeof(OSyncDebugGroup)); OSyncError *error = NULL; debug->group = osync_group_new(&error); fail_unless(debug->group != NULL, NULL); fail_unless(error == NULL, NULL); debug->member1 = osync_member_new(&error); fail_unless(debug->member1 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member1); osync_member_set_pluginname(debug->member1, "mock-sync"); char *path = g_strdup_printf("%s/configs/group/1", testbed); osync_member_set_configdir(debug->member1, path); g_free(path); osync_member_set_start_type(debug->member1, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member1, "file"); debug->member2 = osync_member_new(&error); fail_unless(debug->member2 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member2); osync_member_set_pluginname(debug->member2, "mock-sync"); path = g_strdup_printf("%s/configs/group/2", testbed); osync_member_set_configdir(debug->member2, path); g_free(path); osync_member_set_start_type(debug->member2, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member2, "file"); osync_member_add_objtype(debug->member2, "contact"); osync_member_add_objtype(debug->member2, "note"); debug->plugin = osync_plugin_new(&error); fail_unless(debug->plugin != NULL, NULL); fail_unless(error == NULL, NULL); osync_plugin_set_name(debug->plugin, "mock-sync"); osync_plugin_set_longname(debug->plugin, "Mock Sync Plugin"); osync_plugin_set_description(debug->plugin, "This is a pseudo plugin"); osync_plugin_set_initialize(debug->plugin, initialize6); osync_plugin_set_finalize(debug->plugin, finalize6); debug->client1 = osync_client_new(&error); fail_unless(debug->client1 != NULL, NULL); fail_unless(error == NULL, NULL); char *pipe_path = g_strdup_printf("%s/configs/group/1/pluginpipe", testbed); osync_client_run_external(debug->client1, pipe_path, debug->plugin, &error); g_free(pipe_path); debug->client2 = osync_client_new(&error); fail_unless(debug->client2 != NULL, NULL); fail_unless(error == NULL, NULL); pipe_path = g_strdup_printf("%s/configs/group/2/pluginpipe", testbed); osync_client_run_external(debug->client2, pipe_path, debug->plugin, &error); g_free(pipe_path); osync_trace(TRACE_EXIT, "%s: %p", __func__, debug); return debug; } START_TEST (engine_sync_read_write_stress) { char *testbed = setup_testbed("sync_setup"); OSyncError *error = NULL; OSyncDebugGroup *debug = _create_group6(testbed); OSyncEngine *engine = osync_engine_new(debug->group, &error); fail_unless(engine != NULL, NULL); fail_unless(error == NULL, NULL); osync_engine_set_plugindir(engine, testbed); osync_engine_set_formatdir(engine, testbed); fail_unless(osync_engine_initialize(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_synchronize_and_block(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_finalize(engine, &error), NULL); fail_unless(error == NULL, NULL); _free_group(debug); osync_engine_unref(engine); destroy_testbed(testbed); } END_TEST static void get_changes7(void *data, OSyncPluginInfo *info, OSyncContext *ctx) { mock_env *env = data; int i; osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, info, ctx); OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info); osync_assert(formatenv != NULL); OSyncObjFormat *format = osync_format_env_find_objformat(formatenv, "mockformat1"); osync_assert(format != NULL); OSyncError *error = NULL; for (i = 0; i < 2; i++) { OSyncChange *change = osync_change_new(&error); osync_assert(change != NULL); osync_assert(error == NULL); osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_ADDED); char *uid = g_strdup_printf("uid%i", i); osync_change_set_uid(change, uid); g_free(uid); OSyncFileFormat *file = osync_try_malloc0(sizeof(OSyncFileFormat), &error); osync_assert(file != NULL); file->path = g_strdup(osync_change_get_uid(change)); file->data = g_strdup_printf("%p", change); file->size = strlen(file->data); OSyncData *changedata = osync_data_new((char *)file, sizeof(OSyncFileFormat), format, &error); osync_assert(changedata != NULL); osync_data_set_objtype(changedata, "file"); osync_assert(changedata != NULL); osync_assert(error == NULL); osync_change_set_data(change, changedata); osync_data_unref(changedata); osync_context_report_change(ctx, change); osync_change_unref(change); osync_data_unref(data); } g_atomic_int_inc(&(env->num_get_changes)); osync_context_report_success(ctx); osync_trace(TRACE_EXIT, "%s", __func__); } static void *initialize7(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) { osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, info, error); mock_env *env = osync_try_malloc0(sizeof(mock_env), error); if (!env) goto error; OSyncObjTypeSink *sink = osync_objtype_sink_new("file", error); if (!sink) goto error; osync_objtype_sink_add_objformat(sink, "mockformat1"); OSyncObjTypeSinkFunctions functions; memset(&functions, 0, sizeof(functions)); functions.connect = connect5; functions.disconnect = disconnect5; functions.get_changes = get_changes7; functions.commit = commit_change5; osync_objtype_sink_set_functions(sink, functions, NULL); osync_plugin_info_add_objtype(info, sink); osync_objtype_sink_unref(sink); osync_trace(TRACE_EXIT, "%s: %p", __func__, env); return (void *)env; error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return NULL; } static void finalize7(void *data) { mock_env *env = data; osync_assert(env->num_connect == 1); osync_assert(env->num_disconnect == 1); osync_assert(env->num_get_changes == 1); osync_assert(env->num_commit_changes == 2); osync_assert(env->main_connect == 0); osync_assert(env->main_disconnect == 0); osync_assert(env->main_get_changes == 0); g_free(env); } static OSyncDebugGroup *_create_group7(char *testbed) { osync_trace(TRACE_ENTRY, "%s(%s)", __func__, testbed); OSyncDebugGroup *debug = g_malloc0(sizeof(OSyncDebugGroup)); OSyncError *error = NULL; debug->group = osync_group_new(&error); fail_unless(debug->group != NULL, NULL); fail_unless(error == NULL, NULL); debug->member1 = osync_member_new(&error); fail_unless(debug->member1 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member1); osync_member_set_pluginname(debug->member1, "mock-sync"); char *path = g_strdup_printf("%s/configs/group/1", testbed); osync_member_set_configdir(debug->member1, path); g_free(path); osync_member_set_start_type(debug->member1, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member1, "file"); debug->member2 = osync_member_new(&error); fail_unless(debug->member2 != NULL, NULL); fail_unless(error == NULL, NULL); osync_group_add_member(debug->group, debug->member2); osync_member_set_pluginname(debug->member2, "mock-sync"); path = g_strdup_printf("%s/configs/group/2", testbed); osync_member_set_configdir(debug->member2, path); g_free(path); osync_member_set_start_type(debug->member2, OSYNC_START_TYPE_EXTERNAL); osync_member_add_objtype(debug->member2, "file"); osync_member_add_objtype(debug->member2, "contact"); osync_member_add_objtype(debug->member2, "note"); debug->plugin = osync_plugin_new(&error); fail_unless(debug->plugin != NULL, NULL); fail_unless(error == NULL, NULL); osync_plugin_set_name(debug->plugin, "mock-sync"); osync_plugin_set_longname(debug->plugin, "Mock Sync Plugin"); osync_plugin_set_description(debug->plugin, "This is a pseudo plugin"); osync_plugin_set_initialize(debug->plugin, initialize7); osync_plugin_set_finalize(debug->plugin, finalize7); debug->client1 = osync_client_new(&error); fail_unless(debug->client1 != NULL, NULL); fail_unless(error == NULL, NULL); char *pipe_path = g_strdup_printf("%s/configs/group/1/pluginpipe", testbed); osync_client_run_external(debug->client1, pipe_path, debug->plugin, &error); g_free(pipe_path); debug->client2 = osync_client_new(&error); fail_unless(debug->client2 != NULL, NULL); fail_unless(error == NULL, NULL); pipe_path = g_strdup_printf("%s/configs/group/2/pluginpipe", testbed); osync_client_run_external(debug->client2, pipe_path, debug->plugin, &error); g_free(pipe_path); osync_trace(TRACE_EXIT, "%s: %p", __func__, debug); return debug; } START_TEST (engine_sync_read_write_stress2) { char *testbed = setup_testbed("sync_setup"); OSyncError *error = NULL; OSyncDebugGroup *debug = _create_group7(testbed); OSyncEngine *engine = osync_engine_new(debug->group, &error); fail_unless(engine != NULL, NULL); fail_unless(error == NULL, NULL); osync_engine_set_plugindir(engine, testbed); osync_engine_set_formatdir(engine, testbed); fail_unless(osync_engine_initialize(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_synchronize_and_block(engine, &error), NULL); fail_unless(error == NULL, NULL); fail_unless(osync_engine_finalize(engine, &error), NULL); fail_unless(error == NULL, NULL); _free_group(debug); osync_engine_unref(engine); destroy_testbed(testbed); } END_TEST Suite *engine_suite(void) { Suite *s = suite_create("Engine"); // Suite *s2 = suite_create("Engine"); create_case(s, "engine_new", engine_new); create_case(s, "engine_init", engine_init); create_case(s, "engine_sync", engine_sync); create_case(s, "engine_sync_multi_obj", engine_sync_multi_obj); create_case(s, "engine_sync_out_of_order", engine_sync_out_of_order); create_case(s, "engine_sync_reuse", engine_sync_reuse); // This test cases would timeout within 30seconds (default timeout) - at least if OSYNC_TRACE is enabled -> higher timeout create_case_timeout(s, "engine_sync_stress", engine_sync_stress, 60); create_case_timeout(s, "engine_sync_read_write_stress", engine_sync_read_write_stress, 300); // FIXME: Deadlocks create_case(s, "engine_sync_read_write", engine_sync_read_write); // FIXME: DEADlocks create_case(s, "engine_sync_read_write_stress2", engine_sync_read_write_stress2); // FIXME: DEADlocks //batch commit //connect problem //get_changes problem return s; } int main(void) { int nf; Suite *s = engine_suite(); SRunner *sr; sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); nf = srunner_ntests_failed(sr); srunner_free(sr); return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE; }