From: Simon McVittie Date: Thu, 18 Oct 2018 12:45:12 +0000 (+0100) Subject: Add basic test coverage for the bus' desktop file parser X-Git-Tag: dbus-1.13.8~59^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5defe7d9eb066d5d3fa73123b389dc12009ee713;p=thirdparty%2Fdbus.git Add basic test coverage for the bus' desktop file parser This doesn't cover backslash-escaping in values, or various other corner cases, but it's a start. Signed-off-by: Simon McVittie --- diff --git a/test/Makefile.am b/test/Makefile.am index 7e2e202f6..399c3370d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -161,6 +161,7 @@ installable_tests += \ test-corrupt \ test-dbus-daemon \ test-dbus-daemon-eavesdrop \ + test-desktop-file \ test-fdpass \ test-header-fields \ test-message \ @@ -327,6 +328,15 @@ test_dbus_daemon_eavesdrop_LDADD = \ $(GLIB_LIBS) \ $(NULL) +test_desktop_file_SOURCES = \ + internals/desktop-file.c \ + $(NULL) +test_desktop_file_LDADD = \ + libdbus-testutils.la \ + $(top_builddir)/dbus/libdbus-internal.la \ + $(GLIB_LIBS) \ + $(NULL) + test_header_fields_SOURCES = \ header-fields.c \ $(NULL) diff --git a/test/internals/desktop-file.c b/test/internals/desktop-file.c new file mode 100644 index 000000000..d636e7b1b --- /dev/null +++ b/test/internals/desktop-file.c @@ -0,0 +1,275 @@ +/* + * Copyright 2018 Collabora Ltd. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +/* The code we're testing isn't available in a convenience library yet + * (see https://gitlab.freedesktop.org/dbus/dbus/merge_requests/1) and + * older Automake versions don't like source files in other directories, + * so we #include it. */ +#include "bus/desktop-file.h" +#include "bus/desktop-file.c" +const char bus_no_memory_message[] = "no memory"; + +#include +#include + +#include "test-utils-glib.h" + +typedef struct +{ + gchar *temp_file_name; +} Fixture; + +typedef struct +{ + const char *title; + const char *text; + gssize length; + const char *section; + const char *key; + const char *raw_value; + const char *value; +} Test; + +static const Test valid_content[] = +{ + { "newlines", "\n\n\n\n\n", -1 }, + { "spaces", " ", -1 }, + { "normal", + "[Foo]\n" + "bar=baz\n", + -1, + "Foo", + "bar", + "baz", + "baz" }, + { "empty value", + "[Foo]\n" + "bar=\n", + -1, + "Foo", + "bar", + "", + "" }, + { "empty section", + "[D-BUS Service]", + -1, + "D-BUS Service", + "foo", + NULL, + NULL }, + { "empty section with newline", + "[D-BUS Service]\n", + -1 }, + { "odd whitespace", + "\n\n \n[D-BUS Service]\n \n", + -1 }, + { "empty", "", -1 } +}; + +static const Test invalid_content[] = +{ + { "unterminated section heading", + "[D-BUS Service", + -1 }, + { "newline in section heading", + "[D-BUS Service\n]", + -1 }, + { "bare string not in section", + "aaaa", + -1 }, + { "key-value not in section", + "foo=bar", + -1 }, + { "contains control character", + "[foo]\001", + 6 }, + { "contains nul", + "[foo]\000", + 6 }, + { "empty section name", + "[]", + -1 } +}; + +static void +setup (Fixture *f, + gconstpointer data) +{ + const Test *test = data; + GError *error = NULL; + gboolean ok; + int fd; + + fd = g_file_open_tmp ("dbus-XXXXXX.desktop", &f->temp_file_name, &error); + + g_assert_no_error (error); + g_assert_cmpint (fd, >=, 0); + + ok = g_close (fd, &error); + g_assert_no_error (error); + g_assert_true (ok); + + ok = g_file_set_contents (f->temp_file_name, test->text, test->length, + &error); + g_assert_no_error (error); + g_assert_true (ok); +} + +/* + * If @test specifies a section and key, check that it contains the + * intended value. + */ +static void +test_content (const Test *test, + BusDesktopFile *bdf) +{ + if (test->section != NULL) + { + const char *raw = NULL; + char *val = NULL; + dbus_bool_t ok; + DBusError error = DBUS_ERROR_INIT; + + g_assert (test->key != NULL); + + ok = bus_desktop_file_get_raw (bdf, test->section, test->key, &raw); + + if (test->raw_value == NULL) + { + g_assert (test->value == NULL); + g_assert_false (ok); + } + else + { + g_assert_true (ok); + g_assert_cmpstr (raw, ==, test->raw_value); + } + + ok = bus_desktop_file_get_string (bdf, test->section, test->key, + &val, &error); + + if (test->value == NULL) + { + g_assert_nonnull (error.name); + g_assert_nonnull (error.message); + g_assert_false (ok); + g_assert_null (val); + } + else + { + test_assert_no_error (&error); + g_assert_true (ok); + g_assert_cmpstr (val, ==, test->value); + dbus_free (val); + } + } +} + +static void +test_valid (Fixture *f, + gconstpointer data) +{ + const Test *test = data; + BusDesktopFile *bdf; + DBusString str; + DBusError error = DBUS_ERROR_INIT; + + _dbus_string_init_const (&str, f->temp_file_name); + + bdf = bus_desktop_file_load (&str, &error); + test_assert_no_error (&error); + g_assert_nonnull (bdf); + test_content (test, bdf); + bus_desktop_file_free (bdf); + + /* Check that it's OK to ignore the error */ + bdf = bus_desktop_file_load (&str, NULL); + g_assert_nonnull (bdf); + test_content (test, bdf); + bus_desktop_file_free (bdf); +} + +static void +test_invalid (Fixture *f, + gconstpointer data) +{ + BusDesktopFile *bdf; + DBusString str; + DBusError error = DBUS_ERROR_INIT; + + _dbus_string_init_const (&str, f->temp_file_name); + + bdf = bus_desktop_file_load (&str, &error); + g_assert_nonnull (error.name); + g_assert_nonnull (error.message); + g_assert_null (bdf); + + /* Check that it's OK to ignore the error */ + bdf = bus_desktop_file_load (&str, NULL); + g_assert_null (bdf); +} + +static void +teardown (Fixture *f, + gconstpointer data) +{ + g_unlink (f->temp_file_name); + g_free (f->temp_file_name); +} + +int +main (int argc, + char **argv) +{ + gsize i; + int ret; + + test_init (&argc, &argv); + + for (i = 0; i < G_N_ELEMENTS (valid_content); i++) + { + gchar *title = g_strdup_printf ("/desktop-file/valid/%s", + valid_content[i].title); + + g_test_add (title, Fixture, &valid_content[i], + setup, test_valid, teardown); + g_free (title); + } + + for (i = 0; i < G_N_ELEMENTS (invalid_content); i++) + { + gchar *title = g_strdup_printf ("/desktop-file/invalid/%s", + invalid_content[i].title); + + g_test_add (title, Fixture, &invalid_content[i], + setup, test_invalid, teardown); + g_free (title); + } + + ret = g_test_run (); + dbus_shutdown (); + return ret; +}