diff options
Diffstat (limited to 'tests/engine.c')
-rw-r--r-- | tests/engine.c | 162 |
1 files changed, 158 insertions, 4 deletions
diff --git a/tests/engine.c b/tests/engine.c index fd2a348..b0ad884 100644 --- a/tests/engine.c +++ b/tests/engine.c @@ -1466,7 +1466,7 @@ test_watch_sync (void) static void test_change_fast (void) { - DConfChangeset *empty, *good_write, *bad_write, *very_good_write, *slightly_bad_write; + DConfChangeset *empty, *good_write, *good_write2, *bad_write, *very_good_write, *slightly_bad_write; GvdbTable *table, *locks; DConfEngine *engine; gboolean success; @@ -1483,6 +1483,7 @@ test_change_fast (void) empty = dconf_changeset_new (); good_write = dconf_changeset_new_write ("/value", g_variant_new_string ("value")); + good_write2 = dconf_changeset_new_write ("/value2", g_variant_new_string ("value2")); bad_write = dconf_changeset_new_write ("/locked", g_variant_new_string ("value")); very_good_write = dconf_changeset_new_write ("/value", g_variant_new_string ("value")); dconf_changeset_set (very_good_write, "/to-reset", NULL); @@ -1517,6 +1518,15 @@ test_change_fast (void) dconf_mock_dbus_assert_no_async (); g_assert_cmpstr (change_log->str, ==, ""); + /* Verify that value is unset initially */ + value = dconf_engine_read (engine, DCONF_READ_FLAGS_NONE, NULL, "/value"); + g_assert (value == NULL); + + /* Verify that value2 is unset initially */ + value = dconf_engine_read (engine, DCONF_READ_FLAGS_NONE, NULL, "/value2"); + g_assert (value == NULL); + + /* change /value */ success = dconf_engine_change_fast (engine, good_write, NULL, &error); g_assert_no_error (error); g_assert (success); @@ -1530,7 +1540,48 @@ test_change_fast (void) g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "value"); g_variant_unref (value); - /* Fail the attempted write. This should cause a warning and a change. */ + /* Repeat the same write for /value (which is already in the in_flight queue) */ + success = dconf_engine_change_fast (engine, good_write, NULL, &error); + g_assert_no_error (error); + g_assert (success); + + /* Verify that /value is (still) set */ + value = dconf_engine_read (engine, DCONF_READ_FLAGS_NONE, NULL, "/value"); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "value"); + g_variant_unref (value); + + /* That should not have emitted a synthetic change event, since the (local) value did not change */ + g_assert_cmpstr (change_log->str, ==, ""); + g_string_set_size (change_log, 0); + + /* change /value2 */ + success = dconf_engine_change_fast (engine, good_write2, NULL, &error); + g_assert_no_error (error); + g_assert (success); + + /* That should have emitted a synthetic change event */ + g_assert_cmpstr (change_log->str, ==, "/value2:1::nil;"); + g_string_set_size (change_log, 0); + + /* Verify that /value2 is set */ + value = dconf_engine_read (engine, DCONF_READ_FLAGS_NONE, NULL, "/value2"); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "value2"); + g_variant_unref (value); + + /* change /value2 a second time */ + success = dconf_engine_change_fast (engine, good_write2, NULL, &error); + g_assert_no_error (error); + g_assert (success); + + /* That should not have emitted a synthetic change event because the (local) value didn't change */ + g_assert_cmpstr (change_log->str, ==, ""); + + /* Verify that /value2 is still set */ + value = dconf_engine_read (engine, DCONF_READ_FLAGS_NONE, NULL, "/value2"); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "value2"); + g_variant_unref (value); + + /* Fail the first attempted write. This should cause a warning and a signal. */ error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_NOENT, "something failed"); dconf_mock_dbus_async_reply (NULL, error); g_clear_error (&error); @@ -1539,8 +1590,25 @@ test_change_fast (void) assert_pop_message ("dconf", G_LOG_LEVEL_WARNING, "failed to commit changes to dconf: something failed"); - /* Verify that the value became unset due to the failure */ - value = dconf_engine_read (engine, DCONF_READ_FLAGS_NONE, NULL, "value"); + /* Verify that /value is still set (because the second write is in progress) */ + value = dconf_engine_read (engine, DCONF_READ_FLAGS_NONE, NULL, "/value"); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "value"); + g_variant_unref (value); + + /* Verify that /value2 is still set because the write is in progress */ + value = dconf_engine_read (engine, DCONF_READ_FLAGS_NONE, NULL, "/value2"); + g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "value2"); + g_variant_unref (value); + + /* Now allow the second set of writes to succeed */ + dconf_mock_dbus_async_reply (g_variant_new ("(s)", "tag"), NULL); + + /* Verify that /value became unset due to the in flight queue clearing */ + value = dconf_engine_read (engine, DCONF_READ_FLAGS_NONE, NULL, "/value"); + g_assert (value == NULL); + + /* Verify that /value2 became unset due to the in flight queue clearing */ + value = dconf_engine_read (engine, DCONF_READ_FLAGS_NONE, NULL, "/value2"); g_assert (value == NULL); /* Now try a successful write */ @@ -1619,6 +1687,91 @@ test_change_fast (void) change_log = NULL; } +/** + * Tests that dconf_engine_change_fast() emits local optimistic change + * notifications in the right circumstances + */ +static void +test_change_fast_redundant (void) +{ + DConfChangeset *change; + DConfEngine *engine; + change_log = g_string_new (NULL); + + // Initialise an empty engine + engine = dconf_engine_new (SRCDIR "/profile/dos", NULL, NULL); + + // Send an empty changeset, which has no effect + change = dconf_changeset_new (); + dconf_engine_change_fast (engine, change, NULL, NULL); + dconf_changeset_unref (change); + g_assert_cmpstr (change_log->str, ==, ""); + + // Reset the root directory, which has no effect since the database is empty + change = dconf_changeset_new_write ("/", NULL); + dconf_engine_change_fast (engine, change, NULL, NULL); + dconf_changeset_unref (change); + g_assert_cmpstr (change_log->str, ==, ""); + + // Set apple to NULL, which has no effect because it was already unset + change = dconf_changeset_new_write ("/apple", NULL); + dconf_engine_change_fast (engine, change, NULL, NULL); + dconf_changeset_unref (change); + g_assert_cmpstr (change_log->str, ==, ""); + + // Set apple to apple + change = dconf_changeset_new_write ("/apple", g_variant_new_string ("apple")); + dconf_engine_change_fast (engine, change, NULL, NULL); + dconf_changeset_unref (change); + g_assert_cmpstr (change_log->str, ==, "/apple:1::nil;"); + g_string_set_size (change_log, 0); + + // Set apple to apple, which has no effect because it is the same as the old value + change = dconf_changeset_new_write ("/apple", g_variant_new_string ("apple")); + dconf_engine_change_fast (engine, change, NULL, NULL); + dconf_changeset_unref (change); + g_assert_cmpstr (change_log->str, ==, ""); + g_string_set_size (change_log, 0); + + // Set apple to orange, which has an effect because it is different to the old value + change = dconf_changeset_new_write ("/apple", g_variant_new_string ("orange")); + dconf_engine_change_fast (engine, change, NULL, NULL); + dconf_changeset_unref (change); + g_assert_cmpstr (change_log->str, ==, "/apple:1::nil;"); + g_string_set_size (change_log, 0); + + // Set apple to NULL, which has an effect because it was previously set + change = dconf_changeset_new_write ("/apple", NULL); + dconf_engine_change_fast (engine, change, NULL, NULL); + dconf_changeset_unref (change); + g_assert_cmpstr (change_log->str, ==, "/apple:1::nil;"); + g_string_set_size (change_log, 0); + + // Set apple to apple + change = dconf_changeset_new_write ("/apple", g_variant_new_string ("apple")); + dconf_engine_change_fast (engine, change, NULL, NULL); + dconf_changeset_unref (change); + g_assert_cmpstr (change_log->str, ==, "/apple:1::nil;"); + g_string_set_size (change_log, 0); + + // Reset the root directory, which has an effect since the database is not empty + change = dconf_changeset_new_write ("/", NULL); + dconf_engine_change_fast (engine, change, NULL, NULL); + dconf_changeset_unref (change); + g_assert_cmpstr (change_log->str, ==, "/:1::nil;"); + g_string_set_size (change_log, 0); + + // Reset the root directory again, which has no effect since the database is empty + change = dconf_changeset_new_write ("/", NULL); + dconf_engine_change_fast (engine, change, NULL, NULL); + dconf_changeset_unref (change); + g_assert_cmpstr (change_log->str, ==, ""); + + dconf_engine_unref (engine); + g_string_free (change_log, TRUE); + change_log = NULL; +} + static GError *change_sync_error; static GVariant *change_sync_result; @@ -2087,6 +2240,7 @@ main (int argc, char **argv) g_test_add_func ("/engine/watch/fast/short_lived", test_watch_fast_short_lived_subscriptions); g_test_add_func ("/engine/watch/sync", test_watch_sync); g_test_add_func ("/engine/change/fast", test_change_fast); + g_test_add_func ("/engine/change/fast_redundant", test_change_fast_redundant); g_test_add_func ("/engine/change/sync", test_change_sync); g_test_add_func ("/engine/signals", test_signals); g_test_add_func ("/engine/sync", test_sync); |