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 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 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 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 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 130 TEST(TimeTest, DISABLED_CurrentTmTime) { 131 struct tm tm; 132 int microseconds; 133 134 time_t before = ::time(NULL); 135 CurrentTmTime(&tm, µseconds); 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: 149 TimestampWrapAroundHandlerTest() {} 150 151 protected: 152 TimestampWrapAroundHandler wraparound_handler_; 153 }; 154 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: 172 TmToSeconds() { 173 // Set use of the test RNG to get deterministic expiration timestamp. 174 rtc::SetRandomTestMode(true); 175 } 176 ~TmToSeconds() { 177 // Put it back for the next test. 178 rtc::SetRandomTestMode(false); 179 } 180 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 261 TEST_F(TmToSeconds, TestTmToSeconds) { 262 TestTmToSeconds(100000); 263 } 264 265 } // namespace rtc 266