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