1 /* Unit tests for GAsyncQueue
2 * Copyright (C) 2011 Red Hat, Inc
3 * Author: Matthias Clasen
4 *
5 * SPDX-License-Identifier: LicenseRef-old-glib-tests
6 *
7 * This work is provided "as is"; redistribution and modification
8 * in whole or in part, in any medium, physical or electronic is
9 * permitted without restriction.
10 *
11 * This work is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 *
15 * In no event shall the authors or contributors be liable for any
16 * direct, indirect, incidental, special, exemplary, or consequential
17 * damages (including, but not limited to, procurement of substitute
18 * goods or services; loss of use, data, or profits; or business
19 * interruption) however caused and on any theory of liability, whether
20 * in contract, strict liability, or tort (including negligence or
21 * otherwise) arising in any way out of the use of this software, even
22 * if advised of the possibility of such damage.
23 */
24
25 /* We are testing some deprecated APIs here */
26 #ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
27 #define GLIB_DISABLE_DEPRECATION_WARNINGS
28 #endif
29
30 #include <glib.h>
31
32 static gint
33 compare_func (gconstpointer d1, gconstpointer d2, gpointer data)
34 {
35 gint i1, i2;
36
37 i1 = GPOINTER_TO_INT (d1);
38 i2 = GPOINTER_TO_INT (d2);
39
40 return i1 - i2;
41 }
42
43 static
44 void test_async_queue_sort (void)
45 {
46 GAsyncQueue *q;
47
48 q = g_async_queue_new ();
49
50 g_async_queue_push (q, GINT_TO_POINTER (10));
51 g_async_queue_push (q, GINT_TO_POINTER (2));
52 g_async_queue_push (q, GINT_TO_POINTER (7));
53
54 g_async_queue_sort (q, compare_func, NULL);
55
56 if (g_test_undefined ())
57 {
58 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
59 "*assertion* failed*");
60 g_async_queue_push_sorted (NULL, GINT_TO_POINTER (1),
61 compare_func, NULL);
62 g_test_assert_expected_messages ();
63
64 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
65 "*assertion* failed*");
66 g_async_queue_push_sorted_unlocked (NULL, GINT_TO_POINTER (1),
67 compare_func, NULL);
68 g_test_assert_expected_messages ();
69
70 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
71 "*assertion* failed*");
72 g_async_queue_sort (NULL, compare_func, NULL);
73 g_test_assert_expected_messages ();
74
75 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
76 "*assertion* failed*");
77 g_async_queue_sort (q, NULL, NULL);
78 g_test_assert_expected_messages ();
79
80 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
81 "*assertion* failed*");
82 g_async_queue_sort_unlocked (NULL, compare_func, NULL);
83 g_test_assert_expected_messages ();
84
85 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
86 "*assertion* failed*");
87 g_async_queue_sort_unlocked (q, NULL, NULL);
88 g_test_assert_expected_messages ();
89 }
90
91 g_async_queue_push_sorted (q, GINT_TO_POINTER (1), compare_func, NULL);
92 g_async_queue_push_sorted (q, GINT_TO_POINTER (8), compare_func, NULL);
93
94 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1);
95 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2);
96 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 7);
97 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 8);
98 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10);
99
100 g_assert_null (g_async_queue_try_pop (q));
101
102 g_async_queue_unref (q);
103 }
104
105 static gint destroy_count;
106
107 static void
108 destroy_notify (gpointer item)
109 {
110 destroy_count++;
111 }
112
113 static void
114 test_async_queue_destroy (void)
115 {
116 GAsyncQueue *q;
117
118 destroy_count = 0;
119
120 q = g_async_queue_new_full (destroy_notify);
121
122 g_assert_cmpint (destroy_count, ==, 0);
123
124 g_async_queue_push (q, GINT_TO_POINTER (1));
125 g_async_queue_push (q, GINT_TO_POINTER (1));
126 g_async_queue_push (q, GINT_TO_POINTER (1));
127 g_async_queue_push (q, GINT_TO_POINTER (1));
128
129 g_assert_cmpint (g_async_queue_length (q), ==, 4);
130
131 g_async_queue_unref (q);
132
133 g_assert_cmpint (destroy_count, ==, 4);
134 }
135
136 static GAsyncQueue *global_queue;
137
138 static GThread *threads[10];
139 static gint counts[10];
140 static gint sums[10];
141 static gint total;
142
143 static gpointer
144 thread_func (gpointer data)
145 {
146 gint pos = GPOINTER_TO_INT (data);
147 gint value;
148
149 while (1)
150 {
151 value = GPOINTER_TO_INT (g_async_queue_pop (global_queue));
152
153 if (value == -1)
154 break;
155
156 counts[pos]++;
157 sums[pos] += value;
158
159 g_usleep (1000);
160 }
161
162 return NULL;
163 }
164
165 static void
166 test_async_queue_threads (void)
167 {
168 gint i, j;
169 gint s, c;
170 gint value;
171
172 global_queue = g_async_queue_new ();
173
174 for (i = 0; i < 10; i++)
175 threads[i] = g_thread_new ("test", thread_func, GINT_TO_POINTER (i));
176
177 for (i = 0; i < 100; i++)
178 {
179 g_async_queue_lock (global_queue);
180 for (j = 0; j < 10; j++)
181 {
182 value = g_random_int_range (1, 100);
183 total += value;
184 g_async_queue_push_unlocked (global_queue, GINT_TO_POINTER (value));
185 }
186 g_async_queue_unlock (global_queue);
187
188 g_usleep (1000);
189 }
190
191 for (i = 0; i < 10; i++)
192 g_async_queue_push (global_queue, GINT_TO_POINTER (-1));
193
194 for (i = 0; i < 10; i++)
195 g_thread_join (threads[i]);
196
197 g_assert_cmpint (g_async_queue_length (global_queue), ==, 0);
198
199 s = c = 0;
200
201 for (i = 0; i < 10; i++)
202 {
203 g_assert_cmpint (sums[i], >, 0);
204 g_assert_cmpint (counts[i], >, 0);
205 s += sums[i];
206 c += counts[i];
207 }
208
209 g_assert_cmpint (s, ==, total);
210 g_assert_cmpint (c, ==, 1000);
211
212 g_async_queue_unref (global_queue);
213 }
214
215 static void
216 test_async_queue_timed (void)
217 {
218 GAsyncQueue *q;
219 GTimeVal tv;
220 gint64 start, end, diff;
221 gpointer val;
222
223 GDateTime *dt = g_date_time_new_now_utc ();
224 int year = g_date_time_get_year (dt);
225 g_date_time_unref (dt);
226 if (year >= 2038)
227 {
228 g_test_skip ("Test relies on GTimeVal which is Y2038 unsafe and will cause a failure.");
229 return;
230 }
231
232 g_get_current_time (&tv);
233 if (g_test_undefined ())
234 {
235 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
236 "*assertion* failed*");
237 g_async_queue_timed_pop (NULL, &tv);
238 g_test_assert_expected_messages ();
239
240 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
241 "*assertion* failed*");
242 g_async_queue_timed_pop_unlocked (NULL, &tv);
243 g_test_assert_expected_messages ();
244 }
245
246 q = g_async_queue_new ();
247
248 start = g_get_monotonic_time ();
249 g_assert_null (g_async_queue_timeout_pop (q, G_USEC_PER_SEC / 10));
250
251 end = g_get_monotonic_time ();
252 diff = end - start;
253 g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
254 /* diff should be only a little bit more than G_USEC_PER_SEC/10, but
255 * we have to leave some wiggle room for heavily-loaded machines...
256 */
257 g_assert_cmpint (diff, <, 2 * G_USEC_PER_SEC);
258
259 g_async_queue_push (q, GINT_TO_POINTER (10));
260 val = g_async_queue_timed_pop (q, NULL);
261 g_assert_cmpint (GPOINTER_TO_INT (val), ==, 10);
262 g_assert_null (g_async_queue_try_pop (q));
263
264 start = end;
265 g_get_current_time (&tv);
266 g_time_val_add (&tv, G_USEC_PER_SEC / 10);
267 g_assert_null (g_async_queue_timed_pop (q, &tv));
268
269 end = g_get_monotonic_time ();
270 diff = end - start;
271 g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
272 g_assert_cmpint (diff, <, 2 * G_USEC_PER_SEC);
273
274 g_async_queue_push (q, GINT_TO_POINTER (10));
275 val = g_async_queue_timed_pop_unlocked (q, NULL);
276 g_assert_cmpint (GPOINTER_TO_INT (val), ==, 10);
277 g_assert_null (g_async_queue_try_pop (q));
278
279 start = end;
280 g_get_current_time (&tv);
281 g_time_val_add (&tv, G_USEC_PER_SEC / 10);
282 g_async_queue_lock (q);
283 g_assert_null (g_async_queue_timed_pop_unlocked (q, &tv));
284 g_async_queue_unlock (q);
285
286 end = g_get_monotonic_time ();
287 diff = end - start;
288 g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
289 g_assert_cmpint (diff, <, 2 * G_USEC_PER_SEC);
290
291 g_async_queue_unref (q);
292 }
293
294 static void
295 test_async_queue_remove (void)
296 {
297 GAsyncQueue *q;
298
299 q = g_async_queue_new ();
300
301 if (g_test_undefined ())
302 {
303 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
304 "*assertion* failed*");
305 g_async_queue_remove (NULL, GINT_TO_POINTER (1));
306 g_test_assert_expected_messages ();
307
308 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
309 "*assertion* failed*");
310 g_async_queue_remove (q, NULL);
311 g_test_assert_expected_messages ();
312
313 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
314 "*assertion* failed*");
315 g_async_queue_remove_unlocked (NULL, GINT_TO_POINTER (1));
316 g_test_assert_expected_messages ();
317
318 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
319 "*assertion* failed*");
320 g_async_queue_remove_unlocked (q, NULL);
321 g_test_assert_expected_messages ();
322 }
323
324 g_async_queue_push (q, GINT_TO_POINTER (10));
325 g_async_queue_push (q, GINT_TO_POINTER (2));
326 g_async_queue_push (q, GINT_TO_POINTER (7));
327 g_async_queue_push (q, GINT_TO_POINTER (1));
328
329 g_async_queue_remove (q, GINT_TO_POINTER (7));
330
331 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10);
332 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2);
333 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1);
334
335 g_assert_null (g_async_queue_try_pop (q));
336
337 g_async_queue_unref (q);
338 }
339
340 static void
341 test_async_queue_push_front (void)
342 {
343 GAsyncQueue *q;
344
345 q = g_async_queue_new ();
346
347 if (g_test_undefined ())
348 {
349 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
350 "*assertion* failed*");
351 g_async_queue_push_front (NULL, GINT_TO_POINTER (1));
352 g_test_assert_expected_messages ();
353
354 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
355 "*assertion* failed*");
356 g_async_queue_push_front (q, NULL);
357 g_test_assert_expected_messages ();
358
359 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
360 "*assertion* failed*");
361 g_async_queue_push_front_unlocked (NULL, GINT_TO_POINTER (1));
362 g_test_assert_expected_messages ();
363
364 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
365 "*assertion* failed*");
366 g_async_queue_push_front_unlocked (q, NULL);
367 g_test_assert_expected_messages ();
368 }
369
370 g_async_queue_push (q, GINT_TO_POINTER (10));
371 g_async_queue_push (q, GINT_TO_POINTER (2));
372 g_async_queue_push (q, GINT_TO_POINTER (7));
373
374 g_async_queue_push_front (q, GINT_TO_POINTER (1));
375
376 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1);
377 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10);
378 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2);
379 g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 7);
380
381 g_assert_null (g_async_queue_try_pop (q));
382
383 g_async_queue_unref (q);
384 }
385
386 static void
387 test_basics (void)
388 {
389 GAsyncQueue *q;
390 gpointer item;
391
392 destroy_count = 0;
393
394 if (g_test_undefined ())
395 {
396 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
397 "*assertion* failed*");
398 g_async_queue_length (NULL);
399 g_test_assert_expected_messages ();
400
401 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
402 "*assertion* failed*");
403 g_async_queue_length_unlocked (NULL);
404 g_test_assert_expected_messages ();
405
406 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
407 "*assertion* failed*");
408 g_async_queue_ref (NULL);
409 g_test_assert_expected_messages ();
410
411 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
412 "*assertion* failed*");
413 g_async_queue_ref_unlocked (NULL);
414 g_test_assert_expected_messages ();
415
416 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
417 "*assertion* failed*");
418 g_async_queue_unref (NULL);
419 g_test_assert_expected_messages ();
420
421 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
422 "*assertion* failed*");
423 g_async_queue_unref_and_unlock (NULL);
424 g_test_assert_expected_messages ();
425
426 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
427 "*assertion* failed*");
428 g_async_queue_lock (NULL);
429 g_test_assert_expected_messages ();
430
431 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
432 "*assertion* failed*");
433 g_async_queue_unlock (NULL);
434 g_test_assert_expected_messages ();
435
436 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
437 "*assertion* failed*");
438 g_async_queue_pop (NULL);
439 g_test_assert_expected_messages ();
440
441 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
442 "*assertion* failed*");
443 g_async_queue_pop_unlocked (NULL);
444 g_test_assert_expected_messages ();
445
446 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
447 "*assertion* failed*");
448 g_async_queue_try_pop (NULL);
449 g_test_assert_expected_messages ();
450
451 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
452 "*assertion* failed*");
453 g_async_queue_try_pop_unlocked (NULL);
454 g_test_assert_expected_messages ();
455
456 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
457 "*assertion* failed*");
458 g_async_queue_timeout_pop (NULL, 1);
459 g_test_assert_expected_messages ();
460
461 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
462 "*assertion* failed*");
463 g_async_queue_timeout_pop_unlocked (NULL, 1);
464 g_test_assert_expected_messages ();
465 }
466
467 q = g_async_queue_new_full (destroy_notify);
468
469 if (g_test_undefined ())
470 {
471 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
472 "*assertion* failed*");
473 g_async_queue_push (NULL, GINT_TO_POINTER (1));
474 g_test_assert_expected_messages ();
475
476 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
477 "*assertion* failed*");
478 g_async_queue_push (q, NULL);
479 g_test_assert_expected_messages ();
480
481 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
482 "*assertion* failed*");
483 g_async_queue_push_unlocked (NULL, GINT_TO_POINTER (1));
484 g_test_assert_expected_messages ();
485
486 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
487 "*assertion* failed*");
488 g_async_queue_push_unlocked (q, NULL);
489 g_test_assert_expected_messages ();
490 }
491
492 g_async_queue_lock (q);
493 g_async_queue_ref (q);
494 g_async_queue_unlock (q);
495 g_async_queue_lock (q);
496 g_async_queue_ref_unlocked (q);
497 g_async_queue_unref_and_unlock (q);
498
499 item = g_async_queue_try_pop (q);
500 g_assert_null (item);
501
502 g_async_queue_lock (q);
503 item = g_async_queue_try_pop_unlocked (q);
504 g_async_queue_unlock (q);
505 g_assert_null (item);
506
507 g_async_queue_push (q, GINT_TO_POINTER (1));
508 g_async_queue_push (q, GINT_TO_POINTER (2));
509 g_async_queue_push (q, GINT_TO_POINTER (3));
510 g_assert_cmpint (destroy_count, ==, 0);
511
512 g_async_queue_unref (q);
513 g_assert_cmpint (destroy_count, ==, 0);
514
515 item = g_async_queue_pop (q);
516 g_assert_cmpint (GPOINTER_TO_INT (item), ==, 1);
517 g_assert_cmpint (destroy_count, ==, 0);
518
519 g_async_queue_unref (q);
520 g_assert_cmpint (destroy_count, ==, 2);
521 }
522
523 int
524 main (int argc, char *argv[])
525 {
526 g_test_init (&argc, &argv, NULL);
527
528 g_test_add_func ("/asyncqueue/basics", test_basics);
529 g_test_add_func ("/asyncqueue/sort", test_async_queue_sort);
530 g_test_add_func ("/asyncqueue/destroy", test_async_queue_destroy);
531 g_test_add_func ("/asyncqueue/threads", test_async_queue_threads);
532 g_test_add_func ("/asyncqueue/timed", test_async_queue_timed);
533 g_test_add_func ("/asyncqueue/remove", test_async_queue_remove);
534 g_test_add_func ("/asyncqueue/push_front", test_async_queue_push_front);
535
536 return g_test_run ();
537 }