]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
Add basic test coverage for the bus' desktop file parser
authorSimon McVittie <smcv@collabora.com>
Thu, 18 Oct 2018 12:45:12 +0000 (13:45 +0100)
committerSimon McVittie <smcv@collabora.com>
Fri, 19 Oct 2018 11:11:55 +0000 (11:11 +0000)
This doesn't cover backslash-escaping in values, or various other
corner cases, but it's a start.

Signed-off-by: Simon McVittie <smcv@collabora.com>
test/Makefile.am
test/internals/desktop-file.c [new file with mode: 0644]

index 7e2e202f6e727e2ee0f5ac9e6fd06280de3a09b7..399c3370d652267dfcc4c320c7cd33395c142b77 100644 (file)
@@ -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 (file)
index 0000000..d636e7b
--- /dev/null
@@ -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 <config.h>
+
+/* 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 <glib.h>
+#include <glib/gstdio.h>
+
+#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;
+}