• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/common.h"
12 #include "webrtc/base/gunit.h"
13 #include "webrtc/base/helpers.h"
14 #include "webrtc/base/thread.h"
15 #include "webrtc/base/timeutils.h"
16 
17 namespace rtc {
18 
TEST(TimeTest,TimeInMs)19 TEST(TimeTest, TimeInMs) {
20   uint32_t ts_earlier = Time();
21   Thread::SleepMs(100);
22   uint32_t ts_now = Time();
23   // 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 
TEST(TimeTest,Comparison)29 TEST(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 
52   // Common comparisons
53   EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_now,     ts_later));
54   EXPECT_FALSE(TimeIsBetween(ts_earlier, ts_later,   ts_now));
55   EXPECT_FALSE(TimeIsBetween(ts_now,     ts_earlier, ts_later));
56   EXPECT_TRUE( TimeIsBetween(ts_now,     ts_later,   ts_earlier));
57   EXPECT_TRUE( TimeIsBetween(ts_later,   ts_earlier, ts_now));
58   EXPECT_FALSE(TimeIsBetween(ts_later,   ts_now,     ts_earlier));
59 
60   // Edge cases
61   EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_earlier, ts_earlier));
62   EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_earlier, ts_later));
63   EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_later,   ts_later));
64 
65   // Earlier of two times
66   EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier));
67   EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_now));
68   EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later));
69   EXPECT_EQ(ts_earlier, TimeMin(ts_now,     ts_earlier));
70   EXPECT_EQ(ts_earlier, TimeMin(ts_later,   ts_earlier));
71 
72   // Later of two times
73   EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier));
74   EXPECT_EQ(ts_now,     TimeMax(ts_earlier, ts_now));
75   EXPECT_EQ(ts_later,   TimeMax(ts_earlier, ts_later));
76   EXPECT_EQ(ts_now,     TimeMax(ts_now,     ts_earlier));
77   EXPECT_EQ(ts_later,   TimeMax(ts_later,   ts_earlier));
78 }
79 
TEST(TimeTest,Intervals)80 TEST(TimeTest, Intervals) {
81   TimeStamp ts_earlier = Time();
82   TimeStamp ts_later = TimeAfter(500);
83 
84   // We can't depend on ts_later and ts_earlier to be exactly 500 apart
85   // since time elapses between the calls to Time() and TimeAfter(500)
86   EXPECT_LE(500,  TimeDiff(ts_later, ts_earlier));
87   EXPECT_GE(-500, TimeDiff(ts_earlier, ts_later));
88 
89   // Time has elapsed since ts_earlier
90   EXPECT_GE(TimeSince(ts_earlier), 0);
91 
92   // ts_earlier is earlier than now, so TimeUntil ts_earlier is -ve
93   EXPECT_LE(TimeUntil(ts_earlier), 0);
94 
95   // ts_later likely hasn't happened yet, so TimeSince could be -ve
96   // but within 500
97   EXPECT_GE(TimeSince(ts_later), -500);
98 
99   // TimeUntil ts_later is at most 500
100   EXPECT_LE(TimeUntil(ts_later), 500);
101 }
102 
TEST(TimeTest,BoundaryComparison)103 TEST(TimeTest, BoundaryComparison) {
104   // Obtain two different times, in known order
105   TimeStamp ts_earlier = static_cast<TimeStamp>(-50);
106   TimeStamp ts_later = ts_earlier + 100;
107   EXPECT_NE(ts_earlier, ts_later);
108 
109   // Common comparisons
110   EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_later));
111   EXPECT_TRUE( TimeIsLater(       ts_earlier, ts_later));
112   EXPECT_FALSE(TimeIsLaterOrEqual(ts_later,   ts_earlier));
113   EXPECT_FALSE(TimeIsLater(       ts_later,   ts_earlier));
114 
115   // Earlier of two times
116   EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier));
117   EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later));
118   EXPECT_EQ(ts_earlier, TimeMin(ts_later,   ts_earlier));
119 
120   // Later of two times
121   EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier));
122   EXPECT_EQ(ts_later,   TimeMax(ts_earlier, ts_later));
123   EXPECT_EQ(ts_later,   TimeMax(ts_later,   ts_earlier));
124 
125   // Interval
126   EXPECT_EQ(100,  TimeDiff(ts_later, ts_earlier));
127   EXPECT_EQ(-100, TimeDiff(ts_earlier, ts_later));
128 }
129 
TEST(TimeTest,DISABLED_CurrentTmTime)130 TEST(TimeTest, DISABLED_CurrentTmTime) {
131   struct tm tm;
132   int microseconds;
133 
134   time_t before = ::time(NULL);
135   CurrentTmTime(&tm, &microseconds);
136   time_t after = ::time(NULL);
137 
138   // Assert that 'tm' represents a time between 'before' and 'after'.
139   // mktime() uses local time, so we have to compensate for that.
140   time_t local_delta = before - ::mktime(::gmtime(&before));  // NOLINT
141   time_t t = ::mktime(&tm) + local_delta;
142 
143   EXPECT_TRUE(before <= t && t <= after);
144   EXPECT_TRUE(0 <= microseconds && microseconds < 1000000);
145 }
146 
147 class TimestampWrapAroundHandlerTest : public testing::Test {
148  public:
TimestampWrapAroundHandlerTest()149   TimestampWrapAroundHandlerTest() {}
150 
151  protected:
152   TimestampWrapAroundHandler wraparound_handler_;
153 };
154 
TEST_F(TimestampWrapAroundHandlerTest,Unwrap)155 TEST_F(TimestampWrapAroundHandlerTest, Unwrap) {
156   uint32_t ts = 0xfffffff2;
157   int64_t unwrapped_ts = ts;
158   EXPECT_EQ(ts, wraparound_handler_.Unwrap(ts));
159   ts = 2;
160   unwrapped_ts += 0x10;
161   EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts));
162   ts = 0xfffffff2;
163   unwrapped_ts += 0xfffffff0;
164   EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts));
165   ts = 0;
166   unwrapped_ts += 0xe;
167   EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts));
168 }
169 
170 class TmToSeconds : public testing::Test {
171  public:
TmToSeconds()172   TmToSeconds() {
173     // Set use of the test RNG to get deterministic expiration timestamp.
174     rtc::SetRandomTestMode(true);
175   }
~TmToSeconds()176   ~TmToSeconds() {
177     // Put it back for the next test.
178     rtc::SetRandomTestMode(false);
179   }
180 
TestTmToSeconds(int times)181   void TestTmToSeconds(int times) {
182     static char mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
183     for (int i = 0; i < times; i++) {
184 
185       // First generate something correct and check that TmToSeconds is happy.
186       int year = rtc::CreateRandomId() % 400 + 1970;
187 
188       bool leap_year = false;
189       if (year % 4 == 0)
190         leap_year = true;
191       if (year % 100 == 0)
192         leap_year = false;
193       if (year % 400 == 0)
194         leap_year = true;
195 
196       std::tm tm;
197       tm.tm_year = year - 1900;  // std::tm is year 1900 based.
198       tm.tm_mon = rtc::CreateRandomId() % 12;
199       tm.tm_mday = rtc::CreateRandomId() % mdays[tm.tm_mon] + 1;
200       tm.tm_hour = rtc::CreateRandomId() % 24;
201       tm.tm_min = rtc::CreateRandomId() % 60;
202       tm.tm_sec = rtc::CreateRandomId() % 60;
203       int64_t t = rtc::TmToSeconds(tm);
204       EXPECT_TRUE(t >= 0);
205 
206       // Now damage a random field and check that TmToSeconds is unhappy.
207       switch (rtc::CreateRandomId() % 11) {
208         case 0:
209           tm.tm_year = 1969 - 1900;
210           break;
211         case 1:
212           tm.tm_mon = -1;
213           break;
214         case 2:
215           tm.tm_mon = 12;
216           break;
217         case 3:
218           tm.tm_mday = 0;
219           break;
220         case 4:
221           tm.tm_mday = mdays[tm.tm_mon] + (leap_year && tm.tm_mon == 1) + 1;
222           break;
223         case 5:
224           tm.tm_hour = -1;
225           break;
226         case 6:
227           tm.tm_hour = 24;
228           break;
229         case 7:
230           tm.tm_min = -1;
231           break;
232         case 8:
233           tm.tm_min = 60;
234           break;
235         case 9:
236           tm.tm_sec = -1;
237           break;
238         case 10:
239           tm.tm_sec = 60;
240           break;
241       }
242       EXPECT_EQ(rtc::TmToSeconds(tm), -1);
243     }
244     // Check consistency with the system gmtime_r.  With time_t, we can only
245     // portably test dates until 2038, which is achieved by the % 0x80000000.
246     for (int i = 0; i < times; i++) {
247       time_t t = rtc::CreateRandomId() % 0x80000000;
248 #if defined(WEBRTC_WIN)
249       std::tm* tm = std::gmtime(&t);
250       EXPECT_TRUE(tm);
251       EXPECT_TRUE(rtc::TmToSeconds(*tm) == t);
252 #else
253       std::tm tm;
254       EXPECT_TRUE(gmtime_r(&t, &tm));
255       EXPECT_TRUE(rtc::TmToSeconds(tm) == t);
256 #endif
257     }
258   }
259 };
260 
TEST_F(TmToSeconds,TestTmToSeconds)261 TEST_F(TmToSeconds, TestTmToSeconds) {
262   TestTmToSeconds(100000);
263 }
264 
265 }  // namespace rtc
266