blob: 0971c037fa551a8c6bca1fe9403a839b6748460f [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) {
Honghai Zhang82d78622016-05-06 11:29:15 -070020 int64_t ts_earlier = TimeMillis();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000021 Thread::SleepMs(100);
Honghai Zhang82d78622016-05-06 11:29:15 -070022 int64_t ts_now = TimeMillis();
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
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000029TEST(TimeTest, Intervals) {
Honghai Zhang82d78622016-05-06 11:29:15 -070030 int64_t ts_earlier = TimeMillis();
31 int64_t ts_later = TimeAfter(500);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000032
33 // We can't depend on ts_later and ts_earlier to be exactly 500 apart
Honghai Zhang82d78622016-05-06 11:29:15 -070034 // since time elapses between the calls to TimeMillis() and TimeAfter(500)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000035 EXPECT_LE(500, TimeDiff(ts_later, ts_earlier));
36 EXPECT_GE(-500, TimeDiff(ts_earlier, ts_later));
37
38 // Time has elapsed since ts_earlier
39 EXPECT_GE(TimeSince(ts_earlier), 0);
40
41 // ts_earlier is earlier than now, so TimeUntil ts_earlier is -ve
42 EXPECT_LE(TimeUntil(ts_earlier), 0);
43
44 // ts_later likely hasn't happened yet, so TimeSince could be -ve
45 // but within 500
46 EXPECT_GE(TimeSince(ts_later), -500);
47
48 // TimeUntil ts_later is at most 500
49 EXPECT_LE(TimeUntil(ts_later), 500);
50}
51
honghaiz34b11eb2016-03-16 08:55:44 -070052TEST(TimeTest, TestTimeDiff64) {
53 int64_t ts_diff = 100;
nisse1bffc1d2016-05-02 08:18:55 -070054 int64_t ts_earlier = rtc::TimeMillis();
honghaiz34b11eb2016-03-16 08:55:44 -070055 int64_t ts_later = ts_earlier + ts_diff;
56 EXPECT_EQ(ts_diff, rtc::TimeDiff(ts_later, ts_earlier));
57 EXPECT_EQ(-ts_diff, rtc::TimeDiff(ts_earlier, ts_later));
58}
59
henrike@webrtc.org99b41622014-05-21 20:42:17 +000060class TimestampWrapAroundHandlerTest : public testing::Test {
61 public:
62 TimestampWrapAroundHandlerTest() {}
63
64 protected:
65 TimestampWrapAroundHandler wraparound_handler_;
66};
67
68TEST_F(TimestampWrapAroundHandlerTest, Unwrap) {
sprang1b3530b2016-03-10 01:32:53 -080069 // Start value.
70 int64_t ts = 2;
71 EXPECT_EQ(ts,
72 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
73
74 // Wrap backwards.
75 ts = -2;
76 EXPECT_EQ(ts,
77 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
78
79 // Forward to 2 again.
henrike@webrtc.org99b41622014-05-21 20:42:17 +000080 ts = 2;
sprang1b3530b2016-03-10 01:32:53 -080081 EXPECT_EQ(ts,
82 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
83
84 // Max positive skip ahead, until max value (0xffffffff).
85 for (uint32_t i = 0; i <= 0xf; ++i) {
86 ts = (i << 28) + 0x0fffffff;
87 EXPECT_EQ(
88 ts, wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
89 }
90
91 // Wrap around.
92 ts += 2;
93 EXPECT_EQ(ts,
94 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
95
96 // Max wrap backward...
97 ts -= 0x0fffffff;
98 EXPECT_EQ(ts,
99 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
100
101 // ...and back again.
102 ts += 0x0fffffff;
103 EXPECT_EQ(ts,
104 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
105}
106
107TEST_F(TimestampWrapAroundHandlerTest, NoNegativeStart) {
108 int64_t ts = 0xfffffff0;
109 EXPECT_EQ(ts,
110 wraparound_handler_.Unwrap(static_cast<uint32_t>(ts & 0xffffffff)));
henrike@webrtc.org99b41622014-05-21 20:42:17 +0000111}
112
Torbjorn Granlund46c9cc02015-12-01 13:06:34 +0100113class TmToSeconds : public testing::Test {
114 public:
115 TmToSeconds() {
116 // Set use of the test RNG to get deterministic expiration timestamp.
117 rtc::SetRandomTestMode(true);
118 }
119 ~TmToSeconds() {
120 // Put it back for the next test.
121 rtc::SetRandomTestMode(false);
122 }
123
124 void TestTmToSeconds(int times) {
125 static char mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
126 for (int i = 0; i < times; i++) {
127
128 // First generate something correct and check that TmToSeconds is happy.
129 int year = rtc::CreateRandomId() % 400 + 1970;
130
131 bool leap_year = false;
132 if (year % 4 == 0)
133 leap_year = true;
134 if (year % 100 == 0)
135 leap_year = false;
136 if (year % 400 == 0)
137 leap_year = true;
138
139 std::tm tm;
140 tm.tm_year = year - 1900; // std::tm is year 1900 based.
141 tm.tm_mon = rtc::CreateRandomId() % 12;
142 tm.tm_mday = rtc::CreateRandomId() % mdays[tm.tm_mon] + 1;
143 tm.tm_hour = rtc::CreateRandomId() % 24;
144 tm.tm_min = rtc::CreateRandomId() % 60;
145 tm.tm_sec = rtc::CreateRandomId() % 60;
146 int64_t t = rtc::TmToSeconds(tm);
147 EXPECT_TRUE(t >= 0);
148
149 // Now damage a random field and check that TmToSeconds is unhappy.
150 switch (rtc::CreateRandomId() % 11) {
151 case 0:
152 tm.tm_year = 1969 - 1900;
153 break;
154 case 1:
155 tm.tm_mon = -1;
156 break;
157 case 2:
158 tm.tm_mon = 12;
159 break;
160 case 3:
161 tm.tm_mday = 0;
162 break;
163 case 4:
164 tm.tm_mday = mdays[tm.tm_mon] + (leap_year && tm.tm_mon == 1) + 1;
165 break;
166 case 5:
167 tm.tm_hour = -1;
168 break;
169 case 6:
170 tm.tm_hour = 24;
171 break;
172 case 7:
173 tm.tm_min = -1;
174 break;
175 case 8:
176 tm.tm_min = 60;
177 break;
178 case 9:
179 tm.tm_sec = -1;
180 break;
181 case 10:
182 tm.tm_sec = 60;
183 break;
184 }
185 EXPECT_EQ(rtc::TmToSeconds(tm), -1);
186 }
187 // Check consistency with the system gmtime_r. With time_t, we can only
188 // portably test dates until 2038, which is achieved by the % 0x80000000.
189 for (int i = 0; i < times; i++) {
190 time_t t = rtc::CreateRandomId() % 0x80000000;
191#if defined(WEBRTC_WIN)
192 std::tm* tm = std::gmtime(&t);
193 EXPECT_TRUE(tm);
194 EXPECT_TRUE(rtc::TmToSeconds(*tm) == t);
195#else
196 std::tm tm;
197 EXPECT_TRUE(gmtime_r(&t, &tm));
198 EXPECT_TRUE(rtc::TmToSeconds(tm) == t);
199#endif
200 }
201 }
202};
203
204TEST_F(TmToSeconds, TestTmToSeconds) {
205 TestTmToSeconds(100000);
206}
207
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000208} // namespace rtc