301 lines
9.2 KiB
C++
301 lines
9.2 KiB
C++
// Copyright 2025 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine License
|
|
// Agreement.
|
|
#include "wv_timestamp.h"
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <chrono>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "wv_duration.h"
|
|
|
|
namespace wvutil {
|
|
namespace test {
|
|
namespace {
|
|
constexpr uint64_t kRawValidEpochSeconds = 1733526346;
|
|
constexpr Seconds kValidEpochSeconds = Seconds(kRawValidEpochSeconds);
|
|
|
|
constexpr uint64_t kRawOutOfRangeEpochSeconds = 253402300800; // Year 10000
|
|
constexpr Seconds kOutOfRangeEpochSeconds = Seconds(kRawOutOfRangeEpochSeconds);
|
|
|
|
constexpr uint64_t kOneS = 1;
|
|
constexpr uint64_t kOneMinuteS = kOneS * 60;
|
|
constexpr uint64_t kOneHourS = kOneMinuteS * 60;
|
|
constexpr uint64_t kOneDayS = kOneHourS * 24;
|
|
} // namespace
|
|
|
|
TEST(WvTimestampUtilTest, DefaultConstructor) {
|
|
const Timestamp ts;
|
|
EXPECT_FALSE(ts.IsSet());
|
|
EXPECT_EQ(ts.epoch_milliseconds(), Milliseconds::zero());
|
|
EXPECT_EQ(ts.epoch_seconds(), Seconds::zero());
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, MinMax) {
|
|
const Timestamp max = Timestamp::Max();
|
|
EXPECT_TRUE(max.IsSet());
|
|
const Timestamp min = Timestamp::Min();
|
|
EXPECT_TRUE(min.IsSet());
|
|
EXPECT_LE(min, max);
|
|
EXPECT_GE(max, min);
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, FromUnixSeconds) {
|
|
const Milliseconds epoch_milliseconds =
|
|
std::chrono::duration_cast<Milliseconds>(kValidEpochSeconds);
|
|
|
|
const Timestamp ts = Timestamp::FromUnixSeconds(kValidEpochSeconds);
|
|
EXPECT_TRUE(ts.IsSet());
|
|
|
|
EXPECT_EQ(ts.epoch_seconds(), kValidEpochSeconds);
|
|
EXPECT_EQ(ts.epoch_milliseconds(), epoch_milliseconds);
|
|
EXPECT_EQ(ts.milliseconds(), 0u);
|
|
|
|
EXPECT_EQ(ts, Timestamp::FromUnixSeconds(kRawValidEpochSeconds));
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, FromUnixSeconds_WithMs) {
|
|
constexpr uint32_t raw_milliseconds = 123;
|
|
const Milliseconds epoch_milliseconds =
|
|
kValidEpochSeconds + Milliseconds(raw_milliseconds);
|
|
|
|
const Timestamp ts =
|
|
Timestamp::FromUnixSeconds(kValidEpochSeconds, raw_milliseconds);
|
|
EXPECT_TRUE(ts.IsSet());
|
|
|
|
EXPECT_EQ(ts.epoch_seconds(), kValidEpochSeconds);
|
|
EXPECT_EQ(ts.epoch_milliseconds(), epoch_milliseconds);
|
|
EXPECT_EQ(ts.milliseconds(), raw_milliseconds);
|
|
|
|
EXPECT_EQ(
|
|
ts, Timestamp::FromUnixSeconds(kRawValidEpochSeconds, raw_milliseconds));
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, FromUnixSeconds_SecondsOutOfRange) {
|
|
EXPECT_FALSE(Timestamp::FromUnixSeconds(kRawOutOfRangeEpochSeconds).IsSet());
|
|
EXPECT_FALSE(Timestamp::FromUnixSeconds(kOutOfRangeEpochSeconds).IsSet());
|
|
|
|
constexpr Seconds negative_epoch_seconds = Seconds(-1);
|
|
EXPECT_FALSE(Timestamp::FromUnixSeconds(negative_epoch_seconds).IsSet());
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, FromUnixSeconds_MsOutOfRange) {
|
|
EXPECT_FALSE(Timestamp::FromUnixSeconds(kValidEpochSeconds, 1000).IsSet());
|
|
EXPECT_FALSE(Timestamp::FromUnixSeconds(kRawValidEpochSeconds, 1000).IsSet());
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, FromUnixMilliseconds) {
|
|
constexpr uint32_t raw_milliseconds = 123;
|
|
constexpr uint64_t raw_total_milliseconds =
|
|
(kRawValidEpochSeconds * 1000) + raw_milliseconds;
|
|
constexpr Milliseconds epoch_milliseconds =
|
|
Milliseconds(raw_total_milliseconds);
|
|
|
|
constexpr Timestamp ts = Timestamp::FromUnixMilliseconds(epoch_milliseconds);
|
|
|
|
EXPECT_TRUE(ts.IsSet());
|
|
|
|
EXPECT_EQ(ts.epoch_seconds(), kValidEpochSeconds);
|
|
EXPECT_EQ(ts.epoch_milliseconds(), epoch_milliseconds);
|
|
EXPECT_EQ(ts.milliseconds(), raw_milliseconds);
|
|
|
|
EXPECT_EQ(ts, Timestamp::FromUnixMilliseconds(raw_total_milliseconds));
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, FromUnixMilliseconds_OutOfRange) {
|
|
constexpr uint64_t raw_total_milliseconds = kRawOutOfRangeEpochSeconds * 1000;
|
|
constexpr Milliseconds epoch_milliseconds =
|
|
Milliseconds(raw_total_milliseconds);
|
|
EXPECT_FALSE(Timestamp::FromUnixMilliseconds(raw_total_milliseconds).IsSet());
|
|
EXPECT_FALSE(Timestamp::FromUnixMilliseconds(epoch_milliseconds).IsSet());
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, Clear) {
|
|
Timestamp ts = Timestamp::FromUnixSeconds(kValidEpochSeconds);
|
|
EXPECT_TRUE(ts.IsSet());
|
|
ts.Clear();
|
|
EXPECT_FALSE(ts.IsSet());
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, Comparison) {
|
|
constexpr Timestamp ts_a = Timestamp::Min();
|
|
constexpr Timestamp ts_b =
|
|
Timestamp::FromUnixSeconds(kRawValidEpochSeconds - kOneDayS);
|
|
constexpr Timestamp ts_c = Timestamp::FromUnixSeconds(kValidEpochSeconds);
|
|
constexpr Timestamp ts_d =
|
|
Timestamp::FromUnixSeconds(kValidEpochSeconds, 123);
|
|
constexpr Timestamp ts_e = Timestamp::Max();
|
|
|
|
// Equality
|
|
EXPECT_EQ(ts_a, ts_a);
|
|
EXPECT_EQ(ts_b, ts_b);
|
|
EXPECT_EQ(ts_c, ts_c);
|
|
EXPECT_EQ(ts_d, ts_d);
|
|
EXPECT_EQ(ts_e, ts_e);
|
|
|
|
// Inequality.
|
|
EXPECT_NE(ts_a, ts_b);
|
|
EXPECT_NE(ts_a, ts_c);
|
|
EXPECT_NE(ts_a, ts_d);
|
|
EXPECT_NE(ts_a, ts_e);
|
|
EXPECT_NE(ts_b, ts_c);
|
|
EXPECT_NE(ts_b, ts_d);
|
|
EXPECT_NE(ts_b, ts_e);
|
|
EXPECT_NE(ts_c, ts_d);
|
|
EXPECT_NE(ts_c, ts_e);
|
|
EXPECT_NE(ts_d, ts_e);
|
|
|
|
// Less than
|
|
EXPECT_LT(ts_a, ts_b);
|
|
EXPECT_LT(ts_a, ts_c);
|
|
EXPECT_LT(ts_a, ts_d);
|
|
EXPECT_LT(ts_a, ts_e);
|
|
EXPECT_LT(ts_b, ts_c);
|
|
EXPECT_LT(ts_b, ts_d);
|
|
EXPECT_LT(ts_b, ts_e);
|
|
EXPECT_LT(ts_c, ts_d);
|
|
EXPECT_LT(ts_c, ts_e);
|
|
EXPECT_LT(ts_d, ts_e);
|
|
|
|
// Less than or equal.
|
|
EXPECT_LE(ts_a, ts_a);
|
|
EXPECT_LE(ts_a, ts_b);
|
|
EXPECT_LE(ts_a, ts_c);
|
|
EXPECT_LE(ts_a, ts_d);
|
|
EXPECT_LE(ts_a, ts_e);
|
|
EXPECT_LE(ts_b, ts_b);
|
|
EXPECT_LE(ts_b, ts_c);
|
|
EXPECT_LE(ts_b, ts_d);
|
|
EXPECT_LE(ts_b, ts_e);
|
|
EXPECT_LE(ts_c, ts_c);
|
|
EXPECT_LE(ts_c, ts_d);
|
|
EXPECT_LE(ts_c, ts_e);
|
|
EXPECT_LE(ts_d, ts_d);
|
|
EXPECT_LE(ts_d, ts_e);
|
|
EXPECT_LE(ts_e, ts_e);
|
|
|
|
// Greater than
|
|
EXPECT_GT(ts_b, ts_a);
|
|
EXPECT_GT(ts_c, ts_a);
|
|
EXPECT_GT(ts_d, ts_a);
|
|
EXPECT_GT(ts_e, ts_a);
|
|
EXPECT_GT(ts_c, ts_b);
|
|
EXPECT_GT(ts_d, ts_b);
|
|
EXPECT_GT(ts_e, ts_b);
|
|
EXPECT_GT(ts_d, ts_c);
|
|
EXPECT_GT(ts_e, ts_c);
|
|
EXPECT_GT(ts_e, ts_d);
|
|
|
|
// Greater than or equal.
|
|
EXPECT_GE(ts_a, ts_a);
|
|
EXPECT_GE(ts_b, ts_a);
|
|
EXPECT_GE(ts_c, ts_a);
|
|
EXPECT_GE(ts_d, ts_a);
|
|
EXPECT_GE(ts_e, ts_a);
|
|
EXPECT_GE(ts_b, ts_b);
|
|
EXPECT_GE(ts_c, ts_b);
|
|
EXPECT_GE(ts_d, ts_b);
|
|
EXPECT_GE(ts_e, ts_b);
|
|
EXPECT_GE(ts_c, ts_c);
|
|
EXPECT_GE(ts_d, ts_c);
|
|
EXPECT_GE(ts_e, ts_c);
|
|
EXPECT_GE(ts_d, ts_d);
|
|
EXPECT_GE(ts_e, ts_d);
|
|
EXPECT_GE(ts_e, ts_e);
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, Addition_WithDuration) {
|
|
constexpr Timestamp start = Timestamp::FromUnixSeconds(kValidEpochSeconds);
|
|
constexpr Duration one_day = Duration::FromSeconds(kOneDayS);
|
|
|
|
constexpr Timestamp tomorrow = start + one_day;
|
|
constexpr decltype(tomorrow.epoch_seconds().count()) expected_second_count =
|
|
kRawValidEpochSeconds + kOneDayS;
|
|
EXPECT_EQ(tomorrow.epoch_seconds().count(), expected_second_count);
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, Addition_WithDuration_Unset) {
|
|
constexpr Timestamp unset;
|
|
constexpr Duration one_day = Duration::FromSeconds(kOneDayS);
|
|
|
|
constexpr Timestamp result = unset + one_day;
|
|
EXPECT_FALSE(result.IsSet());
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, Addition_WithDuration_Overflow) {
|
|
Timestamp start = Timestamp::Max();
|
|
constexpr Duration one_day = Duration::FromSeconds(kOneDayS);
|
|
|
|
Timestamp result = start + one_day;
|
|
EXPECT_FALSE(result.IsSet());
|
|
|
|
start = Timestamp::Min();
|
|
constexpr Duration very_long_duration =
|
|
Duration::FromSeconds(kOneDayS * 365 * 10000);
|
|
result = start + very_long_duration;
|
|
EXPECT_FALSE(result.IsSet());
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, Subtraction_WithDuration) {
|
|
constexpr Timestamp start = Timestamp::FromUnixSeconds(kValidEpochSeconds);
|
|
constexpr Duration one_day = Duration::FromSeconds(kOneDayS);
|
|
|
|
constexpr Timestamp yesterday = start - one_day;
|
|
constexpr decltype(yesterday.epoch_seconds().count()) expected_second_count =
|
|
kRawValidEpochSeconds - kOneDayS;
|
|
EXPECT_EQ(yesterday.epoch_seconds().count(), expected_second_count);
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, Subtraction_WithDuration_Unset) {
|
|
constexpr Timestamp unset;
|
|
constexpr Duration one_day = Duration::FromSeconds(kOneDayS);
|
|
|
|
constexpr Timestamp result = unset - one_day;
|
|
EXPECT_FALSE(result.IsSet());
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, Subtraction_WithDuration_Underflow) {
|
|
Timestamp start = Timestamp::Min();
|
|
constexpr Duration one_day = Duration::FromSeconds(kOneDayS);
|
|
|
|
Timestamp result = start - one_day;
|
|
EXPECT_FALSE(result.IsSet());
|
|
|
|
start = Timestamp::Max();
|
|
constexpr Duration very_long_duration =
|
|
Duration::FromSeconds(kOneDayS * 365 * 10000);
|
|
result = start - very_long_duration;
|
|
EXPECT_FALSE(result.IsSet());
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, Difference) {
|
|
// 4 days, 3 hours, 2 minutes and 1 second.
|
|
constexpr int64_t kDifferenceS =
|
|
1 + 2 * kOneMinuteS + 3 * kOneHourS + 4 * kOneDayS;
|
|
|
|
constexpr Timestamp ts_a = Timestamp::FromUnixSeconds(kValidEpochSeconds);
|
|
constexpr Timestamp ts_b =
|
|
Timestamp::FromUnixSeconds(kRawValidEpochSeconds + kDifferenceS);
|
|
|
|
constexpr Duration diff_ab = ts_b - ts_a;
|
|
EXPECT_EQ(diff_ab.total_seconds().count(), kDifferenceS);
|
|
|
|
constexpr Duration diff_ba = ts_a - ts_b;
|
|
EXPECT_EQ(diff_ba.total_seconds().count(), -kDifferenceS);
|
|
}
|
|
|
|
TEST(WvTimestampUtilTest, Difference_Unset) {
|
|
constexpr Duration unset_duration;
|
|
|
|
constexpr Timestamp ts = Timestamp::FromUnixSeconds(kValidEpochSeconds);
|
|
constexpr Timestamp unset;
|
|
|
|
EXPECT_EQ(ts - unset, unset_duration);
|
|
EXPECT_EQ(unset - ts, unset_duration);
|
|
EXPECT_EQ(unset - unset, unset_duration);
|
|
}
|
|
} // namespace test
|
|
} // namespace wvutil
|