From 756b7431a7a0c7dd84efbabc4e620de875185822 Mon Sep 17 00:00:00 2001 From: Dirk Ziegelmeier Date: Thu, 4 Jan 2018 13:37:05 +0100 Subject: [PATCH] Start implementing unit tests for timers --- src/core/timeouts.c | 12 +++++- src/include/lwip/timeouts.h | 8 +++- test/unit/Filelists.mk | 1 + test/unit/arch/sys_arch.c | 6 ++- test/unit/arch/sys_arch.h | 3 ++ test/unit/core/test_timers.c | 79 ++++++++++++++++++++++++++++++++++++ test/unit/core/test_timers.h | 8 ++++ test/unit/lwip_unittests.c | 2 + test/unit/lwipopts.h | 4 +- 9 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 test/unit/core/test_timers.c create mode 100644 test/unit/core/test_timers.h diff --git a/src/core/timeouts.c b/src/core/timeouts.c index 4196f9b4..722cf864 100644 --- a/src/core/timeouts.c +++ b/src/core/timeouts.c @@ -113,6 +113,14 @@ const int lwip_num_cyclic_timers = LWIP_ARRAYSIZE(lwip_cyclic_timers); static struct sys_timeo *next_timeout; static u32_t timeouts_last_time; +#if LWIP_TESTMODE +struct sys_timeo** +lwip_sys_timers_get_next_timout(void) +{ + return &next_timeout; +} +#endif + #if LWIP_TCP /** global variable that shows if the tcp timer is currently scheduled or not */ static int tcpip_tcp_timer_active; @@ -313,7 +321,7 @@ sys_untimeout(sys_timeout_handler handler, void *arg) * * Must be called periodically from your main loop. */ -#if !NO_SYS && !defined __DOXYGEN__ +#if !LWIP_TESTMODE && !NO_SYS && !defined __DOXYGEN__ static #endif /* !NO_SYS */ void @@ -377,7 +385,7 @@ sys_restart_timeouts(void) /** Return the time left before the next timeout is due. If no timeouts are * enqueued, returns 0xffffffff */ -#if !NO_SYS +#if !LWIP_TESTMODE && !NO_SYS static #endif /* !NO_SYS */ u32_t diff --git a/src/include/lwip/timeouts.h b/src/include/lwip/timeouts.h index 002fcd45..b424a7d7 100644 --- a/src/include/lwip/timeouts.h +++ b/src/include/lwip/timeouts.h @@ -106,13 +106,17 @@ void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg); void sys_untimeout(sys_timeout_handler handler, void *arg); void sys_restart_timeouts(void); -#if NO_SYS +#if LWIP_TESTMODE || NO_SYS void sys_check_timeouts(void); u32_t sys_timeouts_sleeptime(void); -#else /* NO_SYS */ +#endif +#if !NO_SYS void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg); #endif /* NO_SYS */ +#if LWIP_TESTMODE +struct sys_timeo** lwip_sys_timers_get_next_timout(void); +#endif #endif /* LWIP_TIMERS */ diff --git a/test/unit/Filelists.mk b/test/unit/Filelists.mk index 35269412..acb9148f 100644 --- a/test/unit/Filelists.mk +++ b/test/unit/Filelists.mk @@ -36,6 +36,7 @@ TESTFILES=$(TESTDIR)/lwip_unittests.c \ $(TESTDIR)/core/test_def.c \ $(TESTDIR)/core/test_mem.c \ $(TESTDIR)/core/test_pbuf.c \ + $(TESTDIR)/core/test_timers.c \ $(TESTDIR)/dhcp/test_dhcp.c \ $(TESTDIR)/etharp/test_etharp.c \ $(TESTDIR)/ip4/test_ip4.c \ diff --git a/test/unit/arch/sys_arch.c b/test/unit/arch/sys_arch.c index 27c90bcb..cc01a6db 100644 --- a/test/unit/arch/sys_arch.c +++ b/test/unit/arch/sys_arch.c @@ -42,14 +42,16 @@ #include +u32_t lwip_sys_now; + u32_t sys_jiffies(void) { - return (u32_t)0; /* todo */ + return lwip_sys_now; } u32_t sys_now(void) { - return (u32_t)0; /* todo */ + return lwip_sys_now; } void sys_init(void) diff --git a/test/unit/arch/sys_arch.h b/test/unit/arch/sys_arch.h index 752e4595..331c2f2f 100644 --- a/test/unit/arch/sys_arch.h +++ b/test/unit/arch/sys_arch.h @@ -65,5 +65,8 @@ typedef u32_t sys_thread_t; typedef int (*test_sys_arch_waiting_fn)(sys_sem_t* wait_sem, sys_mbox_t* wait_mbox); void test_sys_arch_wait_callback(test_sys_arch_waiting_fn waiting_fn); +/* current time */ +extern u32_t lwip_sys_now; + #endif /* LWIP_HDR_TEST_SYS_ARCH_H */ diff --git a/test/unit/core/test_timers.c b/test/unit/core/test_timers.c new file mode 100644 index 00000000..ab28bd9e --- /dev/null +++ b/test/unit/core/test_timers.c @@ -0,0 +1,79 @@ +#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 = lwip_sys_timers_get_next_timout(); + old_list_head = *list_head; + *list_head = NULL; +} + +static void +timers_teardown(void) +{ + struct sys_timeo** list_head = lwip_sys_timers_get_next_timout(); + *list_head = old_list_head; + lwip_sys_now = 0; +} + +static void dummy_handler(void* arg) +{ + LWIP_UNUSED_ARG(arg); +} + +static void test_timers(void) +{ + struct sys_timeo** list_head = lwip_sys_timers_get_next_timout(); + + lwip_sys_now = 100; + + sys_timeout(10, dummy_handler, NULL); + fail_unless(sys_timeouts_sleeptime() == 10); + sys_timeout(20, dummy_handler, NULL); + fail_unless(sys_timeouts_sleeptime() == 10); + sys_timeout( 5, dummy_handler, NULL); + fail_unless(sys_timeouts_sleeptime() == 5); + + sys_untimeout(dummy_handler, NULL); + sys_untimeout(dummy_handler, NULL); + sys_untimeout(dummy_handler, NULL); + + lwip_sys_now = 0xfffffff0; + + sys_timeout(10, dummy_handler, NULL); + fail_unless(sys_timeouts_sleeptime() == 10); + sys_timeout(20, dummy_handler, NULL); + fail_unless(sys_timeouts_sleeptime() == 10); + sys_timeout( 5, dummy_handler, NULL); + fail_unless(sys_timeouts_sleeptime() == 5); + + sys_untimeout(dummy_handler, NULL); + sys_untimeout(dummy_handler, NULL); + sys_untimeout(dummy_handler, NULL); +} + +START_TEST(test_lwip_timers) +{ + LWIP_UNUSED_ARG(_i); + + test_timers(); +} +END_TEST + +/** Create the suite including all tests for this module */ +Suite * +timers_suite(void) +{ + testfunc tests[] = { + TESTFUNC(test_lwip_timers) + }; + return create_suite("TIMERS", tests, LWIP_ARRAYSIZE(tests), timers_setup, timers_teardown); +} diff --git a/test/unit/core/test_timers.h b/test/unit/core/test_timers.h new file mode 100644 index 00000000..b16ab75b --- /dev/null +++ b/test/unit/core/test_timers.h @@ -0,0 +1,8 @@ +#ifndef LWIP_HDR_TEST_TIMERS_H +#define LWIP_HDR_TEST_TIMERS_H + +#include "../lwip_check.h" + +Suite *timers_suite(void); + +#endif diff --git a/test/unit/lwip_unittests.c b/test/unit/lwip_unittests.c index d9e65d54..4a34d869 100644 --- a/test/unit/lwip_unittests.c +++ b/test/unit/lwip_unittests.c @@ -7,6 +7,7 @@ #include "core/test_def.h" #include "core/test_mem.h" #include "core/test_pbuf.h" +#include "core/test_timers.h" #include "etharp/test_etharp.h" #include "dhcp/test_dhcp.h" #include "mdns/test_mdns.h" @@ -66,6 +67,7 @@ int main(void) def_suite, mem_suite, pbuf_suite, + timers_suite, etharp_suite, dhcp_suite, mdns_suite, diff --git a/test/unit/lwipopts.h b/test/unit/lwipopts.h index 953c5d09..2e94d4f9 100644 --- a/test/unit/lwipopts.h +++ b/test/unit/lwipopts.h @@ -32,6 +32,8 @@ #ifndef LWIP_HDR_LWIPOPTS_H #define LWIP_HDR_LWIPOPTS_H +#define LWIP_TESTMODE 1 + #define LWIP_IPV6 1 /* We link to special sys_arch.c (for basic non-waiting API layers unit tests) */ @@ -65,7 +67,7 @@ /* Minimal changes to opt.h required for etharp unit tests: */ #define ETHARP_SUPPORT_STATIC_ENTRIES 1 -#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 1) +#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 5) /* MIB2 stats are required to check IPv4 reassembly results */ #define MIB2_STATS 1