1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <assert.h>
6 #include <stdio.h>
7 #include <threads.h>
8
9 #include <lib/zx/timer.h>
10
11
12 #include <unistd.h>
13 #include <unittest/unittest.h>
14
deadline_after()15 static bool deadline_after() {
16 BEGIN_TEST;
17 auto then = zx_clock_get_monotonic();
18 // The day we manage to boot and run this test in less than 1uS we need to fix this.
19 ASSERT_GT(then, 1000u);
20
21 auto one_hour_later = zx_deadline_after(ZX_HOUR(1));
22 EXPECT_LT(then, one_hour_later);
23
24 zx_duration_t too_big = INT64_MAX - 100;
25 auto clamped = zx_deadline_after(too_big);
26 EXPECT_EQ(clamped, ZX_TIME_INFINITE);
27
28 EXPECT_LT(0, zx_deadline_after(10 * 365 * ZX_HOUR(24)));
29 EXPECT_LT(zx_deadline_after(ZX_TIME_INFINITE_PAST), 0);
30 END_TEST;
31 }
32
timer_set_negative_deadline()33 static bool timer_set_negative_deadline() {
34 BEGIN_TEST;
35 zx::timer timer;
36 ASSERT_EQ(zx::timer::create(0, ZX_CLOCK_MONOTONIC, &timer), ZX_OK);
37 zx::duration slack;
38 ASSERT_EQ(timer.set(zx::time(-1), slack), ZX_OK);
39 zx_signals_t pending;
40 ASSERT_EQ(timer.wait_one(ZX_TIMER_SIGNALED, zx::time::infinite(), &pending), ZX_OK);
41 ASSERT_EQ(pending, ZX_TIMER_SIGNALED);
42 END_TEST;
43 }
44
timer_set_negative_deadline_max()45 static bool timer_set_negative_deadline_max() {
46 BEGIN_TEST;
47 zx::timer timer;
48 ASSERT_EQ(zx::timer::create(0, ZX_CLOCK_MONOTONIC, &timer), ZX_OK);
49 zx::duration slack;
50 ASSERT_EQ(timer.set(zx::time(ZX_TIME_INFINITE_PAST), slack), ZX_OK);
51 zx_signals_t pending;
52 ASSERT_EQ(timer.wait_one(ZX_TIMER_SIGNALED, zx::time::infinite(), &pending), ZX_OK);
53 ASSERT_EQ(pending, ZX_TIMER_SIGNALED);
54 END_TEST;
55 }
56
timer_set_negative_slack()57 static bool timer_set_negative_slack() {
58 BEGIN_TEST;
59 zx::timer timer;
60 ASSERT_EQ(zx::timer::create(0, ZX_CLOCK_MONOTONIC, &timer), ZX_OK);
61 ASSERT_EQ(timer.set(zx::time(), zx::duration(-1)), ZX_ERR_OUT_OF_RANGE);
62 END_TEST;
63 }
64
basic_test()65 static bool basic_test() {
66 BEGIN_TEST;
67 zx::timer timer;
68 ASSERT_EQ(zx::timer::create(0, ZX_CLOCK_MONOTONIC, &timer), ZX_OK);
69
70 zx_signals_t pending;
71 EXPECT_EQ(timer.wait_one(ZX_TIMER_SIGNALED, zx::time(), &pending), ZX_ERR_TIMED_OUT);
72 EXPECT_EQ(pending, 0u);
73
74 for (int ix = 0; ix != 10; ++ix) {
75 const auto deadline_timer = zx::deadline_after(zx::msec(50));
76 const auto deadline_wait = zx::deadline_after(zx::sec(1));
77 // Timer should fire faster than the wait timeout.
78 ASSERT_EQ(timer.set(deadline_timer, zx::nsec(0)), ZX_OK);
79
80 EXPECT_EQ(timer.wait_one(ZX_TIMER_SIGNALED, deadline_wait, &pending), ZX_OK);
81 EXPECT_EQ(pending, ZX_TIMER_SIGNALED);
82 }
83 END_TEST;
84 }
85
restart_test()86 static bool restart_test() {
87 BEGIN_TEST;
88 zx::timer timer;
89 ASSERT_EQ(zx::timer::create(0, ZX_CLOCK_MONOTONIC, &timer), ZX_OK);
90
91 zx_signals_t pending;
92 for (int ix = 0; ix != 10; ++ix) {
93 const auto deadline_timer = zx::deadline_after(zx::msec(500));
94 const auto deadline_wait = zx::deadline_after(zx::msec(1));
95 // Setting a timer already running is equivalent to a cancel + set.
96 ASSERT_EQ(timer.set(deadline_timer, zx::nsec(0)), ZX_OK);
97
98 EXPECT_EQ(timer.wait_one(ZX_TIMER_SIGNALED, deadline_wait, &pending), ZX_ERR_TIMED_OUT);
99 EXPECT_EQ(pending, 0u);
100 }
101 END_TEST;
102 }
103
invalid_calls()104 static bool invalid_calls() {
105 BEGIN_TEST;
106
107 zx::timer timer;
108 ASSERT_EQ(zx::timer::create(0, ZX_CLOCK_UTC, &timer), ZX_ERR_INVALID_ARGS);
109 ASSERT_EQ(zx::timer::create(ZX_TIMER_SLACK_LATE + 1, ZX_CLOCK_UTC, &timer), ZX_ERR_INVALID_ARGS);
110
111 END_TEST;
112 }
113
edge_cases()114 static bool edge_cases() {
115 BEGIN_TEST;
116
117 zx::timer timer;
118 ASSERT_EQ(zx::timer::create(0, ZX_CLOCK_MONOTONIC, &timer), ZX_OK);
119 ASSERT_EQ(timer.set(zx::time(), zx::nsec(0)), ZX_OK);
120
121 END_TEST;
122 }
123
124 // furiously spin resetting the timer, trying to race with it going off to look for
125 // race conditions.
restart_race()126 static bool restart_race() {
127 BEGIN_TEST;
128
129 const zx_time_t kTestDuration = ZX_SEC(5);
130 auto start = zx_clock_get_monotonic();
131
132 zx::timer timer;
133 ASSERT_EQ(zx::timer::create(0, ZX_CLOCK_MONOTONIC, &timer), ZX_OK);
134 while (zx_clock_get_monotonic() - start < kTestDuration) {
135 ASSERT_EQ(timer.set(zx::deadline_after(zx::usec(100)), zx::nsec(0)), ZX_OK);
136 }
137
138 EXPECT_EQ(timer.cancel(), ZX_OK);
139
140 END_TEST;
141 }
142
143 // If the timer is already due at the moment it is started then the signal should be
144 // asserted immediately. Likewise canceling the timer should immediately deassert
145 // the signal.
signals_asserted_immediately()146 static bool signals_asserted_immediately() {
147 BEGIN_TEST;
148 zx::timer timer;
149 ASSERT_EQ(zx::timer::create(0, ZX_CLOCK_MONOTONIC, &timer), ZX_OK);
150
151 for (int i = 0; i < 100; i++) {
152 zx::time now = zx::clock::get_monotonic();
153
154 EXPECT_EQ(timer.set(now, zx::nsec(0)), ZX_OK);
155
156 zx_signals_t pending;
157 EXPECT_EQ(timer.wait_one(ZX_TIMER_SIGNALED, zx::time(), &pending), ZX_OK);
158 EXPECT_EQ(pending, ZX_TIMER_SIGNALED);
159
160 EXPECT_EQ(timer.cancel(), ZX_OK);
161
162 EXPECT_EQ(timer.wait_one(ZX_TIMER_SIGNALED, zx::time(), &pending), ZX_ERR_TIMED_OUT);
163 EXPECT_EQ(pending, 0u);
164 }
165
166 END_TEST;
167 }
168
169 // This test is disabled because is flaky. The system might have a timer
170 // nearby |deadline_1| or |deadline_2| and as such the test will fire
171 // either earlier or later than expected. The precise behavior is still
172 // tested by the "k timer tests" command.
173 //
174 // See ZX-1087 for the current owner.
175
coalesce_test(uint32_t mode)176 static bool coalesce_test(uint32_t mode) {
177 BEGIN_TEST;
178 // The second timer will coalesce to the first one for ZX_TIMER_SLACK_LATE
179 // but not for ZX_TIMER_SLACK_EARLY. This test is not precise because the
180 // system might have other timers that interfere with it. Precise tests are
181 // avaliable as kernel tests.
182
183 zx::timer timer_1;
184 ASSERT_EQ(zx::timer::create(0, ZX_CLOCK_MONOTONIC, &timer_1), ZX_OK);
185 zx::timer timer_2;
186 ASSERT_EQ(zx::timer::create(mode, ZX_CLOCK_MONOTONIC, &timer_2), ZX_OK);
187
188 zx_time_t start = zx_clock_get_monotonic();
189
190 const auto deadline_1 = zx::time(start + ZX_MSEC(350));
191 const auto deadline_2 = zx::time(start + ZX_MSEC(250));
192
193 ASSERT_EQ(timer_1.set(deadline_1, zx::nsec(0)), ZX_OK);
194 ASSERT_EQ(timer_2.set(deadline_2, zx::msec(110)), ZX_OK);
195
196 zx_signals_t pending;
197 EXPECT_EQ(timer_2.wait_one(ZX_TIMER_SIGNALED, zx::time::infinite(), &pending), ZX_OK);
198 EXPECT_EQ(pending, ZX_TIMER_SIGNALED);
199
200 auto duration = zx_clock_get_monotonic() - start;
201
202 if (mode == ZX_TIMER_SLACK_LATE) {
203 EXPECT_GE(duration, ZX_MSEC(350));
204 } else if (mode == ZX_TIMER_SLACK_EARLY) {
205 EXPECT_LE(duration, ZX_MSEC(345));
206 } else {
207 assert(false);
208 }
209 END_TEST;
210 }
211
212 // Test is disabled, see coalesce_test().
coalesce_test_early()213 static bool coalesce_test_early() {
214 return coalesce_test(ZX_TIMER_SLACK_EARLY);
215 }
216
217 // Test is disabled, see coalesce_test().
coalesce_test_late()218 static bool coalesce_test_late() {
219 return coalesce_test(ZX_TIMER_SLACK_LATE);
220 }
221
222 BEGIN_TEST_CASE(timers_test)
RUN_TEST(deadline_after)223 RUN_TEST(deadline_after)
224 RUN_TEST(timer_set_negative_deadline)
225 RUN_TEST(timer_set_negative_deadline_max)
226 RUN_TEST(timer_set_negative_slack)
227 RUN_TEST(invalid_calls)
228 RUN_TEST(basic_test)
229 // Disabled: RUN_TEST(coalesce_test_late)
230 // Disabled: RUN_TEST(coalesce_test_early)
231 RUN_TEST(restart_test)
232 RUN_TEST(edge_cases)
233 RUN_TEST(restart_race)
234 RUN_TEST(signals_asserted_immediately)
235 END_TEST_CASE(timers_test)
236
237 int main(int argc, char** argv) {
238 bool success = unittest_run_all_tests(argc, argv);
239 return success ? 0 : -1;
240 }
241