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