• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "test_timers.h"
2 
3 #include "lwip/def.h"
4 #include "lwip/timeouts.h"
5 #include "arch/sys_arch.h"
6 
7 /* Setups/teardown functions */
8 
9 static struct sys_timeo* old_list_head;
10 
11 static void
timers_setup(void)12 timers_setup(void)
13 {
14   struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
15   old_list_head = *list_head;
16   *list_head = NULL;
17 }
18 
19 static void
timers_teardown(void)20 timers_teardown(void)
21 {
22   struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
23   *list_head = old_list_head;
24   lwip_sys_now = 0;
25 }
26 
27 static int fired[3];
28 static void
dummy_handler(void * arg)29 dummy_handler(void* arg)
30 {
31   int index = LWIP_PTR_NUMERIC_CAST(int, arg);
32   fired[index] = 1;
33 }
34 
35 #define HANDLER_EXECUTION_TIME 5
36 static int cyclic_fired;
37 static void
dummy_cyclic_handler(void)38 dummy_cyclic_handler(void)
39 {
40    cyclic_fired = 1;
41    lwip_sys_now += HANDLER_EXECUTION_TIME;
42 }
43 
44 struct lwip_cyclic_timer test_cyclic = {10, dummy_cyclic_handler};
45 
46 static void
do_test_cyclic_timers(u32_t offset)47 do_test_cyclic_timers(u32_t offset)
48 {
49   struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
50 
51   /* verify normal timer expiration */
52   lwip_sys_now = offset + 0;
53   sys_timeout(test_cyclic.interval_ms, lwip_cyclic_timer, &test_cyclic);
54 
55   cyclic_fired = 0;
56   sys_check_timeouts();
57   fail_unless(cyclic_fired == 0);
58 
59   lwip_sys_now = offset + test_cyclic.interval_ms;
60   sys_check_timeouts();
61   fail_unless(cyclic_fired == 1);
62 
63   fail_unless((*list_head)->time == (u32_t)(lwip_sys_now + test_cyclic.interval_ms - HANDLER_EXECUTION_TIME));
64 
65   sys_untimeout(lwip_cyclic_timer, &test_cyclic);
66 
67 
68   /* verify "overload" - next cyclic timer execution is already overdue twice */
69   lwip_sys_now = offset + 0;
70   sys_timeout(test_cyclic.interval_ms, lwip_cyclic_timer, &test_cyclic);
71 
72   cyclic_fired = 0;
73   sys_check_timeouts();
74   fail_unless(cyclic_fired == 0);
75 
76   lwip_sys_now = offset + 2*test_cyclic.interval_ms;
77   sys_check_timeouts();
78   fail_unless(cyclic_fired == 1);
79 
80   fail_unless((*list_head)->time == (u32_t)(lwip_sys_now + test_cyclic.interval_ms));
81 }
82 
START_TEST(test_cyclic_timers)83 START_TEST(test_cyclic_timers)
84 {
85   LWIP_UNUSED_ARG(_i);
86 
87   /* check without u32_t wraparound */
88   do_test_cyclic_timers(0);
89 
90   /* check with u32_t wraparound */
91   do_test_cyclic_timers(0xfffffff0);
92 }
93 END_TEST
94 
95 /* reproduce bug #52748: the bug in timeouts.c */
START_TEST(test_bug52748)96 START_TEST(test_bug52748)
97 {
98   LWIP_UNUSED_ARG(_i);
99 
100   memset(&fired, 0, sizeof(fired));
101 
102   lwip_sys_now = 50;
103   sys_timeout(20, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
104   sys_timeout( 5, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2));
105 
106   lwip_sys_now = 55;
107   sys_check_timeouts();
108   fail_unless(fired[0] == 0);
109   fail_unless(fired[1] == 0);
110   fail_unless(fired[2] == 1);
111 
112   lwip_sys_now = 60;
113   sys_timeout(10, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1));
114   sys_check_timeouts();
115   fail_unless(fired[0] == 0);
116   fail_unless(fired[1] == 0);
117   fail_unless(fired[2] == 1);
118 
119   lwip_sys_now = 70;
120   sys_check_timeouts();
121   fail_unless(fired[0] == 1);
122   fail_unless(fired[1] == 1);
123   fail_unless(fired[2] == 1);
124 }
125 END_TEST
126 
127 static void
do_test_timers(u32_t offset)128 do_test_timers(u32_t offset)
129 {
130   struct sys_timeo** list_head = sys_timeouts_get_next_timeout();
131 
132   lwip_sys_now = offset + 0;
133 
134   sys_timeout(10, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
135   fail_unless(sys_timeouts_sleeptime() == 10);
136   sys_timeout(20, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1));
137   fail_unless(sys_timeouts_sleeptime() == 10);
138   sys_timeout( 5, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2));
139   fail_unless(sys_timeouts_sleeptime() == 5);
140 
141   /* linked list correctly sorted? */
142   fail_unless((*list_head)->time             == (u32_t)(lwip_sys_now + 5));
143   fail_unless((*list_head)->next->time       == (u32_t)(lwip_sys_now + 10));
144   fail_unless((*list_head)->next->next->time == (u32_t)(lwip_sys_now + 20));
145 
146   /* check timers expire in correct order */
147   memset(&fired, 0, sizeof(fired));
148 
149   lwip_sys_now += 4;
150   sys_check_timeouts();
151   fail_unless(fired[2] == 0);
152 
153   lwip_sys_now += 1;
154   sys_check_timeouts();
155   fail_unless(fired[2] == 1);
156 
157   lwip_sys_now += 4;
158   sys_check_timeouts();
159   fail_unless(fired[0] == 0);
160 
161   lwip_sys_now += 1;
162   sys_check_timeouts();
163   fail_unless(fired[0] == 1);
164 
165   lwip_sys_now += 9;
166   sys_check_timeouts();
167   fail_unless(fired[1] == 0);
168 
169   lwip_sys_now += 1;
170   sys_check_timeouts();
171   fail_unless(fired[1] == 1);
172 
173   sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
174   sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 1));
175   sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 2));
176 }
177 
START_TEST(test_timers)178 START_TEST(test_timers)
179 {
180   LWIP_UNUSED_ARG(_i);
181 
182   /* check without u32_t wraparound */
183   do_test_timers(0);
184 
185   /* check with u32_t wraparound */
186   do_test_timers(0xfffffff0);
187 }
188 END_TEST
189 
START_TEST(test_long_timer)190 START_TEST(test_long_timer)
191 {
192   LWIP_UNUSED_ARG(_i);
193 
194   memset(&fired, 0, sizeof(fired));
195   lwip_sys_now = 0;
196 
197   sys_timeout(LWIP_UINT32_MAX / 4, dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
198   fail_unless(sys_timeouts_sleeptime() == LWIP_UINT32_MAX / 4);
199 
200   sys_check_timeouts();
201   fail_unless(fired[0] == 0);
202 
203   lwip_sys_now += LWIP_UINT32_MAX / 8;
204 
205   sys_check_timeouts();
206   fail_unless(fired[0] == 0);
207 
208   lwip_sys_now += LWIP_UINT32_MAX / 8;
209 
210   sys_check_timeouts();
211   fail_unless(fired[0] == 0);
212 
213   lwip_sys_now += 1;
214 
215   sys_check_timeouts();
216   fail_unless(fired[0] == 1);
217 
218   sys_untimeout(dummy_handler, LWIP_PTR_NUMERIC_CAST(void*, 0));
219 }
220 END_TEST
221 
222 /** Create the suite including all tests for this module */
223 Suite *
timers_suite(void)224 timers_suite(void)
225 {
226   testfunc tests[] = {
227     TESTFUNC(test_bug52748),
228     TESTFUNC(test_cyclic_timers),
229     TESTFUNC(test_timers),
230     TESTFUNC(test_long_timer),
231   };
232   return create_suite("TIMERS", tests, LWIP_ARRAYSIZE(tests), timers_setup, timers_teardown);
233 }
234