1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/*
2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *
4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */
10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/common.h"
12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/gunit.h"
1346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund#include "webrtc/base/helpers.h"
14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/thread.h"
15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/timeutils.h"
16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
17f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc {
18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgTEST(TimeTest, TimeInMs) {
200c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t ts_earlier = Time();
21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Thread::SleepMs(100);
220c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t ts_now = Time();
23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Allow for the thread to wakeup ~20ms early.
24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_GE(ts_now, ts_earlier + 80);
25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Make sure the Time is not returning in smaller unit like microseconds.
26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_LT(ts_now, ts_earlier + 1000);
27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgTEST(TimeTest, Comparison) {
30f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Obtain two different times, in known order
31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TimeStamp ts_earlier = Time();
32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Thread::SleepMs(100);
33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TimeStamp ts_now = Time();
34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_NE(ts_earlier, ts_now);
35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Common comparisons
37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_now));
38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsLater(       ts_earlier, ts_now));
39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(TimeIsLaterOrEqual(ts_now,     ts_earlier));
40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(TimeIsLater(       ts_now,     ts_earlier));
41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Edge cases
43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_earlier));
44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(TimeIsLater(       ts_earlier, ts_earlier));
45f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
46f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Obtain a third time
47f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TimeStamp ts_later = TimeAfter(100);
48f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_NE(ts_now, ts_later);
49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsLater(ts_now,     ts_later));
50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsLater(ts_earlier, ts_later));
51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Common comparisons
53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_now,     ts_later));
54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(TimeIsBetween(ts_earlier, ts_later,   ts_now));
55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(TimeIsBetween(ts_now,     ts_earlier, ts_later));
56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsBetween(ts_now,     ts_later,   ts_earlier));
57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsBetween(ts_later,   ts_earlier, ts_now));
58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(TimeIsBetween(ts_later,   ts_now,     ts_earlier));
59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Edge cases
61f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_earlier, ts_earlier));
62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_earlier, ts_later));
63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsBetween(ts_earlier, ts_later,   ts_later));
64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Earlier of two times
66f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier));
67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_now));
68f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later));
69f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_earlier, TimeMin(ts_now,     ts_earlier));
70f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_earlier, TimeMin(ts_later,   ts_earlier));
71f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Later of two times
73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier));
74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_now,     TimeMax(ts_earlier, ts_now));
75f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_later,   TimeMax(ts_earlier, ts_later));
76f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_now,     TimeMax(ts_now,     ts_earlier));
77f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_later,   TimeMax(ts_later,   ts_earlier));
78f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
79f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgTEST(TimeTest, Intervals) {
81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TimeStamp ts_earlier = Time();
82f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TimeStamp ts_later = TimeAfter(500);
83f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
84f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // We can't depend on ts_later and ts_earlier to be exactly 500 apart
85f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // since time elapses between the calls to Time() and TimeAfter(500)
86f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_LE(500,  TimeDiff(ts_later, ts_earlier));
87f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_GE(-500, TimeDiff(ts_earlier, ts_later));
88f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
89f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Time has elapsed since ts_earlier
90f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_GE(TimeSince(ts_earlier), 0);
91f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
92f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // ts_earlier is earlier than now, so TimeUntil ts_earlier is -ve
93f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_LE(TimeUntil(ts_earlier), 0);
94f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
95f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // ts_later likely hasn't happened yet, so TimeSince could be -ve
96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // but within 500
97f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_GE(TimeSince(ts_later), -500);
98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // TimeUntil ts_later is at most 500
100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_LE(TimeUntil(ts_later), 500);
101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgTEST(TimeTest, BoundaryComparison) {
104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Obtain two different times, in known order
105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TimeStamp ts_earlier = static_cast<TimeStamp>(-50);
106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TimeStamp ts_later = ts_earlier + 100;
107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_NE(ts_earlier, ts_later);
108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Common comparisons
110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsLaterOrEqual(ts_earlier, ts_later));
111f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE( TimeIsLater(       ts_earlier, ts_later));
112f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(TimeIsLaterOrEqual(ts_later,   ts_earlier));
113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(TimeIsLater(       ts_later,   ts_earlier));
114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Earlier of two times
116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_earlier));
117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_earlier, TimeMin(ts_earlier, ts_later));
118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_earlier, TimeMin(ts_later,   ts_earlier));
119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Later of two times
121f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_earlier, TimeMax(ts_earlier, ts_earlier));
122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_later,   TimeMax(ts_earlier, ts_later));
123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(ts_later,   TimeMax(ts_later,   ts_earlier));
124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Interval
126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(100,  TimeDiff(ts_later, ts_earlier));
127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(-100, TimeDiff(ts_earlier, ts_later));
128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
129f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
130f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgTEST(TimeTest, DISABLED_CurrentTmTime) {
131f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  struct tm tm;
132f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int microseconds;
133f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
134f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  time_t before = ::time(NULL);
135f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  CurrentTmTime(&tm, &microseconds);
136f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  time_t after = ::time(NULL);
137f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
138f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Assert that 'tm' represents a time between 'before' and 'after'.
139f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // mktime() uses local time, so we have to compensate for that.
140f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  time_t local_delta = before - ::mktime(::gmtime(&before));  // NOLINT
141f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  time_t t = ::mktime(&tm) + local_delta;
142f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
143f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(before <= t && t <= after);
144f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(0 <= microseconds && microseconds < 1000000);
145f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
146f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
14799b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.orgclass TimestampWrapAroundHandlerTest : public testing::Test {
14899b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org public:
14999b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  TimestampWrapAroundHandlerTest() {}
15099b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org
15199b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org protected:
15299b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  TimestampWrapAroundHandler wraparound_handler_;
15399b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org};
15499b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org
15599b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.orgTEST_F(TimestampWrapAroundHandlerTest, Unwrap) {
1560c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t ts = 0xfffffff2;
1570c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  int64_t unwrapped_ts = ts;
15899b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  EXPECT_EQ(ts, wraparound_handler_.Unwrap(ts));
15999b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  ts = 2;
16099b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  unwrapped_ts += 0x10;
16199b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts));
16299b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  ts = 0xfffffff2;
16399b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  unwrapped_ts += 0xfffffff0;
16499b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts));
16599b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  ts = 0;
16699b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  unwrapped_ts += 0xe;
16799b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org  EXPECT_EQ(unwrapped_ts, wraparound_handler_.Unwrap(ts));
16899b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org}
16999b4162ccf5bf1ab2f695849d4309f4db302c46ahenrike@webrtc.org
17046c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlundclass TmToSeconds : public testing::Test {
17146c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund public:
17246c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund  TmToSeconds() {
17346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    // Set use of the test RNG to get deterministic expiration timestamp.
17446c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    rtc::SetRandomTestMode(true);
17546c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund  }
17646c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund  ~TmToSeconds() {
17746c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    // Put it back for the next test.
17846c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    rtc::SetRandomTestMode(false);
17946c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund  }
18046c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund
18146c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund  void TestTmToSeconds(int times) {
18246c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    static char mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
18346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    for (int i = 0; i < times; i++) {
18446c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund
18546c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      // First generate something correct and check that TmToSeconds is happy.
18646c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      int year = rtc::CreateRandomId() % 400 + 1970;
18746c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund
18846c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      bool leap_year = false;
18946c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      if (year % 4 == 0)
19046c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        leap_year = true;
19146c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      if (year % 100 == 0)
19246c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        leap_year = false;
19346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      if (year % 400 == 0)
19446c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        leap_year = true;
19546c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund
19646c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      std::tm tm;
19746c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      tm.tm_year = year - 1900;  // std::tm is year 1900 based.
19846c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      tm.tm_mon = rtc::CreateRandomId() % 12;
19946c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      tm.tm_mday = rtc::CreateRandomId() % mdays[tm.tm_mon] + 1;
20046c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      tm.tm_hour = rtc::CreateRandomId() % 24;
20146c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      tm.tm_min = rtc::CreateRandomId() % 60;
20246c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      tm.tm_sec = rtc::CreateRandomId() % 60;
20346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      int64_t t = rtc::TmToSeconds(tm);
20446c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      EXPECT_TRUE(t >= 0);
20546c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund
20646c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      // Now damage a random field and check that TmToSeconds is unhappy.
20746c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      switch (rtc::CreateRandomId() % 11) {
20846c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 0:
20946c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_year = 1969 - 1900;
21046c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
21146c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 1:
21246c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_mon = -1;
21346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
21446c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 2:
21546c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_mon = 12;
21646c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
21746c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 3:
21846c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_mday = 0;
21946c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
22046c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 4:
22146c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_mday = mdays[tm.tm_mon] + (leap_year && tm.tm_mon == 1) + 1;
22246c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
22346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 5:
22446c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_hour = -1;
22546c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
22646c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 6:
22746c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_hour = 24;
22846c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
22946c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 7:
23046c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_min = -1;
23146c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
23246c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 8:
23346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_min = 60;
23446c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
23546c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 9:
23646c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_sec = -1;
23746c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
23846c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund        case 10:
23946c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          tm.tm_sec = 60;
24046c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund          break;
24146c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      }
24246c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      EXPECT_EQ(rtc::TmToSeconds(tm), -1);
24346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    }
24446c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    // Check consistency with the system gmtime_r.  With time_t, we can only
24546c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    // portably test dates until 2038, which is achieved by the % 0x80000000.
24646c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    for (int i = 0; i < times; i++) {
24746c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      time_t t = rtc::CreateRandomId() % 0x80000000;
24846c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund#if defined(WEBRTC_WIN)
24946c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      std::tm* tm = std::gmtime(&t);
25046c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      EXPECT_TRUE(tm);
25146c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      EXPECT_TRUE(rtc::TmToSeconds(*tm) == t);
25246c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund#else
25346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      std::tm tm;
25446c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      EXPECT_TRUE(gmtime_r(&t, &tm));
25546c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund      EXPECT_TRUE(rtc::TmToSeconds(tm) == t);
25646c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund#endif
25746c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund    }
25846c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund  }
25946c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund};
26046c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund
26146c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn GranlundTEST_F(TmToSeconds, TestTmToSeconds) {
26246c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund  TestTmToSeconds(100000);
26346c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund}
26446c9cc01901ecd3af0191872f9660b710d5fe757Torbjorn Granlund
265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}  // namespace rtc
266