blob: 27784a91c9f30386c5ed91a00d1e05953cd2bd3e [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"
12#include "webrtc/base/gunit.h"
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +010013#include "webrtc/base/helpers.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000014#include "webrtc/base/thread.h"
15#include "webrtc/base/timeutils.h"
16
17namespace rtc {
18
19TEST(TimeTest, TimeInMs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +020020 uint32_t ts_earlier = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000021 Thread::SleepMs(100);
Peter Boström0c4e06b2015-10-07 12:23:21 +020022 uint32_t ts_now = Time();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000023 // Allow for the thread to wakeup ~20ms early.
24 EXPECT_GE(ts_now, ts_earlier + 80);
25 // Make sure the Time is not returning in smaller unit like microseconds.
26 EXPECT_LT(ts_now, ts_earlier + 1000);
27}
28
29TEST(TimeTest, Comparison) {
30 // Obtain two different times, in known order
31 TimeStamp ts_earlier = Time();
32 Thread::SleepMs(100);
33 TimeStamp ts_now = Time();
34 EXPECT_NE(ts_earlier, ts_now);
35
36 // Common comparisons
37 EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_now));
38 EXPECT_TRUE( TimeIsLater( ts_earlier, ts_now));
39 EXPECT_FALSE(TimeIsLaterOrEqual(ts_now, ts_earlier));
40 EXPECT_FALSE(TimeIsLater( ts_now, ts_earlier));
41
42 // Edge cases
43 EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_earlier));
44 EXPECT_FALSE(TimeIsLater( ts_earlier, ts_earlier));
45
46 // Obtain a third time
47 TimeStamp ts_later = TimeAfter(100);
48 EXPECT_NE(ts_now, ts_later);
49 EXPECT_TRUE( TimeIsLater(ts_now, ts_later));
50 EXPECT_TRUE( TimeIsLater(ts_earlier, ts_later));
51
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000052 // Earlier of two times
53 EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier));
54 EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_now));
55 EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later));
56 EXPECT_EQ(ts_earlier, TimeMin(ts_now, ts_earlier));
57 EXPECT_EQ(ts_earlier, TimeMin(ts_later, ts_earlier));
58
59 // Later of two times
60 EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier));
61 EXPECT_EQ(ts_now, TimeMax(ts_earlier, ts_now));
62 EXPECT_EQ(ts_later, TimeMax(ts_earlier, ts_later));
63 EXPECT_EQ(ts_now, TimeMax(ts_now, ts_earlier));
64 EXPECT_EQ(ts_later, TimeMax(ts_later, ts_earlier));
65}
66
67TEST(TimeTest, Intervals) {
68 TimeStamp ts_earlier = Time();
69 TimeStamp ts_later = TimeAfter(500);
70
71 // We can't depend on ts_later and ts_earlier to be exactly 500 apart
72 // since time elapses between the calls to Time() and TimeAfter(500)
73 EXPECT_LE(500, TimeDiff(ts_later, ts_earlier));
74 EXPECT_GE(-500, TimeDiff(ts_earlier, ts_later));
75
76 // Time has elapsed since ts_earlier
77 EXPECT_GE(TimeSince(ts_earlier), 0);
78
79 // ts_earlier is earlier than now, so TimeUntil ts_earlier is -ve
80 EXPECT_LE(TimeUntil(ts_earlier), 0);
81
82 // ts_later likely hasn't happened yet, so TimeSince could be -ve
83 // but within 500
84 EXPECT_GE(TimeSince(ts_later), -500);
85
86 // TimeUntil ts_later is at most 500
87 EXPECT_LE(TimeUntil(ts_later), 500);
88}
89
90TEST(TimeTest, BoundaryComparison) {
91 // Obtain two different times, in known order
92 TimeStamp ts_earlier = static_cast<TimeStamp>(-50);
93 TimeStamp ts_later = ts_earlier + 100;
94 EXPECT_NE(ts_earlier, ts_later);
95
96 // Common comparisons
97 EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_later));
98 EXPECT_TRUE( TimeIsLater( ts_earlier, ts_later));
99 EXPECT_FALSE(TimeIsLaterOrEqual(ts_later, ts_earlier));
100 EXPECT_FALSE(TimeIsLater( ts_later, ts_earlier));
101
102 // Earlier of two times
103 EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier));
104 EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later));
105 EXPECT_EQ(ts_earlier, TimeMin(ts_later, ts_earlier));
106
107 // Later of two times
108 EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier));
109 EXPECT_EQ(ts_later, TimeMax(ts_earlier, ts_later));
110 EXPECT_EQ(ts_later, TimeMax(ts_later, ts_earlier));
111
112 // Interval
113 EXPECT_EQ(100, TimeDiff(ts_later, ts_earlier));
114 EXPECT_EQ(-100, TimeDiff(ts_earlier, ts_later));
115}
116
honghaiz34b11eb2016-03-16 08:55:44 -0700117TEST(TimeTest, TestTimeDiff64) {
118 int64_t ts_diff = 100;
nisse1bffc1d2016-05-02 08:18:55 -0700119 int64_t ts_earlier = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -0700120 int64_t ts_later = ts_earlier + ts_diff;
121 EXPECT_EQ(ts_diff, rtc::TimeDiff(ts_later, ts_earlier));
122 EXPECT_EQ(-ts_diff, rtc::TimeDiff(ts_earlier, ts_later));
123}
124
henrike@webrtc.org99b41622014-05-21 20:42:17 +0000125class TimestampWrapAroundHandlerTest : public testing::Test {
126 public:
127 TimestampWrapAroundHandlerTest() {}
128
129 protected:
130 TimestampWrapAroundHandler wraparound_handler_;
131};
132
133TEST_F(TimestampWrapAroundHandlerTest, Unwrap) {
sprang1b3530b2016-03-10 01:32:53 -0800134 // Start value.
135 int64_t ts = 2;
136 EXPECT_EQ(ts,
137 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
138
139 // Wrap backwards.
140 ts = -2;
141 EXPECT_EQ(ts,
142 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
143
144 // Forward to 2 again.
henrike@webrtc.org99b41622014-05-21 20:42:17 +0000145 ts = 2;
sprang1b3530b2016-03-10 01:32:53 -0800146 EXPECT_EQ(ts,
147 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
148
149 // Max positive skip ahead, until max value (0xffffffff).
150 for (uint32_t i = 0; i <= 0xf; ++i) {
151 ts = (i << 28) + 0x0fffffff;
152 EXPECT_EQ(
153 ts, wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
154 }
155
156 // Wrap around.
157 ts += 2;
158 EXPECT_EQ(ts,
159 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
160
161 // Max wrap backward...
162 ts -= 0x0fffffff;
163 EXPECT_EQ(ts,
164 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
165
166 // ...and back again.
167 ts += 0x0fffffff;
168 EXPECT_EQ(ts,
169 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
170}
171
172TEST_F(TimestampWrapAroundHandlerTest, NoNegativeStart) {
173 int64_t ts = 0xfffffff0;
174 EXPECT_EQ(ts,
175 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
henrike@webrtc.org99b41622014-05-21 20:42:17 +0000176}
177
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100178class TmToSeconds : public testing::Test {
179 public:
180 TmToSeconds() {
181 // Set use of the test RNG to get deterministic expiration timestamp.
182 rtc::SetRandomTestMode(true);
183 }
184 ~TmToSeconds() {
185 // Put it back for the next test.
186 rtc::SetRandomTestMode(false);
187 }
188
189 void TestTmToSeconds(int times) {
190 static char mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
191 for (int i = 0; i < times; i++) {
192
193 // First generate something correct and check that TmToSeconds is happy.
194 int year = rtc::CreateRandomId() % 400 + 1970;
195
196 bool leap_year = false;
197 if (year % 4 == 0)
198 leap_year = true;
199 if (year % 100 == 0)
200 leap_year = false;
201 if (year % 400 == 0)
202 leap_year = true;
203
204 std::tm tm;
205 tm.tm_year = year - 1900; // std::tm is year 1900 based.
206 tm.tm_mon = rtc::CreateRandomId() % 12;
207 tm.tm_mday = rtc::CreateRandomId() % mdays[tm.tm_mon] + 1;
208 tm.tm_hour = rtc::CreateRandomId() % 24;
209 tm.tm_min = rtc::CreateRandomId() % 60;
210 tm.tm_sec = rtc::CreateRandomId() % 60;
211 int64_t t = rtc::TmToSeconds(tm);
212 EXPECT_TRUE(t >= 0);
213
214 // Now damage a random field and check that TmToSeconds is unhappy.
215 switch (rtc::CreateRandomId() % 11) {
216 case 0:
217 tm.tm_year = 1969 - 1900;
218 break;
219 case 1:
220 tm.tm_mon = -1;
221 break;
222 case 2:
223 tm.tm_mon = 12;
224 break;
225 case 3:
226 tm.tm_mday = 0;
227 break;
228 case 4:
229 tm.tm_mday = mdays[tm.tm_mon] + (leap_year && tm.tm_mon == 1) + 1;
230 break;
231 case 5:
232 tm.tm_hour = -1;
233 break;
234 case 6:
235 tm.tm_hour = 24;
236 break;
237 case 7:
238 tm.tm_min = -1;
239 break;
240 case 8:
241 tm.tm_min = 60;
242 break;
243 case 9:
244 tm.tm_sec = -1;
245 break;
246 case 10:
247 tm.tm_sec = 60;
248 break;
249 }
250 EXPECT_EQ(rtc::TmToSeconds(tm), -1);
251 }
252 // Check consistency with the system gmtime_r. With time_t, we can only
253 // portably test dates until 2038, which is achieved by the % 0x80000000.
254 for (int i = 0; i < times; i++) {
255 time_t t = rtc::CreateRandomId() % 0x80000000;
256#if defined(WEBRTC_WIN)
257 std::tm* tm = std::gmtime(&t);
258 EXPECT_TRUE(tm);
259 EXPECT_TRUE(rtc::TmToSeconds(*tm) == t);
260#else
261 std::tm tm;
262 EXPECT_TRUE(gmtime_r(&t, &tm));
263 EXPECT_TRUE(rtc::TmToSeconds(tm) == t);
264#endif
265 }
266 }
267};
268
269TEST_F(TmToSeconds, TestTmToSeconds) {
270 TestTmToSeconds(100000);
271}
272
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000273} // namespace rtc