blob: 09fb8166366ded29fc33dcce9b6db1ea05cfe602 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
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
Steve Anton10542f22019-01-11 17:11:0011#include "rtc_base/time_utils.h"
Yves Gerey3e707812018-11-28 15:47:4912
13#include <memory>
14
15#include "api/units/time_delta.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3116#include "rtc_base/event.h"
Steve Anton10542f22019-01-11 17:11:0017#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3118#include "rtc_base/helpers.h"
19#include "rtc_base/thread.h"
Yves Gerey3e707812018-11-28 15:47:4920#include "test/gtest.h"
henrike@webrtc.orgf0488722014-05-13 18:00:2621
22namespace rtc {
Danil Chapovalov5286dcf2022-07-18 15:04:5623using ::webrtc::TimeDelta;
henrike@webrtc.orgf0488722014-05-13 18:00:2624
25TEST(TimeTest, TimeInMs) {
Honghai Zhang82d78622016-05-06 18:29:1526 int64_t ts_earlier = TimeMillis();
henrike@webrtc.orgf0488722014-05-13 18:00:2627 Thread::SleepMs(100);
Honghai Zhang82d78622016-05-06 18:29:1528 int64_t ts_now = TimeMillis();
henrike@webrtc.orgf0488722014-05-13 18:00:2629 // Allow for the thread to wakeup ~20ms early.
30 EXPECT_GE(ts_now, ts_earlier + 80);
31 // Make sure the Time is not returning in smaller unit like microseconds.
32 EXPECT_LT(ts_now, ts_earlier + 1000);
33}
34
henrike@webrtc.orgf0488722014-05-13 18:00:2635TEST(TimeTest, Intervals) {
Honghai Zhang82d78622016-05-06 18:29:1536 int64_t ts_earlier = TimeMillis();
37 int64_t ts_later = TimeAfter(500);
henrike@webrtc.orgf0488722014-05-13 18:00:2638
39 // We can't depend on ts_later and ts_earlier to be exactly 500 apart
Honghai Zhang82d78622016-05-06 18:29:1540 // since time elapses between the calls to TimeMillis() and TimeAfter(500)
Yves Gerey665174f2018-06-19 13:03:0541 EXPECT_LE(500, TimeDiff(ts_later, ts_earlier));
henrike@webrtc.orgf0488722014-05-13 18:00:2642 EXPECT_GE(-500, TimeDiff(ts_earlier, ts_later));
43
44 // Time has elapsed since ts_earlier
45 EXPECT_GE(TimeSince(ts_earlier), 0);
46
47 // ts_earlier is earlier than now, so TimeUntil ts_earlier is -ve
48 EXPECT_LE(TimeUntil(ts_earlier), 0);
49
50 // ts_later likely hasn't happened yet, so TimeSince could be -ve
51 // but within 500
52 EXPECT_GE(TimeSince(ts_later), -500);
53
54 // TimeUntil ts_later is at most 500
55 EXPECT_LE(TimeUntil(ts_later), 500);
56}
57
honghaiz34b11eb2016-03-16 15:55:4458TEST(TimeTest, TestTimeDiff64) {
59 int64_t ts_diff = 100;
nisse1bffc1d2016-05-02 15:18:5560 int64_t ts_earlier = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 15:55:4461 int64_t ts_later = ts_earlier + ts_diff;
62 EXPECT_EQ(ts_diff, rtc::TimeDiff(ts_later, ts_earlier));
63 EXPECT_EQ(-ts_diff, rtc::TimeDiff(ts_earlier, ts_later));
64}
65
Mirko Bonadei6a489f22019-04-09 13:11:1266class TmToSeconds : public ::testing::Test {
Torbjorn Granlund46c9cc02015-12-01 12:06:3467 public:
68 TmToSeconds() {
69 // Set use of the test RNG to get deterministic expiration timestamp.
70 rtc::SetRandomTestMode(true);
71 }
ehmaldonadoda8dcfb2017-01-04 15:11:2372 ~TmToSeconds() override {
Torbjorn Granlund46c9cc02015-12-01 12:06:3473 // Put it back for the next test.
74 rtc::SetRandomTestMode(false);
75 }
76
77 void TestTmToSeconds(int times) {
78 static char mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
79 for (int i = 0; i < times; i++) {
Torbjorn Granlund46c9cc02015-12-01 12:06:3480 // First generate something correct and check that TmToSeconds is happy.
81 int year = rtc::CreateRandomId() % 400 + 1970;
82
83 bool leap_year = false;
84 if (year % 4 == 0)
85 leap_year = true;
86 if (year % 100 == 0)
87 leap_year = false;
88 if (year % 400 == 0)
89 leap_year = true;
90
91 std::tm tm;
92 tm.tm_year = year - 1900; // std::tm is year 1900 based.
93 tm.tm_mon = rtc::CreateRandomId() % 12;
94 tm.tm_mday = rtc::CreateRandomId() % mdays[tm.tm_mon] + 1;
95 tm.tm_hour = rtc::CreateRandomId() % 24;
96 tm.tm_min = rtc::CreateRandomId() % 60;
97 tm.tm_sec = rtc::CreateRandomId() % 60;
98 int64_t t = rtc::TmToSeconds(tm);
99 EXPECT_TRUE(t >= 0);
100
101 // Now damage a random field and check that TmToSeconds is unhappy.
102 switch (rtc::CreateRandomId() % 11) {
103 case 0:
104 tm.tm_year = 1969 - 1900;
105 break;
106 case 1:
107 tm.tm_mon = -1;
108 break;
109 case 2:
110 tm.tm_mon = 12;
111 break;
112 case 3:
113 tm.tm_mday = 0;
114 break;
115 case 4:
116 tm.tm_mday = mdays[tm.tm_mon] + (leap_year && tm.tm_mon == 1) + 1;
117 break;
118 case 5:
119 tm.tm_hour = -1;
120 break;
121 case 6:
122 tm.tm_hour = 24;
123 break;
124 case 7:
125 tm.tm_min = -1;
126 break;
127 case 8:
128 tm.tm_min = 60;
129 break;
130 case 9:
131 tm.tm_sec = -1;
132 break;
133 case 10:
134 tm.tm_sec = 60;
135 break;
136 }
137 EXPECT_EQ(rtc::TmToSeconds(tm), -1);
138 }
139 // Check consistency with the system gmtime_r. With time_t, we can only
140 // portably test dates until 2038, which is achieved by the % 0x80000000.
141 for (int i = 0; i < times; i++) {
142 time_t t = rtc::CreateRandomId() % 0x80000000;
143#if defined(WEBRTC_WIN)
144 std::tm* tm = std::gmtime(&t);
145 EXPECT_TRUE(tm);
146 EXPECT_TRUE(rtc::TmToSeconds(*tm) == t);
147#else
148 std::tm tm;
149 EXPECT_TRUE(gmtime_r(&t, &tm));
150 EXPECT_TRUE(rtc::TmToSeconds(tm) == t);
151#endif
152 }
153 }
154};
155
156TEST_F(TmToSeconds, TestTmToSeconds) {
157 TestTmToSeconds(100000);
158}
159
Taylor Brandstetterb3c68102016-05-27 21:15:43160// Test that all the time functions exposed by TimeUtils get time from the
161// fake clock when it's set.
162TEST(FakeClock, TimeFunctionsUseFakeClock) {
163 FakeClock clock;
deadbeeff5f03e82016-06-06 18:16:06164 SetClockForTesting(&clock);
Taylor Brandstetterb3c68102016-05-27 21:15:43165
Danil Chapovalov0c626af2020-02-10 10:16:00166 clock.SetTime(webrtc::Timestamp::Micros(987654));
Taylor Brandstetterb3c68102016-05-27 21:15:43167 EXPECT_EQ(987u, Time32());
168 EXPECT_EQ(987, TimeMillis());
nissedeb95f32016-11-28 09:54:54169 EXPECT_EQ(987654, TimeMicros());
Sebastian Janssond624c392019-04-17 08:36:03170 EXPECT_EQ(987654000, TimeNanos());
Taylor Brandstetterb3c68102016-05-27 21:15:43171 EXPECT_EQ(1000u, TimeAfter(13));
172
deadbeeff5f03e82016-06-06 18:16:06173 SetClockForTesting(nullptr);
Taylor Brandstetterb3c68102016-05-27 21:15:43174 // After it's unset, we should get a normal time.
175 EXPECT_NE(987, TimeMillis());
176}
177
178TEST(FakeClock, InitialTime) {
179 FakeClock clock;
nissedeb95f32016-11-28 09:54:54180 EXPECT_EQ(0, clock.TimeNanos());
Taylor Brandstetterb3c68102016-05-27 21:15:43181}
182
Sebastian Janssond624c392019-04-17 08:36:03183TEST(FakeClock, SetTime) {
Taylor Brandstetterb3c68102016-05-27 21:15:43184 FakeClock clock;
Danil Chapovalov0c626af2020-02-10 10:16:00185 clock.SetTime(webrtc::Timestamp::Micros(123));
Sebastian Janssond624c392019-04-17 08:36:03186 EXPECT_EQ(123000, clock.TimeNanos());
Danil Chapovalov0c626af2020-02-10 10:16:00187 clock.SetTime(webrtc::Timestamp::Micros(456));
Sebastian Janssond624c392019-04-17 08:36:03188 EXPECT_EQ(456000, clock.TimeNanos());
Taylor Brandstetterb3c68102016-05-27 21:15:43189}
190
191TEST(FakeClock, AdvanceTime) {
192 FakeClock clock;
Danil Chapovalov0c626af2020-02-10 10:16:00193 clock.AdvanceTime(webrtc::TimeDelta::Micros(1u));
Sebastian Jansson5f83cf02018-05-08 12:52:22194 EXPECT_EQ(1000, clock.TimeNanos());
Danil Chapovalov0c626af2020-02-10 10:16:00195 clock.AdvanceTime(webrtc::TimeDelta::Micros(2222u));
Sebastian Jansson5f83cf02018-05-08 12:52:22196 EXPECT_EQ(2223000, clock.TimeNanos());
Danil Chapovalov0c626af2020-02-10 10:16:00197 clock.AdvanceTime(webrtc::TimeDelta::Millis(3333u));
Sebastian Jansson5f83cf02018-05-08 12:52:22198 EXPECT_EQ(3335223000, clock.TimeNanos());
Danil Chapovalov0c626af2020-02-10 10:16:00199 clock.AdvanceTime(webrtc::TimeDelta::Seconds(4444u));
Sebastian Jansson5f83cf02018-05-08 12:52:22200 EXPECT_EQ(4447335223000, clock.TimeNanos());
Taylor Brandstetterb3c68102016-05-27 21:15:43201}
202
203// When the clock is advanced, threads that are waiting in a socket select
204// should wake up and look at the new time. This allows tests using the
205// fake clock to run much faster, if the test is bound by time constraints
206// (such as a test for a STUN ping timeout).
207TEST(FakeClock, SettingTimeWakesThreads) {
208 int64_t real_start_time_ms = TimeMillis();
209
Sebastian Janssond624c392019-04-17 08:36:03210 ThreadProcessingFakeClock clock;
deadbeeff5f03e82016-06-06 18:16:06211 SetClockForTesting(&clock);
Taylor Brandstetterb3c68102016-05-27 21:15:43212
tommie7251592017-07-14 21:44:46213 std::unique_ptr<Thread> worker(Thread::CreateWithSocketServer());
214 worker->Start();
Taylor Brandstetterb3c68102016-05-27 21:15:43215
216 // Post an event that won't be executed for 10 seconds.
Niels Möllerc572ff32018-11-07 07:43:50217 Event message_handler_dispatched;
Danil Chapovalov5286dcf2022-07-18 15:04:56218 worker->PostDelayedTask(
219 [&message_handler_dispatched] { message_handler_dispatched.Set(); },
220 TimeDelta::Seconds(60));
Taylor Brandstetterb3c68102016-05-27 21:15:43221
222 // Wait for a bit for the worker thread to be started and enter its socket
deadbeeff5f03e82016-06-06 18:16:06223 // select(). Otherwise this test would be trivial since the worker thread
224 // would process the event as soon as it was started.
Taylor Brandstetterb3c68102016-05-27 21:15:43225 Thread::Current()->SleepMs(1000);
226
227 // Advance the fake clock, expecting the worker thread to wake up
deadbeeff5f03e82016-06-06 18:16:06228 // and dispatch the message instantly.
Danil Chapovalov0c626af2020-02-10 10:16:00229 clock.AdvanceTime(webrtc::TimeDelta::Seconds(60u));
Markus Handell2cfc1af2022-08-19 08:16:48230 EXPECT_TRUE(message_handler_dispatched.Wait(webrtc::TimeDelta::Zero()));
tommie7251592017-07-14 21:44:46231 worker->Stop();
Taylor Brandstetterb3c68102016-05-27 21:15:43232
deadbeeff5f03e82016-06-06 18:16:06233 SetClockForTesting(nullptr);
Taylor Brandstetterb3c68102016-05-27 21:15:43234
deadbeeff5f03e82016-06-06 18:16:06235 // The message should have been dispatched long before the 60 seconds fully
236 // elapsed (just a sanity check).
Taylor Brandstetterb3c68102016-05-27 21:15:43237 int64_t real_end_time_ms = TimeMillis();
deadbeeff5f03e82016-06-06 18:16:06238 EXPECT_LT(real_end_time_ms - real_start_time_ms, 10000);
Taylor Brandstetterb3c68102016-05-27 21:15:43239}
240
henrike@webrtc.orgf0488722014-05-13 18:00:26241} // namespace rtc