diff options
| author | swarmer <[email protected]> | 2025-10-03 20:25:26 +0300 |
|---|---|---|
| committer | swarmer <[email protected]> | 2025-10-03 20:50:00 +0300 |
| commit | 08d7ed83f95bdff4ddd3fd1b05b16d12f6bedbb1 (patch) | |
| tree | e7c89fa017ee7154ef1a16761d4e9fa4d816e785 /util/datetime/base_ut.cpp | |
| parent | e8e38bf51bdfebc163b2fa9310c302f4f9e1c720 (diff) | |
TDuration/TInstant named constructors should return staturated value on overflow
`TDuration::Seconds(sec)` now returns `TDuration::Max()` if `sec` is greater than the largest representable value.
Previously, a silent wrap-around could produce a significantly shorter interval (even a zero one).
commit_hash:552fde08fa3b8201ede23894bb363df2d6bbd5af
Diffstat (limited to 'util/datetime/base_ut.cpp')
| -rw-r--r-- | util/datetime/base_ut.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/util/datetime/base_ut.cpp b/util/datetime/base_ut.cpp index 3ac1a90a908..ed437da4e8f 100644 --- a/util/datetime/base_ut.cpp +++ b/util/datetime/base_ut.cpp @@ -413,6 +413,11 @@ Y_UNIT_TEST_SUITE(DateTimeTest) { } } + Y_UNIT_TEST(TestFromConverableType) { + std::atomic<ui64> timestamp{42}; + UNIT_ASSERT_EQUAL(TInstant::Seconds(42), TInstant::Seconds(timestamp)); + } + Y_UNIT_TEST(TestSleep) { // check does not throw Sleep(TDuration::Seconds(0)); @@ -582,6 +587,45 @@ Y_UNIT_TEST_SUITE(DateTimeTest) { static_cast<float>(::Max<ui64>()) / 1000 + 0.1})); } + template <class T> + void TestDurationCurationConstructorFunctionSaturation() { + const ui64 maxMilliseconds = ::Max<ui64>() / T::MilliSeconds(1).GetValue(); + const ui64 maxSeconds = ::Max<ui64>() / T::Seconds(1).GetValue(); + const ui64 maxMinutes = ::Max<ui64>() / T::Minutes(1).GetValue(); + const ui64 maxHours = ::Max<ui64>() / T::Hours(1).GetValue(); + const ui64 maxDays = ::Max<ui64>() / T::Days(1).GetValue(); + + auto test = [](ui64 maxValue, T (*constructor)(ui64), TStringBuf name) { + UNIT_ASSERT_VALUES_UNEQUAL_C(constructor(maxValue), T::Max(), LabeledOutput(name)); + UNIT_ASSERT_VALUES_EQUAL_C(constructor(Max<ui64>()), T::Max(), LabeledOutput(name)); + for (ui64 v = maxValue + 1; v != Max<ui64>(); v = std::midpoint(Max<ui64>(), v)) { + UNIT_ASSERT_VALUES_EQUAL_C(constructor(v), T::Max(), LabeledOutput(name, v)); + } + for (ui64 v = maxValue; v != 0; v = std::midpoint(ui64(0), v)) { + UNIT_ASSERT_VALUES_UNEQUAL_C(constructor(v), T::Max(), LabeledOutput(name, v)); + } + }; + test(maxMilliseconds, &T::MilliSeconds, "MilliSeconds"); + test(maxSeconds, &T::Seconds, "Seconds"); + test(maxMinutes, &T::Minutes, "Minutes"); + test(maxHours, &T::Hours, "Hours"); + test(maxDays, &T::Days, "Days"); + } + + Y_UNIT_TEST(TestDurationCurationConstructorFunctionSaturation) { + UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(-5.f), TDuration::Zero()); + UNIT_ASSERT_VALUES_EQUAL(TDuration::MilliSeconds(-5.f), TDuration::Zero()); + UNIT_ASSERT_VALUES_EQUAL(TDuration::MilliSeconds(0x1p63), TDuration::Max()); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(0x1p45), TDuration::Max()); + UNIT_ASSERT_VALUES_UNEQUAL(TDuration::Seconds(0x1p44), TDuration::Max()); + + TestDurationCurationConstructorFunctionSaturation<TDuration>(); + } + + Y_UNIT_TEST(TestInstantCurationConstructorFunctionSaturation) { + TestDurationCurationConstructorFunctionSaturation<TInstant>(); + } + Y_UNIT_TEST(TestTDurationCompareWithStdChronoDuration) { UNIT_ASSERT(TDuration::Zero() == 0ms); UNIT_ASSERT(TDuration::Seconds(42) == 42s); |
