Add a regression test for validating various string types with the public API
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Fri, 24 Feb 2012 12:44:14 +0000 (12:44 +0000)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Fri, 24 Feb 2012 12:44:14 +0000 (12:44 +0000)
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=39549
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Will Thompson <will.thompson@collabora.co.uk>
test/Makefile.am
test/syntax.c [new file with mode: 0644]

index f2abe28..9e66bd2 100644 (file)
@@ -105,6 +105,7 @@ installable_tests += \
        test-marshal \
        test-refs \
        test-relay \
+       test-syntax \
        test-syslog \
        $(NULL)
 endif DBUS_WITH_GLIB
@@ -155,6 +156,10 @@ test_marshal_LDADD = $(top_builddir)/dbus/libdbus-1.la \
     $(GLIB_LIBS) \
     $(DBUS_GLIB_LIBS)
 
+test_syntax_SOURCES = syntax.c
+test_syntax_LDADD = $(top_builddir)/dbus/libdbus-1.la \
+    $(GLIB_LIBS)
+
 if DBUS_ENABLE_MODULAR_TESTS
 TESTS += $(installable_tests)
 installcheck_tests += $(installable_tests)
diff --git a/test/syntax.c b/test/syntax.c
new file mode 100644 (file)
index 0000000..88db963
--- /dev/null
@@ -0,0 +1,289 @@
+/* Simple sanity-check for D-Bus syntax validation.
+ *
+ * Author: Simon McVittie <simon.mcvittie@collabora.co.uk>
+ * Copyright © 2010-2011 Nokia Corporation
+ *
+ * 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>
+
+#include <glib.h>
+
+#include <dbus/dbus.h>
+
+typedef struct {
+    DBusError e;
+} Fixture;
+
+typedef struct {
+    dbus_bool_t (*function) (const char *, DBusError *);
+    const char * const * valid;
+    const char * const * invalid;
+} Test;
+
+Test paths, interfaces, members, errors, bus_names, signatures,
+     single_signatures, strings;
+
+const char * const valid_paths[] = {
+    "/",
+    "/a",
+    "/_",
+    "/a/b/c",
+    "/com/example/123",
+    "/org/freedesktop/DBus",
+    "/org/freedesktop/Telepathy/AccountManager",
+    NULL
+};
+
+const char * const invalid_paths[] = {
+    "",
+    ".",
+    "//",
+    "/a/",
+    "/-",
+    "/com//example/MyApp",
+    "/$",
+    "/\xa9",      /* © in latin-1 */
+    "/\xc2\xa9",  /* © in UTF-8 */
+    NULL
+};
+
+const char * const valid_interfaces[] = {
+    "com.example",
+    "com.example.a0",
+    "org.freedesktop.DBus",
+    NULL
+};
+
+const char * const invalid_interfaces[] = {
+   "",
+    "com",
+    "com.example.",
+    "com.example..a0",
+    "com.example.0a",
+    "com.example.a$",
+    "com.example.a\xa9",
+    "com.example.a\xc2\xa9",
+    NULL
+};
+
+const char * const valid_members[] = {
+    "_",
+    "a",
+    "a0",
+    "GetAll",
+    "BadgerMushroomSnake",
+    NULL
+};
+
+const char * const invalid_members[] = {
+    "",
+    "-",
+    "a-",
+    "0",
+    "0_",
+    "Badger.Mushroom",
+    "a$",
+    "a\xa9",
+    "a\xc2\xa9",
+    NULL
+};
+
+const char * const valid_errors[] = {
+    "com.example",
+    "com.example.a0",
+    "org.freedesktop.DBus.NameHasNoOwner",
+    NULL
+};
+
+const char * const invalid_errors[] = {
+   "",
+    "com",
+    "com.example.",
+    "com.example..a0",
+    "com.example.0a",
+    "com.example.a$",
+    "com.example.a\xa9",
+    "com.example.a\xc2\xa9",
+    NULL
+};
+
+const char * const valid_bus_names[] = {
+    "com.example",
+    "com.example.a0",
+    "com.example._",
+    ":1.42",
+    ":1.2.3.4.5",
+    ":com.example",
+    "org.freedesktop.DBus",
+    NULL
+};
+
+const char * const invalid_bus_names[] = {
+   "",
+    "com",
+    "com.example.",
+    "com.example..a0",
+    "com.example.0a",
+    "com.example.a:b",
+    "com.example.a\xa9",
+    "com.example.a\xc2\xa9",
+    NULL
+};
+
+const char * const valid_signatures[] = {
+    "",
+    "a{sv}",
+    NULL
+};
+
+const char * const invalid_signatures[] = {
+    "a",
+    "a{s_}",
+    NULL
+};
+
+const char * const valid_single_signatures[] = {
+    "s",
+    "a{sv}",
+    NULL
+};
+
+const char * const invalid_single_signatures[] = {
+    "",
+    "a",
+    "sv",
+    "a{sv}as",
+    NULL
+};
+
+const char * const valid_strings[] = {
+    "",
+    "\xc2\xa9",
+    NULL
+};
+
+const char * const invalid_strings[] = {
+    "\xa9",
+    NULL
+};
+
+static void
+setup (Fixture *f,
+    gconstpointer arg G_GNUC_UNUSED)
+{
+  dbus_error_init (&f->e);
+
+#define FILL_TEST(name, func) \
+  do { \
+    (name).function = (func); \
+    (name).valid = valid_ ## name; \
+    (name).invalid = invalid_ ## name; \
+  } while (0)
+
+  FILL_TEST (paths, dbus_validate_path);
+  FILL_TEST (interfaces, dbus_validate_interface);
+  FILL_TEST (members, dbus_validate_member);
+  FILL_TEST (errors, dbus_validate_error_name);
+  FILL_TEST (bus_names, dbus_validate_bus_name);
+  FILL_TEST (signatures, dbus_signature_validate);
+  FILL_TEST (single_signatures, dbus_signature_validate_single);
+  FILL_TEST (strings, dbus_validate_utf8);
+}
+
+static void
+test_syntax (Fixture *f,
+    gconstpointer arg)
+{
+  const Test *test = arg;
+  int i;
+
+  g_assert (test != NULL);
+  g_assert (test->function != NULL);
+  g_assert (test->valid != NULL);
+  g_assert (test->invalid != NULL);
+
+  for (i = 0; test->valid[i] != NULL; i++)
+    {
+      dbus_bool_t ok = test->function (test->valid[i], &f->e);
+
+      if (dbus_error_is_set (&f->e))
+        g_error ("%s was considered invalid: %s: %s", test->valid[i],
+            f->e.name, f->e.message);
+
+      if (!ok)
+        g_error ("%s was considered invalid without an error", test->valid[i]);
+    }
+
+  for (i = 0; test->invalid[i] != NULL; i++)
+    {
+      dbus_bool_t ok = test->function (test->invalid[i], &f->e);
+
+      if (ok)
+        g_error ("%s should have been considered invalid", test->invalid[i]);
+
+      if (!dbus_error_is_set (&f->e))
+        g_error ("%s should have an error set", test->invalid[i]);
+
+      if (!dbus_validate_error_name (f->e.name, NULL))
+        g_error ("%s produced an invalid error name: %s",
+            test->invalid[i], f->e.name);
+
+      if (!dbus_validate_utf8 (f->e.message, NULL))
+        g_error ("%s produced an invalid error message: %s",
+            test->invalid[i], f->e.message);
+
+      dbus_error_free (&f->e);
+    }
+}
+
+static void
+teardown (Fixture *f,
+    gconstpointer arg G_GNUC_UNUSED)
+{
+  dbus_error_free (&f->e);
+}
+
+int
+main (int argc,
+    char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add ("/syntax/path", Fixture, &paths, setup, test_syntax, teardown);
+  g_test_add ("/syntax/interface", Fixture, &interfaces,
+      setup, test_syntax, teardown);
+  g_test_add ("/syntax/error", Fixture, &errors,
+      setup, test_syntax, teardown);
+  g_test_add ("/syntax/member", Fixture, &members,
+      setup, test_syntax, teardown);
+  g_test_add ("/syntax/bus-name", Fixture, &bus_names,
+      setup, test_syntax, teardown);
+  g_test_add ("/syntax/signature", Fixture, &signatures,
+      setup, test_syntax, teardown);
+  g_test_add ("/syntax/single-signature", Fixture, &single_signatures,
+      setup, test_syntax, teardown);
+  g_test_add ("/syntax/utf8", Fixture, &strings,
+      setup, test_syntax, teardown);
+
+  return g_test_run ();
+}