[folks] tests: Add python-dbusmock support to the base TestCase class



commit 02bf00de034ba639a5a81faf555001c084975da6
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Thu Nov 14 08:54:25 2013 +0000

    tests: Add python-dbusmock support to the base TestCase class
    
    This allows derived test cases to easily use python-dbusmock to mock up
    D-Bus services which are used by the code under test. The derived code
    simply needs to call:
        this.create_dbusmock_service (BusType.SESSION, "org.foo", "foo")
    to allow instantiation of the ‘org.foo’ service using the ‘foo’
    python-dbusmock template.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=712274

 tests/lib/Makefile.am                    |    1 +
 tests/lib/org-freedesktop-dbus-mock.vala |  124 ++++++++++++++++++++++++++++++
 tests/lib/test-case.vala                 |   84 ++++++++++++++++++++
 3 files changed, 209 insertions(+), 0 deletions(-)
---
diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am
index 233a754..4486e43 100644
--- a/tests/lib/Makefile.am
+++ b/tests/lib/Makefile.am
@@ -46,6 +46,7 @@ libfolks_test_la_SOURCES = \
        test-case.vala \
        test-case-helper.c \
        test-utils.vala \
+       org-freedesktop-dbus-mock.vala \
        $(NULL)
 
 libfolks_test_la_CFLAGS = \
diff --git a/tests/lib/org-freedesktop-dbus-mock.vala b/tests/lib/org-freedesktop-dbus-mock.vala
new file mode 100644
index 0000000..386477f
--- /dev/null
+++ b/tests/lib/org-freedesktop-dbus-mock.vala
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2013 Collabora Ltd.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Philip Withnall <philip withnall collabora co uk>
+ */
+
+using GLib;
+
+/**
+ * Vala wrapper for the standard org.freedesktop.DBus.Mock interface.
+ *
+ * This is exposed by python-dbusmock as the primary means of controlling a
+ * mocked up D-Bus service.
+ *
+ * @since UNRELEASED
+ */
+
+/* Reference:
+ * http://bazaar.launchpad.net/~pitti/python-dbusmock/trunk/view/head:/README.rst */
+namespace org
+  {
+    namespace freedesktop
+      {
+        namespace DBus
+          {
+            [DBus (name = "org.freedesktop.DBus.Mock")]
+            public interface Mock : Object
+              {
+                /* Signals. */
+                [DBus (name = "MethodCalled")]
+                public abstract signal void method_called (string method_name,
+                    Variant[] args);
+
+                /* Methods. */
+                [DBus (name = "AddMethod")]
+                public abstract void add_method (string interface_name,
+                    string name, string in_sig, string out_sig, string code)
+                        throws IOError;
+
+                /* Parameter to AddMethods(). */
+                public struct Method
+                  {
+                    public string name;
+                    public string in_sig;
+                    public string out_sig;
+                  }
+
+                [DBus (name = "AddMethods")]
+                public abstract void add_methods (string interface_name,
+                    Method[] methods) throws IOError;
+
+                [DBus (name = "AddObject")]
+                public abstract void add_object (string path,
+                    string interface_name,
+                    HashTable<string, Variant> properties, Method[] methods)
+                        throws IOError;
+
+                [DBus (name = "AddProperties")]
+                public abstract void add_properties (string interface_name,
+                    HashTable<string, Variant> properties) throws IOError;
+
+                [DBus (name = "AddProperty")]
+                public abstract void add_property (string interface_name,
+                    string name, Variant val) throws IOError;
+
+                [DBus (name = "AddTemplate")]
+                public abstract void add_template (string template_name,
+                    HashTable<string, Variant> template_params)
+                        throws IOError;
+
+                [DBus (name = "ClearCalls")]
+                public abstract void clear_calls () throws IOError;
+
+                [DBus (name = "EmitSignal")]
+                public abstract void emit_signal (string interface_name,
+                    string name, string signature, Variant[] args)
+                        throws IOError;
+
+                /* Returned by GetCalls(). */
+                public struct Call
+                  {
+                    public uint64 call_time;
+                    public string method_name;
+                    public Variant[] args;
+                  }
+
+                [DBus (name = "GetCalls")]
+                public abstract Call[] get_calls () throws IOError;
+
+                /* Returned by GetMethodCalls(). */
+                public struct MethodCall
+                  {
+                    public uint64 call_time;
+                    public Variant[] args;
+                  }
+
+                [DBus (name = "GetMethodCalls")]
+                public abstract MethodCall[] get_method_calls (string method)
+                    throws IOError;
+
+                [DBus (name = "RemoveObject")]
+                public abstract void remove_object (string path)
+                    throws IOError;
+
+                [DBus (name = "Reset")]
+                public abstract void reset () throws IOError;
+              }
+          }
+      }
+  }
diff --git a/tests/lib/test-case.vala b/tests/lib/test-case.vala
index 30e101b..11673ba 100644
--- a/tests/lib/test-case.vala
+++ b/tests/lib/test-case.vala
@@ -195,6 +195,87 @@ public abstract class Folks.TestCase : Object
     }
 
   /**
+   * Create a D-Bus service file for a python-dbusmock service.
+   *
+   * Create a service file to allow auto-launching a python-dbusmock service
+   * which uses the given ``dbusmock_template_name`` to mock up the service
+   * running at ``bus_name`` on the ``bus_type`` bus (which must either be
+   * { link BusType.SYSTEM} or { link BusType.SESSION}.
+   *
+   * This requires Python 3 to be installed and available to run as ``python3``
+   * somewhere in the system ``PATH``.
+   *
+   * It will create a temporary log file which python-dbusmock will log to if
+   * launched. The name of the log file will be printed to the test logs.
+   *
+   * The D-Bus service file itself will be created in a subdirectory of
+   * { link TestCase.transient_dir}, which the { link TestDBus} instance has
+   * already been configured to use as a service directory. This requires
+   * { link TestCase.create_transient_dir} to have been called already.
+   *
+   * @param bus_type the bus the service should be auto-launchable from
+   * @param bus_name the well-known bus name used by the service
+   * @param dbusmock_template_name name of the python-dbusmock template to use
+   *
+   * @since UNRELEASED
+   */
+  public void create_dbusmock_service (BusType bus_type, string bus_name,
+      string dbusmock_template_name)
+    {
+      string service_dir;
+      switch (bus_type)
+        {
+          case BusType.SYSTEM:
+            service_dir = "system-services";
+            break;
+          case BusType.SESSION:
+            service_dir = "services";
+            break;
+          case BusType.STARTER:
+          case BusType.NONE:
+          default:
+            assert_not_reached ();
+        }
+
+      /* Find where the Python 3 executable is (service files require absolute
+       * paths). */
+      var python = Environment.find_program_in_path ("python3");
+      if (python == null)
+        {
+          error ("Couldn’t find `python3` in $PATH; can’t run " +
+              "python-dbusmock.");
+        }
+
+      /* Create a temporary log file for dbusmock to use. This doesn’t need to
+       * use mkstemp() because it’s already in a unique temporary directory. */
+      var log_file_name =
+          Path.build_filename (this.transient_dir,
+              "dbusmock-%s-%s-%s.log".printf (service_dir, bus_name,
+                  dbusmock_template_name));
+      Test.message ("python-dbusmock service ‘%s’ (template ‘%s’) will log " +
+          "to ‘%s’.", bus_name, dbusmock_template_name, log_file_name);
+
+      /* Write out the service file for the dbusmock service. */
+      var service_file_name =
+          Path.build_filename (this.transient_dir, "dbus-1", service_dir,
+              dbusmock_template_name + ".service");
+      var service_file = ("[D-BUS Service]\n" +
+          "Name=%s\n" +
+          "Exec=%s -m dbusmock --template %s -l %s\n").printf (bus_name, python,
+              dbusmock_template_name, log_file_name);
+
+      try
+        {
+          FileUtils.set_contents (service_file_name, service_file);
+        }
+      catch (FileError e2)
+        {
+          error ("Error creating D-Bus service file ‘%s’: %s",
+              service_file_name, e2.message);
+        }
+    }
+
+  /**
    * A private D-Bus session, normally created by private_bus_up()
    * from the constructor.
    *
@@ -234,6 +315,9 @@ public abstract class Folks.TestCase : Object
    *
    * This is per-process, not per-test, for the reasons mentioned for
    * //test_dbus//.
+   *
+   * By calling { link TestCase.create_dbusmock_service} in an overridden
+   * version of this method, python-dbusmock services may be set up.
    */
   public virtual void private_bus_up ()
     {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]