1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /* e-test-server-utils.c - Test scaffolding to run tests with in-tree data server.
5 * Copyright (C) 2012 Intel Corporation
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) version 3.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with the program; if not, see <http://www.gnu.org/licenses/>
20 * Authors: Tristan Van Berkom <tristanvb@openismus.com>
23 #include "e-test-server-utils.h"
25 #define ADDRESS_BOOK_SOURCE_UID "test-address-book"
26 #define CALENDAR_SOURCE_UID "test-calendar"
28 /* FIXME, currently we are unable to achieve server activation
29 * twice in a single test case, so we're using one D-Bus server
30 * throughout an entire test suite.
32 * When this is fixed we can migrate the D-Bus initialization
33 * and teardown from e_test_server_utils_run() to
34 * e_test_server_utils_setup() and e_test_server_utils_teardown()
35 * and this will transparantly change the way tests run using
36 * this test framework.
38 #define GLOBAL_DBUS_DAEMON 1
40 #if GLOBAL_DBUS_DAEMON
41 static GTestDBus *global_test_dbus = NULL;
45 ETestServerFixture *fixture;
46 ETestServerClosure *closure;
50 setup_environment (void)
52 g_assert (g_setenv ("XDG_DATA_HOME", EDS_TEST_WORK_DIR, TRUE));
53 g_assert (g_setenv ("XDG_CACHE_HOME", EDS_TEST_WORK_DIR, TRUE));
54 g_assert (g_setenv ("XDG_CONFIG_HOME", EDS_TEST_WORK_DIR, TRUE));
55 g_assert (g_setenv ("GSETTINGS_SCHEMA_DIR", EDS_TEST_SCHEMA_DIR, TRUE));
56 g_assert (g_setenv ("EDS_CALENDAR_MODULES", EDS_TEST_CALENDAR_DIR, TRUE));
57 g_assert (g_setenv ("EDS_ADDRESS_BOOK_MODULES", EDS_TEST_ADDRESS_BOOK_DIR, TRUE));
61 delete_work_directory (void)
63 /* XXX Instead of complex error checking here, we should ideally use
64 * a recursive GDir / g_unlink() function.
66 * We cannot use GFile and the recursive delete function without
67 * corrupting our contained D-Bus environment with service files
70 const gchar *argv[] = { "/bin/rm", "-rf", EDS_TEST_WORK_DIR, NULL };
71 gboolean spawn_succeeded;
74 spawn_succeeded = g_spawn_sync (
75 NULL, (gchar **) argv, NULL, 0, NULL, NULL,
76 NULL, NULL, &exit_status, NULL);
78 g_assert (spawn_succeeded);
79 g_assert (WIFEXITED (exit_status));
80 g_assert_cmpint (WEXITSTATUS (exit_status), ==, 0);
84 e_test_server_utils_bootstrap_timeout (FixturePair *pair)
86 ESource *source = NULL;
89 switch (pair->closure->type) {
90 case E_TEST_SERVER_ADDRESS_BOOK:
91 source = e_source_registry_ref_source (pair->fixture->registry, ADDRESS_BOOK_SOURCE_UID);
93 g_error ("Unable to fetch newly created addressbook source from the registry");
95 pair->fixture->service.book_client = e_book_client_new (source, &error);
96 if (!pair->fixture->service.book_client)
97 g_error ("Unable to create the test book: %s", error->message);
99 if (!e_client_open_sync (E_CLIENT (pair->fixture->service.book_client), FALSE, NULL, &error))
100 g_error ("Unable to open book client: %s", error->message);
104 case E_TEST_SERVER_DEPRECATED_ADDRESS_BOOK:
105 source = e_source_registry_ref_source (pair->fixture->registry, ADDRESS_BOOK_SOURCE_UID);
107 g_error ("Unable to fetch newly created addressbook source from the registry");
109 pair->fixture->service.book = e_book_new (source, &error);
110 if (!pair->fixture->service.book)
111 g_error ("Unable to create the test book: %s", error->message);
113 if (!e_book_open (pair->fixture->service.book, FALSE, &error))
114 g_error ("Unable to open book: %s", error->message);
118 case E_TEST_SERVER_CALENDAR:
119 source = e_source_registry_ref_source (pair->fixture->registry, CALENDAR_SOURCE_UID);
121 g_error ("Unable to fetch newly created addressbook source from the registry");
123 pair->fixture->service.calendar_client = e_cal_client_new (source,
124 pair->closure->calendar_source_type,
126 if (!pair->fixture->service.calendar_client)
127 g_error ("Unable to create the test calendar: %s", error->message);
129 if (!e_client_open_sync (E_CLIENT (pair->fixture->service.calendar_client), FALSE, NULL, &error))
130 g_error ("Unable to open calendar client: %s", error->message);
134 case E_TEST_SERVER_DEPRECATED_CALENDAR:
135 source = e_source_registry_ref_source (pair->fixture->registry, CALENDAR_SOURCE_UID);
137 g_error ("Unable to fetch newly created addressbook source from the registry");
139 pair->fixture->service.calendar = e_cal_new (source, pair->closure->calendar_source_type);
140 if (!pair->fixture->service.calendar)
141 g_error ("Unable to create the test calendar");
143 if (!e_cal_open (pair->fixture->service.calendar, FALSE, &error))
144 g_error ("Unable to open calendar: %s", error->message);
148 case E_TEST_SERVER_NONE:
153 g_object_unref (source);
155 g_main_loop_quit (pair->fixture->loop);
161 e_test_server_utils_bootstrap_idle (FixturePair *pair)
163 ESourceBackend *backend = NULL;
164 ESource *scratch = NULL;
165 GError *error = NULL;
167 pair->fixture->registry = e_source_registry_new_sync (NULL, &error);
169 if (!pair->fixture->registry)
170 g_error ("Unable to create the test registry: %s", error->message);
172 /* Create an address book */
173 switch (pair->closure->type) {
174 case E_TEST_SERVER_ADDRESS_BOOK:
175 case E_TEST_SERVER_DEPRECATED_ADDRESS_BOOK:
177 scratch = e_source_new_with_uid (ADDRESS_BOOK_SOURCE_UID, NULL, &error);
179 g_error ("Failed to create scratch source for an addressbook: %s", error->message);
181 /* Ensure Book type */
182 backend = e_source_get_extension (scratch, E_SOURCE_EXTENSION_ADDRESS_BOOK);
183 e_source_backend_set_backend_name (backend, "local");
186 case E_TEST_SERVER_CALENDAR:
187 case E_TEST_SERVER_DEPRECATED_CALENDAR:
189 scratch = e_source_new_with_uid (CALENDAR_SOURCE_UID, NULL, &error);
191 g_error ("Failed to create scratch source for a calendar: %s", error->message);
193 /* Ensure Calendar type source (how to specify the backend here ?? */
194 backend = e_source_get_extension (scratch, E_SOURCE_EXTENSION_CALENDAR);
195 e_source_backend_set_backend_name (backend, "local");
199 case E_TEST_SERVER_NONE:
204 if (pair->closure->customize)
205 pair->closure->customize (scratch, pair->closure);
207 if (!e_source_registry_commit_source_sync (pair->fixture->registry, scratch, NULL, &error))
208 g_error ("Unable to add new addressbook source to the registry: %s", error->message);
210 g_object_unref (scratch);
213 if (pair->closure->type != E_TEST_SERVER_NONE)
214 g_timeout_add (20, (GSourceFunc) e_test_server_utils_bootstrap_timeout, pair);
216 g_main_loop_quit (pair->fixture->loop);
222 * e_test_server_utils_setup:
223 * @fixture: A #ETestServerFixture
224 * @user_data: A #ETestServerClosure or derived structure provided by the test.
226 * A setup function for the #ETestServerFixture fixture
229 e_test_server_utils_setup (ETestServerFixture *fixture,
230 gconstpointer user_data)
232 ETestServerClosure *closure = (ETestServerClosure *) user_data;
233 FixturePair pair = { fixture, closure };
235 /* Create work directory */
236 g_assert (g_mkdir_with_parents (EDS_TEST_WORK_DIR, 0755) == 0);
238 fixture->loop = g_main_loop_new (NULL, FALSE);
240 #if !GLOBAL_DBUS_DAEMON
241 /* Create the global dbus-daemon for this test suite */
242 fixture->dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
244 /* Add the private directory with our in-tree service files */
245 g_test_dbus_add_service_dir (fixture->dbus, EDS_TEST_DBUS_SERVICE_DIR);
247 /* Start the private D-Bus daemon */
248 g_test_dbus_up (fixture->dbus);
250 fixture->dbus = global_test_dbus;
253 g_idle_add ((GSourceFunc) e_test_server_utils_bootstrap_idle, &pair);
254 g_main_loop_run (fixture->loop);
258 * e_test_server_utils_teardown:
259 * @fixture: A #ETestServerFixture
260 * @user_data: A #ETestServerClosure or derived structure provided by the test.
262 * A teardown function for the #ETestServerFixture fixture
265 e_test_server_utils_teardown (ETestServerFixture *fixture,
266 gconstpointer user_data)
268 ETestServerClosure *closure = (ETestServerClosure *) user_data;
269 GError *error = NULL;
271 switch (closure->type) {
272 case E_TEST_SERVER_ADDRESS_BOOK:
273 if (!e_client_remove_sync (E_CLIENT (fixture->service.book_client), NULL, &error)) {
274 g_message ("Failed to remove test book: %s (ignoring)", error->message);
275 g_clear_error (&error);
277 g_object_unref (fixture->service.book_client);
278 fixture->service.book_client = NULL;
281 case E_TEST_SERVER_DEPRECATED_ADDRESS_BOOK:
282 if (!e_book_remove (fixture->service.book, &error)) {
283 g_message ("Failed to remove test book: %s (ignoring)", error->message);
284 g_clear_error (&error);
286 g_object_unref (fixture->service.book);
287 fixture->service.book = NULL;
290 case E_TEST_SERVER_CALENDAR:
291 if (!e_client_remove_sync (E_CLIENT (fixture->service.calendar_client), NULL, &error)) {
292 g_message ("Failed to remove test calendar: %s (ignoring)", error->message);
293 g_clear_error (&error);
295 g_object_unref (fixture->service.calendar_client);
296 fixture->service.calendar_client = NULL;
299 case E_TEST_SERVER_DEPRECATED_CALENDAR:
300 if (!e_cal_remove (fixture->service.calendar, &error)) {
301 g_message ("Failed to remove test calendar: %s (ignoring)", error->message);
302 g_clear_error (&error);
304 g_object_unref (fixture->service.calendar);
305 fixture->service.calendar = NULL;
307 case E_TEST_SERVER_NONE:
311 g_object_run_dispose (G_OBJECT (fixture->registry));
312 g_object_unref (fixture->registry);
313 fixture->registry = NULL;
315 g_main_loop_unref (fixture->loop);
316 fixture->loop = NULL;
318 #if !GLOBAL_DBUS_DAEMON
319 /* Teardown the D-Bus Daemon
321 * Note that we intentionally leak the TestDBus daemon
322 * in this case, presumably this is due to some leaked
323 * GDBusConnection reference counting
325 g_test_dbus_down (fixture->dbus);
326 g_object_unref (fixture->dbus);
327 fixture->dbus = NULL;
329 fixture->dbus = NULL;
332 /* Cleanup work directory */
333 if (!closure->keep_work_directory)
334 delete_work_directory ();
338 e_test_server_utils_run (void)
342 /* Cleanup work directory */
343 delete_work_directory ();
345 setup_environment ();
347 #if GLOBAL_DBUS_DAEMON
349 /* Create the global dbus-daemon for this test suite */
350 global_test_dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
352 /* Add the private directory with our in-tree service files */
353 g_test_dbus_add_service_dir (global_test_dbus, EDS_TEST_DBUS_SERVICE_DIR);
355 /* Start the private D-Bus daemon */
356 g_test_dbus_up (global_test_dbus);
359 /* Run the GTest suite */
360 tests_ret = g_test_run ();
362 #if GLOBAL_DBUS_DAEMON
363 /* Teardown the D-Bus Daemon
365 * Note that we intentionally leak the TestDBus daemon
366 * in this case, presumably this is due to some leaked
367 * GDBusConnection reference counting
369 g_test_dbus_stop (global_test_dbus);
370 /* g_object_unref (global_test_dbus); */
371 global_test_dbus = NULL;