dispatch: test <check> rule sandbox/pohly/tizen
authorPatrick Ohly <patrick.ohly@intel.com>
Fri, 1 Aug 2014 18:35:31 +0000 (20:35 +0200)
committerPatrick Ohly <patrick.ohly@intel.com>
Fri, 1 Aug 2014 18:47:48 +0000 (20:47 +0200)
The test replaces the check_privilege() implementation and therefore
a) works without a real implementation and b) can verify that exactly
the right calls to that method happen.

To run it manually, invoke inside the build dir's test directory:

XDG_RUNTIME_DIR=`pwd`/XDG_RUNTIME_DIR \
DBUS_FATAL_WARNINGS=1 \
DBUS_TEST_DATA=`pwd`/data \
DBUS_TEST_DAEMON=`pwd`/../bus/dbus-daemon \
DBUS_TEST_HOMEDIR=`pwd`/../dbus \
../bus/test-bus `pwd`/data dispatch

When running under gdb, drop the DBUS_FATAL_WARNINGS=1. At least here
the test aborted because of some additional file descriptors created
by (or inherited accidentally from?) gdb.

bus/dispatch.c
configure.ac
test/Makefile.am
test/data/valid-config-files/.gitignore
test/data/valid-config-files/debug-check-some.conf.in [new file with mode: 0644]

index 66c91e6..d899511 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <config.h>
 #include "dispatch.h"
+#include "check.h"
 #include "connection.h"
 #include "driver.h"
 #include "services.h"
@@ -34,6 +35,7 @@
 #include "signals.h"
 #include "test.h"
 #include <dbus/dbus-internals.h>
+#include <dbus/dbus-connection-internal.h>
 #include <dbus/dbus-misc.h>
 #include <string.h>
 
@@ -4739,9 +4741,132 @@ bus_dispatch_test_conf_fail (const DBusString *test_data_dir,
   return TRUE;
 }
 
+typedef struct {
+  DBusTimeout *timeout;
+  DBusConnection *connection;
+  dbus_bool_t timedout;
+  int check_counter;
+} BusTestCheckData;
+
+static BusTestCheckData *cdata;
+
+static dbus_bool_t
+bus_dispatch_test_check_timeout (void *data)
+{
+  _dbus_verbose ("timeout triggered - pretend that privilege check result is available");
+
+  /* should only happen once during the test */
+  _dbus_assert (!cdata->timedout);
+  cdata->timedout = TRUE;
+  _dbus_connection_enable_dispatch (cdata->connection);
+
+  /* don't call this again */
+  _dbus_loop_remove_timeout (bus_connection_get_loop (cdata->connection),
+                             cdata->timeout);
+  dbus_connection_unref (cdata->connection);
+  cdata->connection = NULL;
+  return TRUE;
+}
+
+static dbus_bool_t
+bus_dispatch_test_check_override (DBusConnection *connection,
+                                  const char *privilege)
+{
+  _dbus_verbose ("overriding privilege check %s #%d", privilege, cdata->check_counter);
+  cdata->check_counter++;
+  if (!cdata->timedout)
+    {
+      dbus_bool_t added;
+
+      /* Should be the first privilege check for the "Echo" method. */
+      _dbus_assert (cdata->check_counter == 1);
+      cdata->timeout = _dbus_timeout_new (1, bus_dispatch_test_check_timeout,
+                                          NULL, NULL);
+      _dbus_assert (cdata->timeout);
+      added = _dbus_loop_add_timeout (bus_connection_get_loop (connection),
+                                      cdata->timeout);
+      _dbus_assert (added);
+      cdata->connection = connection;
+      dbus_connection_ref (connection);
+      _dbus_connection_disable_dispatch (connection);
+      return BUS_RESULT_LATER;
+    }
+  else
+    {
+      /* Should only be checked one more time, and this time succeeds. */
+      _dbus_assert (cdata->check_counter == 2);
+      return BUS_RESULT_TRUE;
+    }
+}
+
+static dbus_bool_t
+bus_dispatch_test_check (const DBusString *test_data_dir)
+{
+  const char *filename = "valid-config-files/debug-check-some.conf";
+  BusContext *context;
+  DBusConnection *foo;
+  DBusError error;
+  dbus_bool_t result = TRUE;
+  BusTestCheckData data;
+
+  /* save the config name for the activation helper */
+  if (!setenv_TEST_LAUNCH_HELPER_CONFIG (test_data_dir, filename))
+    _dbus_assert_not_reached ("no memory setting TEST_LAUNCH_HELPER_CONFIG");
+
+  dbus_error_init (&error);
+
+  context = bus_context_new_test (test_data_dir, filename);
+  if (context == NULL)
+    return FALSE;
+
+  foo = dbus_connection_open_private (TEST_DEBUG_PIPE, &error);
+  if (foo == NULL)
+    _dbus_assert_not_reached ("could not alloc connection");
+
+  if (!bus_setup_debug_client (foo))
+    _dbus_assert_not_reached ("could not set up connection");
+
+  spin_connection_until_authenticated (context, foo);
+
+  if (!check_hello_message (context, foo))
+    _dbus_assert_not_reached ("hello message failed");
+
+  if (!check_double_hello_message (context, foo))
+    _dbus_assert_not_reached ("double hello message failed");
+
+  if (!check_add_match_all (context, foo))
+    _dbus_assert_not_reached ("AddMatch message failed");
+
+  /*
+   * Cause bus_check_privilege() to return BUS_RESULT_LATER in the
+   * first call, then BUS_RESULT_TRUE.
+   */
+  cdata = &data;
+  memset (cdata, 0, sizeof(*cdata));
+  bus_check_test_override = bus_dispatch_test_check_override;
+
+  result = check_existent_service_auto_start (context, foo);
+
+  _dbus_assert (cdata->check_counter == 2);
+  _dbus_assert (cdata->timedout);
+  _dbus_assert (cdata->timeout);
+  _dbus_assert (!cdata->connection);
+  _dbus_timeout_unref (cdata->timeout);
+
+  kill_client_connection_unchecked (foo);
+
+  bus_context_unref (context);
+
+  return result;
+}
+
 dbus_bool_t
 bus_dispatch_test (const DBusString *test_data_dir)
 {
+  _dbus_verbose ("<check> tests\n");
+  if (!bus_dispatch_test_check (test_data_dir))
+    return FALSE;
+
   /* run normal activation tests */
   _dbus_verbose ("Normal activation tests\n");
   if (!bus_dispatch_test_conf (test_data_dir,
index d95e102..f16ec5d 100644 (file)
@@ -1789,6 +1789,7 @@ dbus-1.pc
 dbus-1-uninstalled.pc
 test/data/valid-config-files/debug-allow-all.conf
 test/data/valid-config-files/debug-allow-all-sha1.conf
+test/data/valid-config-files/debug-check-some.conf
 test/data/valid-config-files/incoming-limit.conf
 test/data/valid-config-files-system/debug-allow-all-pass.conf
 test/data/valid-config-files-system/debug-allow-all-fail.conf
index cec5cda..1c7782e 100644 (file)
@@ -249,6 +249,7 @@ in_data = \
        data/valid-config-files-system/debug-allow-all-pass.conf.in \
        data/valid-config-files/debug-allow-all-sha1.conf.in \
        data/valid-config-files/debug-allow-all.conf.in \
+       data/valid-config-files/debug-check-some.conf.in \
        data/valid-config-files/incoming-limit.conf.in \
        data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoExec.service.in \
        data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoService.service.in \
index a38e9d1..a4095ae 100644 (file)
@@ -1,5 +1,6 @@
 debug-allow-all.conf
 debug-allow-all-sha1.conf
+debug-check-some.conf
 session.conf
 system.conf
 run-with-tmp-session-bus.conf
diff --git a/test/data/valid-config-files/debug-check-some.conf.in b/test/data/valid-config-files/debug-check-some.conf.in
new file mode 100644 (file)
index 0000000..47ee854
--- /dev/null
@@ -0,0 +1,18 @@
+<!-- Bus that listens on a debug pipe and doesn't create any restrictions -->
+
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+  <listen>debug-pipe:name=test-server</listen>
+  <listen>@TEST_LISTEN@</listen>
+  <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir>
+  <policy context="default">
+    <allow send_interface="*"/>
+    <allow receive_interface="*"/>
+    <allow own="*"/>
+    <allow user="*"/>
+
+    <deny send_interface="org.freedesktop.TestSuite" send_member="Echo"/>
+    <check privilege="foo" send_interface="org.freedesktop.TestSuite" send_member="Echo"/>
+  </policy>
+</busconfig>