~ubuntu-branches/ubuntu/oneiric/libgdata/oneiric-backports

« back to all changes in this revision

Viewing changes to gdata/tests/common.h

  • Committer: Package Import Robot
  • Author(s): Evan Broder
  • Date: 2011-11-15 21:59:48 UTC
  • mfrom: (4.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20111115215948-e17s889ocgu5fv4f
Tags: 0.10.1-1~oneiric1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
G_BEGIN_DECLS
27
27
 
28
28
#define CLIENT_ID "ytapi-GNOME-libgdata-444fubtt-0"
29
 
#define USERNAME "libgdata.test@gmail.com"
30
29
#define DOCUMENTS_USERNAME "libgdata.documents@gmail.com"
 
30
 
 
31
/* These two must match */
 
32
#define USERNAME_NO_DOMAIN "libgdata.test"
 
33
#define USERNAME USERNAME_NO_DOMAIN "@gmail.com"
 
34
 
 
35
/* This must not match the above two */
 
36
#define INCORRECT_USERNAME "libgdata.test.invalid@gmail.com"
 
37
 
 
38
/* These two must not match (obviously) */
31
39
#define PASSWORD "gdata-libgdata"
 
40
#define INCORRECT_PASSWORD "bad-password"
32
41
 
33
42
void gdata_test_init (int argc, char **argv);
34
43
 
35
44
gboolean gdata_test_internet (void);
 
45
gboolean gdata_test_interactive (void);
36
46
 
37
47
guint gdata_test_batch_operation_query (GDataBatchOperation *operation, const gchar *id, GType entry_type,
38
48
                                        GDataEntry *entry, GDataEntry **returned_entry, GError **error);
52
62
                g_assert (_test_success == TRUE); \
53
63
        } G_STMT_END
54
64
 
 
65
/* Common code for tests of async query functions that have progress callbacks */
 
66
typedef struct {
 
67
    guint progress_destroy_notify_count;
 
68
    guint async_ready_notify_count;
 
69
    GMainLoop *main_loop;
 
70
} GDataAsyncProgressClosure;
 
71
void gdata_test_async_progress_callback (GDataEntry *entry, guint entry_key, guint entry_count, GDataAsyncProgressClosure *data);
 
72
void gdata_test_async_progress_closure_free (GDataAsyncProgressClosure *data);
 
73
void gdata_test_async_progress_finish_callback (GObject *service, GAsyncResult *res, GDataAsyncProgressClosure *data);
 
74
 
 
75
typedef struct {
 
76
        /*< private >*/
 
77
        GMainLoop *main_loop;
 
78
        GCancellable *cancellable;
 
79
        guint cancellation_timeout; /* timeout period in ms */
 
80
        guint cancellation_timeout_id; /* ID of the callback source */
 
81
        gboolean cancellation_successful;
 
82
 
 
83
        gconstpointer test_data;
 
84
} GDataAsyncTestData;
 
85
 
 
86
/**
 
87
 * GDATA_ASYNC_CLOSURE_FUNCTIONS:
 
88
 * @CLOSURE_NAME: the name of the closure
 
89
 * @TestStructType: the type of the synchronous closure structure
 
90
 *
 
91
 * Defines set up and tear down functions for a version of @TestStructType which is wrapped by #GDataAsyncTestData (i.e. allocated and pointed to by
 
92
 * the #GDataAsyncTestData.test_data pointer). These functions will be named <function>set_up_<replaceable>CLOSURE_NAME</replaceable>_async</function>
 
93
 * and <function>tear_down_<replaceable>CLOSURE_NAME</replaceable>_async</function>.
 
94
 *
 
95
 * Since: 0.10.0
 
96
 */
 
97
#define GDATA_ASYNC_CLOSURE_FUNCTIONS(CLOSURE_NAME, TestStructType) \
 
98
static void \
 
99
set_up_##CLOSURE_NAME##_async (GDataAsyncTestData *async_data, gconstpointer service) \
 
100
{ \
 
101
        TestStructType *test_data = g_slice_new (TestStructType); \
 
102
        set_up_##CLOSURE_NAME (test_data, service); \
 
103
        gdata_set_up_async_test_data (async_data, test_data); \
 
104
} \
 
105
 \
 
106
static void \
 
107
tear_down_##CLOSURE_NAME##_async (GDataAsyncTestData *async_data, gconstpointer service) \
 
108
{ \
 
109
        tear_down_##CLOSURE_NAME ((TestStructType*) async_data->test_data, service); \
 
110
        g_slice_free (TestStructType, (TestStructType*) async_data->test_data); \
 
111
        gdata_tear_down_async_test_data (async_data, async_data->test_data); \
 
112
}
 
113
 
 
114
/**
 
115
 * GDATA_ASYNC_STARTING_TIMEOUT:
 
116
 *
 
117
 * The initial timeout for cancellation tests, which will be the first timeout used after testing cancelling the operation before it's started.
 
118
 * The value is in milliseconds.
 
119
 *
 
120
 * Since: 0.10.0
 
121
 */
 
122
#define GDATA_ASYNC_STARTING_TIMEOUT 20 /* ms */
 
123
 
 
124
/**
 
125
 * GDATA_ASYNC_TIMEOUT_MULTIPLIER:
 
126
 *
 
127
 * The factor by which the asynchronous cancellation timeout will be multiplied between iterations of the cancellation test.
 
128
 *
 
129
 * Since: 0.10.0
 
130
 */
 
131
#define GDATA_ASYNC_TIMEOUT_MULTIPLIER 3
 
132
 
 
133
/**
 
134
 * GDATA_ASYNC_MAXIMUM_TIMEOUT:
 
135
 *
 
136
 * The maximum timeout value for cancellation tests before they fail. i.e. If an operation takes longer than this period of time, the asynchronous
 
137
 * operation test will fail.
 
138
 * The value is in milliseconds.
 
139
 *
 
140
 * Since: 0.10.0
 
141
 */
 
142
#define GDATA_ASYNC_MAXIMUM_TIMEOUT 43740 /* ms */
 
143
 
 
144
/**
 
145
 * GDATA_ASYNC_TEST_FUNCTIONS:
 
146
 * @TEST_NAME: the name of the test, excluding the “test_” prefix and the “_async” suffix
 
147
 * @TestStructType: type of the closure structure to use, or <type>void</type>
 
148
 * @TEST_BEGIN_CODE: code to execute to begin the test and start the asynchronous call
 
149
 * @TEST_END_CODE: code to execute once the asynchronous call has completed, which will check the return values and any changed state
 
150
 *
 
151
 * Defines test and callback functions to test normal asynchronous operation and the cancellation behaviour of the given asynchronous function call.
 
152
 *
 
153
 * The asynchronous function call should be started in @TEST_BEGIN_CODE, using <varname>cancellable</varname> as its #GCancellable parameter,
 
154
 * <varname>async_ready_callback</varname> as its #GAsyncReadyCallback parameter and <varname>async_data</varname> as its <varname>user_data</varname>
 
155
 * parameter. There is no need for the code to create its own main loop: that's taken care of by the wrapper code.
 
156
 *
 
157
 * The code in @TEST_END_CODE will be inserted into the callback function for both the normal asynchronous test and the cancellation test, so should
 
158
 * finish the asynchronous function call, using <varname>obj</varname> as the object on which the asynchronous function call was made,
 
159
 * <varname>async_result</varname> as its #GAsyncResult parameter and <varname>error</varname> as its #GError parameter. The code should then check
 
160
 * <varname>error</code>: if it's %NULL, the code should assert success conditions; if it's non-%NULL, the code should assert failure conditions.
 
161
 * The wrapper code will ensure that the error is a %G_IO_ERROR_CANCELLED at the appropriate times.
 
162
 *
 
163
 * The following functions will be defined, and should be added to the test suite using the #GAsyncTestData closure structure:
 
164
 * <function>test_<replaceable>TEST_NAME</replaceable>_async</function> and
 
165
 * <function>test_<replaceable>TEST_NAME</replaceable>_async_cancellation</function>.
 
166
 *
 
167
 * Since: 0.10.0
 
168
 */
 
169
#define GDATA_ASYNC_TEST_FUNCTIONS(TEST_NAME, TestStructType, TEST_BEGIN_CODE, TEST_END_CODE) \
 
170
static void \
 
171
test_##TEST_NAME##_async_cb (GObject *obj, GAsyncResult *async_result, GDataAsyncTestData *async_data) \
 
172
{ \
 
173
        TestStructType *data = (TestStructType*) async_data->test_data; \
 
174
        GError *error = NULL; \
 
175
 \
 
176
        (void) data; /* hide potential unused variable warning */ \
 
177
 \
 
178
        { \
 
179
                TEST_END_CODE; \
 
180
 \
 
181
                if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) == TRUE) { \
 
182
                        g_assert (g_cancellable_is_cancelled (async_data->cancellable) == TRUE); \
 
183
                        async_data->cancellation_successful = TRUE; \
 
184
                } else if (error == NULL) { \
 
185
                        g_assert (g_cancellable_is_cancelled (async_data->cancellable) == FALSE || async_data->cancellation_timeout > 0); \
 
186
                        async_data->cancellation_successful = FALSE; \
 
187
                } else { \
 
188
                        /* Unexpected error: explode. */ \
 
189
                        g_assert_no_error (error); \
 
190
                        async_data->cancellation_successful = FALSE; \
 
191
                } \
 
192
        } \
 
193
 \
 
194
        g_clear_error (&error); \
 
195
 \
 
196
        g_main_loop_quit (async_data->main_loop); \
 
197
} \
 
198
\
 
199
static void \
 
200
test_##TEST_NAME##_async (GDataAsyncTestData *async_data, gconstpointer service) \
 
201
{ \
 
202
        GAsyncReadyCallback async_ready_callback = (GAsyncReadyCallback) test_##TEST_NAME##_async_cb; \
 
203
        TestStructType *data = (TestStructType*) async_data->test_data; \
 
204
        GCancellable *cancellable = NULL; /* don't expose the cancellable, so the test proceeds as normal */ \
 
205
 \
 
206
        (void) data; /* hide potential unused variable warning */ \
 
207
 \
 
208
        /* Just run the test without doing any cancellation, and assert that it succeeds. */ \
 
209
        async_data->cancellation_timeout = 0; \
 
210
 \
 
211
        g_test_message ("Running normal operation test…"); \
 
212
 \
 
213
        { \
 
214
                TEST_BEGIN_CODE; \
 
215
        } \
 
216
 \
 
217
        g_main_loop_run (async_data->main_loop); \
 
218
} \
 
219
 \
 
220
static void \
 
221
test_##TEST_NAME##_async_cancellation (GDataAsyncTestData *async_data, gconstpointer service) \
 
222
{ \
 
223
        async_data->cancellation_timeout = 0; \
 
224
 \
 
225
        /* Starting with a short timeout, repeatedly run the async. operation, cancelling it after the timeout and increasing the timeout until
 
226
         * the operation succeeds for the first time. We then finish the test. This guarantees that if, for example, the test creates an entry on
 
227
         * the server, it only ever creates one; because the test only ever succeeds once. (Of course, this assumes that the server does not change
 
228
         * state if we cancel the operation, which is a fairly optimistic assumption. Sigh.) */ \
 
229
        do { \
 
230
                GCancellable *cancellable = async_data->cancellable; \
 
231
                GAsyncReadyCallback async_ready_callback = (GAsyncReadyCallback) test_##TEST_NAME##_async_cb; \
 
232
                TestStructType *data = (TestStructType*) async_data->test_data; \
 
233
 \
 
234
                (void) data; /* hide potential unused variable warning */ \
 
235
 \
 
236
                /* Ensure the timeout remains sane. */ \
 
237
                g_assert_cmpuint (async_data->cancellation_timeout, <=, GDATA_ASYNC_MAXIMUM_TIMEOUT); \
 
238
 \
 
239
                /* Schedule the cancellation after the timeout. */ \
 
240
                if (async_data->cancellation_timeout == 0) { \
 
241
                        /* For the first test, cancel the cancellable before the test code is run */ \
 
242
                        gdata_async_test_cancellation_cb (async_data); \
 
243
                } else { \
 
244
                        async_data->cancellation_timeout_id = g_timeout_add (async_data->cancellation_timeout, \
 
245
                                                                             (GSourceFunc) gdata_async_test_cancellation_cb, async_data); \
 
246
                } \
 
247
 \
 
248
                /* Mark the cancellation as unsuccessful and hope we get proven wrong. */ \
 
249
                async_data->cancellation_successful = FALSE; \
 
250
 \
 
251
                g_test_message ("Running cancellation test with timeout of %u ms…", async_data->cancellation_timeout); \
 
252
 \
 
253
                { \
 
254
                        TEST_BEGIN_CODE; \
 
255
                } \
 
256
 \
 
257
                g_main_loop_run (async_data->main_loop); \
 
258
 \
 
259
                /* Reset the cancellable for the next iteration and increase the timeout geometrically. */ \
 
260
                g_cancellable_reset (cancellable); \
 
261
 \
 
262
                if (async_data->cancellation_timeout == 0) { \
 
263
                        async_data->cancellation_timeout = GDATA_ASYNC_STARTING_TIMEOUT; /* ms */ \
 
264
                } else { \
 
265
                        async_data->cancellation_timeout *= GDATA_ASYNC_TIMEOUT_MULTIPLIER; \
 
266
                } \
 
267
        } while (async_data->cancellation_successful == TRUE); \
 
268
 \
 
269
        /* Clean up the last timeout callback */ \
 
270
        if (async_data->cancellation_timeout_id != 0) { \
 
271
                g_source_remove (async_data->cancellation_timeout_id); \
 
272
        } \
 
273
}
 
274
 
 
275
gboolean gdata_async_test_cancellation_cb (GDataAsyncTestData *async_data);
 
276
void gdata_set_up_async_test_data (GDataAsyncTestData *async_data, gconstpointer test_data);
 
277
void gdata_tear_down_async_test_data (GDataAsyncTestData *async_data, gconstpointer test_data);
 
278
 
55
279
G_END_DECLS
56
280
 
57
281
#endif /* !GDATA_TEST_COMMON_H */