| #include <stdlib.h> |
| #include <gio/gio.h> |
| |
| /* These tests were written for the inotify implementation. |
| * Other implementations may require slight adjustments in |
| * the tests, e.g. the length of timeouts |
| */ |
| |
| typedef struct |
| { |
| gint event_type; |
| gchar *file; |
| gchar *other_file; |
| gint step; |
| } RecordedEvent; |
| |
| static void |
| free_recorded_event (RecordedEvent *event) |
| { |
| g_free (event->file); |
| g_free (event->other_file); |
| g_free (event); |
| } |
| |
| typedef struct |
| { |
| GFile *file; |
| GFileMonitor *monitor; |
| GMainLoop *loop; |
| gint step; |
| GList *events; |
| } TestData; |
| |
| #if 0 |
| static void |
| output_event (RecordedEvent *event) |
| { |
| if (event->step >= 0) |
| g_print (">>>> step %d\n", event->step); |
| else |
| { |
| GTypeClass *class; |
| |
| class = g_type_class_ref (g_type_from_name ("GFileMonitorEvent")); |
| g_print ("%s file=%s other_file=%s\n", |
| g_enum_get_value (G_ENUM_CLASS (class), event->event_type)->value_nick, |
| event->file, |
| event->other_file); |
| g_type_class_unref (class); |
| } |
| } |
| |
| static void |
| output_events (GList *list) |
| { |
| GList *l; |
| |
| g_print (">>>output events\n"); |
| for (l = list; l; l = l->next) |
| output_event ((RecordedEvent *)l->data); |
| } |
| #endif |
| |
| /* a placeholder for temp file names we don't want to compare */ |
| static const gchar DONT_CARE[] = ""; |
| |
| static void |
| check_expected_event (gint i, |
| RecordedEvent *e1, |
| RecordedEvent *e2) |
| { |
| g_assert_cmpint (e1->step, ==, e2->step); |
| if (e1->step < 0) |
| return; |
| |
| g_assert_cmpint (e1->event_type, ==, e2->event_type); |
| |
| if (e1->file != DONT_CARE) |
| g_assert_cmpstr (e1->file, ==, e2->file); |
| |
| if (e1->other_file != DONT_CARE) |
| g_assert_cmpstr (e1->other_file, ==, e2->other_file); |
| } |
| |
| static void |
| check_expected_events (RecordedEvent *expected, |
| gsize n_expected, |
| GList *recorded) |
| { |
| gint i; |
| GList *l; |
| |
| g_assert_cmpint (n_expected, ==, g_list_length (recorded)); |
| |
| for (i = 0, l = recorded; i < n_expected; i++, l = l->next) |
| { |
| RecordedEvent *e1 = &expected[i]; |
| RecordedEvent *e2 = (RecordedEvent *)l->data; |
| |
| check_expected_event (i, e1, e2); |
| } |
| } |
| |
| static void |
| record_event (TestData *data, |
| gint event_type, |
| const gchar *file, |
| const gchar *other_file, |
| gint step) |
| { |
| RecordedEvent *event; |
| |
| event = g_new0 (RecordedEvent, 1); |
| event->event_type = event_type; |
| event->file = g_strdup (file); |
| event->other_file = g_strdup (other_file); |
| event->step = step; |
| |
| data->events = g_list_append (data->events, event); |
| } |
| |
| static void |
| monitor_changed (GFileMonitor *monitor, |
| GFile *file, |
| GFile *other_file, |
| GFileMonitorEvent event_type, |
| gpointer user_data) |
| { |
| TestData *data = user_data; |
| gchar *basename, *other_base; |
| |
| basename = g_file_get_basename (file); |
| if (other_file) |
| other_base = g_file_get_basename (other_file); |
| else |
| other_base = NULL; |
| |
| record_event (data, event_type, basename, other_base, -1); |
| |
| g_free (basename); |
| g_free (other_base); |
| } |
| |
| static gboolean |
| atomic_replace_step (gpointer user_data) |
| { |
| TestData *data = user_data; |
| GError *error = NULL; |
| |
| switch (data->step) |
| { |
| case 0: |
| record_event (data, -1, NULL, NULL, 0); |
| g_file_replace_contents (data->file, "step 0", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); |
| g_assert_no_error (error); |
| break; |
| case 1: |
| record_event (data, -1, NULL, NULL, 1); |
| g_file_replace_contents (data->file, "step 1", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); |
| g_assert_no_error (error); |
| break; |
| case 2: |
| record_event (data, -1, NULL, NULL, 2); |
| g_file_delete (data->file, NULL, NULL); |
| break; |
| case 3: |
| record_event (data, -1, NULL, NULL, 3); |
| g_main_loop_quit (data->loop); |
| return G_SOURCE_REMOVE; |
| } |
| |
| data->step++; |
| |
| return G_SOURCE_CONTINUE; |
| } |
| |
| /* this is the output we expect from the above steps */ |
| static RecordedEvent atomic_replace_output[] = { |
| { -1, NULL, NULL, 0 }, |
| { G_FILE_MONITOR_EVENT_CREATED, "atomic_replace_file", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGED, "atomic_replace_file", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "atomic_replace_file", NULL, -1 }, |
| { -1, NULL, NULL, 1 }, |
| { G_FILE_MONITOR_EVENT_RENAMED, (gchar*)DONT_CARE, "atomic_replace_file", -1 }, |
| { -1, NULL, NULL, 2 }, |
| { G_FILE_MONITOR_EVENT_DELETED, "atomic_replace_file", NULL, -1 }, |
| { -1, NULL, NULL, 3 } |
| }; |
| |
| static void |
| test_atomic_replace (void) |
| { |
| GError *error = NULL; |
| TestData data; |
| |
| data.step = 0; |
| data.events = NULL; |
| |
| data.file = g_file_new_for_path ("atomic_replace_file"); |
| g_file_delete (data.file, NULL, NULL); |
| |
| data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error); |
| g_assert_no_error (error); |
| |
| g_file_monitor_set_rate_limit (data.monitor, 200); |
| g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data); |
| |
| data.loop = g_main_loop_new (NULL, TRUE); |
| |
| g_timeout_add (500, atomic_replace_step, &data); |
| |
| g_main_loop_run (data.loop); |
| |
| /*output_events (data.events);*/ |
| check_expected_events (atomic_replace_output, G_N_ELEMENTS (atomic_replace_output), data.events); |
| |
| g_list_free_full (data.events, (GDestroyNotify)free_recorded_event); |
| g_main_loop_unref (data.loop); |
| g_object_unref (data.monitor); |
| g_object_unref (data.file); |
| } |
| |
| static gboolean |
| change_step (gpointer user_data) |
| { |
| TestData *data = user_data; |
| GOutputStream *stream; |
| GError *error = NULL; |
| guint32 mode = 0660; |
| |
| switch (data->step) |
| { |
| case 0: |
| record_event (data, -1, NULL, NULL, 0); |
| g_file_replace_contents (data->file, "step 0", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); |
| g_assert_no_error (error); |
| break; |
| case 1: |
| record_event (data, -1, NULL, NULL, 1); |
| stream = (GOutputStream *)g_file_append_to (data->file, G_FILE_CREATE_NONE, NULL, &error); |
| g_assert_no_error (error); |
| g_output_stream_write_all (stream, " step 1", 7, NULL, NULL, &error); |
| g_assert_no_error (error); |
| g_output_stream_close (stream, NULL, &error); |
| g_assert_no_error (error); |
| break; |
| case 2: |
| record_event (data, -1, NULL, NULL, 2); |
| g_file_set_attribute (data->file, |
| G_FILE_ATTRIBUTE_UNIX_MODE, |
| G_FILE_ATTRIBUTE_TYPE_UINT32, |
| &mode, |
| G_FILE_QUERY_INFO_NONE, |
| NULL, |
| &error); |
| g_assert_no_error (error); |
| break; |
| case 3: |
| record_event (data, -1, NULL, NULL, 3); |
| g_file_delete (data->file, NULL, NULL); |
| break; |
| case 4: |
| record_event (data, -1, NULL, NULL, 4); |
| g_main_loop_quit (data->loop); |
| return G_SOURCE_REMOVE; |
| } |
| |
| data->step++; |
| |
| return G_SOURCE_CONTINUE; |
| } |
| |
| /* this is the output we expect from the above steps */ |
| static RecordedEvent change_output[] = { |
| { -1, NULL, NULL, 0 }, |
| { G_FILE_MONITOR_EVENT_CREATED, "change_file", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGED, "change_file", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "change_file", NULL, -1 }, |
| { -1, NULL, NULL, 1 }, |
| { G_FILE_MONITOR_EVENT_CHANGED, "change_file", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "change_file", NULL, -1 }, |
| { -1, NULL, NULL, 2 }, |
| { G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED, "change_file", NULL, -1 }, |
| { -1, NULL, NULL, 3 }, |
| { G_FILE_MONITOR_EVENT_DELETED, "change_file", NULL, -1 }, |
| { -1, NULL, NULL, 4 } |
| }; |
| |
| static void |
| test_file_changes (void) |
| { |
| GError *error = NULL; |
| TestData data; |
| |
| data.step = 0; |
| data.events = NULL; |
| |
| data.file = g_file_new_for_path ("change_file"); |
| g_file_delete (data.file, NULL, NULL); |
| |
| data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error); |
| g_assert_no_error (error); |
| |
| g_file_monitor_set_rate_limit (data.monitor, 200); |
| g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data); |
| |
| data.loop = g_main_loop_new (NULL, TRUE); |
| |
| g_timeout_add (500, change_step, &data); |
| |
| g_main_loop_run (data.loop); |
| |
| /*output_events (data.events);*/ |
| check_expected_events (change_output, G_N_ELEMENTS (change_output), data.events); |
| |
| g_list_free_full (data.events, (GDestroyNotify)free_recorded_event); |
| g_main_loop_unref (data.loop); |
| g_object_unref (data.monitor); |
| g_object_unref (data.file); |
| } |
| |
| static gboolean |
| dir_step (gpointer user_data) |
| { |
| TestData *data = user_data; |
| GFile *parent, *file, *file2; |
| GError *error = NULL; |
| |
| switch (data->step) |
| { |
| case 1: |
| record_event (data, -1, NULL, NULL, 1); |
| parent = g_file_get_parent (data->file); |
| file = g_file_get_child (parent, "dir_test_file"); |
| g_file_replace_contents (file, "step 1", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); |
| g_assert_no_error (error); |
| g_object_unref (file); |
| g_object_unref (parent); |
| break; |
| case 2: |
| record_event (data, -1, NULL, NULL, 2); |
| parent = g_file_get_parent (data->file); |
| file = g_file_get_child (parent, "dir_test_file"); |
| file2 = g_file_get_child (data->file, "dir_test_file"); |
| g_file_move (file, file2, G_FILE_COPY_NONE, NULL, NULL, NULL, &error); |
| g_assert_no_error (error); |
| g_object_unref (file); |
| g_object_unref (file2); |
| g_object_unref (parent); |
| break; |
| case 3: |
| record_event (data, -1, NULL, NULL, 3); |
| file = g_file_get_child (data->file, "dir_test_file"); |
| file2 = g_file_get_child (data->file, "dir_test_file2"); |
| g_file_move (file, file2, G_FILE_COPY_NONE, NULL, NULL, NULL, &error); |
| g_assert_no_error (error); |
| g_object_unref (file); |
| g_object_unref (file2); |
| break; |
| case 4: |
| record_event (data, -1, NULL, NULL, 4); |
| parent = g_file_get_parent (data->file); |
| file = g_file_get_child (data->file, "dir_test_file2"); |
| file2 = g_file_get_child (parent, "dir_test_file2"); |
| g_file_move (file, file2, G_FILE_COPY_NONE, NULL, NULL, NULL, &error); |
| g_assert_no_error (error); |
| g_file_delete (file2, NULL, NULL); |
| g_object_unref (file); |
| g_object_unref (file2); |
| g_object_unref (parent); |
| break; |
| case 5: |
| record_event (data, -1, NULL, NULL, 5); |
| g_file_delete (data->file, NULL, NULL); |
| break; |
| case 6: |
| record_event (data, -1, NULL, NULL, 6); |
| g_main_loop_quit (data->loop); |
| return G_SOURCE_REMOVE; |
| } |
| |
| data->step++; |
| |
| return G_SOURCE_CONTINUE; |
| } |
| |
| /* this is the output we expect from the above steps */ |
| static RecordedEvent dir_output[] = { |
| { -1, NULL, NULL, 1 }, |
| { -1, NULL, NULL, 2 }, |
| { G_FILE_MONITOR_EVENT_MOVED_IN, "dir_test_file", NULL, -1 }, |
| { -1, NULL, NULL, 3 }, |
| { G_FILE_MONITOR_EVENT_RENAMED, "dir_test_file", "dir_test_file2", -1 }, |
| { -1, NULL, NULL, 4 }, |
| { G_FILE_MONITOR_EVENT_MOVED_OUT, "dir_test_file2", NULL, -1 }, |
| { -1, NULL, NULL, 5 }, |
| { G_FILE_MONITOR_EVENT_DELETED, "dir_monitor_test", NULL, -1 }, |
| { -1, NULL, NULL, 6 } |
| }; |
| |
| static void |
| test_dir_monitor (void) |
| { |
| GError *error = NULL; |
| TestData data; |
| |
| data.step = 0; |
| data.events = NULL; |
| |
| data.file = g_file_new_for_path ("dir_monitor_test"); |
| g_file_delete (data.file, NULL, NULL); |
| g_file_make_directory (data.file, NULL, &error); |
| |
| data.monitor = g_file_monitor_directory (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error); |
| g_assert_no_error (error); |
| |
| g_file_monitor_set_rate_limit (data.monitor, 200); |
| g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data); |
| |
| data.loop = g_main_loop_new (NULL, TRUE); |
| |
| g_timeout_add (500, dir_step, &data); |
| |
| g_main_loop_run (data.loop); |
| |
| /*output_events (data.events);*/ |
| check_expected_events (dir_output, G_N_ELEMENTS (dir_output), data.events); |
| |
| g_list_free_full (data.events, (GDestroyNotify)free_recorded_event); |
| g_main_loop_unref (data.loop); |
| g_object_unref (data.monitor); |
| g_object_unref (data.file); |
| } |
| |
| static gboolean |
| nodir_step (gpointer user_data) |
| { |
| TestData *data = user_data; |
| GFile *parent; |
| GError *error = NULL; |
| |
| switch (data->step) |
| { |
| case 0: |
| record_event (data, -1, NULL, NULL, 0); |
| parent = g_file_get_parent (data->file); |
| g_file_make_directory (parent, NULL, &error); |
| g_assert_no_error (error); |
| g_object_unref (parent); |
| break; |
| case 1: |
| record_event (data, -1, NULL, NULL, 1); |
| g_file_replace_contents (data->file, "step 1", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); |
| g_assert_no_error (error); |
| break; |
| case 2: |
| record_event (data, -1, NULL, NULL, 2); |
| g_file_delete (data->file, NULL, &error); |
| g_assert_no_error (error); |
| break; |
| case 3: |
| record_event (data, -1, NULL, NULL, 3); |
| parent = g_file_get_parent (data->file); |
| g_file_delete (parent, NULL, &error); |
| g_assert_no_error (error); |
| g_object_unref (parent); |
| break; |
| case 4: |
| record_event (data, -1, NULL, NULL, 4); |
| g_main_loop_quit (data->loop); |
| return G_SOURCE_REMOVE; |
| } |
| |
| data->step++; |
| |
| return G_SOURCE_CONTINUE; |
| } |
| |
| static RecordedEvent nodir_output[] = { |
| { -1, NULL, NULL, 0 }, |
| { G_FILE_MONITOR_EVENT_CREATED, "nosuchfile", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "nosuchfile", NULL, -1 }, |
| { -1, NULL, NULL, 1 }, |
| { G_FILE_MONITOR_EVENT_CREATED, "nosuchfile", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGED, "nosuchfile", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "nosuchfile", NULL, -1 }, |
| { -1, NULL, NULL, 2 }, |
| { G_FILE_MONITOR_EVENT_DELETED, "nosuchfile", NULL, -1 }, |
| { -1, NULL, NULL, 3 }, |
| { -1, NULL, NULL, 4 } |
| }; |
| |
| static void |
| test_dir_non_existent (void) |
| { |
| TestData data; |
| GError *error = NULL; |
| |
| data.step = 0; |
| data.events = NULL; |
| |
| data.file = g_file_new_for_path ("nosuchdir/nosuchfile"); |
| data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error); |
| g_assert_no_error (error); |
| |
| g_file_monitor_set_rate_limit (data.monitor, 200); |
| g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data); |
| |
| data.loop = g_main_loop_new (NULL, TRUE); |
| |
| /* we need a long timeout here, since the inotify implementation only scans |
| * for missing files every 4 seconds. |
| */ |
| g_timeout_add (5000, nodir_step, &data); |
| |
| g_main_loop_run (data.loop); |
| |
| /*output_events (data.events);*/ |
| check_expected_events (nodir_output, G_N_ELEMENTS (nodir_output), data.events); |
| |
| g_list_free_full (data.events, (GDestroyNotify)free_recorded_event); |
| g_main_loop_unref (data.loop); |
| g_object_unref (data.monitor); |
| g_object_unref (data.file); |
| } |
| |
| static gboolean |
| cross_dir_step (gpointer user_data) |
| { |
| TestData *data = user_data; |
| GFile *file, *file2; |
| GError *error = NULL; |
| |
| switch (data[0].step) |
| { |
| case 0: |
| record_event (&data[0], -1, NULL, NULL, 0); |
| record_event (&data[1], -1, NULL, NULL, 0); |
| file = g_file_get_child (data[1].file, "a"); |
| g_file_replace_contents (file, "step 0", 6, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, &error); |
| g_assert_no_error (error); |
| g_object_unref (file); |
| break; |
| case 1: |
| record_event (&data[0], -1, NULL, NULL, 1); |
| record_event (&data[1], -1, NULL, NULL, 1); |
| file = g_file_get_child (data[1].file, "a"); |
| file2 = g_file_get_child (data[0].file, "a"); |
| g_file_move (file, file2, 0, NULL, NULL, NULL, &error); |
| g_assert_no_error (error); |
| g_object_unref (file); |
| g_object_unref (file2); |
| break; |
| case 2: |
| record_event (&data[0], -1, NULL, NULL, 2); |
| record_event (&data[1], -1, NULL, NULL, 2); |
| file2 = g_file_get_child (data[0].file, "a"); |
| g_file_delete (file2, NULL, NULL); |
| g_file_delete (data[0].file, NULL, NULL); |
| g_file_delete (data[1].file, NULL, NULL); |
| g_object_unref (file2); |
| break; |
| case 3: |
| record_event (&data[0], -1, NULL, NULL, 3); |
| record_event (&data[1], -1, NULL, NULL, 3); |
| g_main_loop_quit (data->loop); |
| return G_SOURCE_REMOVE; |
| } |
| |
| data->step++; |
| |
| return G_SOURCE_CONTINUE; |
| } |
| |
| static RecordedEvent cross_dir_a_output[] = { |
| { -1, NULL, NULL, 0 }, |
| { -1, NULL, NULL, 1 }, |
| { G_FILE_MONITOR_EVENT_CREATED, "a", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "a", NULL, -1 }, |
| { -1, NULL, NULL, 2 }, |
| { G_FILE_MONITOR_EVENT_DELETED, "a", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_DELETED, "cross_dir_a", NULL, -1 }, |
| { -1, NULL, NULL, 3 }, |
| }; |
| |
| static RecordedEvent cross_dir_b_output[] = { |
| { -1, NULL, NULL, 0 }, |
| { G_FILE_MONITOR_EVENT_CREATED, "a", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGED, "a", NULL, -1 }, |
| { G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, "a", NULL, -1 }, |
| { -1, NULL, NULL, 1 }, |
| { G_FILE_MONITOR_EVENT_MOVED_OUT, "a", "a", -1 }, |
| { -1, NULL, NULL, 2 }, |
| { G_FILE_MONITOR_EVENT_DELETED, "cross_dir_b", NULL, -1 }, |
| { -1, NULL, NULL, 3 }, |
| }; |
| static void |
| test_cross_dir_moves (void) |
| { |
| GError *error = NULL; |
| TestData data[2]; |
| |
| data[0].step = 0; |
| data[0].events = NULL; |
| |
| data[0].file = g_file_new_for_path ("cross_dir_a"); |
| g_file_delete (data[0].file, NULL, NULL); |
| g_file_make_directory (data[0].file, NULL, &error); |
| |
| data[0].monitor = g_file_monitor_directory (data[0].file, 0, NULL, &error); |
| g_assert_no_error (error); |
| |
| g_file_monitor_set_rate_limit (data[0].monitor, 200); |
| g_signal_connect (data[0].monitor, "changed", G_CALLBACK (monitor_changed), &data[0]); |
| |
| data[1].step = 0; |
| data[1].events = NULL; |
| |
| data[1].file = g_file_new_for_path ("cross_dir_b"); |
| g_file_delete (data[1].file, NULL, NULL); |
| g_file_make_directory (data[1].file, NULL, &error); |
| |
| data[1].monitor = g_file_monitor_directory (data[1].file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error); |
| g_assert_no_error (error); |
| |
| g_file_monitor_set_rate_limit (data[1].monitor, 200); |
| g_signal_connect (data[1].monitor, "changed", G_CALLBACK (monitor_changed), &data[1]); |
| |
| data[0].loop = g_main_loop_new (NULL, TRUE); |
| |
| g_timeout_add (500, cross_dir_step, data); |
| |
| g_main_loop_run (data[0].loop); |
| |
| #if 0 |
| g_print ("monitor a:\n"); |
| output_events (data[0].events); |
| g_print ("monitor b:\n"); |
| output_events (data[1].events); |
| #endif |
| |
| check_expected_events (cross_dir_a_output, G_N_ELEMENTS (cross_dir_a_output), data[0].events); |
| check_expected_events (cross_dir_b_output, G_N_ELEMENTS (cross_dir_b_output), data[1].events); |
| |
| g_list_free_full (data[0].events, (GDestroyNotify)free_recorded_event); |
| g_main_loop_unref (data[0].loop); |
| g_object_unref (data[0].monitor); |
| g_object_unref (data[0].file); |
| |
| g_list_free_full (data[1].events, (GDestroyNotify)free_recorded_event); |
| g_object_unref (data[1].monitor); |
| g_object_unref (data[1].file); |
| } |
| |
| int |
| main (int argc, char *argv[]) |
| { |
| g_test_init (&argc, &argv, NULL); |
| |
| g_test_add_func ("/monitor/atomic-replace", test_atomic_replace); |
| g_test_add_func ("/monitor/file-changes", test_file_changes); |
| g_test_add_func ("/monitor/dir-monitor", test_dir_monitor); |
| g_test_add_func ("/monitor/dir-not-existent", test_dir_non_existent); |
| g_test_add_func ("/monitor/cross-dir-moves", test_cross_dir_moves); |
| |
| return g_test_run (); |
| } |