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 protected override void setStruct(GObject* obj) 131 { 132 gTestDBus = cast(GTestDBus*)obj; 133 super.setStruct(obj); 134 } 135 136 /** 137 * Sets our main struct and passes it to the parent class. 138 */ 139 public this (GTestDBus* gTestDBus, bool ownedRef = false) 140 { 141 this.gTestDBus = gTestDBus; 142 super(cast(GObject*)gTestDBus, ownedRef); 143 } 144 145 146 /** */ 147 public static GType getType() 148 { 149 return g_test_dbus_get_type(); 150 } 151 152 /** 153 * Create a new #GTestDBus object. 154 * 155 * Params: 156 * flags = a #GTestDBusFlags 157 * 158 * Returns: a new #GTestDBus. 159 * 160 * Throws: ConstructionException GTK+ fails to create the object. 161 */ 162 public this(GTestDBusFlags flags) 163 { 164 auto p = g_test_dbus_new(flags); 165 166 if(p is null) 167 { 168 throw new ConstructionException("null returned by new"); 169 } 170 171 this(cast(GTestDBus*) p, true); 172 } 173 174 /** 175 * Unset DISPLAY and DBUS_SESSION_BUS_ADDRESS env variables to ensure the test 176 * won't use user's session bus. 177 * 178 * This is useful for unit tests that want to verify behaviour when no session 179 * bus is running. It is not necessary to call this if unit test already calls 180 * g_test_dbus_up() before acquiring the session bus. 181 */ 182 public static void unset() 183 { 184 g_test_dbus_unset(); 185 } 186 187 /** 188 * Add a path where dbus-daemon will look up .service files. This can't be 189 * called after g_test_dbus_up(). 190 * 191 * Params: 192 * path = path to a directory containing .service files 193 */ 194 public void addServiceDir(string path) 195 { 196 g_test_dbus_add_service_dir(gTestDBus, Str.toStringz(path)); 197 } 198 199 /** 200 * Stop the session bus started by g_test_dbus_up(). 201 * 202 * This will wait for the singleton returned by g_bus_get() or g_bus_get_sync() 203 * is destroyed. This is done to ensure that the next unit test won't get a 204 * leaked singleton from this test. 205 */ 206 public void down() 207 { 208 g_test_dbus_down(gTestDBus); 209 } 210 211 /** 212 * Get the address on which dbus-daemon is running. If g_test_dbus_up() has not 213 * been called yet, %NULL is returned. This can be used with 214 * g_dbus_connection_new_for_address(). 215 * 216 * Returns: the address of the bus, or %NULL. 217 */ 218 public string getBusAddress() 219 { 220 return Str.toString(g_test_dbus_get_bus_address(gTestDBus)); 221 } 222 223 /** 224 * Get the flags of the #GTestDBus object. 225 * 226 * Returns: the value of #GTestDBus:flags property 227 */ 228 public GTestDBusFlags getFlags() 229 { 230 return g_test_dbus_get_flags(gTestDBus); 231 } 232 233 /** 234 * Stop the session bus started by g_test_dbus_up(). 235 * 236 * Unlike g_test_dbus_down(), this won't verify the #GDBusConnection 237 * singleton returned by g_bus_get() or g_bus_get_sync() is destroyed. Unit 238 * tests wanting to verify behaviour after the session bus has been stopped 239 * can use this function but should still call g_test_dbus_down() when done. 240 */ 241 public void stop() 242 { 243 g_test_dbus_stop(gTestDBus); 244 } 245 246 /** 247 * Start a dbus-daemon instance and set DBUS_SESSION_BUS_ADDRESS. After this 248 * call, it is safe for unit tests to start sending messages on the session bus. 249 * 250 * If this function is called from setup callback of g_test_add(), 251 * g_test_dbus_down() must be called in its teardown callback. 252 * 253 * If this function is called from unit test's main(), then g_test_dbus_down() 254 * must be called after g_test_run(). 255 */ 256 public void up() 257 { 258 g_test_dbus_up(gTestDBus); 259 } 260 }