xref: /netbsd-src/external/mit/libuv/dist/test/test-timer.c (revision 9fd8799cb5ceb66c69f2eb1a6d26a1d587ba1f1e)
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21 
22 #include "uv.h"
23 #include "task.h"
24 
25 
26 static int once_cb_called = 0;
27 static int once_close_cb_called = 0;
28 static int repeat_cb_called = 0;
29 static int repeat_close_cb_called = 0;
30 static int order_cb_called = 0;
31 static uint64_t start_time;
32 static uv_timer_t tiny_timer;
33 static uv_timer_t huge_timer1;
34 static uv_timer_t huge_timer2;
35 
36 
37 static void once_close_cb(uv_handle_t* handle) {
38   printf("ONCE_CLOSE_CB\n");
39 
40   ASSERT(handle != NULL);
41   ASSERT(0 == uv_is_active(handle));
42 
43   once_close_cb_called++;
44 }
45 
46 
47 static void once_cb(uv_timer_t* handle) {
48   printf("ONCE_CB %d\n", once_cb_called);
49 
50   ASSERT(handle != NULL);
51   ASSERT(0 == uv_is_active((uv_handle_t*) handle));
52 
53   once_cb_called++;
54 
55   uv_close((uv_handle_t*)handle, once_close_cb);
56 
57   /* Just call this randomly for the code coverage. */
58   uv_update_time(uv_default_loop());
59 }
60 
61 
62 static void repeat_close_cb(uv_handle_t* handle) {
63   printf("REPEAT_CLOSE_CB\n");
64 
65   ASSERT(handle != NULL);
66 
67   repeat_close_cb_called++;
68 }
69 
70 
71 static void repeat_cb(uv_timer_t* handle) {
72   printf("REPEAT_CB\n");
73 
74   ASSERT(handle != NULL);
75   ASSERT(1 == uv_is_active((uv_handle_t*) handle));
76 
77   repeat_cb_called++;
78 
79   if (repeat_cb_called == 5) {
80     uv_close((uv_handle_t*)handle, repeat_close_cb);
81   }
82 }
83 
84 
85 static void never_cb(uv_timer_t* handle) {
86   FATAL("never_cb should never be called");
87 }
88 
89 
90 TEST_IMPL(timer) {
91   uv_timer_t once_timers[10];
92   uv_timer_t *once;
93   uv_timer_t repeat, never;
94   unsigned int i;
95   int r;
96 
97   start_time = uv_now(uv_default_loop());
98   ASSERT(0 < start_time);
99 
100   /* Let 10 timers time out in 500 ms total. */
101   for (i = 0; i < ARRAY_SIZE(once_timers); i++) {
102     once = once_timers + i;
103     r = uv_timer_init(uv_default_loop(), once);
104     ASSERT(r == 0);
105     r = uv_timer_start(once, once_cb, i * 50, 0);
106     ASSERT(r == 0);
107   }
108 
109   /* The 11th timer is a repeating timer that runs 4 times */
110   r = uv_timer_init(uv_default_loop(), &repeat);
111   ASSERT(r == 0);
112   r = uv_timer_start(&repeat, repeat_cb, 100, 100);
113   ASSERT(r == 0);
114 
115   /* The 12th timer should not do anything. */
116   r = uv_timer_init(uv_default_loop(), &never);
117   ASSERT(r == 0);
118   r = uv_timer_start(&never, never_cb, 100, 100);
119   ASSERT(r == 0);
120   r = uv_timer_stop(&never);
121   ASSERT(r == 0);
122   uv_unref((uv_handle_t*)&never);
123 
124   uv_run(uv_default_loop(), UV_RUN_DEFAULT);
125 
126   ASSERT(once_cb_called == 10);
127   ASSERT(once_close_cb_called == 10);
128   printf("repeat_cb_called %d\n", repeat_cb_called);
129   ASSERT(repeat_cb_called == 5);
130   ASSERT(repeat_close_cb_called == 1);
131 
132   ASSERT(500 <= uv_now(uv_default_loop()) - start_time);
133 
134   MAKE_VALGRIND_HAPPY();
135   return 0;
136 }
137 
138 
139 TEST_IMPL(timer_start_twice) {
140   uv_timer_t once;
141   int r;
142 
143   r = uv_timer_init(uv_default_loop(), &once);
144   ASSERT(r == 0);
145   r = uv_timer_start(&once, never_cb, 86400 * 1000, 0);
146   ASSERT(r == 0);
147   r = uv_timer_start(&once, once_cb, 10, 0);
148   ASSERT(r == 0);
149   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
150   ASSERT(r == 0);
151 
152   ASSERT(once_cb_called == 1);
153 
154   MAKE_VALGRIND_HAPPY();
155   return 0;
156 }
157 
158 
159 TEST_IMPL(timer_init) {
160   uv_timer_t handle;
161 
162   ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
163   ASSERT(0 == uv_timer_get_repeat(&handle));
164   ASSERT(0 == uv_is_active((uv_handle_t*) &handle));
165 
166   MAKE_VALGRIND_HAPPY();
167   return 0;
168 }
169 
170 
171 static void order_cb_a(uv_timer_t *handle) {
172   ASSERT(order_cb_called++ == *(int*)handle->data);
173 }
174 
175 
176 static void order_cb_b(uv_timer_t *handle) {
177   ASSERT(order_cb_called++ == *(int*)handle->data);
178 }
179 
180 
181 TEST_IMPL(timer_order) {
182   int first;
183   int second;
184   uv_timer_t handle_a;
185   uv_timer_t handle_b;
186 
187   first = 0;
188   second = 1;
189   ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_a));
190   ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_b));
191 
192   /* Test for starting handle_a then handle_b */
193   handle_a.data = &first;
194   ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0));
195   handle_b.data = &second;
196   ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0));
197   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
198 
199   ASSERT(order_cb_called == 2);
200 
201   ASSERT(0 == uv_timer_stop(&handle_a));
202   ASSERT(0 == uv_timer_stop(&handle_b));
203 
204   /* Test for starting handle_b then handle_a */
205   order_cb_called = 0;
206   handle_b.data = &first;
207   ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0));
208 
209   handle_a.data = &second;
210   ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0));
211   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
212 
213   ASSERT(order_cb_called == 2);
214 
215   MAKE_VALGRIND_HAPPY();
216   return 0;
217 }
218 
219 
220 static void tiny_timer_cb(uv_timer_t* handle) {
221   ASSERT(handle == &tiny_timer);
222   uv_close((uv_handle_t*) &tiny_timer, NULL);
223   uv_close((uv_handle_t*) &huge_timer1, NULL);
224   uv_close((uv_handle_t*) &huge_timer2, NULL);
225 }
226 
227 
228 TEST_IMPL(timer_huge_timeout) {
229   ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer));
230   ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1));
231   ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer2));
232   ASSERT(0 == uv_timer_start(&tiny_timer, tiny_timer_cb, 1, 0));
233   ASSERT(0 == uv_timer_start(&huge_timer1, tiny_timer_cb, 0xffffffffffffLL, 0));
234   ASSERT(0 == uv_timer_start(&huge_timer2, tiny_timer_cb, (uint64_t) -1, 0));
235   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
236   MAKE_VALGRIND_HAPPY();
237   return 0;
238 }
239 
240 
241 static void huge_repeat_cb(uv_timer_t* handle) {
242   static int ncalls;
243 
244   if (ncalls == 0)
245     ASSERT(handle == &huge_timer1);
246   else
247     ASSERT(handle == &tiny_timer);
248 
249   if (++ncalls == 10) {
250     uv_close((uv_handle_t*) &tiny_timer, NULL);
251     uv_close((uv_handle_t*) &huge_timer1, NULL);
252   }
253 }
254 
255 
256 TEST_IMPL(timer_huge_repeat) {
257   ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer));
258   ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1));
259   ASSERT(0 == uv_timer_start(&tiny_timer, huge_repeat_cb, 2, 2));
260   ASSERT(0 == uv_timer_start(&huge_timer1, huge_repeat_cb, 1, (uint64_t) -1));
261   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
262   MAKE_VALGRIND_HAPPY();
263   return 0;
264 }
265 
266 
267 static unsigned int timer_run_once_timer_cb_called;
268 
269 
270 static void timer_run_once_timer_cb(uv_timer_t* handle) {
271   timer_run_once_timer_cb_called++;
272 }
273 
274 
275 TEST_IMPL(timer_run_once) {
276   uv_timer_t timer_handle;
277 
278   ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
279   ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 0, 0));
280   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
281   ASSERT(1 == timer_run_once_timer_cb_called);
282 
283   ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 1, 0));
284   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
285   ASSERT(2 == timer_run_once_timer_cb_called);
286 
287   uv_close((uv_handle_t*) &timer_handle, NULL);
288   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
289 
290   MAKE_VALGRIND_HAPPY();
291   return 0;
292 }
293 
294 
295 TEST_IMPL(timer_is_closing) {
296   uv_timer_t handle;
297 
298   ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
299   uv_close((uv_handle_t *)&handle, NULL);
300 
301   ASSERT(UV_EINVAL == uv_timer_start(&handle, never_cb, 100, 100));
302 
303   MAKE_VALGRIND_HAPPY();
304   return 0;
305 }
306 
307 
308 TEST_IMPL(timer_null_callback) {
309   uv_timer_t handle;
310 
311   ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
312   ASSERT(UV_EINVAL == uv_timer_start(&handle, NULL, 100, 100));
313 
314   MAKE_VALGRIND_HAPPY();
315   return 0;
316 }
317 
318 
319 static uint64_t timer_early_check_expected_time;
320 
321 
322 static void timer_early_check_cb(uv_timer_t* handle) {
323   uint64_t hrtime = uv_hrtime() / 1000000;
324   ASSERT(hrtime >= timer_early_check_expected_time);
325 }
326 
327 
328 TEST_IMPL(timer_early_check) {
329   uv_timer_t timer_handle;
330   const uint64_t timeout_ms = 10;
331 
332   timer_early_check_expected_time = uv_now(uv_default_loop()) + timeout_ms;
333 
334   ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
335   ASSERT(0 == uv_timer_start(&timer_handle, timer_early_check_cb, timeout_ms, 0));
336   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
337 
338   uv_close((uv_handle_t*) &timer_handle, NULL);
339   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
340 
341   MAKE_VALGRIND_HAPPY();
342   return 0;
343 }
344