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