1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
5
#include <libebook/libebook.h>
6
#include <libedata-book/libedata-book.h>
8
#include "client-test-utils.h"
9
#include "e-test-server-utils.h"
11
static ETestServerClosure book_closure_sync = { E_TEST_SERVER_ADDRESS_BOOK, NULL, 0, FALSE, NULL, FALSE };
12
static ETestServerClosure book_closure_async = { E_TEST_SERVER_ADDRESS_BOOK, NULL, 0, FALSE, NULL, TRUE };
13
static ETestServerClosure book_closure_direct_sync = { E_TEST_SERVER_DIRECT_ADDRESS_BOOK, NULL, 0, FALSE, NULL, FALSE };
14
static ETestServerClosure book_closure_direct_async = { E_TEST_SERVER_DIRECT_ADDRESS_BOOK, NULL, 0, FALSE, NULL, TRUE };
20
ETestServerClosure *closure;
22
const gchar *book_uid;
24
EBookClientView *view;
28
GMutex complete_mutex;
35
objects_added (EBookClientView *view,
36
const GSList *contacts,
41
g_assert (g_thread_self () == data->thread);
43
for (l = contacts; l; l = l->next) {
44
/* print_email (l->data); */
51
objects_modified (EBookClientView *view,
52
const GSList *contacts,
57
g_assert (g_thread_self () == data->thread);
59
for (l = contacts; l; l = l->next) {
60
/* print_email (l->data); */
65
objects_removed (EBookClientView *view,
71
g_assert (g_thread_self () == data->thread);
73
for (l = ids; l; l = l->next) {
74
/* printf (" Removed contact: %s\n", (gchar *) l->data); */
81
complete (EBookClientView *view,
85
g_assert (g_thread_self () == data->thread);
87
g_mutex_lock (&data->complete_mutex);
88
data->complete = TRUE;
89
g_cond_signal (&data->complete_cond);
90
g_mutex_unlock (&data->complete_mutex);
94
finish_thread_test (ThreadData *data)
96
g_assert_cmpint (data->n_contacts, ==, N_CONTACTS);
98
g_main_loop_quit (data->loop);
99
g_thread_join (data->thread);
100
g_mutex_clear (&data->complete_mutex);
101
g_cond_clear (&data->complete_cond);
102
g_slice_free (ThreadData, data);
105
/************************************
106
* Threads using async API *
107
************************************/
109
view_ready (GObject *source_object,
113
ThreadData *data = (ThreadData *) user_data;
114
GError *error = NULL;
116
if (!e_book_client_get_view_finish (E_BOOK_CLIENT (source_object), res, &(data->view), &error))
117
g_error ("Getting view failed: %s", error->message);
119
g_signal_connect (data->view, "objects-added", G_CALLBACK (objects_added), data);
120
g_signal_connect (data->view, "objects-modified", G_CALLBACK (objects_modified), data);
121
g_signal_connect (data->view, "objects-removed", G_CALLBACK (objects_removed), data);
122
g_signal_connect (data->view, "complete", G_CALLBACK (complete), data);
124
e_book_client_view_set_fields_of_interest (data->view, NULL, &error);
126
g_error ("set fields of interest: %s", error->message);
128
e_book_client_view_start (data->view, &error);
130
g_error ("start view: %s", error->message);
134
start_thread_test_async (ThreadData *data)
139
query = e_book_query_any_field_contains ("");
140
sexp = e_book_query_to_string (query);
142
e_book_client_get_view (data->client, sexp, NULL, view_ready, data);
144
e_book_query_unref (query);
149
connect_ready (GObject *source_object,
153
ThreadData *data = (ThreadData *) user_data;
154
GError *error = NULL;
156
data->client = (EBookClient *) e_book_client_connect_finish (res, &error);
158
g_error ("Error asynchronously connecting to client");
160
start_thread_test_async (data);
164
test_view_thread_async (ThreadData *data)
166
GMainContext *context;
167
ESourceRegistry *registry;
169
GError *error = NULL;
171
context = g_main_context_new ();
172
data->loop = g_main_loop_new (context, FALSE);
173
g_main_context_push_thread_default (context);
175
/* Open the test book client in this thread */
176
registry = e_source_registry_new_sync (NULL, &error);
178
g_error ("Unable to create the registry: %s", error->message);
180
source = e_source_registry_ref_source (registry, data->book_uid);
182
g_error ("Unable to fetch source uid '%s' from the registry", data->book_uid);
184
if (data->closure->type == E_TEST_SERVER_DIRECT_ADDRESS_BOOK) {
185
/* There is no Async API to open a direct book for now, let's stick with the sync API
187
data->client = (EBookClient *) e_book_client_connect_direct_sync (registry, source, NULL, &error);
190
g_error ("Unable to create EBookClient for uid '%s': %s", data->book_uid, error->message);
192
/* Fetch the view right away */
193
start_thread_test_async (data);
196
/* Connect asynchronously */
197
e_book_client_connect (source, NULL, connect_ready, data);
200
g_main_loop_run (data->loop);
202
g_object_unref (source);
203
g_object_unref (registry);
205
g_object_unref (data->client);
206
g_main_context_pop_thread_default (context);
207
g_main_loop_unref (data->loop);
208
g_main_context_unref (context);
213
/************************************
214
* Threads using sync API *
215
************************************/
217
start_thread_test_sync (ThreadData *data)
221
GError *error = NULL;
223
query = e_book_query_any_field_contains ("");
224
sexp = e_book_query_to_string (query);
226
if (!e_book_client_get_view_sync (data->client, sexp,
227
&(data->view), NULL, &error))
228
g_error ("Error getting view: %s", error->message);
230
g_signal_connect (data->view, "objects-added", G_CALLBACK (objects_added), data);
231
g_signal_connect (data->view, "objects-modified", G_CALLBACK (objects_modified), data);
232
g_signal_connect (data->view, "objects-removed", G_CALLBACK (objects_removed), data);
233
g_signal_connect (data->view, "complete", G_CALLBACK (complete), data);
235
e_book_client_view_set_fields_of_interest (data->view, NULL, &error);
237
g_error ("set fields of interest: %s", error->message);
239
e_book_client_view_start (data->view, &error);
241
g_error ("start view: %s", error->message);
243
e_book_query_unref (query);
248
test_view_thread_sync (ThreadData *data)
250
GMainContext *context;
251
ESourceRegistry *registry;
253
GError *error = NULL;
255
context = g_main_context_new ();
256
data->loop = g_main_loop_new (context, FALSE);
257
g_main_context_push_thread_default (context);
259
/* Open the test book client in this thread */
260
registry = e_source_registry_new_sync (NULL, &error);
262
g_error ("Unable to create the registry: %s", error->message);
264
source = e_source_registry_ref_source (registry, data->book_uid);
266
g_error ("Unable to fetch source uid '%s' from the registry", data->book_uid);
268
if (data->closure->type == E_TEST_SERVER_DIRECT_ADDRESS_BOOK)
269
data->client = (EBookClient *) e_book_client_connect_direct_sync (registry, source, NULL, &error);
271
data->client = (EBookClient *) e_book_client_connect_sync (source, NULL, &error);
274
g_error ("Unable to create EBookClient for uid '%s': %s", data->book_uid, error->message);
276
start_thread_test_sync (data);
278
g_main_loop_run (data->loop);
280
g_object_unref (source);
281
g_object_unref (registry);
283
g_object_unref (data->client);
284
g_main_context_pop_thread_default (context);
285
g_main_loop_unref (data->loop);
286
g_main_context_unref (context);
292
create_test_thread (const gchar *book_uid,
293
gconstpointer user_data,
296
ThreadData *data = g_slice_new0 (ThreadData);
298
data->book_uid = book_uid;
299
data->closure = (ETestServerClosure *) user_data;
301
g_mutex_init (&data->complete_mutex);
302
g_cond_init (&data->complete_cond);
305
data->thread = g_thread_new ("test-thread", (GThreadFunc) test_view_thread_sync, data);
307
data->thread = g_thread_new ("test-thread", (GThreadFunc) test_view_thread_async, data);
313
test_concurrent_views (ETestServerFixture *fixture,
314
gconstpointer user_data,
317
EBookClient *main_client;
319
const gchar *book_uid = NULL;
323
main_client = E_TEST_SERVER_UTILS_SERVICE (fixture, EBookClient);
324
source = e_client_get_source (E_CLIENT (main_client));
325
book_uid = e_source_get_uid (source);
327
/* Create out test contacts */
328
if (!add_contact_from_test_case_verify (main_client, "custom-1", NULL) ||
329
!add_contact_from_test_case_verify (main_client, "custom-2", NULL) ||
330
!add_contact_from_test_case_verify (main_client, "custom-3", NULL) ||
331
!add_contact_from_test_case_verify (main_client, "custom-4", NULL) ||
332
!add_contact_from_test_case_verify (main_client, "custom-5", NULL)) {
333
g_object_unref (main_client);
334
g_error ("Failed to create contacts for testing");
337
/* Create all concurrent threads accessing the same addressbook */
338
tests = g_new0 (ThreadData *, N_THREADS);
339
for (i = 0; i < N_THREADS; i++)
340
tests[i] = create_test_thread (book_uid, user_data, sync);
342
/* Wait for all threads to receive the complete signal */
343
for (i = 0; i < N_THREADS; i++) {
344
g_mutex_lock (&(tests[i]->complete_mutex));
345
while (!tests[i]->complete)
347
&(tests[i]->complete_cond),
348
&(tests[i]->complete_mutex));
349
g_mutex_unlock (&(tests[i]->complete_mutex));
352
/* Finish all tests */
353
for (i = 0; i < N_THREADS; i++)
354
finish_thread_test (tests[i]);
361
test_concurrent_views_sync (ETestServerFixture *fixture,
362
gconstpointer user_data)
364
test_concurrent_views (fixture, user_data, TRUE);
368
test_concurrent_views_async (ETestServerFixture *fixture,
369
gconstpointer user_data)
371
test_concurrent_views (fixture, user_data, FALSE);
378
g_test_init (&argc, &argv, NULL);
379
g_test_bug_base ("http://bugzilla.gnome.org/");
381
setlocale (LC_ALL, "en_US.UTF-8");
384
"/EBookClient/ConcurrentViews/Sync",
387
e_test_server_utils_setup,
388
test_concurrent_views_sync,
389
e_test_server_utils_teardown);
391
"/EBookClient/ConcurrentViews/Async",
394
e_test_server_utils_setup,
395
test_concurrent_views_async,
396
e_test_server_utils_teardown);
398
"/EBookClient/DirectAccess/ConcurrentViews/Sync",
400
&book_closure_direct_sync,
401
e_test_server_utils_setup,
402
test_concurrent_views_sync,
403
e_test_server_utils_teardown);
405
"/EBookClient/DirectAccess/ConcurrentViews/Async",
407
&book_closure_direct_async,
408
e_test_server_utils_setup,
409
test_concurrent_views_async,
410
e_test_server_utils_teardown);
412
return e_test_server_utils_run ();