windows port - replaced sleep with g_usleep
[opensync.git] / tools / osynctest.c
blob45a218c2edf7c31f06d9e9c5b3311f03e1d0c8e6
1 #include <opensync/opensync.h>
2 #include <opensync/opensync_internals.h>
3 #include "engine.h"
4 #include "engine_internals.h"
5 #include <errno.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/types.h>
10 #include <sys/wait.h>
11 #include <glib.h>
12 #include <sys/time.h>
14 GMutex *working;
15 GMutex *working2;
16 GList *changes;
17 GList *tests;
18 osync_bool alwaysempty;
19 osync_bool noaccess = FALSE;
21 typedef struct OSyncPluginTest {
22 char *name;
23 double (*test)(OSyncEngine *engine, OSyncMember *file, int num, const char *);
24 double alltime;
25 double connecttime;
26 double readtime;
27 double writetime;
28 double othertime;
29 int num;
30 } OSyncPluginTest;
32 static void usage (char *name, int ecode)
34 fprintf (stderr, "Usage: %s <pluginname>\n", name);
35 fprintf (stderr, "--config <filename>\tSet the config file to use\n");
36 fprintf (stderr, "--type <object type>\tSets the objtype to test\n");
37 fprintf (stderr, "--empty\tOnly deleta all data. Do not test\n");
38 exit (ecode);
41 gboolean only_random = FALSE;
42 char *localdir = NULL;
44 static void sync_now(OSyncEngine *engine)
46 OSyncError *error = NULL;
47 printf(".");
48 fflush(stdout);
50 if (!osengine_sync_and_block(engine, &error)) {
51 printf("Error while starting synchronization: %s\n", osync_error_print(&error));
52 osync_error_unref(&error);
53 exit(1);
56 printf(".");
57 fflush(stdout);
60 static void check_empty(void)
62 printf(".");
63 fflush(stdout);
64 char *command = g_strdup_printf("test \"x$(ls %s)\" = \"x\"", localdir);
65 int ret = system(command);
66 g_free(command);
67 if (ret)
68 abort();
69 printf(".");
70 fflush(stdout);
73 double starttime;
74 double currenttime;
76 double connecttime;
77 double readtime;
78 double writetime;
80 double _second() /* note that some compilers like AIX xlf do not require the trailing '_' */
82 struct timeval tp;
83 int rtn;
84 rtn=gettimeofday(&tp, NULL);
86 return ((double)tp.tv_sec+(1.e-6)*tp.tv_usec);
89 void engine_status(OSyncEngine *engine, OSyncEngineUpdate *status, void *user_data)
91 switch (status->type) {
92 case ENG_ENDPHASE_CON:
93 osync_trace(TRACE_INTERNAL, "++++++++++++++++ Connection Phase ended ++++++++++++++");
94 currenttime = _second();
95 connecttime = currenttime - starttime;
96 break;
97 case ENG_ENDPHASE_READ:
98 osync_trace(TRACE_INTERNAL, "++++++++++++++++ Read Phase ended ++++++++++++++");
99 readtime = _second() - currenttime;
100 currenttime = _second();
101 break;
102 case ENG_ENDPHASE_WRITE:
103 osync_trace(TRACE_INTERNAL, "++++++++++++++++ Write Phase ended ++++++++++++++");
104 writetime = _second() - currenttime;
105 currenttime = _second();
106 break;
107 default:
112 double check_sync(OSyncEngine *engine, const char *name, int num)
114 int ret;
115 printf(".");
116 fflush(stdout);
117 starttime = _second();
118 osync_trace(TRACE_INTERNAL, "++++++++++++++++ Test \"%s %i\" starting ++++++++++++++", name, num);
119 osengine_set_enginestatus_callback(engine, engine_status, NULL);
120 sync_now(engine);
121 osengine_set_enginestatus_callback(engine, NULL, NULL);
122 int wasted = 0;
123 int alldeciders = 0;
124 osengine_get_wasted(engine, &alldeciders, &wasted);
125 osync_trace(TRACE_INTERNAL, "++++++++++++++++ Test \"%s %i\" ended (%i / %i (%i%%)) ++++++++++++++", name, num, wasted, alldeciders, (int)(((float)wasted / (float)alldeciders) * 100));
126 double thistime = _second() - starttime;
128 printf(".");
129 fflush(stdout);
131 char *tempdir = g_strdup_printf("%s/plgtest.XXXXXX", g_get_tmp_dir());
132 if (!mkdtemp(tempdir))
134 g_free(tempdir);
135 osync_trace(TRACE_INTERNAL, "unable to create temporary dir: %s", g_strerror(errno));
136 abort();
138 char *command = g_strdup_printf("mv %s/* %s &> /dev/null", localdir, tempdir);
139 ret = system(command);
140 if (ret)
142 g_free(tempdir);
143 g_free(command);
144 osync_trace(TRACE_INTERNAL, "Unable to move files to temporary dir: %d", ret);
145 abort();
147 g_free(command);
148 printf(".");
149 fflush(stdout);
151 check_empty();
153 printf(".");
154 fflush(stdout);
156 osync_group_set_slow_sync(engine->group, "data", TRUE);
158 sync_now(engine);
159 printf(".");
160 fflush(stdout);
161 command = g_strdup_printf("test \"x$(diff -x \".*\" %s %s)\" = \"x\"", localdir, tempdir);
162 int result = system(command);
163 g_free(command);
165 g_free(tempdir);
166 if (result)
167 abort();
169 printf(" success\n");
170 return thistime;
173 void add_data(OSyncMember *member, const char *objtype)
175 OSyncChange *change = osync_change_new();
176 if (!osync_member_make_random_data(member, change, objtype)) {
177 printf("Unable to create random data\n");
178 abort();
181 char *filename = NULL;
182 while (1) {
183 char *randstr = osync_rand_str(8);
184 filename = g_strdup_printf("%s/%s", localdir, randstr);
185 g_free(randstr);
186 char *command = g_strdup_printf("ls %s &> /dev/null", filename);
187 int ret = system(command);
188 g_free(command);
189 if (ret)
190 break;
191 g_free(filename);
194 OSyncError *error = NULL;
195 if (!osync_file_write(filename, osync_change_get_data(change), osync_change_get_datasize(change), 0700, &error)) {
196 printf("Unable to write to file %s\n", osync_error_print(&error));
197 abort();
199 g_free(filename);
202 void modify_data(OSyncMember *member, const char *objtype)
204 GDir *dir;
205 GError *gerror = NULL;
207 dir = g_dir_open(localdir, 0, &gerror);
208 if (!dir)
209 abort();
211 const char *de = NULL;
212 while ((de = g_dir_read_name(dir))) {
213 char *filename = g_build_filename(localdir, de, NULL);
215 OSyncChange *change = osync_change_new();
216 if (!osync_member_make_random_data(member, change, objtype)) {
217 printf("Unable to create random data\n");
218 abort();
221 OSyncError *error = NULL;
222 if (!osync_file_write(filename, osync_change_get_data(change), osync_change_get_datasize(change), 0700, &error)) {
223 printf("Unable to write to file %s\n", osync_error_print(&error));
224 abort();
227 g_free(filename);
229 g_dir_close(dir);
233 void delete_data(OSyncMember *member, const char *objtype)
235 char *command = g_strdup_printf("rm -f %s/*", localdir);
236 int ret = system(command);
237 if (ret)
239 osync_trace(TRACE_INTERNAL, "Unable to delete data: %d", ret);
240 abort();
242 g_free(command);
245 static void empty_all(OSyncEngine *engine)
247 printf(".");
248 fflush(stdout);
250 osync_group_set_slow_sync(engine->group, "data", TRUE);
251 sync_now(engine);
253 char *command = g_strdup_printf("rm -f %s/*", localdir);
254 int ret = system(command);
255 if (ret)
257 osync_trace(TRACE_INTERNAL, "Unable to delete data: %d", ret);
258 abort();
260 g_free(command);
261 sync_now(engine);
263 printf(".");
264 fflush(stdout);
266 check_empty();
270 double add_test(OSyncEngine *engine, OSyncMember *member, int num, const char *objtype)
272 printf("Test \"Add %i\" starting", num);
273 fflush(stdout);
275 empty_all(engine);
277 printf(".");
278 fflush(stdout);
279 int i = 0;
280 for (i = 0; i < num; i++)
281 add_data(member, objtype);
282 printf(".");
283 fflush(stdout);
285 return check_sync(engine, "Add", num);
288 double modify_test(OSyncEngine *engine, OSyncMember *member, int num, const char *objtype)
290 printf("Test \"Modify %i\" starting", num);
291 fflush(stdout);
293 empty_all(engine);
295 printf(".");
296 fflush(stdout);
297 int i = 0;
298 for (i = 0; i < num; i++)
299 add_data(member, objtype);
300 printf(".");
301 fflush(stdout);
303 check_sync(engine, "None", num);
305 printf(".");
306 fflush(stdout);
307 modify_data(member, objtype);
308 printf(".");
309 fflush(stdout);
311 return check_sync(engine, "Modify", num);
314 double delete_test(OSyncEngine *engine, OSyncMember *member, int num, const char *objtype)
316 printf("Test \"Delete %i\" starting", num);
317 fflush(stdout);
319 empty_all(engine);
321 printf(".");
322 fflush(stdout);
323 int i = 0;
324 for (i = 0; i < num; i++)
325 add_data(member, objtype);
326 printf(".");
327 fflush(stdout);
329 check_sync(engine, "None", num);
331 printf(".");
332 fflush(stdout);
333 delete_data(member, objtype);
334 printf(".");
335 fflush(stdout);
337 return check_sync(engine, "Delete", num);
340 static void run_all_tests(OSyncEngine *engine, OSyncMember *file, OSyncMember *target, const char *objtype)
343 GList *t;
344 for (t = tests; t; t = t->next) {
345 OSyncPluginTest *test = t->data;
346 test->alltime = test->test(engine, target, test->num, objtype);
347 test->connecttime = connecttime;
348 test->readtime = readtime;
349 test->writetime = writetime;
350 test->othertime = test->alltime - test->connecttime - test->readtime - test->writetime;
353 printf("\nOutcome:\n");
355 for (t = tests; t; t = t->next) {
356 OSyncPluginTest *test = t->data;
357 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));
361 static void register_test(const char *name, double test(OSyncEngine *engine, OSyncMember *file, int num, const char *), int num)
363 OSyncPluginTest *newtest = g_malloc0(sizeof(OSyncPluginTest));
364 newtest->name = g_strdup(name);
365 newtest->test = test;
366 newtest->num = num;
367 tests = g_list_append(tests, newtest);
370 static void register_tests(void)
372 tests = NULL;
373 /*register_test("add_test1", add_test, 1);
374 register_test("add_test5", add_test, 5);
375 register_test("add_test10", add_test, 10);
376 register_test("add_test20", add_test, 20);*/
377 /*register_test("add_test50", add_test, 50);
378 register_test("add_test100", add_test, 100);
379 register_test("add_test200", add_test, 200);*/
381 /*register_test("modify_test1", modify_test, 1);
382 register_test("modify_test5", modify_test, 5);
383 register_test("modify_test10", modify_test, 10);
384 register_test("modify_test20", modify_test, 20);
385 register_test("modify_test50", modify_test, 50);*/
386 register_test("modify_test100", modify_test, 100);
387 //register_test("modify_test200", modify_test, 200);
389 /*register_test("delete_test1", delete_test, 1);
390 register_test("delete_test5", delete_test, 5);
391 register_test("delete_test10", delete_test, 10);
392 register_test("delete_test20", delete_test, 20);
393 register_test("delete_test50", delete_test, 50);*/
394 //register_test("delete_test100", delete_test, 100);
395 //register_test("delete_test200", delete_test, 200);
398 void change_content(void)
400 printf("changing content\n");
403 int main (int argc, char *argv[])
405 int i;
406 char *pluginname = NULL;
407 char *plugindir = NULL;
408 char *configfile = NULL;
409 char *objtype = NULL;
410 OSyncError *error = NULL;
412 if (argc < 2)
413 usage (argv[0], 1);
415 pluginname = argv[1];
416 for (i = 2; i < argc; i++) {
417 char *arg = argv[i];
418 if (!strcmp (arg, "--config")) {
419 configfile = argv[i + 1];
420 i++;
421 if (!configfile)
422 usage (argv[0], 1);
423 } else if (!strcmp (arg, "--type")) {
424 objtype = argv[i + 1];
425 i++;
426 if (!objtype)
427 usage (argv[0], 1);
428 } else if (!strcmp (arg, "--plugindir")) {
429 printf("plugindir %s\n", argv[i + 1]);
430 plugindir = argv[i + 1];
431 i++;
432 if (!plugindir)
433 usage (argv[0], 1);
434 } else if (!strcmp (arg, "--random")) {
435 only_random = TRUE;
436 } else if (!strcmp (arg, "--help")) {
437 usage (argv[0], 0);
438 } else {
439 usage (argv[0], 1);
443 OSyncEnv *env = osync_env_new(NULL);
444 osync_env_set_option(env, "LOAD_GROUPS", "FALSE");
446 if (plugindir)
447 osync_env_set_option(env, "PLUGINS_DIRECTORY", plugindir);
449 if (!osync_env_initialize(env, &error)) {
450 printf("Unable to initialize environment: %s\n", osync_error_print(&error));
451 osync_error_unref(&error);
452 return 1;
455 char *testdir = g_strdup_printf("%s/plgtest.XXXXXX", g_get_tmp_dir());
456 char *result = mkdtemp(testdir);
458 if (result == NULL)
460 osync_trace(TRACE_EXIT_ERROR, "unable to create temporary dir: %s", g_strerror(errno));
461 return 1;
464 OSyncGroup *group = osync_group_new(env);
465 osync_group_set_name(group, osync_rand_str(8));
466 osync_group_set_configdir(group, testdir);
467 OSyncMember *member = osync_member_new(group);
469 char *config = NULL;
470 int size = 0;
471 if (configfile) {
472 if (!osync_file_read(configfile, &config, &size, &error)) {
473 fprintf(stderr, "Unable to read config: %s\n", osync_error_print(&error));
474 osync_error_unref(&error);
475 return 1;
477 osync_member_set_config(member, config, size);
480 osync_member_set_pluginname(member, pluginname);
482 OSyncMember *file = osync_member_new(group);
484 localdir = g_strdup_printf("%s/plgtest.XXXXXX", g_get_tmp_dir());
485 result = mkdtemp(localdir);
487 if (result == NULL)
489 osync_trace(TRACE_EXIT_ERROR, "unable to create temporary dir: %s", g_strerror(errno));
490 return 1;
493 config = g_strdup_printf("<config><path>%s</path><recursive>0</recursive></config>", localdir);
494 osync_member_set_config(file, config, strlen(config) + 1);
495 osync_member_set_pluginname(file, "file-sync");
497 if (!osync_group_save(group, &error)) {
498 printf("Error while creating syncengine: %s\n", osync_error_print(&error));
499 osync_error_unref(&error);
500 goto error_free_env;
503 if (!g_thread_supported ()) g_thread_init (NULL);
505 OSyncEngine *engine = osengine_new(group, &error);
506 if (!engine) {
507 printf("Error while creating syncengine: %s\n", osync_error_print(&error));
508 osync_error_unref(&error);
509 goto error_free_env;
512 if (!osengine_init(engine, &error)) {
513 printf("Error while initializing syncengine: %s\n", osync_error_print(&error));
514 osync_error_unref(&error);
515 goto error_free_engine;
518 int count = 0;
519 if (only_random) {
520 do {
521 count++;
522 printf("++++++++++++++++++++++++++++++\n");
523 printf("Initializing new round #%i!\n", count);
525 if (g_random_int_range(0, 5) == 0) {
526 int i;
527 OSyncFormatEnv *env = osync_group_get_format_env(group);
528 for (i = 0; i < osync_conv_num_objtypes(env); i++) {
529 if (g_random_int_range(0, 5) == 0) {
530 OSyncObjType *type = osync_conv_nth_objtype(env, i);
531 osync_group_set_slow_sync(group, osync_objtype_get_name(type), TRUE);
532 printf("Requesting slow-sync for: %s\n", osync_objtype_get_name(type));
535 osync_conv_env_free(env);
538 change_content();
540 check_sync(engine, "Random", 1);
541 } while (g_random_int_range(0, 3) != 0);
543 printf("Finalizing engine\n");
544 osengine_finalize(engine);
545 osengine_free(engine);
547 engine = osengine_new(group, &error);
548 if (!engine) {
549 printf("Error while creating syncengine: %s\n", osync_error_print(&error));
550 osync_error_unref(&error);
551 goto error_free_env;
554 if (!osengine_init(engine, &error)) {
555 printf("Error while initializing syncengine: %s\n", osync_error_print(&error));
556 osync_error_unref(&error);
557 goto error_free_engine;
559 } else {
560 register_tests();
561 run_all_tests(engine, file, member, objtype);
564 printf("\nCompleted successfully\n");
565 return 0;
567 error_free_engine:
568 osengine_free(engine);
569 error_free_env:
570 osync_group_free(group);
571 osync_env_free(env);
572 return 1;