blob: f183684e6ccf41d3c1e9801ac987da55f7f1426e [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/base/common.h"
Taylor Brandstetterb3c68102016-05-27 14:15:43 -070012#include "webrtc/base/event.h"
13#include "webrtc/base/fakeclock.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000014#include "webrtc/base/gunit.h"
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +010015#include "webrtc/base/helpers.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000016#include "webrtc/base/thread.h"
17#include "webrtc/base/timeutils.h"
18
19namespace rtc {
20
21TEST(TimeTest, TimeInMs) {
Honghai Zhang82d78622016-05-06 11:29:15 -070022 int64_t ts_earlier = TimeMillis();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000023 Thread::SleepMs(100);
Honghai Zhang82d78622016-05-06 11:29:15 -070024 int64_t ts_now = TimeMillis();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000025 // Allow for the thread to wakeup ~20ms early.
26 EXPECT_GE(ts_now, ts_earlier + 80);
27 // Make sure the Time is not returning in smaller unit like microseconds.
28 EXPECT_LT(ts_now, ts_earlier + 1000);
29}
30
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000031TEST(TimeTest, Intervals) {
Honghai Zhang82d78622016-05-06 11:29:15 -070032 int64_t ts_earlier = TimeMillis();
33 int64_t ts_later = TimeAfter(500);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000034
35 // We can't depend on ts_later and ts_earlier to be exactly 500 apart
Honghai Zhang82d78622016-05-06 11:29:15 -070036 // since time elapses between the calls to TimeMillis() and TimeAfter(500)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000037 EXPECT_LE(500, TimeDiff(ts_later, ts_earlier));
38 EXPECT_GE(-500, TimeDiff(ts_earlier, ts_later));
39
40 // Time has elapsed since ts_earlier
41 EXPECT_GE(TimeSince(ts_earlier), 0);
42
43 // ts_earlier is earlier than now, so TimeUntil ts_earlier is -ve
44 EXPECT_LE(TimeUntil(ts_earlier), 0);
45
46 // ts_later likely hasn't happened yet, so TimeSince could be -ve
47 // but within 500
48 EXPECT_GE(TimeSince(ts_later), -500);
49
50 // TimeUntil ts_later is at most 500
51 EXPECT_LE(TimeUntil(ts_later), 500);
52}
53
honghaiz34b11eb2016-03-16 08:55:44 -070054TEST(TimeTest, TestTimeDiff64) {
55 int64_t ts_diff = 100;
nisse1bffc1d2016-05-02 08:18:55 -070056 int64_t ts_earlier = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -070057 int64_t ts_later = ts_earlier + ts_diff;
58 EXPECT_EQ(ts_diff, rtc::TimeDiff(ts_later, ts_earlier));
59 EXPECT_EQ(-ts_diff, rtc::TimeDiff(ts_earlier, ts_later));
60}
61
henrike@webrtc.org99b41622014-05-21 20:42:17 +000062class TimestampWrapAroundHandlerTest : public testing::Test {
63 public:
64 TimestampWrapAroundHandlerTest() {}
65
66 protected:
67 TimestampWrapAroundHandler wraparound_handler_;
68};
69
70TEST_F(TimestampWrapAroundHandlerTest, Unwrap) {
sprang1b3530b2016-03-10 01:32:53 -080071 // Start value.
72 int64_t ts = 2;
73 EXPECT_EQ(ts,
74 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
75
76 // Wrap backwards.
77 ts = -2;
78 EXPECT_EQ(ts,
79 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
80
81 // Forward to 2 again.
henrike@webrtc.org99b41622014-05-21 20:42:17 +000082 ts = 2;
sprang1b3530b2016-03-10 01:32:53 -080083 EXPECT_EQ(ts,
84 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
85
86 // Max positive skip ahead, until max value (0xffffffff).
87 for (uint32_t i = 0; i <= 0xf; ++i) {
88 ts = (i << 28) + 0x0fffffff;
89 EXPECT_EQ(
90 ts, wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
91 }
92
93 // Wrap around.
94 ts += 2;
95 EXPECT_EQ(ts,
96 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
97
98 // Max wrap backward...
99 ts -= 0x0fffffff;
100 EXPECT_EQ(ts,
101 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
102
103 // ...and back again.
104 ts += 0x0fffffff;
105 EXPECT_EQ(ts,
106 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
107}
108
109TEST_F(TimestampWrapAroundHandlerTest, NoNegativeStart) {
110 int64_t ts = 0xfffffff0;
111 EXPECT_EQ(ts,
112 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
henrike@webrtc.org99b41622014-05-21 20:42:17 +0000113}
114
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100115class TmToSeconds : public testing::Test {
116 public:
117 TmToSeconds() {
118 // Set use of the test RNG to get deterministic expiration timestamp.
119 rtc::SetRandomTestMode(true);
120 }
121 ~TmToSeconds() {
122 // Put it back for the next test.
123 rtc::SetRandomTestMode(false);
124 }
125
126 void TestTmToSeconds(int times) {
127 static char mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
128 for (int i = 0; i < times; i++) {
129
130 // First generate something correct and check that TmToSeconds is happy.
131 int year = rtc::CreateRandomId() % 400 + 1970;
132
133 bool leap_year = false;
134 if (year % 4 == 0)
135 leap_year = true;
136 if (year % 100 == 0)
137 leap_year = false;
138 if (year % 400 == 0)
139 leap_year = true;
140
141 std::tm tm;
142 tm.tm_year = year - 1900; // std::tm is year 1900 based.
143 tm.tm_mon = rtc::CreateRandomId() % 12;
144 tm.tm_mday = rtc::CreateRandomId() % mdays[tm.tm_mon] + 1;
145 tm.tm_hour = rtc::CreateRandomId() % 24;
146 tm.tm_min = rtc::CreateRandomId() % 60;
147 tm.tm_sec = rtc::CreateRandomId() % 60;
148 int64_t t = rtc::TmToSeconds(tm);
149 EXPECT_TRUE(t >= 0);
150
151 // Now damage a random field and check that TmToSeconds is unhappy.
152 switch (rtc::CreateRandomId() % 11) {
153 case 0:
154 tm.tm_year = 1969 - 1900;
155 break;
156 case 1:
157 tm.tm_mon = -1;
158 break;
159 case 2:
160 tm.tm_mon = 12;
161 break;
162 case 3:
163 tm.tm_mday = 0;
164 break;
165 case 4:
166 tm.tm_mday = mdays[tm.tm_mon] + (leap_year && tm.tm_mon == 1) + 1;
167 break;
168 case 5:
169 tm.tm_hour = -1;
170 break;
171 case 6:
172 tm.tm_hour = 24;
173 break;
174 case 7:
175 tm.tm_min = -1;
176 break;
177 case 8:
178 tm.tm_min = 60;
179 break;
180 case 9:
181 tm.tm_sec = -1;
182 break;
183 case 10:
184 tm.tm_sec = 60;
185 break;
186 }
187 EXPECT_EQ(rtc::TmToSeconds(tm), -1);
188 }
189 // Check consistency with the system gmtime_r. With time_t, we can only
190 // portably test dates until 2038, which is achieved by the % 0x80000000.
191 for (int i = 0; i < times; i++) {
192 time_t t = rtc::CreateRandomId() % 0x80000000;
193#if defined(WEBRTC_WIN)
194 std::tm* tm = std::gmtime(&t);
195 EXPECT_TRUE(tm);
196 EXPECT_TRUE(rtc::TmToSeconds(*tm) == t);
197#else
198 std::tm tm;
199 EXPECT_TRUE(gmtime_r(&t, &tm));
200 EXPECT_TRUE(rtc::TmToSeconds(tm) == t);
201#endif
202 }
203 }
204};
205
206TEST_F(TmToSeconds, TestTmToSeconds) {
207 TestTmToSeconds(100000);
208}
209
Taylor Brandstetterb3c68102016-05-27 14:15:43 -0700210TEST(TimeDelta, FromAndTo) {
211 EXPECT_TRUE(TimeDelta::FromSeconds(2) == TimeDelta::FromMilliseconds(2000));
212 EXPECT_TRUE(TimeDelta::FromMilliseconds(3) ==
213 TimeDelta::FromMicroseconds(3000));
214 EXPECT_TRUE(TimeDelta::FromMicroseconds(4) ==
215 TimeDelta::FromNanoseconds(4000));
216 EXPECT_EQ(13, TimeDelta::FromSeconds(13).ToSeconds());
217 EXPECT_EQ(13, TimeDelta::FromMilliseconds(13).ToMilliseconds());
218 EXPECT_EQ(13, TimeDelta::FromMicroseconds(13).ToMicroseconds());
219 EXPECT_EQ(13, TimeDelta::FromNanoseconds(13).ToNanoseconds());
220}
221
222TEST(TimeDelta, ComparisonOperators) {
223 EXPECT_LT(TimeDelta::FromSeconds(1), TimeDelta::FromSeconds(2));
224 EXPECT_EQ(TimeDelta::FromSeconds(3), TimeDelta::FromSeconds(3));
225 EXPECT_GT(TimeDelta::FromSeconds(5), TimeDelta::FromSeconds(4));
226}
227
228TEST(TimeDelta, NumericOperators) {
229 double d = 0.5;
230 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
231 TimeDelta::FromMilliseconds(1000) * d);
232 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
233 TimeDelta::FromMilliseconds(1000) / d);
234 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
235 TimeDelta::FromMilliseconds(1000) *= d);
236 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
237 TimeDelta::FromMilliseconds(1000) /= d);
238 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
239 d * TimeDelta::FromMilliseconds(1000));
240
241 float f = 0.5;
242 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
243 TimeDelta::FromMilliseconds(1000) * f);
244 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
245 TimeDelta::FromMilliseconds(1000) / f);
246 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
247 TimeDelta::FromMilliseconds(1000) *= f);
248 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
249 TimeDelta::FromMilliseconds(1000) /= f);
250 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
251 f * TimeDelta::FromMilliseconds(1000));
252
253 int i = 2;
254 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
255 TimeDelta::FromMilliseconds(1000) * i);
256 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
257 TimeDelta::FromMilliseconds(1000) / i);
258 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
259 TimeDelta::FromMilliseconds(1000) *= i);
260 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
261 TimeDelta::FromMilliseconds(1000) /= i);
262 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
263 i * TimeDelta::FromMilliseconds(1000));
264
265 int64_t i64 = 2;
266 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
267 TimeDelta::FromMilliseconds(1000) * i64);
268 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
269 TimeDelta::FromMilliseconds(1000) / i64);
270 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
271 TimeDelta::FromMilliseconds(1000) *= i64);
272 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
273 TimeDelta::FromMilliseconds(1000) /= i64);
274 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
275 i64 * TimeDelta::FromMilliseconds(1000));
276
277 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
278 TimeDelta::FromMilliseconds(1000) * 0.5);
279 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
280 TimeDelta::FromMilliseconds(1000) / 0.5);
281 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
282 TimeDelta::FromMilliseconds(1000) *= 0.5);
283 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
284 TimeDelta::FromMilliseconds(1000) /= 0.5);
285 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
286 0.5 * TimeDelta::FromMilliseconds(1000));
287
288 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
289 TimeDelta::FromMilliseconds(1000) * 2);
290 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
291 TimeDelta::FromMilliseconds(1000) / 2);
292 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
293 TimeDelta::FromMilliseconds(1000) *= 2);
294 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
295 TimeDelta::FromMilliseconds(1000) /= 2);
296 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
297 2 * TimeDelta::FromMilliseconds(1000));
298}
299
300// Test that all the time functions exposed by TimeUtils get time from the
301// fake clock when it's set.
302TEST(FakeClock, TimeFunctionsUseFakeClock) {
303 FakeClock clock;
deadbeeff83a94a2016-06-03 16:05:26 -0700304 SetClock(&clock);
Taylor Brandstetterb3c68102016-05-27 14:15:43 -0700305
306 clock.SetTimeNanos(987654321u);
307 EXPECT_EQ(987u, Time32());
308 EXPECT_EQ(987, TimeMillis());
309 EXPECT_EQ(987654u, TimeMicros());
310 EXPECT_EQ(987654321u, TimeNanos());
311 EXPECT_EQ(1000u, TimeAfter(13));
312
deadbeeff83a94a2016-06-03 16:05:26 -0700313 SetClock(nullptr);
Taylor Brandstetterb3c68102016-05-27 14:15:43 -0700314 // After it's unset, we should get a normal time.
315 EXPECT_NE(987, TimeMillis());
316}
317
318TEST(FakeClock, InitialTime) {
319 FakeClock clock;
320 EXPECT_EQ(0u, clock.TimeNanos());
321}
322
323TEST(FakeClock, SetTimeNanos) {
324 FakeClock clock;
325 clock.SetTimeNanos(123u);
326 EXPECT_EQ(123u, clock.TimeNanos());
327 clock.SetTimeNanos(456u);
328 EXPECT_EQ(456u, clock.TimeNanos());
329}
330
331TEST(FakeClock, AdvanceTime) {
332 FakeClock clock;
333 clock.AdvanceTime(TimeDelta::FromNanoseconds(1111u));
334 EXPECT_EQ(1111u, clock.TimeNanos());
335 clock.AdvanceTime(TimeDelta::FromMicroseconds(2222u));
336 EXPECT_EQ(2223111u, clock.TimeNanos());
337 clock.AdvanceTime(TimeDelta::FromMilliseconds(3333u));
338 EXPECT_EQ(3335223111u, clock.TimeNanos());
339 clock.AdvanceTime(TimeDelta::FromSeconds(4444u));
340 EXPECT_EQ(4447335223111u, clock.TimeNanos());
341}
342
343// When the clock is advanced, threads that are waiting in a socket select
344// should wake up and look at the new time. This allows tests using the
345// fake clock to run much faster, if the test is bound by time constraints
346// (such as a test for a STUN ping timeout).
347TEST(FakeClock, SettingTimeWakesThreads) {
348 int64_t real_start_time_ms = TimeMillis();
349
350 FakeClock clock;
deadbeeff83a94a2016-06-03 16:05:26 -0700351 SetClock(&clock);
Taylor Brandstetterb3c68102016-05-27 14:15:43 -0700352
353 Thread worker;
354 worker.Start();
355
356 // Post an event that won't be executed for 10 seconds.
357 Event message_handler_dispatched(false, false);
358 auto functor = [&message_handler_dispatched] {
359 message_handler_dispatched.Set();
360 };
361 FunctorMessageHandler<void, decltype(functor)> handler(functor);
deadbeeff83a94a2016-06-03 16:05:26 -0700362 worker.PostDelayed(10000, &handler);
Taylor Brandstetterb3c68102016-05-27 14:15:43 -0700363
364 // Wait for a bit for the worker thread to be started and enter its socket
deadbeeff83a94a2016-06-03 16:05:26 -0700365 // select().
Taylor Brandstetterb3c68102016-05-27 14:15:43 -0700366 Thread::Current()->SleepMs(1000);
367
368 // Advance the fake clock, expecting the worker thread to wake up
deadbeeff83a94a2016-06-03 16:05:26 -0700369 // and dispatch the message quickly.
370 clock.AdvanceTime(TimeDelta::FromSeconds(10u));
371 message_handler_dispatched.Wait(Event::kForever);
Taylor Brandstetterb3c68102016-05-27 14:15:43 -0700372 worker.Stop();
373
deadbeeff83a94a2016-06-03 16:05:26 -0700374 SetClock(nullptr);
Taylor Brandstetterb3c68102016-05-27 14:15:43 -0700375
deadbeeff83a94a2016-06-03 16:05:26 -0700376 // The message should have been dispatched long before the 10 seconds fully
377 // elapsed.
Taylor Brandstetterb3c68102016-05-27 14:15:43 -0700378 int64_t real_end_time_ms = TimeMillis();
deadbeeff83a94a2016-06-03 16:05:26 -0700379 EXPECT_LT(real_end_time_ms - real_start_time_ms, 2000);
Taylor Brandstetterb3c68102016-05-27 14:15:43 -0700380}
381
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000382} // namespace rtc