#include "support.h"
char *olddir = NULL;
static void reset_env(void)
{
unsetenv("CONNECT_ERROR");
unsetenv("CONNECT_TIMEOUT");
unsetenv("INIT_NULL");
unsetenv("GET_CHANGES_ERROR");
unsetenv("GET_CHANGES_TIMEOUT");
unsetenv("GET_CHANGES_TIMEOUT2");
unsetenv("COMMIT_ERROR");
unsetenv("COMMIT_TIMEOUT");
unsetenv("SYNC_DONE_ERROR");
unsetenv("SYNC_DONE_TIMEOUT");
unsetenv("DISCONNECT_ERROR");
unsetenv("DISCONNECT_TIMEOUT");
}
char *setup_testbed(char *fkt_name)
{
setuid(65534);
char *testbed = g_strdup_printf("%s/testbed.XXXXXX", g_get_tmp_dir());
mkdtemp(testbed);
char *command = NULL;
if (fkt_name) {
command = g_strdup_printf("cp -R "OPENSYNC_TESTDATA"data/%s/* %s", fkt_name, testbed);
if (system(command))
abort();
g_free(command);
}
command = g_strdup_printf("cp -R ../osplugin/osplugin %s", testbed);
if (system(command))
abort();
g_free(command);
command = g_strdup_printf("cp -R mock-plugin/.libs/*.so %s", testbed);
if (system(command))
abort();
g_free(command);
command = g_strdup_printf("cp -R ../formats/.libs/*.so %s", testbed);
if (system(command))
abort();
g_free(command);
command = g_strdup_printf("cp -R ../formats/vformats-xml/.libs/*.so %s", testbed);
if (system(command))
abort();
g_free(command);
command = g_strdup_printf("chmod -R 700 %s", testbed);
if (system(command))
abort();
g_free(command);
olddir = g_get_current_dir();
if (chdir(testbed))
abort();
osync_trace(TRACE_INTERNAL, "Seting up %s at %s", fkt_name, testbed);
// printf(".");
// fflush(NULL);
// fflush(stderr);
reset_env();
return testbed;
}
void destroy_testbed(char *path)
{
char *command = g_strdup_printf("rm -rf %s", path);
if (olddir)
chdir(olddir);
system(command);
g_free(command);
osync_trace(TRACE_INTERNAL, "Tearing down %s", path);
g_free(path);
}
void conflict_handler_choose_first(OSyncEngine *engine, OSyncMapping *mapping, void *user_data)
{
num_conflicts++;
fail_unless(osengine_mapping_num_changes(mapping) == GPOINTER_TO_INT(user_data), NULL);
fail_unless(num_engine_end_conflicts == 0, NULL);
OSyncChange *change = osengine_mapping_nth_change(mapping, 0);
osengine_mapping_solve(engine, mapping, change);
}
void conflict_handler_choose_modified(OSyncEngine *engine, OSyncMapping *mapping, void *user_data)
{
num_conflicts++;
fail_unless(osengine_mapping_num_changes(mapping) == GPOINTER_TO_INT(user_data), NULL);
fail_unless(num_engine_end_conflicts == 0, NULL);
int i;
for (i = 0; i < osengine_mapping_num_changes(mapping); i++) {
OSyncChange *change = osengine_mapping_nth_change(mapping, i);
if (change->changetype == CHANGE_MODIFIED) {
osengine_mapping_solve(engine, mapping, change);
return;
}
}
fail();
}
void conflict_handler_choose_deleted(OSyncEngine *engine, OSyncMapping *mapping, void *user_data)
{
num_conflicts++;
fail_unless(osengine_mapping_num_changes(mapping) == GPOINTER_TO_INT(user_data), NULL);
fail_unless(num_engine_end_conflicts == 0, NULL);
int i;
for (i = 0; i < osengine_mapping_num_changes(mapping); i++) {
OSyncChange *change = osengine_mapping_nth_change(mapping, i);
if (change->changetype == CHANGE_DELETED) {
osengine_mapping_solve(engine, mapping, change);
return;
}
}
fail(NULL);
}
void conflict_handler_duplication(OSyncEngine *engine, OSyncMapping *mapping, void *user_data)
{
num_conflicts++;
fail_unless(osengine_mapping_num_changes(mapping) == GPOINTER_TO_INT(user_data), NULL);
fail_unless(num_engine_end_conflicts == 0, NULL);
osengine_mapping_duplicate(engine, mapping);
}
void conflict_handler_ignore(OSyncEngine *engine, OSyncMapping *mapping, void *user_data)
{
num_conflicts++;
if (user_data)
fail_unless(osengine_mapping_num_changes(mapping) == GPOINTER_TO_INT(user_data), NULL);
fail_unless(num_engine_end_conflicts == 0, NULL);
OSyncError *error = NULL;
fail_unless(osengine_mapping_ignore_conflict(engine, mapping, &error), NULL);
fail_unless(error == NULL, NULL);
}
void conflict_handler_random(OSyncEngine *engine, OSyncMapping *mapping, void *user_data)
{
num_conflicts++;
fail_unless(osengine_mapping_num_changes(mapping) == GPOINTER_TO_INT(user_data), NULL);
fail_unless(num_engine_end_conflicts == 0, NULL);
int num = osengine_mapping_num_changes(mapping);
int choosen = g_random_int_range(0, num);
OSyncChange *change = osengine_mapping_nth_change(mapping, choosen);
osengine_mapping_solve(engine, mapping, change);
}
static void solve_conflict(OSyncMapping *mapping)
{
sleep(5);
OSyncEngine *engine = mapping->table->engine;
int i;
for (i = 0; i < osengine_mapping_num_changes(mapping); i++) {
OSyncChange *change = osengine_mapping_nth_change(mapping, i);
if (change->changetype == CHANGE_MODIFIED) {
osengine_mapping_solve(engine, mapping, change);
return;
}
}
}
void conflict_handler_delay(OSyncEngine *engine, OSyncMapping *mapping, void *user_data)
{
num_conflicts++;
fail_unless(osengine_mapping_num_changes(mapping) == GPOINTER_TO_INT(user_data), NULL);
fail_unless(num_engine_end_conflicts == 0, NULL);
g_thread_create ((GThreadFunc)solve_conflict, mapping, TRUE, NULL);
}
void entry_status(OSyncEngine *engine, OSyncChangeUpdate *status, void *user_data)
{
switch (status->type) {
case CHANGE_RECEIVED:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
num_read++;
break;
case CHANGE_RECEIVED_INFO:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
num_read_info++;
break;
case CHANGE_SENT:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
num_written++;
break;
case CHANGE_WRITE_ERROR:
fail_unless(osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "CHANGE_WRITE_ERROR: %s", status->error->message);
num_written_errors++;
break;
case CHANGE_RECV_ERROR:
fail_unless(osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "CHANGE_RECV_ERROR: %s", status->error->message);
num_recv_errors++;
break;
}
}
void member_status(OSyncMemberUpdate *status, void *user_data)
{
mark_point();
switch (status->type) {
case MEMBER_CONNECTED:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
num_connected++;
break;
case MEMBER_DISCONNECTED:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
num_disconnected++;
break;
case MEMBER_SENT_CHANGES:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
num_member_sent_changes++;
break;
case MEMBER_COMMITTED_ALL:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
num_member_comitted_all++;
break;
case MEMBER_CONNECT_ERROR:
fail_unless(osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "MEMBER_CONNECT_ERROR: %s", status->error->message);
num_member_connect_errors++;
break;
case MEMBER_GET_CHANGES_ERROR:
fail_unless(osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "MEMBER_CONNECT_ERROR: %s", status->error->message);
num_member_get_changes_errors++;
break;
case MEMBER_SYNC_DONE_ERROR:
fail_unless(osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "MEMBER_SYNC_DONE_ERROR: %s", status->error->message);
num_member_sync_done_errors++;
break;
case MEMBER_DISCONNECT_ERROR:
fail_unless(osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "MEMBER_DISCONNECT_ERROR: %s", status->error->message);
num_member_disconnect_errors++;
break;
case MEMBER_COMMITTED_ALL_ERROR:
fail_unless(osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "MEMBER_COMMITTED_ALL_ERROR: %s", status->error->message);
num_member_comitted_all_errors++;
break;
}
}
void engine_status(OSyncEngine *engine, OSyncEngineUpdate *status, void *user_data)
{
switch (status->type) {
case ENG_ENDPHASE_CON:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "All clients connected or error");
num_engine_connected++;
break;
case ENG_ENDPHASE_READ:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "All clients sent changes or error");
num_engine_read++;
break;
case ENG_ENDPHASE_WRITE:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "All clients have writen");
num_engine_wrote++;
break;
case ENG_ENDPHASE_DISCON:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "All clients have disconnected");
num_engine_disconnected++;
break;
case ENG_ERROR:
fail_unless(osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "ENG_ERROR: %s", status->error->message);
num_engine_errors++;
break;
case ENG_SYNC_SUCCESSFULL:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "Sync Successfull");
num_engine_successfull++;
break;
case ENG_PREV_UNCLEAN:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "Previous sync was unclean");
num_engine_prev_unclean++;
break;
case ENG_END_CONFLICTS:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "End conflicts");
num_engine_end_conflicts++;
break;
}
}
void mapping_status(OSyncMappingUpdate *status, void *user_data)
{
switch (status->type) {
case MAPPING_SOLVED:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "Mapping solved");
break;
case MAPPING_SYNCED:
fail_unless(!osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "Mapping Synced");
break;
case MAPPING_WRITE_ERROR:
fail_unless(osync_error_is_set(&(status->error)), NULL);
osync_debug("TEST", 4, "MAPPING_WRITE_ERROR: %s", status->error->message);
num_mapping_errors++;
break;
}
}
OSyncEngine *init_engine(OSyncGroup *group)
{
OSyncError *error = NULL;
OSyncEngine *engine = osengine_new(group, &error);
osengine_set_enginestatus_callback(engine, engine_status, NULL);
osengine_set_memberstatus_callback(engine, member_status, NULL);
osengine_set_mappingstatus_callback(engine, mapping_status, NULL);
osengine_set_changestatus_callback(engine, entry_status, NULL);
mark_point();
fail_unless(engine != NULL, NULL);
fail_unless(osengine_init(engine, &error), NULL);
return engine;
}
osync_bool synchronize_once(OSyncEngine *engine, OSyncError **error)
{
num_connected = 0;
num_disconnected = 0;
num_conflicts = 0;
num_written = 0;
num_read = 0;
num_read_info = 0;
num_member_connect_errors = 0;
num_member_sent_changes = 0;
num_engine_errors = 0;
num_engine_successfull = 0;
num_member_get_changes_errors = 0;
num_written_errors = 0;
num_mapping_errors = 0;
num_member_sync_done_errors = 0;
num_member_disconnect_errors = 0;
num_engine_prev_unclean = 0;
num_engine_end_conflicts = 0;
num_engine_connected = 0;
num_engine_read = 0;
num_engine_wrote = 0;
num_engine_disconnected = 0;
num_member_comitted_all_errors = 0;
num_recv_errors = 0;
num_member_comitted_all = 0;
mark_point();
return osengine_sync_and_block(engine, error);
}
/*needed because of an incompatible API change in 0.94*/
#if CHECK_VERSION <= 903
void create_case(Suite *s, const char *name, void (*function)(void))
#else /*CHECK_VERSION > 903*/
void create_case(Suite *s, const char *name, void (*function)(int))
#endif /*CHECK_VERSION*/
{
TCase *tc_new = tcase_create(name);
tcase_set_timeout(tc_new, 30);
suite_add_tcase (s, tc_new);
tcase_add_test(tc_new, function);
}
OSyncMappingTable *mappingtable_load(OSyncGroup *group, int num_mappings, int num_unmapped)
{
osync_trace(TRACE_ENTRY, "%s(%p, %i, %i)", __func__, group, num_mappings, num_unmapped);
mark_point();
OSyncEnv *osync = init_env();
OSyncGroup *newgroup = osync_group_load(osync, "configs/group", NULL);
OSyncMappingTable *maptable = _osengine_mappingtable_load_group(newgroup);
mark_point();
fail_unless(g_list_length(maptable->mappings) == num_mappings, NULL);
fail_unless(g_list_length(maptable->unmapped) == num_unmapped, NULL);
osync_trace(TRACE_EXIT, "%s: %p", __func__, maptable);
return maptable;
}
void mappingtable_close(OSyncMappingTable *maptable)
{
osync_trace(TRACE_ENTRY, "%s(%p)", __func__, maptable);
osengine_mappingtable_close(maptable);
osync_trace(TRACE_EXIT, "%s", __func__);
}
void check_mapping(OSyncMappingTable *maptable, int memberid, int mappingid, int numentries, const char *uid, const char *format, const char *objecttype)
{
osync_trace(TRACE_ENTRY, "%s(%p, %i, %i, %i, %s, %s, %s)", __func__, maptable, memberid, mappingid, numentries, uid, format, objecttype);
OSyncMapping *mapping = NULL;
mark_point();
OSyncMember *member = osync_member_from_id(maptable->group, memberid);
OSyncMappingView *view = osengine_mappingtable_find_view(maptable, member);
mark_point();
if (mappingid != -1) {
mapping = g_list_nth_data(maptable->mappings, mappingid);
} else {
GList *m;
for (m = maptable->mappings; m; m = m->next) {
mapping = m->data;
OSyncMappingEntry *entry = osengine_mapping_find_entry(mapping, NULL, view);
if (!entry)
continue;
OSyncChange *change = entry->change;
fail_unless(change != NULL, NULL);
if (!strcmp(osync_change_get_uid(change), uid))
break;
}
}
fail_unless(mapping != NULL, NULL);
fail_unless(osengine_mapping_num_changes(mapping) == numentries, "osengine_mapping_num_changes(mapping) == numentries for %s, %i: %i != %i", uid, memberid, osengine_mapping_num_changes(mapping), numentries);
mark_point();
OSyncChange *change = osengine_mapping_find_entry(mapping, NULL, view)->change;
fail_unless(change != NULL, NULL);
if (format)
fail_unless(!strcmp(osync_objformat_get_name(osync_change_get_objformat(change)), format), NULL);
if (objecttype)
fail_unless(!strcmp(osync_objtype_get_name(osync_change_get_objtype(change)), objecttype), NULL);
if (uid && strcmp(osync_change_get_uid(change), uid)) {
printf("uid mismatch: %s != %s for member %i and mapping %i\n", osync_change_get_uid(change), uid, memberid, mappingid);
fail("uid mismatch");
}
osync_trace(TRACE_EXIT, "%s", __func__);
}
OSyncHashTable *hashtable_load(OSyncGroup *group, int memberid, int entries)
{
mark_point();
OSyncMember *member = osync_member_from_id(group, memberid);
mark_point();
OSyncHashTable *table = osync_hashtable_new();
mark_point();
fail_unless(osync_hashtable_load(table, member, NULL), NULL);
mark_point();
fail_unless(osync_hashtable_num_entries(table) == entries, NULL);
return table;
}
void check_hash(OSyncHashTable *table, const char *cmpuid)
{
char *uid = NULL;
char *hash = NULL;
int i;
osync_bool found = FALSE;
for (i = 0; i < osync_hashtable_num_entries(table); i++) {
osync_hashtable_nth_entry(table, i, &uid, &hash);
if (!strcmp(cmpuid, uid))
found = TRUE;
}
fail_unless(found == TRUE, NULL);
}
static void load_format(OSyncEnv *env, const char *name)
{
OSyncError *error = NULL;
char *path = g_strdup_printf("%s/%s", g_get_current_dir(), name);
fail_unless(osync_module_load(env, path, &error), NULL);
g_free(path);
}
OSyncEnv *init_env(void)
{
mark_point();
OSyncEnv *osync = osync_env_new();
mark_point();
osync_env_set_option(osync, "LOAD_GROUPS", "FALSE");
osync_env_set_option(osync, "LOAD_FORMATS", "FALSE");
osync_env_set_option(osync, "LOAD_PLUGINS", "FALSE");
mark_point();
OSyncError *error = NULL;
fail_unless(osync_env_initialize(osync, &error), NULL);
fail_unless(!osync_error_is_set(&error), NULL);
char *path = g_strdup_printf("%s/%s", g_get_current_dir(), "mock_sync.so");
fail_unless(osync_module_load(osync, path, &error), NULL);
g_free(path);
load_format(osync, "contact.so");
load_format(osync, "data.so");
load_format(osync, "event.so");
load_format(osync, "note.so");
load_format(osync, "todo.so");
load_format(osync, "xml-vcal.so");
load_format(osync, "xml-vcard.so");
load_format(osync, "xml-vnote.so");
load_format(osync, "xml-evolution.so");
load_format(osync, "xml-kde.so");
load_format(osync, "mockformat.so");
return osync;
}
OSyncEnv *init_env_none(void)
{
mark_point();
OSyncEnv *osync = osync_env_new();
mark_point();
osync_env_set_option(osync, "LOAD_GROUPS", "FALSE");
osync_env_set_option(osync, "LOAD_FORMATS", "FALSE");
osync_env_set_option(osync, "LOAD_PLUGINS", "FALSE");
mark_point();
OSyncError *error = NULL;
fail_unless(osync_env_initialize(osync, &error), NULL);
fail_unless(!osync_error_is_set(&error), NULL);
return osync;
}
syntax highlighted by Code2HTML, v. 0.9.1