mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-25 19:52:10 +01:00
Merge branch '1634-testfilemonitor-race' into 'master'
Improve testfilemonitor test repeatability and debuggability See merge request GNOME/glib!908
This commit is contained in:
commit
3b5535c5bb
@ -9,6 +9,37 @@
|
|||||||
* the tests, e.g. the length of timeouts
|
* the tests, e.g. the length of timeouts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GFile *tmp_dir;
|
||||||
|
} Fixture;
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup (Fixture *fixture,
|
||||||
|
gconstpointer user_data)
|
||||||
|
{
|
||||||
|
gchar *path = NULL;
|
||||||
|
GError *local_error = NULL;
|
||||||
|
|
||||||
|
path = g_dir_make_tmp ("gio-test-testfilemonitor_XXXXXX", &local_error);
|
||||||
|
g_assert_no_error (local_error);
|
||||||
|
|
||||||
|
fixture->tmp_dir = g_file_new_for_path (path);
|
||||||
|
|
||||||
|
g_test_message ("Using temporary directory: %s", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
teardown (Fixture *fixture,
|
||||||
|
gconstpointer user_data)
|
||||||
|
{
|
||||||
|
GError *local_error = NULL;
|
||||||
|
|
||||||
|
g_file_delete (fixture->tmp_dir, NULL, &local_error);
|
||||||
|
g_assert_no_error (local_error);
|
||||||
|
g_clear_object (&fixture->tmp_dir);
|
||||||
|
}
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
INOTIFY = (1 << 1),
|
INOTIFY = (1 << 1),
|
||||||
@ -48,36 +79,24 @@ typedef struct
|
|||||||
GFileOutputStream *output_stream;
|
GFileOutputStream *output_stream;
|
||||||
} TestData;
|
} TestData;
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void
|
static void
|
||||||
output_event (RecordedEvent *event)
|
output_event (const RecordedEvent *event)
|
||||||
{
|
{
|
||||||
if (event->step >= 0)
|
if (event->step >= 0)
|
||||||
g_print (">>>> step %d\n", event->step);
|
g_test_message (">>>> step %d", event->step);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GTypeClass *class;
|
GTypeClass *class;
|
||||||
|
|
||||||
class = g_type_class_ref (g_type_from_name ("GFileMonitorEvent"));
|
class = g_type_class_ref (g_type_from_name ("GFileMonitorEvent"));
|
||||||
g_print ("%s file=%s other_file=%s\n",
|
g_test_message ("%s file=%s other_file=%s\n",
|
||||||
g_enum_get_value (G_ENUM_CLASS (class), event->event_type)->value_nick,
|
g_enum_get_value (G_ENUM_CLASS (class), event->event_type)->value_nick,
|
||||||
event->file,
|
event->file,
|
||||||
event->other_file);
|
event->other_file);
|
||||||
g_type_class_unref (class);
|
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 */
|
/* a placeholder for temp file names we don't want to compare */
|
||||||
static const gchar DONT_CARE[] = "";
|
static const gchar DONT_CARE[] = "";
|
||||||
|
|
||||||
@ -210,9 +229,20 @@ check_expected_events (RecordedEvent *expected,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Run above checks under g_assert_* again to provide more useful
|
/* Run above checks under g_assert_* again to provide more useful
|
||||||
* error messages. */
|
* error messages. Print the expected and actual events first. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
GList *l;
|
||||||
|
gsize j;
|
||||||
|
|
||||||
|
g_test_message ("Recorded events:");
|
||||||
|
for (l = recorded; l != NULL; l = l->next)
|
||||||
|
output_event ((RecordedEvent *) l->data);
|
||||||
|
|
||||||
|
g_test_message ("Expected events:");
|
||||||
|
for (j = 0; j < n_expected; j++)
|
||||||
|
output_event (&expected[j]);
|
||||||
|
|
||||||
g_assert_cmpint (e1->step, ==, e2->step);
|
g_assert_cmpint (e1->step, ==, e2->step);
|
||||||
g_assert_cmpint (e1->event_type, ==, e2->event_type);
|
g_assert_cmpint (e1->event_type, ==, e2->event_type);
|
||||||
|
|
||||||
@ -322,7 +352,8 @@ static RecordedEvent atomic_replace_output[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_atomic_replace (void)
|
test_atomic_replace (Fixture *fixture,
|
||||||
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
TestData data;
|
TestData data;
|
||||||
@ -330,12 +361,14 @@ test_atomic_replace (void)
|
|||||||
data.step = 0;
|
data.step = 0;
|
||||||
data.events = NULL;
|
data.events = NULL;
|
||||||
|
|
||||||
data.file = g_file_new_for_path ("atomic_replace_file");
|
data.file = g_file_get_child (fixture->tmp_dir, "atomic_replace_file");
|
||||||
g_file_delete (data.file, NULL, NULL);
|
g_file_delete (data.file, NULL, NULL);
|
||||||
|
|
||||||
data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error);
|
data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_test_message ("Using GFileMonitor %s", G_OBJECT_TYPE_NAME (data.monitor));
|
||||||
|
|
||||||
g_file_monitor_set_rate_limit (data.monitor, 200);
|
g_file_monitor_set_rate_limit (data.monitor, 200);
|
||||||
g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data);
|
g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data);
|
||||||
|
|
||||||
@ -345,7 +378,6 @@ test_atomic_replace (void)
|
|||||||
|
|
||||||
g_main_loop_run (data.loop);
|
g_main_loop_run (data.loop);
|
||||||
|
|
||||||
/*output_events (data.events);*/
|
|
||||||
check_expected_events (atomic_replace_output,
|
check_expected_events (atomic_replace_output,
|
||||||
G_N_ELEMENTS (atomic_replace_output),
|
G_N_ELEMENTS (atomic_replace_output),
|
||||||
data.events,
|
data.events,
|
||||||
@ -425,7 +457,8 @@ static RecordedEvent change_output[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_file_changes (void)
|
test_file_changes (Fixture *fixture,
|
||||||
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
TestData data;
|
TestData data;
|
||||||
@ -433,12 +466,14 @@ test_file_changes (void)
|
|||||||
data.step = 0;
|
data.step = 0;
|
||||||
data.events = NULL;
|
data.events = NULL;
|
||||||
|
|
||||||
data.file = g_file_new_for_path ("change_file");
|
data.file = g_file_get_child (fixture->tmp_dir, "change_file");
|
||||||
g_file_delete (data.file, NULL, NULL);
|
g_file_delete (data.file, NULL, NULL);
|
||||||
|
|
||||||
data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error);
|
data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_test_message ("Using GFileMonitor %s", G_OBJECT_TYPE_NAME (data.monitor));
|
||||||
|
|
||||||
g_file_monitor_set_rate_limit (data.monitor, 200);
|
g_file_monitor_set_rate_limit (data.monitor, 200);
|
||||||
g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data);
|
g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data);
|
||||||
|
|
||||||
@ -448,7 +483,6 @@ test_file_changes (void)
|
|||||||
|
|
||||||
g_main_loop_run (data.loop);
|
g_main_loop_run (data.loop);
|
||||||
|
|
||||||
/*output_events (data.events);*/
|
|
||||||
check_expected_events (change_output,
|
check_expected_events (change_output,
|
||||||
G_N_ELEMENTS (change_output),
|
G_N_ELEMENTS (change_output),
|
||||||
data.events,
|
data.events,
|
||||||
@ -540,7 +574,8 @@ static RecordedEvent dir_output[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_dir_monitor (void)
|
test_dir_monitor (Fixture *fixture,
|
||||||
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
TestData data;
|
TestData data;
|
||||||
@ -548,13 +583,15 @@ test_dir_monitor (void)
|
|||||||
data.step = 0;
|
data.step = 0;
|
||||||
data.events = NULL;
|
data.events = NULL;
|
||||||
|
|
||||||
data.file = g_file_new_for_path ("dir_monitor_test");
|
data.file = g_file_get_child (fixture->tmp_dir, "dir_monitor_test");
|
||||||
g_file_delete (data.file, NULL, NULL);
|
g_file_delete (data.file, NULL, NULL);
|
||||||
g_file_make_directory (data.file, NULL, &error);
|
g_file_make_directory (data.file, NULL, &error);
|
||||||
|
|
||||||
data.monitor = g_file_monitor_directory (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error);
|
data.monitor = g_file_monitor_directory (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_test_message ("Using GFileMonitor %s", G_OBJECT_TYPE_NAME (data.monitor));
|
||||||
|
|
||||||
g_file_monitor_set_rate_limit (data.monitor, 200);
|
g_file_monitor_set_rate_limit (data.monitor, 200);
|
||||||
g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data);
|
g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data);
|
||||||
|
|
||||||
@ -564,7 +601,6 @@ test_dir_monitor (void)
|
|||||||
|
|
||||||
g_main_loop_run (data.loop);
|
g_main_loop_run (data.loop);
|
||||||
|
|
||||||
/*output_events (data.events);*/
|
|
||||||
check_expected_events (dir_output,
|
check_expected_events (dir_output,
|
||||||
G_N_ELEMENTS (dir_output),
|
G_N_ELEMENTS (dir_output),
|
||||||
data.events,
|
data.events,
|
||||||
@ -635,7 +671,8 @@ static RecordedEvent nodir_output[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_dir_non_existent (void)
|
test_dir_non_existent (Fixture *fixture,
|
||||||
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
TestData data;
|
TestData data;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
@ -643,10 +680,12 @@ test_dir_non_existent (void)
|
|||||||
data.step = 0;
|
data.step = 0;
|
||||||
data.events = NULL;
|
data.events = NULL;
|
||||||
|
|
||||||
data.file = g_file_new_for_path ("nosuchdir/nosuchfile");
|
data.file = g_file_get_child (fixture->tmp_dir, "nosuchdir/nosuchfile");
|
||||||
data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error);
|
data.monitor = g_file_monitor_file (data.file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_test_message ("Using GFileMonitor %s", G_OBJECT_TYPE_NAME (data.monitor));
|
||||||
|
|
||||||
g_file_monitor_set_rate_limit (data.monitor, 200);
|
g_file_monitor_set_rate_limit (data.monitor, 200);
|
||||||
g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data);
|
g_signal_connect (data.monitor, "changed", G_CALLBACK (monitor_changed), &data);
|
||||||
|
|
||||||
@ -659,7 +698,6 @@ test_dir_non_existent (void)
|
|||||||
|
|
||||||
g_main_loop_run (data.loop);
|
g_main_loop_run (data.loop);
|
||||||
|
|
||||||
/*output_events (data.events);*/
|
|
||||||
check_expected_events (nodir_output,
|
check_expected_events (nodir_output,
|
||||||
G_N_ELEMENTS (nodir_output),
|
G_N_ELEMENTS (nodir_output),
|
||||||
data.events,
|
data.events,
|
||||||
@ -742,7 +780,8 @@ static RecordedEvent cross_dir_b_output[] = {
|
|||||||
{ -1, NULL, NULL, 3, NONE },
|
{ -1, NULL, NULL, 3, NONE },
|
||||||
};
|
};
|
||||||
static void
|
static void
|
||||||
test_cross_dir_moves (void)
|
test_cross_dir_moves (Fixture *fixture,
|
||||||
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
TestData data[2];
|
TestData data[2];
|
||||||
@ -750,26 +789,30 @@ test_cross_dir_moves (void)
|
|||||||
data[0].step = 0;
|
data[0].step = 0;
|
||||||
data[0].events = NULL;
|
data[0].events = NULL;
|
||||||
|
|
||||||
data[0].file = g_file_new_for_path ("cross_dir_a");
|
data[0].file = g_file_get_child (fixture->tmp_dir, "cross_dir_a");
|
||||||
g_file_delete (data[0].file, NULL, NULL);
|
g_file_delete (data[0].file, NULL, NULL);
|
||||||
g_file_make_directory (data[0].file, NULL, &error);
|
g_file_make_directory (data[0].file, NULL, &error);
|
||||||
|
|
||||||
data[0].monitor = g_file_monitor_directory (data[0].file, 0, NULL, &error);
|
data[0].monitor = g_file_monitor_directory (data[0].file, 0, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_test_message ("Using GFileMonitor 0 %s", G_OBJECT_TYPE_NAME (data[0].monitor));
|
||||||
|
|
||||||
g_file_monitor_set_rate_limit (data[0].monitor, 200);
|
g_file_monitor_set_rate_limit (data[0].monitor, 200);
|
||||||
g_signal_connect (data[0].monitor, "changed", G_CALLBACK (monitor_changed), &data[0]);
|
g_signal_connect (data[0].monitor, "changed", G_CALLBACK (monitor_changed), &data[0]);
|
||||||
|
|
||||||
data[1].step = 0;
|
data[1].step = 0;
|
||||||
data[1].events = NULL;
|
data[1].events = NULL;
|
||||||
|
|
||||||
data[1].file = g_file_new_for_path ("cross_dir_b");
|
data[1].file = g_file_get_child (fixture->tmp_dir, "cross_dir_b");
|
||||||
g_file_delete (data[1].file, NULL, NULL);
|
g_file_delete (data[1].file, NULL, NULL);
|
||||||
g_file_make_directory (data[1].file, NULL, &error);
|
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);
|
data[1].monitor = g_file_monitor_directory (data[1].file, G_FILE_MONITOR_WATCH_MOVES, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
|
|
||||||
|
g_test_message ("Using GFileMonitor 1 %s", G_OBJECT_TYPE_NAME (data[1].monitor));
|
||||||
|
|
||||||
g_file_monitor_set_rate_limit (data[1].monitor, 200);
|
g_file_monitor_set_rate_limit (data[1].monitor, 200);
|
||||||
g_signal_connect (data[1].monitor, "changed", G_CALLBACK (monitor_changed), &data[1]);
|
g_signal_connect (data[1].monitor, "changed", G_CALLBACK (monitor_changed), &data[1]);
|
||||||
|
|
||||||
@ -779,13 +822,6 @@ test_cross_dir_moves (void)
|
|||||||
|
|
||||||
g_main_loop_run (data[0].loop);
|
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,
|
check_expected_events (cross_dir_a_output,
|
||||||
G_N_ELEMENTS (cross_dir_a_output),
|
G_N_ELEMENTS (cross_dir_a_output),
|
||||||
data[0].events,
|
data[0].events,
|
||||||
@ -913,7 +949,8 @@ static RecordedEvent file_hard_links_output[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_file_hard_links (void)
|
test_file_hard_links (Fixture *fixture,
|
||||||
|
gconstpointer user_data)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
TestData data;
|
TestData data;
|
||||||
@ -930,7 +967,7 @@ test_file_hard_links (void)
|
|||||||
data.events = NULL;
|
data.events = NULL;
|
||||||
|
|
||||||
/* Create a file which exists and is not a directory. */
|
/* Create a file which exists and is not a directory. */
|
||||||
data.file = g_file_new_for_path ("testfilemonitor.db");
|
data.file = g_file_get_child (fixture->tmp_dir, "testfilemonitor.db");
|
||||||
data.output_stream = g_file_replace (data.file, NULL, FALSE,
|
data.output_stream = g_file_replace (data.file, NULL, FALSE,
|
||||||
G_FILE_CREATE_NONE, NULL, &error);
|
G_FILE_CREATE_NONE, NULL, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
@ -945,6 +982,8 @@ test_file_hard_links (void)
|
|||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert_nonnull (data.monitor);
|
g_assert_nonnull (data.monitor);
|
||||||
|
|
||||||
|
g_test_message ("Using GFileMonitor %s", G_OBJECT_TYPE_NAME (data.monitor));
|
||||||
|
|
||||||
/* Change the file a bit. */
|
/* Change the file a bit. */
|
||||||
g_file_monitor_set_rate_limit (data.monitor, 200);
|
g_file_monitor_set_rate_limit (data.monitor, 200);
|
||||||
g_signal_connect (data.monitor, "changed", (GCallback) monitor_changed, &data);
|
g_signal_connect (data.monitor, "changed", (GCallback) monitor_changed, &data);
|
||||||
@ -953,7 +992,6 @@ test_file_hard_links (void)
|
|||||||
g_timeout_add (500, file_hard_links_step, &data);
|
g_timeout_add (500, file_hard_links_step, &data);
|
||||||
g_main_loop_run (data.loop);
|
g_main_loop_run (data.loop);
|
||||||
|
|
||||||
/* output_events (data.events); */
|
|
||||||
check_expected_events (file_hard_links_output,
|
check_expected_events (file_hard_links_output,
|
||||||
G_N_ELEMENTS (file_hard_links_output),
|
G_N_ELEMENTS (file_hard_links_output),
|
||||||
data.events,
|
data.events,
|
||||||
@ -973,12 +1011,12 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id=");
|
g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id=");
|
||||||
|
|
||||||
g_test_add_func ("/monitor/atomic-replace", test_atomic_replace);
|
g_test_add ("/monitor/atomic-replace", Fixture, NULL, setup, test_atomic_replace, teardown);
|
||||||
g_test_add_func ("/monitor/file-changes", test_file_changes);
|
g_test_add ("/monitor/file-changes", Fixture, NULL, setup, test_file_changes, teardown);
|
||||||
g_test_add_func ("/monitor/dir-monitor", test_dir_monitor);
|
g_test_add ("/monitor/dir-monitor", Fixture, NULL, setup, test_dir_monitor, teardown);
|
||||||
g_test_add_func ("/monitor/dir-not-existent", test_dir_non_existent);
|
g_test_add ("/monitor/dir-not-existent", Fixture, NULL, setup, test_dir_non_existent, teardown);
|
||||||
g_test_add_func ("/monitor/cross-dir-moves", test_cross_dir_moves);
|
g_test_add ("/monitor/cross-dir-moves", Fixture, NULL, setup, test_cross_dir_moves, teardown);
|
||||||
g_test_add_func ("/monitor/file/hard-links", test_file_hard_links);
|
g_test_add ("/monitor/file/hard-links", Fixture, NULL, setup, test_file_hard_links, teardown);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user