xref: /third_party/libuv/test/test-timer.c (revision e66f31c5)
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
26static int once_cb_called = 0;
27static int once_close_cb_called = 0;
28static int twice_cb_called = 0;
29static int twice_close_cb_called = 0;
30static int repeat_cb_called = 0;
31static int repeat_close_cb_called = 0;
32static int order_cb_called = 0;
33static int timer_check_double_call_called = 0;
34static int zero_timeout_cb_calls = 0;
35static uint64_t start_time;
36static uv_timer_t tiny_timer;
37static uv_timer_t huge_timer1;
38static uv_timer_t huge_timer2;
39
40
41static void once_close_cb(uv_handle_t* handle) {
42  printf("ONCE_CLOSE_CB\n");
43
44  ASSERT_NOT_NULL(handle);
45  ASSERT_OK(uv_is_active(handle));
46
47  once_close_cb_called++;
48}
49
50
51static void once_cb(uv_timer_t* handle) {
52  printf("ONCE_CB %d\n", once_cb_called);
53
54  ASSERT_NOT_NULL(handle);
55  ASSERT_OK(uv_is_active((uv_handle_t*) handle));
56
57  once_cb_called++;
58
59  uv_close((uv_handle_t*)handle, once_close_cb);
60
61  /* Just call this randomly for the code coverage. */
62  uv_update_time(uv_default_loop());
63}
64
65static void twice_close_cb(uv_handle_t* handle) {
66  printf("TWICE_CLOSE_CB\n");
67
68  ASSERT_NOT_NULL(handle);
69  ASSERT_OK(uv_is_active(handle));
70
71  twice_close_cb_called++;
72}
73
74static void twice_cb(uv_timer_t* handle) {
75  printf("TWICE_CB %d\n", twice_cb_called);
76
77  ASSERT_NOT_NULL(handle);
78  ASSERT_OK(uv_is_active((uv_handle_t*) handle));
79
80  twice_cb_called++;
81
82  uv_close((uv_handle_t*)handle, twice_close_cb);
83}
84
85
86
87static void repeat_close_cb(uv_handle_t* handle) {
88  printf("REPEAT_CLOSE_CB\n");
89
90  ASSERT_NOT_NULL(handle);
91
92  repeat_close_cb_called++;
93}
94
95
96static void repeat_cb(uv_timer_t* handle) {
97  printf("REPEAT_CB\n");
98
99  ASSERT_NOT_NULL(handle);
100  ASSERT_EQ(1, uv_is_active((uv_handle_t*) handle));
101
102  repeat_cb_called++;
103
104  if (repeat_cb_called == 5) {
105    uv_close((uv_handle_t*)handle, repeat_close_cb);
106  }
107}
108
109
110static void never_cb(uv_timer_t* handle) {
111  FATAL("never_cb should never be called");
112}
113
114
115TEST_IMPL(timer) {
116  uv_timer_t once_timers[10];
117  uv_timer_t *once;
118  uv_timer_t repeat, never;
119  unsigned int i;
120  int r;
121
122  start_time = uv_now(uv_default_loop());
123  ASSERT_LT(0, start_time);
124
125  /* Let 10 timers time out in 500 ms total. */
126  for (i = 0; i < ARRAY_SIZE(once_timers); i++) {
127    once = once_timers + i;
128    r = uv_timer_init(uv_default_loop(), once);
129    ASSERT_OK(r);
130    r = uv_timer_start(once, once_cb, i * 50, 0);
131    ASSERT_OK(r);
132  }
133
134  /* The 11th timer is a repeating timer that runs 4 times */
135  r = uv_timer_init(uv_default_loop(), &repeat);
136  ASSERT_OK(r);
137  r = uv_timer_start(&repeat, repeat_cb, 100, 100);
138  ASSERT_OK(r);
139
140  /* The 12th timer should not do anything. */
141  r = uv_timer_init(uv_default_loop(), &never);
142  ASSERT_OK(r);
143  r = uv_timer_start(&never, never_cb, 100, 100);
144  ASSERT_OK(r);
145  r = uv_timer_stop(&never);
146  ASSERT_OK(r);
147  uv_unref((uv_handle_t*)&never);
148
149  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
150
151  ASSERT_EQ(10, once_cb_called);
152  ASSERT_EQ(10, once_close_cb_called);
153  printf("repeat_cb_called %d\n", repeat_cb_called);
154  ASSERT_EQ(5, repeat_cb_called);
155  ASSERT_EQ(1, repeat_close_cb_called);
156
157  ASSERT_LE(500, uv_now(uv_default_loop()) - start_time);
158
159  MAKE_VALGRIND_HAPPY(uv_default_loop());
160  return 0;
161}
162
163
164TEST_IMPL(timer_start_twice) {
165  uv_timer_t once;
166  int r;
167
168  r = uv_timer_init(uv_default_loop(), &once);
169  ASSERT_OK(r);
170  r = uv_timer_start(&once, never_cb, 86400 * 1000, 0);
171  ASSERT_OK(r);
172  r = uv_timer_start(&once, twice_cb, 10, 0);
173  ASSERT_OK(r);
174  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
175  ASSERT_OK(r);
176
177  ASSERT_EQ(1, twice_cb_called);
178
179  MAKE_VALGRIND_HAPPY(uv_default_loop());
180  return 0;
181}
182
183
184TEST_IMPL(timer_init) {
185  uv_timer_t handle;
186
187  ASSERT_OK(uv_timer_init(uv_default_loop(), &handle));
188  ASSERT_OK(uv_timer_get_repeat(&handle));
189  ASSERT_UINT64_LE(0, uv_timer_get_due_in(&handle));
190  ASSERT_OK(uv_is_active((uv_handle_t*) &handle));
191
192  MAKE_VALGRIND_HAPPY(uv_default_loop());
193  return 0;
194}
195
196
197static void order_cb_a(uv_timer_t *handle) {
198  ASSERT_EQ(order_cb_called++, *(int*)handle->data);
199}
200
201
202static void order_cb_b(uv_timer_t *handle) {
203  ASSERT_EQ(order_cb_called++, *(int*)handle->data);
204}
205
206
207TEST_IMPL(timer_order) {
208  int first;
209  int second;
210  uv_timer_t handle_a;
211  uv_timer_t handle_b;
212
213  first = 0;
214  second = 1;
215  ASSERT_OK(uv_timer_init(uv_default_loop(), &handle_a));
216  ASSERT_OK(uv_timer_init(uv_default_loop(), &handle_b));
217
218  /* Test for starting handle_a then handle_b */
219  handle_a.data = &first;
220  ASSERT_OK(uv_timer_start(&handle_a, order_cb_a, 0, 0));
221  handle_b.data = &second;
222  ASSERT_OK(uv_timer_start(&handle_b, order_cb_b, 0, 0));
223  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
224
225  ASSERT_EQ(2, order_cb_called);
226
227  ASSERT_OK(uv_timer_stop(&handle_a));
228  ASSERT_OK(uv_timer_stop(&handle_b));
229
230  /* Test for starting handle_b then handle_a */
231  order_cb_called = 0;
232  handle_b.data = &first;
233  ASSERT_OK(uv_timer_start(&handle_b, order_cb_b, 0, 0));
234
235  handle_a.data = &second;
236  ASSERT_OK(uv_timer_start(&handle_a, order_cb_a, 0, 0));
237  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
238
239  ASSERT_EQ(2, order_cb_called);
240
241  MAKE_VALGRIND_HAPPY(uv_default_loop());
242  return 0;
243}
244
245
246static void zero_timeout_cb(uv_timer_t* handle) {
247  ASSERT_OK(uv_timer_start(handle, zero_timeout_cb, 0, 0));
248  uv_stop(handle->loop);
249  zero_timeout_cb_calls++;
250}
251
252
253TEST_IMPL(timer_zero_timeout) {
254  uv_timer_t timer;
255  uv_loop_t* loop;
256
257  loop = uv_default_loop();
258  ASSERT_OK(uv_timer_init(loop, &timer));
259  ASSERT_OK(uv_timer_start(&timer, zero_timeout_cb, 0, 0));
260  ASSERT_EQ(1, uv_run(loop, UV_RUN_DEFAULT));  /* because of uv_stop() */
261  ASSERT_EQ(1, zero_timeout_cb_calls);
262  uv_close((uv_handle_t*) &timer, NULL);
263  ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT));
264  ASSERT_EQ(1, zero_timeout_cb_calls);
265
266  MAKE_VALGRIND_HAPPY(loop);
267  return 0;
268}
269
270
271static void tiny_timer_cb(uv_timer_t* handle) {
272  ASSERT_PTR_EQ(handle, &tiny_timer);
273  uv_close((uv_handle_t*) &tiny_timer, NULL);
274  uv_close((uv_handle_t*) &huge_timer1, NULL);
275  uv_close((uv_handle_t*) &huge_timer2, NULL);
276}
277
278
279TEST_IMPL(timer_huge_timeout) {
280  ASSERT_OK(uv_timer_init(uv_default_loop(), &tiny_timer));
281  ASSERT_OK(uv_timer_init(uv_default_loop(), &huge_timer1));
282  ASSERT_OK(uv_timer_init(uv_default_loop(), &huge_timer2));
283  ASSERT_OK(uv_timer_start(&tiny_timer, tiny_timer_cb, 1, 0));
284  ASSERT_OK(uv_timer_start(&huge_timer1,
285                           tiny_timer_cb,
286                           0xffffffffffffLL,
287                           0));
288  ASSERT_OK(uv_timer_start(&huge_timer2, tiny_timer_cb, (uint64_t) -1, 0));
289  ASSERT_UINT64_EQ(1, uv_timer_get_due_in(&tiny_timer));
290  ASSERT_UINT64_EQ(281474976710655, uv_timer_get_due_in(&huge_timer1));
291  ASSERT_UINT64_LE(0, uv_timer_get_due_in(&huge_timer2));
292  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
293  MAKE_VALGRIND_HAPPY(uv_default_loop());
294  return 0;
295}
296
297
298static void huge_repeat_cb(uv_timer_t* handle) {
299  static int ncalls;
300
301  if (ncalls == 0)
302    ASSERT_PTR_EQ(handle, &huge_timer1);
303  else
304    ASSERT_PTR_EQ(handle, &tiny_timer);
305
306  if (++ncalls == 10) {
307    uv_close((uv_handle_t*) &tiny_timer, NULL);
308    uv_close((uv_handle_t*) &huge_timer1, NULL);
309  }
310}
311
312
313TEST_IMPL(timer_huge_repeat) {
314  ASSERT_OK(uv_timer_init(uv_default_loop(), &tiny_timer));
315  ASSERT_OK(uv_timer_init(uv_default_loop(), &huge_timer1));
316  ASSERT_OK(uv_timer_start(&tiny_timer, huge_repeat_cb, 2, 2));
317  ASSERT_OK(uv_timer_start(&huge_timer1, huge_repeat_cb, 1, (uint64_t) -1));
318  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
319  MAKE_VALGRIND_HAPPY(uv_default_loop());
320  return 0;
321}
322
323
324static unsigned int timer_run_once_timer_cb_called;
325
326
327static void timer_run_once_timer_cb(uv_timer_t* handle) {
328  timer_run_once_timer_cb_called++;
329}
330
331
332TEST_IMPL(timer_run_once) {
333  uv_timer_t timer_handle;
334
335  ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
336  ASSERT_OK(uv_timer_start(&timer_handle, timer_run_once_timer_cb, 0, 0));
337  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_ONCE));
338  ASSERT_EQ(1, timer_run_once_timer_cb_called);
339
340  ASSERT_OK(uv_timer_start(&timer_handle, timer_run_once_timer_cb, 1, 0));
341  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_ONCE));
342  ASSERT_EQ(2, timer_run_once_timer_cb_called);
343
344  uv_close((uv_handle_t*) &timer_handle, NULL);
345  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_ONCE));
346
347  MAKE_VALGRIND_HAPPY(uv_default_loop());
348  return 0;
349}
350
351
352TEST_IMPL(timer_is_closing) {
353  uv_timer_t handle;
354
355  ASSERT_OK(uv_timer_init(uv_default_loop(), &handle));
356  uv_close((uv_handle_t *)&handle, NULL);
357
358  ASSERT_EQ(UV_EINVAL, uv_timer_start(&handle, never_cb, 100, 100));
359
360  MAKE_VALGRIND_HAPPY(uv_default_loop());
361  return 0;
362}
363
364
365TEST_IMPL(timer_null_callback) {
366  uv_timer_t handle;
367
368  ASSERT_OK(uv_timer_init(uv_default_loop(), &handle));
369  ASSERT_EQ(UV_EINVAL, uv_timer_start(&handle, NULL, 100, 100));
370
371  MAKE_VALGRIND_HAPPY(uv_default_loop());
372  return 0;
373}
374
375
376static uint64_t timer_early_check_expected_time;
377
378
379static void timer_early_check_cb(uv_timer_t* handle) {
380  uint64_t hrtime = uv_hrtime() / 1000000;
381  ASSERT_GE(hrtime, timer_early_check_expected_time);
382}
383
384
385TEST_IMPL(timer_early_check) {
386  uv_timer_t timer_handle;
387  const uint64_t timeout_ms = 10;
388
389  timer_early_check_expected_time = uv_now(uv_default_loop()) + timeout_ms;
390
391  ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
392  ASSERT_OK(uv_timer_start(&timer_handle,
393                           timer_early_check_cb,
394                           timeout_ms,
395                           0));
396  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
397
398  uv_close((uv_handle_t*) &timer_handle, NULL);
399  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
400
401  MAKE_VALGRIND_HAPPY(uv_default_loop());
402  return 0;
403}
404
405static void timer_check_double_call(uv_timer_t* handle) {
406  timer_check_double_call_called++;
407}
408
409TEST_IMPL(timer_no_double_call_once) {
410  uv_timer_t timer_handle;
411  const uint64_t timeout_ms = 10;
412
413  ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
414  ASSERT_OK(uv_timer_start(&timer_handle,
415                           timer_check_double_call,
416                           timeout_ms,
417                           timeout_ms));
418  uv_sleep(timeout_ms * 2);
419  ASSERT_EQ(1, uv_run(uv_default_loop(), UV_RUN_ONCE));
420  ASSERT_EQ(1, timer_check_double_call_called);
421
422  MAKE_VALGRIND_HAPPY(uv_default_loop());
423  return 0;
424}
425
426TEST_IMPL(timer_no_double_call_nowait) {
427  uv_timer_t timer_handle;
428  const uint64_t timeout_ms = 10;
429
430  ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
431  ASSERT_OK(uv_timer_start(&timer_handle,
432                           timer_check_double_call,
433                           timeout_ms,
434                           timeout_ms));
435  uv_sleep(timeout_ms * 2);
436  ASSERT_EQ(1, uv_run(uv_default_loop(), UV_RUN_NOWAIT));
437  ASSERT_EQ(1, timer_check_double_call_called);
438
439  MAKE_VALGRIND_HAPPY(uv_default_loop());
440  return 0;
441}
442
443TEST_IMPL(timer_no_run_on_unref) {
444  uv_timer_t timer_handle;
445
446  ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
447  ASSERT_OK(uv_timer_start(&timer_handle, (uv_timer_cb) abort, 0, 0));
448  uv_unref((uv_handle_t*) &timer_handle);
449  ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
450
451  MAKE_VALGRIND_HAPPY(uv_default_loop());
452  return 0;
453}
454