/* Unit tests for GAsyncQueue * Copyright (C) 2011 Red Hat, Inc * Author: Matthias Clasen * * This work is provided "as is"; redistribution and modification * in whole or in part, in any medium, physical or electronic is * permitted without restriction. * * This work is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * In no event shall the authors or contributors be liable for any * direct, indirect, incidental, special, exemplary, or consequential * damages (including, but not limited to, procurement of substitute * goods or services; loss of use, data, or profits; or business * interruption) however caused and on any theory of liability, whether * in contract, strict liability, or tort (including negligence or * otherwise) arising in any way out of the use of this software, even * if advised of the possibility of such damage. */ /* We are testing some deprecated APIs here */ #define GLIB_DISABLE_DEPRECATION_WARNINGS #include static gint compare_func (gconstpointer d1, gconstpointer d2, gpointer data) { gint i1, i2; i1 = GPOINTER_TO_INT (d1); i2 = GPOINTER_TO_INT (d2); return i1 - i2; } static void test_async_queue_sort (void) { GAsyncQueue *q; q = g_async_queue_new (); g_async_queue_push (q, GINT_TO_POINTER (10)); g_async_queue_push (q, GINT_TO_POINTER (2)); g_async_queue_push (q, GINT_TO_POINTER (7)); g_async_queue_sort (q, compare_func, NULL); g_async_queue_push_sorted (q, GINT_TO_POINTER (1), compare_func, NULL); g_async_queue_push_sorted (q, GINT_TO_POINTER (8), compare_func, NULL); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 7); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 8); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10); g_assert (g_async_queue_try_pop (q) == NULL); g_async_queue_unref (q); } static gint destroy_count; static void destroy_notify (gpointer item) { destroy_count++; } static void test_async_queue_destroy (void) { GAsyncQueue *q; q = g_async_queue_new_full (destroy_notify); g_assert (destroy_count == 0); g_async_queue_push (q, GINT_TO_POINTER (1)); g_async_queue_push (q, GINT_TO_POINTER (1)); g_async_queue_push (q, GINT_TO_POINTER (1)); g_async_queue_push (q, GINT_TO_POINTER (1)); g_assert (g_async_queue_length (q) == 4); g_async_queue_unref (q); g_assert (destroy_count == 4); } static GAsyncQueue *q; static GThread *threads[10]; static gint counts[10]; static gint sums[10]; static gint total; static gpointer thread_func (gpointer data) { gint pos = GPOINTER_TO_INT (data); gint value; while (1) { value = GPOINTER_TO_INT (g_async_queue_pop (q)); if (value == -1) break; counts[pos]++; sums[pos] += value; g_usleep (1000); } return NULL; } static void test_async_queue_threads (void) { gint i, j; gint s, c; gint value; q = g_async_queue_new (); for (i = 0; i < 10; i++) threads[i] = g_thread_new ("test", thread_func, GINT_TO_POINTER (i)); for (i = 0; i < 100; i++) { g_async_queue_lock (q); for (j = 0; j < 10; j++) { value = g_random_int_range (1, 100); total += value; g_async_queue_push_unlocked (q, GINT_TO_POINTER (value)); } g_async_queue_unlock (q); g_usleep (1000); } for (i = 0; i < 10; i++) g_async_queue_push (q, GINT_TO_POINTER(-1)); for (i = 0; i < 10; i++) g_thread_join (threads[i]); g_assert_cmpint (g_async_queue_length (q), ==, 0); s = c = 0; for (i = 0; i < 10; i++) { g_assert_cmpint (sums[i], >, 0); g_assert_cmpint (counts[i], >, 0); s += sums[i]; c += counts[i]; } g_assert_cmpint (s, ==, total); g_assert_cmpint (c, ==, 1000); g_async_queue_unref (q); } static void test_async_queue_timed (void) { GAsyncQueue *q; GTimeVal tv; gint64 start, end, diff; gpointer val; q = g_async_queue_new (); start = g_get_monotonic_time (); val = g_async_queue_timeout_pop (q, G_USEC_PER_SEC / 10); g_assert (val == NULL); end = g_get_monotonic_time (); diff = end - start; g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10); /* diff should be only a little bit more than G_USEC_PER_SEC/10, but * we have to leave some wiggle room for heavily-loaded machines... */ g_assert_cmpint (diff, <, G_USEC_PER_SEC); start = end; g_get_current_time (&tv); g_time_val_add (&tv, G_USEC_PER_SEC / 10); val = g_async_queue_timed_pop (q, &tv); g_assert (val == NULL); end = g_get_monotonic_time (); diff = end - start; g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10); g_assert_cmpint (diff, <, G_USEC_PER_SEC); start = end; g_get_current_time (&tv); g_time_val_add (&tv, G_USEC_PER_SEC / 10); g_async_queue_lock (q); val = g_async_queue_timed_pop_unlocked (q, &tv); g_async_queue_unlock (q); g_assert (val == NULL); end = g_get_monotonic_time (); diff = end - start; g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10); g_assert_cmpint (diff, <, G_USEC_PER_SEC); g_async_queue_unref (q); } static void test_async_queue_remove (void) { GAsyncQueue *q; q = g_async_queue_new (); g_async_queue_push (q, GINT_TO_POINTER (10)); g_async_queue_push (q, GINT_TO_POINTER (2)); g_async_queue_push (q, GINT_TO_POINTER (7)); g_async_queue_push (q, GINT_TO_POINTER (1)); g_async_queue_remove (q, GINT_TO_POINTER (7)); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1); g_assert (g_async_queue_try_pop (q) == NULL); g_async_queue_unref (q); } static void test_async_queue_push_front (void) { GAsyncQueue *q; q = g_async_queue_new (); g_async_queue_push (q, GINT_TO_POINTER (10)); g_async_queue_push (q, GINT_TO_POINTER (2)); g_async_queue_push (q, GINT_TO_POINTER (7)); g_async_queue_push_front (q, GINT_TO_POINTER (1)); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 1); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 10); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 2); g_assert_cmpint (GPOINTER_TO_INT (g_async_queue_pop (q)), ==, 7); g_assert (g_async_queue_try_pop (q) == NULL); g_async_queue_unref (q); } int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/asyncqueue/sort", test_async_queue_sort); g_test_add_func ("/asyncqueue/destroy", test_async_queue_destroy); g_test_add_func ("/asyncqueue/threads", test_async_queue_threads); g_test_add_func ("/asyncqueue/timed", test_async_queue_timed); g_test_add_func ("/asyncqueue/remove", test_async_queue_remove); g_test_add_func ("/asyncqueue/push_front", test_async_queue_push_front); return g_test_run (); }