Timeout merge complete
[opensync.git] / tools / osynctest.c
blobb2862f646f3ed66c86457e6781b4b741248ac81c
1 #include <opensync/opensync.h>
2 #include "engine.h"
3 #include "engine_internals.h"
4 #include <errno.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/types.h>
9 #include <sys/wait.h>
10 #include <glib.h>
11 #include <sys/time.h>
13 GMutex *working;
14 GMutex *working2;
15 GList *changes;
16 GList *tests;
17 osync_bool alwaysempty;
18 osync_bool noaccess = FALSE;
20 typedef struct OSyncPluginTest {
21 char *name;
22 double (*test)(OSyncEngine *engine, OSyncMember *file, int num, const char *);
23 double alltime;
24 double connecttime;
25 double readtime;
26 double writetime;
27 double othertime;
28 int num;
29 } OSyncPluginTest;
31 static void usage (char *name, int ecode)
33 fprintf (stderr, "Usage: %s <pluginname>\n", name);
34 fprintf (stderr, "--config <filename>\tSet the config file to use\n");
35 fprintf (stderr, "--type <object type>\tSets the objtype to test\n");
36 fprintf (stderr, "--empty\tOnly deleta all data. Do not test\n");
37 exit (ecode);
40 gboolean only_random = FALSE;
41 char *localdir = NULL;
43 static void sync_now(OSyncEngine *engine)
45 OSyncError *error = NULL;
46 printf(".");
47 fflush(stdout);
49 if (!osengine_sync_and_block(engine, &error)) {
50 printf("Error while starting synchronization: %s\n", osync_error_print(&error));
51 osync_error_unref(&error);
52 exit(1);
55 printf(".");
56 fflush(stdout);
59 static void check_empty(void)
61 printf(".");
62 fflush(stdout);
63 char *command = g_strdup_printf("test \"x$(ls %s)\" = \"x\"", localdir);
64 int ret = system(command);
65 g_free(command);
66 if (ret)
67 abort();
68 printf(".");
69 fflush(stdout);
72 double starttime;
73 double currenttime;
75 double connecttime;
76 double readtime;
77 double writetime;
79 double _second() /* note that some compilers like AIX xlf do not require the trailing '_' */
81 struct timeval tp;
82 int rtn;
83 rtn=gettimeofday(&tp, NULL);
85 return ((double)tp.tv_sec+(1.e-6)*tp.tv_usec);
88 void engine_status(OSyncEngine *engine, OSyncEngineUpdate *status, void *user_data)
90 switch (status->type) {
91 case ENG_ENDPHASE_CON:
92 osync_trace(TRACE_INTERNAL, "++++++++++++++++ Connection Phase ended ++++++++++++++");
93 currenttime = _second();
94 connecttime = currenttime - starttime;
95 break;
96 case ENG_ENDPHASE_READ:
97 osync_trace(TRACE_INTERNAL, "++++++++++++++++ Read Phase ended ++++++++++++++");
98 readtime = _second() - currenttime;
99 currenttime = _second();
100 break;
101 case ENG_ENDPHASE_WRITE:
102 osync_trace(TRACE_INTERNAL, "++++++++++++++++ Write Phase ended ++++++++++++++");
103 writetime = _second() - currenttime;
104 currenttime = _second();
105 break;
106 default:
111 double check_sync(OSyncEngine *engine, const char *name, int num)
113 int ret;
114 printf(".");
115 fflush(stdout);
116 starttime = _second();
117 osync_trace(TRACE_INTERNAL, "++++++++++++++++ Test \"%s %i\" starting ++++++++++++++", name, num);
118 osengine_set_enginestatus_callback(engine, engine_status, NULL);
119 sync_now(engine);
120 osengine_set_enginestatus_callback(engine, NULL, NULL);
121 int wasted = 0;
122 int alldeciders = 0;
123 osengine_get_wasted(engine, &alldeciders, &wasted);
124 osync_trace(TRACE_INTERNAL, "++++++++++++++++ Test \"%s %i\" ended (%i / %i (%i%%)) ++++++++++++++", name, num, wasted, alldeciders, (int)(((float)wasted / (float)alldeciders) * 100));
125 double thistime = _second() - starttime;
127 printf(".");
128 fflush(stdout);
130 char *tempdir = g_strdup_printf("%s/plgtest.XXXXXX", g_get_tmp_dir());
131 if (!mkdtemp(tempdir))
133 g_free(tempdir);
134 osync_trace(TRACE_INTERNAL, "unable to create temporary dir: %s", g_strerror(errno));
135 abort();
137 char *command = g_strdup_printf("mv %s/* %s &> /dev/null", localdir, tempdir);
138 ret = system(command);
139 if (ret)
141 g_free(tempdir);
142 g_free(command);
143 osync_trace(TRACE_INTERNAL, "Unable to move files to temporary dir: %d", ret);
144 abort();
146 g_free(command);
147 printf(".");
148 fflush(stdout);
150 check_empty();
152 printf(".");
153 fflush(stdout);
155 osync_group_set_slow_sync(engine->group, "data", TRUE);
157 sync_now(engine);
158 printf(".");
159 fflush(stdout);
160 command = g_strdup_printf("test \"x$(diff -x \".*\" %s %s)\" = \"x\"", localdir, tempdir);
161 int result = system(command);
162 g_free(command);
164 g_free(tempdir);
165 if (result)
166 abort();
168 printf(" success\n");
169 return thistime;
172 void add_data(OSyncMember *member, const char *objtype)
174 OSyncChange *change = osync_change_new();
175 if (!osync_member_make_random_data(member, change, objtype)) {
176 printf("Unable to create random data\n");
177 abort();
180 char *filename = NULL;
181 while (1) {
182 char *randstr = osync_rand_str(8);
183 filename = g_strdup_printf("%s/%s", localdir, randstr);
184 g_free(randstr);
185 char *command = g_strdup_printf("ls %s &> /dev/null", filename);
186 int ret = system(command);
187 g_free(command);
188 if (ret)
189 break;
190 g_free(filename);
193 OSyncError *error = NULL;
194 if (!osync_file_write(filename, osync_change_get_data(change), osync_change_get_datasize(change), 0700, &error)) {
195 printf("Unable to write to file %s\n", osync_error_print(&error));
196 abort();
198 g_free(filename);
201 void modify_data(OSyncMember *member, const char *objtype)
203 GDir *dir;
204 GError *gerror = NULL;
206 dir = g_dir_open(localdir, 0, &gerror);
207 if (!dir)
208 abort();
210 const char *de = NULL;
211 while ((de = g_dir_read_name(dir))) {
212 char *filename = g_build_filename(localdir, de, NULL);
214 OSyncChange *change = osync_change_new();
215 if (!osync_member_make_random_data(member, change, objtype)) {
216 printf("Unable to create random data\n");
217 abort();
220 OSyncError *error = NULL;
221 if (!osync_file_write(filename, osync_change_get_data(change), osync_change_get_datasize(change), 0700, &error)) {
222 printf("Unable to write to file %s\n", osync_error_print(&error));
223 abort();
226 g_free(filename);
228 g_dir_close(dir);
232 void delete_data(OSyncMember *member, const char *objtype)
234 char *command = g_strdup_printf("rm -f %s/*", localdir);
235 int ret = system(command);
236 if (ret)
238 osync_trace(TRACE_INTERNAL, "Unable to delete data: %d", ret);
239 abort();
241 g_free(command);
244 static void empty_all(OSyncEngine *engine)
246 printf(".");
247 fflush(stdout);
249 osync_group_set_slow_sync(engine->group, "data", TRUE);
250 sync_now(engine);
252 char *command = g_strdup_printf("rm -f %s/*", localdir);
253 int ret = system(command);
254 if (ret)
256 osync_trace(TRACE_INTERNAL, "Unable to delete data: %d", ret);
257 abort();
259 g_free(command);
260 sync_now(engine);
262 printf(".");
263 fflush(stdout);
265 check_empty();
269 double add_test(OSyncEngine *engine, OSyncMember *member, int num, const char *objtype)
271 printf("Test \"Add %i\" starting", num);
272 fflush(stdout);
274 empty_all(engine);
276 printf(".");
277 fflush(stdout);
278 int i = 0;
279 for (i = 0; i < num; i++)
280 add_data(member, objtype);
281 printf(".");
282 fflush(stdout);
284 return check_sync(engine, "Add", num);
287 double modify_test(OSyncEngine *engine, OSyncMember *member, int num, const char *objtype)
289 printf("Test \"Modify %i\" starting", num);
290 fflush(stdout);
292 empty_all(engine);
294 printf(".");
295 fflush(stdout);
296 int i = 0;
297 for (i = 0; i < num; i++)
298 add_data(member, objtype);
299 printf(".");
300 fflush(stdout);
302 check_sync(engine, "None", num);
304 printf(".");
305 fflush(stdout);
306 modify_data(member, objtype);
307 printf(".");
308 fflush(stdout);
310 return check_sync(engine, "Modify", num);
313 double delete_test(OSyncEngine *engine, OSyncMember *member, int num, const char *objtype)
315 printf("Test \"Delete %i\" starting", num);
316 fflush(stdout);
318 empty_all(engine);
320 printf(".");
321 fflush(stdout);
322 int i = 0;
323 for (i = 0; i < num; i++)
324 add_data(member, objtype);
325 printf(".");
326 fflush(stdout);
328 check_sync(engine, "None", num);
330 printf(".");
331 fflush(stdout);
332 delete_data(member, objtype);
333 printf(".");
334 fflush(stdout);
336 return check_sync(engine, "Delete", num);
339 static void run_all_tests(OSyncEngine *engine, OSyncMember *file, OSyncMember *target, const char *objtype)
342 GList *t;
343 for (t = tests; t; t = t->next) {
344 OSyncPluginTest *test = t->data;
345 test->alltime = test->test(engine, target, test->num, objtype);
346 test->connecttime = connecttime;
347 test->readtime = readtime;
348 test->writetime = writetime;
349 test->othertime = test->alltime - test->connecttime - test->readtime - test->writetime;
352 printf("\nOutcome:\n");
354 for (t = tests; t; t = t->next) {
355 OSyncPluginTest *test = t->data;
356 printf("Test \"%s\": All: %f Connect: %f(%i%%) Read: %f(%i%%) Write: %f(%i%%) Other: %f(%i%%)\n", test->name, test->alltime, test->connecttime, (int)((test->connecttime / test->alltime)* 100), test->readtime, (int)((test->readtime / test->alltime)* 100), test->writetime, (int)((test->writetime / test->alltime)* 100), test->othertime, (int)((test->othertime / test->alltime)* 100));
360 static void register_test(const char *name, double test(OSyncEngine *engine, OSyncMember *file, int num, const char *), int num)
362 OSyncPluginTest *newtest = g_malloc0(sizeof(OSyncPluginTest));
363 newtest->name = g_strdup(name);
364 newtest->test = test;
365 newtest->num = num;
366 tests = g_list_append(tests, newtest);
369 static void register_tests(void)
371 tests = NULL;
372 /*register_test("add_test1", add_test, 1);
373 register_test("add_test5", add_test, 5);
374 register_test("add_test10", add_test, 10);
375 register_test("add_test20", add_test, 20);*/
376 /*register_test("add_test50", add_test, 50);
377 register_test("add_test100", add_test, 100);
378 register_test("add_test200", add_test, 200);*/
380 /*register_test("modify_test1", modify_test, 1);
381 register_test("modify_test5", modify_test, 5);
382 register_test("modify_test10", modify_test, 10);
383 register_test("modify_test20", modify_test, 20);
384 register_test("modify_test50", modify_test, 50);*/
385 register_test("modify_test100", modify_test, 100);
386 //register_test("modify_test200", modify_test, 200);
388 /*register_test("delete_test1", delete_test, 1);
389 register_test("delete_test5", delete_test, 5);
390 register_test("delete_test10", delete_test, 10);
391 register_test("delete_test20", delete_test, 20);
392 register_test("delete_test50", delete_test, 50);*/
393 //register_test("delete_test100", delete_test, 100);
394 //register_test("delete_test200", delete_test, 200);
397 void change_content(void)
399 printf("changing content\n");
402 int main (int argc, char *argv[])
404 int i;
405 char *pluginname = NULL;
406 char *plugindir = NULL;
407 char *configfile = NULL;
408 char *objtype = NULL;
409 OSyncError *error = NULL;
411 if (argc < 2)
412 usage (argv[0], 1);
414 pluginname = argv[1];
415 for (i = 2; i < argc; i++) {
416 char *arg = argv[i];
417 if (!strcmp (arg, "--config")) {
418 configfile = argv[i + 1];
419 i++;
420 if (!configfile)
421 usage (argv[0], 1);
422 } else if (!strcmp (arg, "--type")) {
423 objtype = argv[i + 1];
424 i++;
425 if (!objtype)
426 usage (argv[0], 1);
427 } else if (!strcmp (arg, "--plugindir")) {
428 printf("plugindir %s\n", argv[i + 1]);
429 plugindir = argv[i + 1];
430 i++;
431 if (!plugindir)
432 usage (argv[0], 1);
433 } else if (!strcmp (arg, "--random")) {
434 only_random = TRUE;
435 } else if (!strcmp (arg, "--help")) {
436 usage (argv[0], 0);
437 } else {
438 usage (argv[0], 1);
442 OSyncEnv *env = osync_env_new(NULL);
443 osync_env_set_option(env, "LOAD_GROUPS", "FALSE");
445 if (plugindir)
446 osync_env_set_option(env, "PLUGINS_DIRECTORY", plugindir);
448 if (!osync_env_initialize(env, &error)) {
449 printf("Unable to initialize environment: %s\n", osync_error_print(&error));
450 osync_error_unref(&error);
451 return 1;
454 char *testdir = g_strdup_printf("%s/plgtest.XXXXXX", g_get_tmp_dir());
455 char *result = mkdtemp(testdir);
457 if (result == NULL)
459 osync_trace(TRACE_EXIT_ERROR, "unable to create temporary dir: %s", g_strerror(errno));
460 return 1;
463 OSyncGroup *group = osync_group_new(env);
464 osync_group_set_name(group, osync_rand_str(8));
465 osync_group_set_configdir(group, testdir);
466 OSyncMember *member = osync_member_new(group);
468 char *config = NULL;
469 int size = 0;
470 if (configfile) {
471 if (!osync_file_read(configfile, &config, &size, &error)) {
472 fprintf(stderr, "Unable to read config: %s\n", osync_error_print(&error));
473 osync_error_unref(&error);
474 return 1;
476 osync_member_set_config(member, config, size);
479 osync_member_set_pluginname(member, pluginname);
481 OSyncMember *file = osync_member_new(group);
483 localdir = g_strdup_printf("%s/plgtest.XXXXXX", g_get_tmp_dir());
484 result = mkdtemp(localdir);
486 if (result == NULL)
488 osync_trace(TRACE_EXIT_ERROR, "unable to create temporary dir: %s", g_strerror(errno));
489 return 1;
492 config = g_strdup_printf("<config><path>%s</path><recursive>0</recursive></config>", localdir);
493 osync_member_set_config(file, config, strlen(config) + 1);
494 osync_member_set_pluginname(file, "file-sync");
496 if (!osync_group_save(group, &error)) {
497 printf("Error while creating syncengine: %s\n", osync_error_print(&error));
498 osync_error_unref(&error);
499 goto error_free_env;
502 if (!g_thread_supported ()) g_thread_init (NULL);
504 OSyncEngine *engine = osengine_new(group, &error);
505 if (!engine) {
506 printf("Error while creating syncengine: %s\n", osync_error_print(&error));
507 osync_error_unref(&error);
508 goto error_free_env;
511 if (!osengine_init(engine, &error)) {
512 printf("Error while initializing syncengine: %s\n", osync_error_print(&error));
513 osync_error_unref(&error);
514 goto error_free_engine;
517 int count = 0;
518 if (only_random) {
519 do {
520 count++;
521 printf("++++++++++++++++++++++++++++++\n");
522 printf("Initializing new round #%i!\n", count);
524 if (g_random_int_range(0, 5) == 0) {
525 int i;
526 OSyncFormatEnv *env = osync_group_get_format_env(group);
527 for (i = 0; i < osync_conv_num_objtypes(env); i++) {
528 if (g_random_int_range(0, 5) == 0) {
529 OSyncObjType *type = osync_conv_nth_objtype(env, i);
530 osync_group_set_slow_sync(group, osync_objtype_get_name(type), TRUE);
531 printf("Requesting slow-sync for: %s\n", osync_objtype_get_name(type));
534 osync_conv_env_free(env);
537 change_content();
539 check_sync(engine, "Random", 1);
540 } while (g_random_int_range(0, 3) != 0);
542 printf("Finalizing engine\n");
543 osengine_finalize(engine);
544 osengine_free(engine);
546 engine = osengine_new(group, &error);
547 if (!engine) {
548 printf("Error while creating syncengine: %s\n", osync_error_print(&error));
549 osync_error_unref(&error);
550 goto error_free_env;
553 if (!osengine_init(engine, &error)) {
554 printf("Error while initializing syncengine: %s\n", osync_error_print(&error));
555 osync_error_unref(&error);
556 goto error_free_engine;
558 } else {
559 register_tests();
560 run_all_tests(engine, file, member, objtype);
563 printf("\nCompleted successfully\n");
564 return 0;
566 error_free_engine:
567 osengine_free(engine);
568 error_free_env:
569 osync_group_free(group);
570 osync_env_free(env);
571 return 1;