From 02bf00de034ba639a5a81faf555001c084975da6 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 14 Nov 2013 08:54:25 +0000 Subject: tests: Add python-dbusmock support to the base TestCase class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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(+) create mode 100644 tests/lib/org-freedesktop-dbus-mock.vala diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index 233a7544..4486e433 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 00000000..386477f0 --- /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 . + * + * Authors: + * Philip Withnall + */ + +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 properties, Method[] methods) + throws IOError; + + [DBus (name = "AddProperties")] + public abstract void add_properties (string interface_name, + HashTable 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 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 30e101b7..11673ba7 100644 --- a/tests/lib/test-case.vala +++ b/tests/lib/test-case.vala @@ -194,6 +194,87 @@ public abstract class Folks.TestCase : Object return transient; } + /** + * 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 () { -- cgit v1.2.3