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