~ubuntu-branches/ubuntu/utopic/evolution-data-server/utopic-proposed

« back to all changes in this revision

Viewing changes to tests/libebook/client/test-book-client-view-operations.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-06-13 12:02:14 UTC
  • mfrom: (1.1.116) (1.2.35 sid)
  • Revision ID: package-import@ubuntu.com-20140613120214-1zx93d8jxwt093aw
Tags: 3.12.2-1ubuntu1
* Merge with Debian, remaining changes:
  - debian/control: build depend on hardening-wrapper
  - Add build-depends and pass configure flag to enable Ubuntu Online
    Accounts support.
  - Filter out -Bsymbolic-functions from LDFLAGS (for future people
    wondering about this change, see e.g. BGO #594473 and duplicates).
  - Enable Ubuntu Online Accounts and split it and GOA into a separate
    package

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 
2
 
 
3
#include <stdlib.h>
 
4
#include <locale.h>
 
5
#include <libebook/libebook.h>
 
6
#include <libedata-book/libedata-book.h>
 
7
 
 
8
#include "client-test-utils.h"
 
9
#include "e-test-server-utils.h"
 
10
 
 
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 };
 
15
 
 
16
#define N_THREADS  5
 
17
#define N_CONTACTS 5
 
18
 
 
19
typedef struct {
 
20
        ETestServerClosure *closure;
 
21
        GThread         *thread;
 
22
        const gchar     *book_uid;
 
23
        EBookClient     *client;
 
24
        EBookClientView *view;
 
25
 
 
26
        GMainLoop       *loop;
 
27
 
 
28
        GMutex           complete_mutex;
 
29
        GCond            complete_cond;
 
30
        gboolean         complete;
 
31
        gint             n_contacts;
 
32
} ThreadData;
 
33
 
 
34
static void
 
35
objects_added (EBookClientView *view,
 
36
               const GSList *contacts,
 
37
               ThreadData *data)
 
38
{
 
39
        const GSList *l;
 
40
 
 
41
        g_assert (g_thread_self () == data->thread);
 
42
 
 
43
        for (l = contacts; l; l = l->next) {
 
44
                /* print_email (l->data); */
 
45
 
 
46
                data->n_contacts++;
 
47
        }
 
48
}
 
49
 
 
50
static void
 
51
objects_modified (EBookClientView *view,
 
52
                  const GSList *contacts,
 
53
                  ThreadData *data)
 
54
{
 
55
        const GSList *l;
 
56
 
 
57
        g_assert (g_thread_self () == data->thread);
 
58
 
 
59
        for (l = contacts; l; l = l->next) {
 
60
                /* print_email (l->data); */
 
61
        }
 
62
}
 
63
 
 
64
static void
 
65
objects_removed (EBookClientView *view,
 
66
                 const GSList *ids,
 
67
                 ThreadData *data)
 
68
{
 
69
        const GSList *l;
 
70
 
 
71
        g_assert (g_thread_self () == data->thread);
 
72
 
 
73
        for (l = ids; l; l = l->next) {
 
74
                /* printf ("   Removed contact: %s\n", (gchar *) l->data); */
 
75
 
 
76
                data->n_contacts--;
 
77
        }
 
78
}
 
79
 
 
80
static void
 
81
complete (EBookClientView *view,
 
82
          const GError *error,
 
83
          ThreadData *data)
 
84
{
 
85
        g_assert (g_thread_self () == data->thread);
 
86
 
 
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);
 
91
}
 
92
 
 
93
static void
 
94
finish_thread_test (ThreadData *data)
 
95
{
 
96
        g_assert_cmpint (data->n_contacts, ==, N_CONTACTS);
 
97
 
 
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);
 
103
}
 
104
 
 
105
/************************************
 
106
 *     Threads using async API      *
 
107
 ************************************/
 
108
static void
 
109
view_ready (GObject *source_object,
 
110
            GAsyncResult *res,
 
111
            gpointer user_data)
 
112
{
 
113
        ThreadData *data = (ThreadData *) user_data;
 
114
        GError *error = NULL;
 
115
 
 
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);
 
118
 
 
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);
 
123
 
 
124
        e_book_client_view_set_fields_of_interest (data->view, NULL, &error);
 
125
        if (error)
 
126
                g_error ("set fields of interest: %s", error->message);
 
127
 
 
128
        e_book_client_view_start (data->view, &error);
 
129
        if (error)
 
130
                g_error ("start view: %s", error->message);
 
131
}
 
132
 
 
133
static void
 
134
start_thread_test_async (ThreadData *data)
 
135
{
 
136
        EBookQuery   *query;
 
137
        gchar        *sexp;
 
138
 
 
139
        query = e_book_query_any_field_contains ("");
 
140
        sexp = e_book_query_to_string (query);
 
141
 
 
142
        e_book_client_get_view (data->client, sexp, NULL, view_ready, data);
 
143
 
 
144
        e_book_query_unref (query);
 
145
        g_free (sexp);
 
146
}
 
147
 
 
148
static void
 
149
connect_ready (GObject *source_object,
 
150
               GAsyncResult *res,
 
151
               gpointer user_data)
 
152
{
 
153
        ThreadData *data = (ThreadData *) user_data;
 
154
        GError     *error = NULL;
 
155
 
 
156
        data->client = (EBookClient *) e_book_client_connect_finish (res, &error);
 
157
        if (!data->client)
 
158
                g_error ("Error asynchronously connecting to client");
 
159
 
 
160
        start_thread_test_async (data);
 
161
}
 
162
 
 
163
static gpointer
 
164
test_view_thread_async (ThreadData *data)
 
165
{
 
166
        GMainContext    *context;
 
167
        ESourceRegistry *registry;
 
168
        ESource         *source;
 
169
        GError          *error = NULL;
 
170
 
 
171
        context = g_main_context_new ();
 
172
        data->loop = g_main_loop_new (context, FALSE);
 
173
        g_main_context_push_thread_default (context);
 
174
 
 
175
        /* Open the test book client in this thread */
 
176
        registry = e_source_registry_new_sync (NULL, &error);
 
177
        if (!registry)
 
178
                g_error ("Unable to create the registry: %s", error->message);
 
179
 
 
180
        source = e_source_registry_ref_source (registry, data->book_uid);
 
181
        if (!source)
 
182
                g_error ("Unable to fetch source uid '%s' from the registry", data->book_uid);
 
183
 
 
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
 
186
                 */
 
187
                data->client = (EBookClient *) e_book_client_connect_direct_sync (registry, source, NULL, &error);
 
188
 
 
189
                if (!data->client)
 
190
                        g_error ("Unable to create EBookClient for uid '%s': %s", data->book_uid, error->message);
 
191
 
 
192
                /* Fetch the view right away */
 
193
                start_thread_test_async (data);
 
194
 
 
195
        } else {
 
196
                /* Connect asynchronously */
 
197
                e_book_client_connect (source, NULL, connect_ready, data);
 
198
        }
 
199
 
 
200
        g_main_loop_run (data->loop);
 
201
 
 
202
        g_object_unref (source);
 
203
        g_object_unref (registry);
 
204
 
 
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);
 
209
 
 
210
        return NULL;
 
211
}
 
212
 
 
213
/************************************
 
214
 *     Threads using sync API       *
 
215
 ************************************/
 
216
static void
 
217
start_thread_test_sync (ThreadData *data)
 
218
{
 
219
        EBookQuery   *query;
 
220
        gchar        *sexp;
 
221
        GError *error = NULL;
 
222
 
 
223
        query = e_book_query_any_field_contains ("");
 
224
        sexp = e_book_query_to_string (query);
 
225
 
 
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);
 
229
 
 
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);
 
234
 
 
235
        e_book_client_view_set_fields_of_interest (data->view, NULL, &error);
 
236
        if (error)
 
237
                g_error ("set fields of interest: %s", error->message);
 
238
 
 
239
        e_book_client_view_start (data->view, &error);
 
240
        if (error)
 
241
                g_error ("start view: %s", error->message);
 
242
 
 
243
        e_book_query_unref (query);
 
244
        g_free (sexp);
 
245
}
 
246
 
 
247
static gpointer
 
248
test_view_thread_sync (ThreadData *data)
 
249
{
 
250
        GMainContext    *context;
 
251
        ESourceRegistry *registry;
 
252
        ESource         *source;
 
253
        GError          *error = NULL;
 
254
 
 
255
        context = g_main_context_new ();
 
256
        data->loop = g_main_loop_new (context, FALSE);
 
257
        g_main_context_push_thread_default (context);
 
258
 
 
259
        /* Open the test book client in this thread */
 
260
        registry = e_source_registry_new_sync (NULL, &error);
 
261
        if (!registry)
 
262
                g_error ("Unable to create the registry: %s", error->message);
 
263
 
 
264
        source = e_source_registry_ref_source (registry, data->book_uid);
 
265
        if (!source)
 
266
                g_error ("Unable to fetch source uid '%s' from the registry", data->book_uid);
 
267
 
 
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);
 
270
        else
 
271
                data->client = (EBookClient *) e_book_client_connect_sync (source, NULL, &error);
 
272
 
 
273
        if (!data->client)
 
274
                g_error ("Unable to create EBookClient for uid '%s': %s", data->book_uid, error->message);
 
275
 
 
276
        start_thread_test_sync (data);
 
277
 
 
278
        g_main_loop_run (data->loop);
 
279
 
 
280
        g_object_unref (source);
 
281
        g_object_unref (registry);
 
282
 
 
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);
 
287
 
 
288
        return NULL;
 
289
}
 
290
 
 
291
static ThreadData *
 
292
create_test_thread (const gchar *book_uid,
 
293
                    gconstpointer user_data,
 
294
                    gboolean sync)
 
295
{
 
296
        ThreadData  *data = g_slice_new0 (ThreadData);
 
297
 
 
298
        data->book_uid = book_uid;
 
299
        data->closure = (ETestServerClosure *) user_data;
 
300
 
 
301
        g_mutex_init (&data->complete_mutex);
 
302
        g_cond_init (&data->complete_cond);
 
303
 
 
304
        if (sync)
 
305
                data->thread = g_thread_new ("test-thread", (GThreadFunc) test_view_thread_sync, data);
 
306
        else
 
307
                data->thread = g_thread_new ("test-thread", (GThreadFunc) test_view_thread_async, data);
 
308
 
 
309
        return data;
 
310
}
 
311
 
 
312
static void
 
313
test_concurrent_views (ETestServerFixture *fixture,
 
314
                       gconstpointer user_data,
 
315
                       gboolean sync)
 
316
{
 
317
        EBookClient *main_client;
 
318
        ESource *source;
 
319
        const gchar *book_uid = NULL;
 
320
        ThreadData **tests;
 
321
        gint i;
 
322
 
 
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);
 
326
 
 
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");
 
335
        }
 
336
 
 
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);
 
341
 
 
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)
 
346
                        g_cond_wait (
 
347
                                &(tests[i]->complete_cond),
 
348
                                &(tests[i]->complete_mutex));
 
349
                g_mutex_unlock (&(tests[i]->complete_mutex));
 
350
        }
 
351
 
 
352
        /* Finish all tests */
 
353
        for (i = 0; i < N_THREADS; i++)
 
354
                finish_thread_test (tests[i]);
 
355
 
 
356
        /* Cleanup */
 
357
        g_free (tests);
 
358
}
 
359
 
 
360
static void
 
361
test_concurrent_views_sync (ETestServerFixture *fixture,
 
362
                            gconstpointer user_data)
 
363
{
 
364
        test_concurrent_views (fixture, user_data, TRUE);
 
365
}
 
366
 
 
367
static void
 
368
test_concurrent_views_async (ETestServerFixture *fixture,
 
369
                             gconstpointer user_data)
 
370
{
 
371
        test_concurrent_views (fixture, user_data, FALSE);
 
372
}
 
373
 
 
374
gint
 
375
main (gint argc,
 
376
      gchar **argv)
 
377
{
 
378
        g_test_init (&argc, &argv, NULL);
 
379
        g_test_bug_base ("http://bugzilla.gnome.org/");
 
380
 
 
381
        setlocale (LC_ALL, "en_US.UTF-8");
 
382
 
 
383
        g_test_add (
 
384
                "/EBookClient/ConcurrentViews/Sync",
 
385
                ETestServerFixture,
 
386
                &book_closure_sync,
 
387
                e_test_server_utils_setup,
 
388
                test_concurrent_views_sync,
 
389
                e_test_server_utils_teardown);
 
390
        g_test_add (
 
391
                "/EBookClient/ConcurrentViews/Async",
 
392
                ETestServerFixture,
 
393
                &book_closure_async,
 
394
                e_test_server_utils_setup,
 
395
                test_concurrent_views_async,
 
396
                e_test_server_utils_teardown);
 
397
        g_test_add (
 
398
                "/EBookClient/DirectAccess/ConcurrentViews/Sync",
 
399
                ETestServerFixture,
 
400
                &book_closure_direct_sync,
 
401
                e_test_server_utils_setup,
 
402
                test_concurrent_views_sync,
 
403
                e_test_server_utils_teardown);
 
404
        g_test_add (
 
405
                "/EBookClient/DirectAccess/ConcurrentViews/Async",
 
406
                ETestServerFixture,
 
407
                &book_closure_direct_async,
 
408
                e_test_server_utils_setup,
 
409
                test_concurrent_views_async,
 
410
                e_test_server_utils_teardown);
 
411
 
 
412
        return e_test_server_utils_run ();
 
413
}