You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
5.5 KiB
233 lines
5.5 KiB
#include "test_timers.h" |
|
|
|
#include "lwip/def.h" |
|
#include "lwip/timeouts.h" |
|
#include "arch/sys_arch.h" |
|
|
|
/* Setups/teardown functions */ |
|
|
|
static struct sys_timeo* old_list_head; |
|
|
|
static void |
|
timers_setup(void) |
|
{ |
|
struct sys_timeo** list_head = sys_timeouts_get_next_timeout(); |
|
old_list_head = *list_head; |
|
*list_head = NULL; |
|
} |
|
|
|
static void |
|
timers_teardown(void) |
|
{ |
|
struct sys_timeo** list_head = sys_timeouts_get_next_timeout(); |
|
*list_head = old_list_head; |
|
lwip_sys_now = 0; |
|
} |
|
|
|
static int fired[3]; |
|
static void |
|
dummy_handler(void* arg) |
|
{ |
|
int index = LWIP_PTR_NUMERIC_CAST(int, arg); |
|
fired[index] = 1; |
|
} |
|
|
|
#define HANDLER_EXECUTION_TIME 5 |
|
static int cyclic_fired; |
|
static void |
|
dummy_cyclic_handler(void) |
|
{ |
|
cyclic_fired = 1; |
|
lwip_sys_now += HANDLER_EXECUTION_TIME; |
|
} |
|
|
|
struct lwip_cyclic_timer test_cyclic = {10, dummy_cyclic_handler}; |
|
|
|
static void |
|
do_test_cyclic_timers(u32_t offset) |
|
{ |
|
struct sys_timeo** list_head = sys_timeouts_get_next_timeout(); |
|
|
|
/* verify normal timer expiration */ |
|
lwip_sys_now = offset + 0; |
|
sys_timeout(test_cyclic.interval_ms, lwip_cyclic_timer, &test_cyclic); |
|
|
|
cyclic_fired = 0; |
|
sys_check_timeouts(); |
|
fail_unless(cyclic_fired == 0); |
|
|
|
lwip_sys_now = offset + test_cyclic.interval_ms; |
|
sys_check_timeouts(); |
|
fail_unless(cyclic_fired == 1); |
|
|
|
fail_unless((*list_head)->time == (u32_t)(lwip_sys_now + test_cyclic.interval_ms - HANDLER_EXECUTION_TIME)); |
|
|
|
sys_untimeout(lwip_cyclic_timer, &test_cyclic); |
|
|
|
|
|
/* verify "overload" - next cyclic timer execution is already overdue twice */ |
|
lwip_sys_now = offset + 0; |
|
sys_timeout(test_cyclic.interval_ms, lwip_cyclic_timer, &test_cyclic); |
|
|
|
cyclic_fired = 0; |
|
sys_check_timeouts(); |
|
fail_unless(cyclic_fired == 0); |
|
|
|
lwip_sys_now = offset + 2*test_cyclic.interval_ms; |
|
sys_check_timeouts(); |
|
fail_unless(cyclic_fired == 1); |
|
|
|
fail_unless((*list_head)->time == (u32_t)(lwip_sys_now + test_cyclic.interval_ms)); |
|
} |
|
|
|
START_TEST(test_cyclic_timers) |
|
{ |
|
LWIP_UNUSED_ARG(_i); |
|
|
|
/* check without u32_t wraparound */ |
|
do_test_cyclic_timers(0); |
|
|
|
/* check with u32_t wraparound */ |
|
do_test_cyclic_timers(0xfffffff0); |
|
} |
|
END_TEST |
|
|
|
/* reproduce bug #52748: the bug in timeouts.c */ |
|
START_TEST(test_bug52748) |
|
{ |
|
LWIP_UNUSED_ARG(_i); |
|
|
|
memset(&fired, 0, sizeof(fired)); |
|
|
|
lwip_sys_now = 50; |
|
sys_timeout(20, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0)); |
|
sys_timeout( 5, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2)); |
|
|
|
lwip_sys_now = 55; |
|
sys_check_timeouts(); |
|
fail_unless(fired[0] == 0); |
|
fail_unless(fired[1] == 0); |
|
fail_unless(fired[2] == 1); |
|
|
|
lwip_sys_now = 60; |
|
sys_timeout(10, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1)); |
|
sys_check_timeouts(); |
|
fail_unless(fired[0] == 0); |
|
fail_unless(fired[1] == 0); |
|
fail_unless(fired[2] == 1); |
|
|
|
lwip_sys_now = 70; |
|
sys_check_timeouts(); |
|
fail_unless(fired[0] == 1); |
|
fail_unless(fired[1] == 1); |
|
fail_unless(fired[2] == 1); |
|
} |
|
END_TEST |
|
|
|
static void |
|
do_test_timers(u32_t offset) |
|
{ |
|
struct sys_timeo** list_head = sys_timeouts_get_next_timeout(); |
|
|
|
lwip_sys_now = offset + 0; |
|
|
|
sys_timeout(10, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0)); |
|
fail_unless(sys_timeouts_sleeptime() == 10); |
|
sys_timeout(20, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1)); |
|
fail_unless(sys_timeouts_sleeptime() == 10); |
|
sys_timeout( 5, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2)); |
|
fail_unless(sys_timeouts_sleeptime() == 5); |
|
|
|
/* linked list correctly sorted? */ |
|
fail_unless((*list_head)->time == (u32_t)(lwip_sys_now + 5)); |
|
fail_unless((*list_head)->next->time == (u32_t)(lwip_sys_now + 10)); |
|
fail_unless((*list_head)->next->next->time == (u32_t)(lwip_sys_now + 20)); |
|
|
|
/* check timers expire in correct order */ |
|
memset(&fired, 0, sizeof(fired)); |
|
|
|
lwip_sys_now += 4; |
|
sys_check_timeouts(); |
|
fail_unless(fired[2] == 0); |
|
|
|
lwip_sys_now += 1; |
|
sys_check_timeouts(); |
|
fail_unless(fired[2] == 1); |
|
|
|
lwip_sys_now += 4; |
|
sys_check_timeouts(); |
|
fail_unless(fired[0] == 0); |
|
|
|
lwip_sys_now += 1; |
|
sys_check_timeouts(); |
|
fail_unless(fired[0] == 1); |
|
|
|
lwip_sys_now += 9; |
|
sys_check_timeouts(); |
|
fail_unless(fired[1] == 0); |
|
|
|
lwip_sys_now += 1; |
|
sys_check_timeouts(); |
|
fail_unless(fired[1] == 1); |
|
|
|
sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0)); |
|
sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1)); |
|
sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2)); |
|
} |
|
|
|
START_TEST(test_timers) |
|
{ |
|
LWIP_UNUSED_ARG(_i); |
|
|
|
/* check without u32_t wraparound */ |
|
do_test_timers(0); |
|
|
|
/* check with u32_t wraparound */ |
|
do_test_timers(0xfffffff0); |
|
} |
|
END_TEST |
|
|
|
START_TEST(test_long_timer) |
|
{ |
|
LWIP_UNUSED_ARG(_i); |
|
|
|
memset(&fired, 0, sizeof(fired)); |
|
lwip_sys_now = 0; |
|
|
|
sys_timeout(LWIP_UINT32_MAX / 4, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0)); |
|
fail_unless(sys_timeouts_sleeptime() == LWIP_UINT32_MAX / 4); |
|
|
|
sys_check_timeouts(); |
|
fail_unless(fired[0] == 0); |
|
|
|
lwip_sys_now += LWIP_UINT32_MAX / 8; |
|
|
|
sys_check_timeouts(); |
|
fail_unless(fired[0] == 0); |
|
|
|
lwip_sys_now += LWIP_UINT32_MAX / 8; |
|
|
|
sys_check_timeouts(); |
|
fail_unless(fired[0] == 0); |
|
|
|
lwip_sys_now += 1; |
|
|
|
sys_check_timeouts(); |
|
fail_unless(fired[0] == 1); |
|
|
|
sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0)); |
|
} |
|
END_TEST |
|
|
|
/** Create the suite including all tests for this module */ |
|
Suite * |
|
timers_suite(void) |
|
{ |
|
testfunc tests[] = { |
|
TESTFUNC(test_bug52748), |
|
TESTFUNC(test_cyclic_timers), |
|
TESTFUNC(test_timers), |
|
TESTFUNC(test_long_timer), |
|
}; |
|
return create_suite("TIMERS", tests, LWIP_ARRAYSIZE(tests), timers_setup, timers_teardown); |
|
}
|
|
|