diff options
author | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
---|---|---|
committer | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
commit | 9c73ef7a5ac10acd6a50d5d52bd721fc2faa5919 (patch) | |
tree | 2a890e1df09e5b896a9b4168a7b22648f559a1f2 /extras/dispatch/tests/timer_test.c | |
parent | 172d9b2a16cfb817bbe632d050acba7e31401cd2 (diff) | |
download | qpid-python-asyncstore.tar.gz |
Update from trunk r1375509 through r1450773asyncstore
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1451244 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'extras/dispatch/tests/timer_test.c')
-rw-r--r-- | extras/dispatch/tests/timer_test.c | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/extras/dispatch/tests/timer_test.c b/extras/dispatch/tests/timer_test.c new file mode 100644 index 0000000000..3d199f2aa2 --- /dev/null +++ b/extras/dispatch/tests/timer_test.c @@ -0,0 +1,388 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <stdio.h> +#include <qpid/dispatch/timer.h> +#include "alloc_private.h" +#include "timer_private.h" +#include "test_case.h" +#include <qpid/dispatch/threading.h> + + +static unsigned long fire_mask; +static dx_timer_list_t pending_timers; +static sys_mutex_t *lock; +static long time; +static dx_timer_t *timers[16]; + + +void dx_server_timer_pending_LH(dx_timer_t *timer) +{ + DEQ_INSERT_TAIL(pending_timers, timer); +} + + +void dx_server_timer_cancel_LH(dx_timer_t *timer) +{ + if (timer->state == TIMER_PENDING) + DEQ_REMOVE(pending_timers, timer); +} + + +static int fire_head() +{ + sys_mutex_lock(lock); + int result = DEQ_SIZE(pending_timers); + dx_timer_t *timer = DEQ_HEAD(pending_timers); + if (timer) { + DEQ_REMOVE_HEAD(pending_timers); + dx_timer_idle_LH(timer); + fire_mask |= (unsigned long) timer->context; + } + sys_mutex_unlock(lock); + return result; +} + + +static char* test_quiet(void *context) +{ + fire_mask = 0; + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + + while(fire_head()); + + if (fire_mask != 0) + return "Expected zero timers fired"; + return 0; +} + +static char* test_immediate(void *context) +{ + while(fire_head()); + fire_mask = 0; + + dx_timer_schedule(timers[0], 0); + + if (fire_mask != 0) return "Premature firing"; + if (fire_head() > 1) return "Too many firings"; + if (fire_mask != 1) return "Incorrect fire mask"; + + return 0; +} + + +static char* test_immediate_plus_delayed(void *context) +{ + while(fire_head()); + fire_mask = 0; + + dx_timer_schedule(timers[0], 0); + dx_timer_schedule(timers[1], 5); + + if (fire_mask != 0) return "Premature firing"; + if (fire_head() > 1) return "Too many firings"; + if (fire_mask != 1) return "Incorrect fire mask 1"; + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + time += 8; + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + + if (fire_head() < 1) return "Delayed Failed to fire"; + if (fire_mask != 3) return "Incorrect fire mask 3"; + + return 0; +} + + +static char* test_single(void *context) +{ + while(fire_head()); + fire_mask = 0; + + dx_timer_schedule(timers[0], 2); + if (fire_head() > 0) return "Premature firing 1"; + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + if (fire_head() > 0) return "Premature firing 2"; + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + if (fire_head() < 1) return "Failed to fire"; + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + if (fire_head() != 0) return "Spurious fires"; + + if (fire_mask != 1) return "Incorrect fire mask"; + if (timers[0]->state != TIMER_IDLE) return "Expected idle timer state"; + + return 0; +} + + +static char* test_two_inorder(void *context) +{ + while(fire_head()); + fire_mask = 0; + + dx_timer_schedule(timers[0], 2); + dx_timer_schedule(timers[1], 4); + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + int count = fire_head(); + if (count < 1) return "First failed to fire"; + if (count > 1) return "Second fired prematurely"; + if (fire_mask != 1) return "Incorrect fire mask 1"; + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + if (fire_head() < 1) return "Second failed to fire"; + if (fire_mask != 3) return "Incorrect fire mask 3"; + + return 0; +} + + +static char* test_two_reverse(void *context) +{ + while(fire_head()); + fire_mask = 0; + + dx_timer_schedule(timers[0], 4); + dx_timer_schedule(timers[1], 2); + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + int count = fire_head(); + if (count < 1) return "First failed to fire"; + if (count > 1) return "Second fired prematurely"; + if (fire_mask != 2) return "Incorrect fire mask 2"; + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + if (fire_head() < 1) return "Second failed to fire"; + if (fire_mask != 3) return "Incorrect fire mask 3"; + + return 0; +} + + +static char* test_two_duplicate(void *context) +{ + while(fire_head()); + fire_mask = 0; + + dx_timer_schedule(timers[0], 2); + dx_timer_schedule(timers[1], 2); + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + int count = fire_head(); + if (count != 2) return "Expected two firings"; + fire_head(); + if (fire_mask != 3) return "Incorrect fire mask 3"; + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + if (fire_head() > 0) return "Spurious timer fires"; + + return 0; +} + + +static char* test_separated(void *context) +{ + int count; + + while(fire_head()); + fire_mask = 0; + + dx_timer_schedule(timers[0], 2); + dx_timer_schedule(timers[1], 4); + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + count = fire_head(); + if (count < 1) return "First failed to fire"; + if (count > 1) return "Second fired prematurely"; + if (fire_mask != 1) return "Incorrect fire mask 1"; + + dx_timer_schedule(timers[2], 2); + dx_timer_schedule(timers[3], 4); + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + count = fire_head(); + fire_head(); + if (count < 1) return "Second failed to fire"; + if (count < 2) return "Third failed to fire"; + if (fire_mask != 7) return "Incorrect fire mask 7"; + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + count = fire_head(); + if (count < 1) return "Fourth failed to fire"; + if (fire_mask != 15) return "Incorrect fire mask 15"; + + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + count = fire_head(); + if (count > 0) return "Spurious fire"; + + return 0; +} + + +static char* test_big(void *context) +{ + while(fire_head()); + fire_mask = 0; + + long durations[16] = + { 5, 8, 7, 6, + 14, 10, 16, 15, + 11, 12, 9, 12, + 1, 2, 3, 4}; + unsigned long masks[18] = { + 0x1000, + 0x3000, + 0x7000, + 0xf000, + 0xf001, + 0xf009, + 0xf00d, + 0xf00f, + 0xf40f, + 0xf42f, + 0xf52f, + 0xff2f, + 0xff2f, + 0xff3f, + 0xffbf, + 0xffff, + 0xffff, + 0xffff + }; + + int i; + for (i = 0; i < 16; i++) + dx_timer_schedule(timers[i], durations[i]); + for (i = 0; i < 18; i++) { + sys_mutex_lock(lock); + dx_timer_visit_LH(time++); + sys_mutex_unlock(lock); + while(fire_head()); + if (fire_mask != masks[i]) { + static char error[100]; + sprintf(error, "Iteration %d: expected mask %04lx, got %04lx", i, masks[i], fire_mask); + return error; + } + } + + return 0; +} + + +int timer_tests(void) +{ + int result = 0; + dx_alloc_initialize(); + + fire_mask = 0; + DEQ_INIT(pending_timers); + lock = sys_mutex(); + dx_timer_initialize(lock); + time = 1; + + timers[0] = dx_timer(0, (void*) 0x00000001); + timers[1] = dx_timer(0, (void*) 0x00000002); + timers[2] = dx_timer(0, (void*) 0x00000004); + timers[3] = dx_timer(0, (void*) 0x00000008); + timers[4] = dx_timer(0, (void*) 0x00000010); + timers[5] = dx_timer(0, (void*) 0x00000020); + timers[6] = dx_timer(0, (void*) 0x00000040); + timers[7] = dx_timer(0, (void*) 0x00000080); + timers[8] = dx_timer(0, (void*) 0x00000100); + timers[9] = dx_timer(0, (void*) 0x00000200); + timers[10] = dx_timer(0, (void*) 0x00000400); + timers[11] = dx_timer(0, (void*) 0x00000800); + timers[12] = dx_timer(0, (void*) 0x00001000); + timers[13] = dx_timer(0, (void*) 0x00002000); + timers[14] = dx_timer(0, (void*) 0x00004000); + timers[15] = dx_timer(0, (void*) 0x00008000); + + TEST_CASE(test_quiet, 0); + TEST_CASE(test_immediate, 0); + TEST_CASE(test_immediate_plus_delayed, 0); + TEST_CASE(test_single, 0); + TEST_CASE(test_two_inorder, 0); + TEST_CASE(test_two_reverse, 0); + TEST_CASE(test_two_duplicate, 0); + TEST_CASE(test_separated, 0); + TEST_CASE(test_big, 0); + + int i; + for (i = 0; i < 16; i++) + dx_timer_free(timers[i]); + + dx_timer_finalize(); + + return result; +} + |