diff options
author | Daniel Playfair Cal <daniel.playfair.cal@gmail.com> | 2019-12-30 00:38:58 +0000 |
---|---|---|
committer | Daniel Playfair Cal <daniel.playfair.cal@gmail.com> | 2019-12-30 00:38:58 +0000 |
commit | a1da64420c365004da1049199b03e6eca9c5f447 (patch) | |
tree | d3eb3350d99e70ee771a09b786db2dc169237b12 /tests/writer.c | |
parent | 7ad890fb7a2ec90a777a756a1fa20a615ec7245e (diff) | |
parent | f3104f75f945bd3418e5cf59fcc7c5044c071f2b (diff) | |
download | dconf-a1da64420c365004da1049199b03e6eca9c5f447.tar.gz |
Merge branch 'patch/service-check' into 'master'
Service: only emit changed signals when values change
See merge request GNOME/dconf!3
Diffstat (limited to 'tests/writer.c')
-rw-r--r-- | tests/writer.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/tests/writer.c b/tests/writer.c index 955ba91..df33fc4 100644 --- a/tests/writer.c +++ b/tests/writer.c @@ -45,6 +45,29 @@ assert_n_warnings (guint expected_n_warnings) n_warnings = 0; } +static guint64 +get_file_mtime_us (char *filename) +{ + GFile *file = g_file_new_for_path (filename); + GError *error = NULL; + GFileInfo *info = g_file_query_info ( + file, + "time::*", + G_FILE_QUERY_INFO_NONE, + NULL, + &error); + if (!info) + { + printf ("failed with error %i: %s\n", error->code, error->message); + exit (1); + } + + guint64 mtime_us = + g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED) * 1000000 + + g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC); + return mtime_us; +} + typedef struct { gchar *dconf_dir; /* (owned) */ @@ -179,6 +202,182 @@ test_writer_begin_corrupt_file (Fixture *fixture, } } +/** + * Test that committing a write operation when no writes have been queued + * does not result in a database write. + */ +static void test_writer_commit_no_change (Fixture *fixture, + gconstpointer test_data) +{ + const char *db_name = "nonexistent"; + g_autoptr(DConfWriter) writer = NULL; + DConfWriterClass *writer_class; + gboolean retval; + g_autoptr(GError) local_error = NULL; + g_autofree gchar *db_filename = g_build_filename (fixture->dconf_dir, db_name, NULL); + + /* Create a writer. */ + writer = DCONF_WRITER (dconf_writer_new (DCONF_TYPE_WRITER, db_name)); + g_assert_nonnull (writer); + writer_class = DCONF_WRITER_GET_CLASS (writer); + + /* Check the database doesn’t exist. */ + g_assert_false (g_file_test (db_filename, G_FILE_TEST_EXISTS)); + + /* Begin transaction */ + retval = writer_class->begin (writer, &local_error); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Commit transaction */ + retval = writer_class->commit (writer, &local_error); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Check the database still doesn’t exist. */ + g_assert_false (g_file_test (db_filename, G_FILE_TEST_EXISTS)); + + /* End transaction */ + writer_class->end (writer); +} + +/** + * Test that committing a write operation when writes that would not change + * the database have been queued does not result in a database write. + */ +static void test_writer_commit_empty_changes (Fixture *fixture, + gconstpointer test_data) +{ + const char *db_name = "nonexistent"; + g_autoptr(DConfWriter) writer = NULL; + DConfWriterClass *writer_class; + gboolean retval; + g_autoptr(GError) local_error = NULL; + g_autofree gchar *db_filename = g_build_filename (fixture->dconf_dir, db_name, NULL); + + /* Create a writer. */ + writer = DCONF_WRITER (dconf_writer_new (DCONF_TYPE_WRITER, db_name)); + g_assert_nonnull (writer); + writer_class = DCONF_WRITER_GET_CLASS (writer); + + /* Check the database doesn’t exist. */ + g_assert_false (g_file_test (db_filename, G_FILE_TEST_EXISTS)); + + /* Begin transaction */ + retval = writer_class->begin (writer, &local_error); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Make a redundant/empty change to the database */ + DConfChangeset *changes = dconf_changeset_new(); + writer_class->change (writer, changes, NULL); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Commit transaction */ + retval = writer_class->commit (writer, &local_error); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Check the database still doesn't exist */ + g_assert_false (g_file_test (db_filename, G_FILE_TEST_EXISTS)); + + /* End transaction */ + writer_class->end (writer); +} + +/** + * Test that committing a write operation when writes that would change + * the database have been queued does result in a database write. + */ +static void test_writer_commit_real_changes (Fixture *fixture, + gconstpointer test_data) +{ + const char *db_name = "nonexistent"; + g_autoptr(DConfWriter) writer = NULL; + DConfWriterClass *writer_class; + DConfChangeset *changes; + gboolean retval; + g_autoptr(GError) local_error = NULL; + guint64 db_mtime_us; + g_autofree gchar *db_filename = g_build_filename (fixture->dconf_dir, db_name, NULL); + + /* Create a writer. */ + writer = DCONF_WRITER (dconf_writer_new (DCONF_TYPE_WRITER, db_name)); + g_assert_nonnull (writer); + writer_class = DCONF_WRITER_GET_CLASS (writer); + + /* Check the database doesn’t exist. */ + g_assert_false (g_file_test (db_filename, G_FILE_TEST_EXISTS)); + + /* Begin transaction */ + retval = writer_class->begin (writer, &local_error); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Make a real change to the database */ + changes = dconf_changeset_new(); + dconf_changeset_set(changes, "/key", g_variant_new ("(s)", "value")); + writer_class->change (writer, changes, NULL); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Commit transaction */ + retval = writer_class->commit (writer, &local_error); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Check the database now exists */ + g_assert_true (g_file_test (db_filename, G_FILE_TEST_EXISTS)); + db_mtime_us = get_file_mtime_us (db_filename); + + /* End transaction */ + writer_class->end (writer); + + /* Begin a second transaction */ + retval = writer_class->begin (writer, &local_error); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Make a redundant/empty change to the database */ + changes = dconf_changeset_new(); + writer_class->change (writer, changes, NULL); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Commit transaction */ + retval = writer_class->commit (writer, &local_error); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* End transaction */ + writer_class->end (writer); + + /* Check that no extra write was done (even afer committing a real change) */ + g_assert_cmpuint (db_mtime_us, ==, get_file_mtime_us (db_filename)); + db_mtime_us = get_file_mtime_us (db_filename); + + /* Begin a third transaction */ + retval = writer_class->begin (writer, &local_error); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Commit transaction (with no changes at all) */ + retval = writer_class->commit (writer, &local_error); + g_assert_no_error (local_error); + g_assert_true (retval); + + /* Check that no extra write was done (even afer committing a real change) */ + g_assert_cmpuint (db_mtime_us, ==, get_file_mtime_us (db_filename)); + db_mtime_us = get_file_mtime_us (db_filename); + + /* End transaction */ + writer_class->end (writer); + + /* Clean up. */ + g_assert_cmpint (g_unlink (db_filename), ==, 0); +} + int main (int argc, char **argv) { @@ -221,6 +420,12 @@ main (int argc, char **argv) test_writer_begin_corrupt_file, tear_down); g_test_add ("/writer/begin/corrupt-file/2", Fixture, &corrupt_file_data2, set_up, test_writer_begin_corrupt_file, tear_down); + g_test_add ("/writer/commit/redundant_change/0", Fixture, NULL, set_up, + test_writer_commit_no_change, tear_down); + g_test_add ("/writer/commit/redundant_change/1", Fixture, NULL, set_up, + test_writer_commit_empty_changes, tear_down); + g_test_add ("/writer/commit/redundant_change/2", Fixture, NULL, set_up, + test_writer_commit_real_changes, tear_down); retval = g_test_run (); |