1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gio.TestDBus; 26 27 private import gio.c.functions; 28 public import gio.c.types; 29 private import glib.ConstructionException; 30 private import glib.Str; 31 private import gobject.ObjectG; 32 public import gtkc.giotypes; 33 34 35 /** 36 * A helper class for testing code which uses D-Bus without touching the user's 37 * session bus. 38 * 39 * Note that #GTestDBus modifies the user’s environment, calling setenv(). 40 * This is not thread-safe, so all #GTestDBus calls should be completed before 41 * threads are spawned, or should have appropriate locking to ensure no access 42 * conflicts to environment variables shared between #GTestDBus and other 43 * threads. 44 * 45 * ## Creating unit tests using GTestDBus 46 * 47 * Testing of D-Bus services can be tricky because normally we only ever run 48 * D-Bus services over an existing instance of the D-Bus daemon thus we 49 * usually don't activate D-Bus services that are not yet installed into the 50 * target system. The #GTestDBus object makes this easier for us by taking care 51 * of the lower level tasks such as running a private D-Bus daemon and looking 52 * up uninstalled services in customizable locations, typically in your source 53 * code tree. 54 * 55 * The first thing you will need is a separate service description file for the 56 * D-Bus daemon. Typically a `services` subdirectory of your `tests` directory 57 * is a good place to put this file. 58 * 59 * The service file should list your service along with an absolute path to the 60 * uninstalled service executable in your source tree. Using autotools we would 61 * achieve this by adding a file such as `my-server.service.in` in the services 62 * directory and have it processed by configure. 63 * |[ 64 * [D-BUS Service] 65 * Name=org.gtk.GDBus.Examples.ObjectManager 66 * Exec=@abs_top_builddir@/gio/tests/gdbus-example-objectmanager-server 67 * ]| 68 * You will also need to indicate this service directory in your test 69 * fixtures, so you will need to pass the path while compiling your 70 * test cases. Typically this is done with autotools with an added 71 * preprocessor flag specified to compile your tests such as: 72 * |[ 73 * -DTEST_SERVICES=\""$(abs_top_builddir)/tests/services"\" 74 * ]| 75 * Once you have a service definition file which is local to your source tree, 76 * you can proceed to set up a GTest fixture using the #GTestDBus scaffolding. 77 * 78 * An example of a test fixture for D-Bus services can be found 79 * here: 80 * [gdbus-test-fixture.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-test-fixture.c) 81 * 82 * Note that these examples only deal with isolating the D-Bus aspect of your 83 * service. To successfully run isolated unit tests on your service you may need 84 * some additional modifications to your test case fixture. For example; if your 85 * service uses GSettings and installs a schema then it is important that your test service 86 * not load the schema in the ordinary installed location (chances are that your service 87 * and schema files are not yet installed, or worse; there is an older version of the 88 * schema file sitting in the install location). 89 * 90 * Most of the time we can work around these obstacles using the 91 * environment. Since the environment is inherited by the D-Bus daemon 92 * created by #GTestDBus and then in turn inherited by any services the 93 * D-Bus daemon activates, using the setup routine for your fixture is 94 * a practical place to help sandbox your runtime environment. For the 95 * rather typical GSettings case we can work around this by setting 96 * `GSETTINGS_SCHEMA_DIR` to the in tree directory holding your schemas 97 * in the above fixture_setup() routine. 98 * 99 * The GSettings schemas need to be locally pre-compiled for this to work. This can be achieved 100 * by compiling the schemas locally as a step before running test cases, an autotools setup might 101 * do the following in the directory holding schemas: 102 * |[ 103 * all-am: 104 * $(GLIB_COMPILE_SCHEMAS) . 105 * 106 * CLEANFILES += gschemas.compiled 107 * ]| 108 * 109 * Since: 2.34 110 */ 111 public class TestDBus : ObjectG 112 { 113 /** the main Gtk struct */ 114 protected GTestDBus* gTestDBus; 115 116 /** Get the main Gtk struct */ 117 public GTestDBus* getTestDBusStruct(bool transferOwnership = false) 118 { 119 if (transferOwnership) 120 ownedRef = false; 121 return gTestDBus; 122 } 123 124 /** the main Gtk struct as a void* */ 125 protected override void* getStruct() 126 { 127 return cast(void*)gTestDBus; 128 } 129 130 /** 131 * Sets our main struct and passes it to the parent class. 132 */ 133 public this (GTestDBus* gTestDBus, bool ownedRef = false) 134 { 135 this.gTestDBus = gTestDBus; 136 super(cast(GObject*)gTestDBus, ownedRef); 137 } 138 139 140 /** */ 141 public static GType getType() 142 { 143 return g_test_dbus_get_type(); 144 } 145 146 /** 147 * Create a new #GTestDBus object. 148 * 149 * Params: 150 * flags = a #GTestDBusFlags 151 * 152 * Returns: a new #GTestDBus. 153 * 154 * Throws: ConstructionException GTK+ fails to create the object. 155 */ 156 public this(GTestDBusFlags flags) 157 { 158 auto __p = g_test_dbus_new(flags); 159 160 if(__p is null) 161 { 162 throw new ConstructionException("null returned by new"); 163 } 164 165 this(cast(GTestDBus*) __p, true); 166 } 167 168 /** 169 * Unset DISPLAY and DBUS_SESSION_BUS_ADDRESS env variables to ensure the test 170 * won't use user's session bus. 171 * 172 * This is useful for unit tests that want to verify behaviour when no session 173 * bus is running. It is not necessary to call this if unit test already calls 174 * g_test_dbus_up() before acquiring the session bus. 175 */ 176 public static void unset() 177 { 178 g_test_dbus_unset(); 179 } 180 181 /** 182 * Add a path where dbus-daemon will look up .service files. This can't be 183 * called after g_test_dbus_up(). 184 * 185 * Params: 186 * path = path to a directory containing .service files 187 */ 188 public void addServiceDir(string path) 189 { 190 g_test_dbus_add_service_dir(gTestDBus, Str.toStringz(path)); 191 } 192 193 /** 194 * Stop the session bus started by g_test_dbus_up(). 195 * 196 * This will wait for the singleton returned by g_bus_get() or g_bus_get_sync() 197 * to be destroyed. This is done to ensure that the next unit test won't get a 198 * leaked singleton from this test. 199 */ 200 public void down() 201 { 202 g_test_dbus_down(gTestDBus); 203 } 204 205 /** 206 * Get the address on which dbus-daemon is running. If g_test_dbus_up() has not 207 * been called yet, %NULL is returned. This can be used with 208 * g_dbus_connection_new_for_address(). 209 * 210 * Returns: the address of the bus, or %NULL. 211 */ 212 public string getBusAddress() 213 { 214 return Str.toString(g_test_dbus_get_bus_address(gTestDBus)); 215 } 216 217 /** 218 * Get the flags of the #GTestDBus object. 219 * 220 * Returns: the value of #GTestDBus:flags property 221 */ 222 public GTestDBusFlags getFlags() 223 { 224 return g_test_dbus_get_flags(gTestDBus); 225 } 226 227 /** 228 * Stop the session bus started by g_test_dbus_up(). 229 * 230 * Unlike g_test_dbus_down(), this won't verify the #GDBusConnection 231 * singleton returned by g_bus_get() or g_bus_get_sync() is destroyed. Unit 232 * tests wanting to verify behaviour after the session bus has been stopped 233 * can use this function but should still call g_test_dbus_down() when done. 234 */ 235 public void stop() 236 { 237 g_test_dbus_stop(gTestDBus); 238 } 239 240 /** 241 * Start a dbus-daemon instance and set DBUS_SESSION_BUS_ADDRESS. After this 242 * call, it is safe for unit tests to start sending messages on the session bus. 243 * 244 * If this function is called from setup callback of g_test_add(), 245 * g_test_dbus_down() must be called in its teardown callback. 246 * 247 * If this function is called from unit test's main(), then g_test_dbus_down() 248 * must be called after g_test_run(). 249 */ 250 public void up() 251 { 252 g_test_dbus_up(gTestDBus); 253 } 254 }