tvl-depot/absl/time/duration_test.cc

1532 lines
61 KiB
C++
Raw Normal View History

2017-09-19 22:54:40 +02:00
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cmath>
#include <cstdint>
#include <ctime>
#include <limits>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/time/time.h"
namespace {
constexpr int64_t kint64max = std::numeric_limits<int64_t>::max();
constexpr int64_t kint64min = std::numeric_limits<int64_t>::min();
// Approximates the given number of years. This is only used to make some test
// code more readable.
absl::Duration ApproxYears(int64_t n) { return absl::Hours(n) * 365 * 24; }
// A gMock matcher to match timespec values. Use this matcher like:
// timespec ts1, ts2;
// EXPECT_THAT(ts1, TimespecMatcher(ts2));
MATCHER_P(TimespecMatcher, ts, "") {
if (ts.tv_sec == arg.tv_sec && ts.tv_nsec == arg.tv_nsec)
return true;
*result_listener << "expected: {" << ts.tv_sec << ", " << ts.tv_nsec << "} ";
*result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_nsec << "}";
return false;
}
// A gMock matcher to match timeval values. Use this matcher like:
// timeval tv1, tv2;
// EXPECT_THAT(tv1, TimevalMatcher(tv2));
MATCHER_P(TimevalMatcher, tv, "") {
if (tv.tv_sec == arg.tv_sec && tv.tv_usec == arg.tv_usec)
return true;
*result_listener << "expected: {" << tv.tv_sec << ", " << tv.tv_usec << "} ";
*result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_usec << "}";
return false;
}
TEST(Duration, ValueSemantics) {
// If this compiles, the test passes.
constexpr absl::Duration a; // Default construction
constexpr absl::Duration b = a; // Copy construction
constexpr absl::Duration c(b); // Copy construction (again)
absl::Duration d;
d = c; // Assignment
}
TEST(Duration, Factories) {
constexpr absl::Duration zero = absl::ZeroDuration();
constexpr absl::Duration nano = absl::Nanoseconds(1);
constexpr absl::Duration micro = absl::Microseconds(1);
constexpr absl::Duration milli = absl::Milliseconds(1);
constexpr absl::Duration sec = absl::Seconds(1);
constexpr absl::Duration min = absl::Minutes(1);
constexpr absl::Duration hour = absl::Hours(1);
EXPECT_EQ(zero, absl::Duration());
EXPECT_EQ(zero, absl::Seconds(0));
EXPECT_EQ(nano, absl::Nanoseconds(1));
EXPECT_EQ(micro, absl::Nanoseconds(1000));
EXPECT_EQ(milli, absl::Microseconds(1000));
EXPECT_EQ(sec, absl::Milliseconds(1000));
EXPECT_EQ(min, absl::Seconds(60));
EXPECT_EQ(hour, absl::Minutes(60));
// Tests factory limits
const absl::Duration inf = absl::InfiniteDuration();
EXPECT_GT(inf, absl::Seconds(kint64max));
EXPECT_LT(-inf, absl::Seconds(kint64min));
EXPECT_LT(-inf, absl::Seconds(-kint64max));
EXPECT_EQ(inf, absl::Minutes(kint64max));
EXPECT_EQ(-inf, absl::Minutes(kint64min));
EXPECT_EQ(-inf, absl::Minutes(-kint64max));
EXPECT_GT(inf, absl::Minutes(kint64max / 60));
EXPECT_LT(-inf, absl::Minutes(kint64min / 60));
EXPECT_LT(-inf, absl::Minutes(-kint64max / 60));
EXPECT_EQ(inf, absl::Hours(kint64max));
EXPECT_EQ(-inf, absl::Hours(kint64min));
EXPECT_EQ(-inf, absl::Hours(-kint64max));
EXPECT_GT(inf, absl::Hours(kint64max / 3600));
EXPECT_LT(-inf, absl::Hours(kint64min / 3600));
EXPECT_LT(-inf, absl::Hours(-kint64max / 3600));
}
TEST(Duration, ToConversion) {
#define TEST_DURATION_CONVERSION(UNIT) \
do { \
const absl::Duration d = absl::UNIT(1.5); \
const absl::Duration z = absl::ZeroDuration(); \
const absl::Duration inf = absl::InfiniteDuration(); \
const double dbl_inf = std::numeric_limits<double>::infinity(); \
EXPECT_EQ(kint64min, absl::ToInt64##UNIT(-inf)); \
EXPECT_EQ(-1, absl::ToInt64##UNIT(-d)); \
EXPECT_EQ(0, absl::ToInt64##UNIT(z)); \
EXPECT_EQ(1, absl::ToInt64##UNIT(d)); \
EXPECT_EQ(kint64max, absl::ToInt64##UNIT(inf)); \
EXPECT_EQ(-dbl_inf, absl::ToDouble##UNIT(-inf)); \
EXPECT_EQ(-1.5, absl::ToDouble##UNIT(-d)); \
EXPECT_EQ(0, absl::ToDouble##UNIT(z)); \
EXPECT_EQ(1.5, absl::ToDouble##UNIT(d)); \
EXPECT_EQ(dbl_inf, absl::ToDouble##UNIT(inf)); \
} while (0)
TEST_DURATION_CONVERSION(Nanoseconds);
TEST_DURATION_CONVERSION(Microseconds);
TEST_DURATION_CONVERSION(Milliseconds);
TEST_DURATION_CONVERSION(Seconds);
TEST_DURATION_CONVERSION(Minutes);
TEST_DURATION_CONVERSION(Hours);
#undef TEST_DURATION_CONVERSION
}
template <int64_t n>
void TestToConversion() {
constexpr absl::Duration nano = absl::Nanoseconds(n);
EXPECT_EQ(n, absl::ToInt64Nanoseconds(nano));
EXPECT_EQ(0, absl::ToInt64Microseconds(nano));
EXPECT_EQ(0, absl::ToInt64Milliseconds(nano));
EXPECT_EQ(0, absl::ToInt64Seconds(nano));
EXPECT_EQ(0, absl::ToInt64Minutes(nano));
EXPECT_EQ(0, absl::ToInt64Hours(nano));
const absl::Duration micro = absl::Microseconds(n);
EXPECT_EQ(n * 1000, absl::ToInt64Nanoseconds(micro));
EXPECT_EQ(n, absl::ToInt64Microseconds(micro));
EXPECT_EQ(0, absl::ToInt64Milliseconds(micro));
EXPECT_EQ(0, absl::ToInt64Seconds(micro));
EXPECT_EQ(0, absl::ToInt64Minutes(micro));
EXPECT_EQ(0, absl::ToInt64Hours(micro));
const absl::Duration milli = absl::Milliseconds(n);
EXPECT_EQ(n * 1000 * 1000, absl::ToInt64Nanoseconds(milli));
EXPECT_EQ(n * 1000, absl::ToInt64Microseconds(milli));
EXPECT_EQ(n, absl::ToInt64Milliseconds(milli));
EXPECT_EQ(0, absl::ToInt64Seconds(milli));
EXPECT_EQ(0, absl::ToInt64Minutes(milli));
EXPECT_EQ(0, absl::ToInt64Hours(milli));
const absl::Duration sec = absl::Seconds(n);
EXPECT_EQ(n * 1000 * 1000 * 1000, absl::ToInt64Nanoseconds(sec));
EXPECT_EQ(n * 1000 * 1000, absl::ToInt64Microseconds(sec));
EXPECT_EQ(n * 1000, absl::ToInt64Milliseconds(sec));
EXPECT_EQ(n, absl::ToInt64Seconds(sec));
EXPECT_EQ(0, absl::ToInt64Minutes(sec));
EXPECT_EQ(0, absl::ToInt64Hours(sec));
const absl::Duration min = absl::Minutes(n);
EXPECT_EQ(n * 60 * 1000 * 1000 * 1000, absl::ToInt64Nanoseconds(min));
EXPECT_EQ(n * 60 * 1000 * 1000, absl::ToInt64Microseconds(min));
EXPECT_EQ(n * 60 * 1000, absl::ToInt64Milliseconds(min));
EXPECT_EQ(n * 60, absl::ToInt64Seconds(min));
EXPECT_EQ(n, absl::ToInt64Minutes(min));
EXPECT_EQ(0, absl::ToInt64Hours(min));
const absl::Duration hour = absl::Hours(n);
EXPECT_EQ(n * 60 * 60 * 1000 * 1000 * 1000, absl::ToInt64Nanoseconds(hour));
EXPECT_EQ(n * 60 * 60 * 1000 * 1000, absl::ToInt64Microseconds(hour));
EXPECT_EQ(n * 60 * 60 * 1000, absl::ToInt64Milliseconds(hour));
EXPECT_EQ(n * 60 * 60, absl::ToInt64Seconds(hour));
EXPECT_EQ(n * 60, absl::ToInt64Minutes(hour));
EXPECT_EQ(n, absl::ToInt64Hours(hour));
}
TEST(Duration, ToConversionDeprecated) {
TestToConversion<43>();
TestToConversion<1>();
TestToConversion<0>();
TestToConversion<-1>();
TestToConversion<-43>();
}
// Used for testing the factory overloads.
template <typename T>
struct ImplicitlyConvertible {
T n_;
explicit ImplicitlyConvertible(T n) : n_(n) {}
// Marking this conversion operator with 'explicit' will cause the test to
// fail (as desired).
operator T() { return n_; }
};
TEST(Duration, FactoryOverloads) {
#define TEST_FACTORY_OVERLOADS(NAME) \
EXPECT_EQ(1, NAME(static_cast<int8_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(static_cast<int16_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(static_cast<int32_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(static_cast<int64_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(static_cast<uint8_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(static_cast<uint16_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(static_cast<uint32_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(static_cast<uint64_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(ImplicitlyConvertible<int8_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(ImplicitlyConvertible<int16_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(ImplicitlyConvertible<int32_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(ImplicitlyConvertible<int64_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint8_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint16_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint32_t>(1)) / NAME(1)); \
EXPECT_EQ(1, NAME(ImplicitlyConvertible<uint64_t>(1)) / NAME(1)); \
EXPECT_EQ(NAME(1) / 2, NAME(static_cast<float>(0.5))); \
EXPECT_EQ(NAME(1) / 2, NAME(static_cast<double>(0.5))); \
EXPECT_EQ(1.5, absl::FDivDuration(NAME(static_cast<float>(1.5)), NAME(1))); \
EXPECT_EQ(1.5, absl::FDivDuration(NAME(static_cast<double>(1.5)), NAME(1)));
TEST_FACTORY_OVERLOADS(absl::Nanoseconds);
TEST_FACTORY_OVERLOADS(absl::Microseconds);
TEST_FACTORY_OVERLOADS(absl::Milliseconds);
TEST_FACTORY_OVERLOADS(absl::Seconds);
TEST_FACTORY_OVERLOADS(absl::Minutes);
TEST_FACTORY_OVERLOADS(absl::Hours);
#undef TEST_FACTORY_OVERLOADS
EXPECT_EQ(absl::Milliseconds(1500), absl::Seconds(1.5));
EXPECT_LT(absl::Nanoseconds(1), absl::Nanoseconds(1.5));
EXPECT_GT(absl::Nanoseconds(2), absl::Nanoseconds(1.5));
const double dbl_inf = std::numeric_limits<double>::infinity();
EXPECT_EQ(absl::InfiniteDuration(), absl::Nanoseconds(dbl_inf));
EXPECT_EQ(absl::InfiniteDuration(), absl::Microseconds(dbl_inf));
EXPECT_EQ(absl::InfiniteDuration(), absl::Milliseconds(dbl_inf));
EXPECT_EQ(absl::InfiniteDuration(), absl::Seconds(dbl_inf));
EXPECT_EQ(absl::InfiniteDuration(), absl::Minutes(dbl_inf));
EXPECT_EQ(absl::InfiniteDuration(), absl::Hours(dbl_inf));
EXPECT_EQ(-absl::InfiniteDuration(), absl::Nanoseconds(-dbl_inf));
EXPECT_EQ(-absl::InfiniteDuration(), absl::Microseconds(-dbl_inf));
EXPECT_EQ(-absl::InfiniteDuration(), absl::Milliseconds(-dbl_inf));
EXPECT_EQ(-absl::InfiniteDuration(), absl::Seconds(-dbl_inf));
EXPECT_EQ(-absl::InfiniteDuration(), absl::Minutes(-dbl_inf));
EXPECT_EQ(-absl::InfiniteDuration(), absl::Hours(-dbl_inf));
}
TEST(Duration, InfinityExamples) {
// These examples are used in the documentation in //base/time.h. They are
// written so that they can be copy-n-pasted easily.
constexpr absl::Duration inf = absl::InfiniteDuration();
constexpr absl::Duration d = absl::Seconds(1); // Any finite duration
EXPECT_TRUE(inf == inf + inf);
EXPECT_TRUE(inf == inf + d);
EXPECT_TRUE(inf == inf - inf);
EXPECT_TRUE(-inf == d - inf);
EXPECT_TRUE(inf == d * 1e100);
EXPECT_TRUE(0 == d / inf); // NOLINT(readability/check)
// Division by zero returns infinity, or kint64min/MAX where necessary.
EXPECT_TRUE(inf == d / 0);
EXPECT_TRUE(kint64max == d / absl::ZeroDuration());
}
TEST(Duration, InfinityComparison) {
const absl::Duration inf = absl::InfiniteDuration();
const absl::Duration any_dur = absl::Seconds(1);
// Equality
EXPECT_EQ(inf, inf);
EXPECT_EQ(-inf, -inf);
EXPECT_NE(inf, -inf);
EXPECT_NE(any_dur, inf);
EXPECT_NE(any_dur, -inf);
// Relational
EXPECT_GT(inf, any_dur);
EXPECT_LT(-inf, any_dur);
EXPECT_LT(-inf, inf);
EXPECT_GT(inf, -inf);
}
TEST(Duration, InfinityAddition) {
const absl::Duration sec_max = absl::Seconds(kint64max);
const absl::Duration sec_min = absl::Seconds(kint64min);
const absl::Duration any_dur = absl::Seconds(1);
const absl::Duration inf = absl::InfiniteDuration();
// Addition
EXPECT_EQ(inf, inf + inf);
EXPECT_EQ(inf, inf + -inf);
EXPECT_EQ(-inf, -inf + inf);
EXPECT_EQ(-inf, -inf + -inf);
EXPECT_EQ(inf, inf + any_dur);
EXPECT_EQ(inf, any_dur + inf);
EXPECT_EQ(-inf, -inf + any_dur);
EXPECT_EQ(-inf, any_dur + -inf);
// Interesting case
absl::Duration almost_inf = sec_max + absl::Nanoseconds(999999999);
EXPECT_GT(inf, almost_inf);
almost_inf += -absl::Nanoseconds(999999999);
EXPECT_GT(inf, almost_inf);
// Addition overflow/underflow
EXPECT_EQ(inf, sec_max + absl::Seconds(1));
EXPECT_EQ(inf, sec_max + sec_max);
EXPECT_EQ(-inf, sec_min + -absl::Seconds(1));
EXPECT_EQ(-inf, sec_min + -sec_max);
// For reference: IEEE 754 behavior
const double dbl_inf = std::numeric_limits<double>::infinity();
EXPECT_TRUE(isinf(dbl_inf + dbl_inf));
EXPECT_TRUE(isnan(dbl_inf + -dbl_inf)); // We return inf
EXPECT_TRUE(isnan(-dbl_inf + dbl_inf)); // We return inf
EXPECT_TRUE(isinf(-dbl_inf + -dbl_inf));
}
TEST(Duration, InfinitySubtraction) {
const absl::Duration sec_max = absl::Seconds(kint64max);
const absl::Duration sec_min = absl::Seconds(kint64min);
const absl::Duration any_dur = absl::Seconds(1);
const absl::Duration inf = absl::InfiniteDuration();
// Subtraction
EXPECT_EQ(inf, inf - inf);
EXPECT_EQ(inf, inf - -inf);
EXPECT_EQ(-inf, -inf - inf);
EXPECT_EQ(-inf, -inf - -inf);
EXPECT_EQ(inf, inf - any_dur);
EXPECT_EQ(-inf, any_dur - inf);
EXPECT_EQ(-inf, -inf - any_dur);
EXPECT_EQ(inf, any_dur - -inf);
// Subtraction overflow/underflow
EXPECT_EQ(inf, sec_max - -absl::Seconds(1));
EXPECT_EQ(inf, sec_max - -sec_max);
EXPECT_EQ(-inf, sec_min - absl::Seconds(1));
EXPECT_EQ(-inf, sec_min - sec_max);
// Interesting case
absl::Duration almost_neg_inf = sec_min;
EXPECT_LT(-inf, almost_neg_inf);
almost_neg_inf -= -absl::Nanoseconds(1);
EXPECT_LT(-inf, almost_neg_inf);
// For reference: IEEE 754 behavior
const double dbl_inf = std::numeric_limits<double>::infinity();
EXPECT_TRUE(isnan(dbl_inf - dbl_inf)); // We return inf
EXPECT_TRUE(isinf(dbl_inf - -dbl_inf));
EXPECT_TRUE(isinf(-dbl_inf - dbl_inf));
EXPECT_TRUE(isnan(-dbl_inf - -dbl_inf)); // We return inf
}
TEST(Duration, InfinityMultiplication) {
const absl::Duration sec_max = absl::Seconds(kint64max);
const absl::Duration sec_min = absl::Seconds(kint64min);
const absl::Duration inf = absl::InfiniteDuration();
#define TEST_INF_MUL_WITH_TYPE(T) \
EXPECT_EQ(inf, inf * static_cast<T>(2)); \
EXPECT_EQ(-inf, inf * static_cast<T>(-2)); \
EXPECT_EQ(-inf, -inf * static_cast<T>(2)); \
EXPECT_EQ(inf, -inf * static_cast<T>(-2)); \
EXPECT_EQ(inf, inf * static_cast<T>(0)); \
EXPECT_EQ(-inf, -inf * static_cast<T>(0)); \
EXPECT_EQ(inf, sec_max * static_cast<T>(2)); \
EXPECT_EQ(inf, sec_min * static_cast<T>(-2)); \
EXPECT_EQ(inf, (sec_max / static_cast<T>(2)) * static_cast<T>(3)); \
EXPECT_EQ(-inf, sec_max * static_cast<T>(-2)); \
EXPECT_EQ(-inf, sec_min * static_cast<T>(2)); \
EXPECT_EQ(-inf, (sec_min / static_cast<T>(2)) * static_cast<T>(3));
TEST_INF_MUL_WITH_TYPE(int64_t); // NOLINT(readability/function)
TEST_INF_MUL_WITH_TYPE(double); // NOLINT(readability/function)
#undef TEST_INF_MUL_WITH_TYPE
const double dbl_inf = std::numeric_limits<double>::infinity();
EXPECT_EQ(inf, inf * dbl_inf);
EXPECT_EQ(-inf, -inf * dbl_inf);
EXPECT_EQ(-inf, inf * -dbl_inf);
EXPECT_EQ(inf, -inf * -dbl_inf);
const absl::Duration any_dur = absl::Seconds(1);
EXPECT_EQ(inf, any_dur * dbl_inf);
EXPECT_EQ(-inf, -any_dur * dbl_inf);
EXPECT_EQ(-inf, any_dur * -dbl_inf);
EXPECT_EQ(inf, -any_dur * -dbl_inf);
// Fixed-point multiplication will produce a finite value, whereas floating
// point fuzziness will overflow to inf.
EXPECT_NE(absl::InfiniteDuration(), absl::Seconds(1) * kint64max);
EXPECT_EQ(inf, absl::Seconds(1) * static_cast<double>(kint64max));
EXPECT_NE(-absl::InfiniteDuration(), absl::Seconds(1) * kint64min);
EXPECT_EQ(-inf, absl::Seconds(1) * static_cast<double>(kint64min));
// Note that sec_max * or / by 1.0 overflows to inf due to the 53-bit
// limitations of double.
EXPECT_NE(inf, sec_max);
EXPECT_NE(inf, sec_max / 1);
EXPECT_EQ(inf, sec_max / 1.0);
EXPECT_NE(inf, sec_max * 1);
EXPECT_EQ(inf, sec_max * 1.0);
}
TEST(Duration, InfinityDivision) {
const absl::Duration sec_max = absl::Seconds(kint64max);
const absl::Duration sec_min = absl::Seconds(kint64min);
const absl::Duration inf = absl::InfiniteDuration();
// Division of Duration by a double
#define TEST_INF_DIV_WITH_TYPE(T) \
EXPECT_EQ(inf, inf / static_cast<T>(2)); \
EXPECT_EQ(-inf, inf / static_cast<T>(-2)); \
EXPECT_EQ(-inf, -inf / static_cast<T>(2)); \
EXPECT_EQ(inf, -inf / static_cast<T>(-2));
TEST_INF_DIV_WITH_TYPE(int64_t); // NOLINT(readability/function)
TEST_INF_DIV_WITH_TYPE(double); // NOLINT(readability/function)
#undef TEST_INF_DIV_WITH_TYPE
// Division of Duration by a double overflow/underflow
EXPECT_EQ(inf, sec_max / 0.5);
EXPECT_EQ(inf, sec_min / -0.5);
EXPECT_EQ(inf, ((sec_max / 0.5) + absl::Seconds(1)) / 0.5);
EXPECT_EQ(-inf, sec_max / -0.5);
EXPECT_EQ(-inf, sec_min / 0.5);
EXPECT_EQ(-inf, ((sec_min / 0.5) - absl::Seconds(1)) / 0.5);
const double dbl_inf = std::numeric_limits<double>::infinity();
EXPECT_EQ(inf, inf / dbl_inf);
EXPECT_EQ(-inf, inf / -dbl_inf);
EXPECT_EQ(-inf, -inf / dbl_inf);
EXPECT_EQ(inf, -inf / -dbl_inf);
const absl::Duration any_dur = absl::Seconds(1);
EXPECT_EQ(absl::ZeroDuration(), any_dur / dbl_inf);
EXPECT_EQ(absl::ZeroDuration(), any_dur / -dbl_inf);
EXPECT_EQ(absl::ZeroDuration(), -any_dur / dbl_inf);
EXPECT_EQ(absl::ZeroDuration(), -any_dur / -dbl_inf);
}
TEST(Duration, InfinityModulus) {
const absl::Duration sec_max = absl::Seconds(kint64max);
const absl::Duration any_dur = absl::Seconds(1);
const absl::Duration inf = absl::InfiniteDuration();
EXPECT_EQ(inf, inf % inf);
EXPECT_EQ(inf, inf % -inf);
EXPECT_EQ(-inf, -inf % -inf);
EXPECT_EQ(-inf, -inf % inf);
EXPECT_EQ(any_dur, any_dur % inf);
EXPECT_EQ(any_dur, any_dur % -inf);
EXPECT_EQ(-any_dur, -any_dur % inf);
EXPECT_EQ(-any_dur, -any_dur % -inf);
EXPECT_EQ(inf, inf % -any_dur);
EXPECT_EQ(inf, inf % any_dur);
EXPECT_EQ(-inf, -inf % -any_dur);
EXPECT_EQ(-inf, -inf % any_dur);
// Remainder isn't affected by overflow.
EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Seconds(1));
EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Milliseconds(1));
EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Microseconds(1));
EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Nanoseconds(1));
EXPECT_EQ(absl::ZeroDuration(), sec_max % absl::Nanoseconds(1) / 4);
}
TEST(Duration, InfinityIDiv) {
const absl::Duration sec_max = absl::Seconds(kint64max);
const absl::Duration any_dur = absl::Seconds(1);
const absl::Duration inf = absl::InfiniteDuration();
const double dbl_inf = std::numeric_limits<double>::infinity();
// IDivDuration (int64_t return value + a remainer)
absl::Duration rem = absl::ZeroDuration();
EXPECT_EQ(kint64max, absl::IDivDuration(inf, inf, &rem));
EXPECT_EQ(inf, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(kint64max, absl::IDivDuration(-inf, -inf, &rem));
EXPECT_EQ(-inf, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(kint64max, absl::IDivDuration(inf, any_dur, &rem));
EXPECT_EQ(inf, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(0, absl::IDivDuration(any_dur, inf, &rem));
EXPECT_EQ(any_dur, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(kint64max, absl::IDivDuration(-inf, -any_dur, &rem));
EXPECT_EQ(-inf, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(0, absl::IDivDuration(-any_dur, -inf, &rem));
EXPECT_EQ(-any_dur, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(kint64min, absl::IDivDuration(-inf, inf, &rem));
EXPECT_EQ(-inf, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(kint64min, absl::IDivDuration(inf, -inf, &rem));
EXPECT_EQ(inf, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(kint64min, absl::IDivDuration(-inf, any_dur, &rem));
EXPECT_EQ(-inf, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(0, absl::IDivDuration(-any_dur, inf, &rem));
EXPECT_EQ(-any_dur, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(kint64min, absl::IDivDuration(inf, -any_dur, &rem));
EXPECT_EQ(inf, rem);
rem = absl::ZeroDuration();
EXPECT_EQ(0, absl::IDivDuration(any_dur, -inf, &rem));
EXPECT_EQ(any_dur, rem);
// IDivDuration overflow/underflow
rem = any_dur;
EXPECT_EQ(kint64max,
absl::IDivDuration(sec_max, absl::Nanoseconds(1) / 4, &rem));
EXPECT_EQ(sec_max - absl::Nanoseconds(kint64max) / 4, rem);
rem = any_dur;
EXPECT_EQ(kint64max,
absl::IDivDuration(sec_max, absl::Milliseconds(1), &rem));
EXPECT_EQ(sec_max - absl::Milliseconds(kint64max), rem);
rem = any_dur;
EXPECT_EQ(kint64max,
absl::IDivDuration(-sec_max, -absl::Milliseconds(1), &rem));
EXPECT_EQ(-sec_max + absl::Milliseconds(kint64max), rem);
rem = any_dur;
EXPECT_EQ(kint64min,
absl::IDivDuration(-sec_max, absl::Milliseconds(1), &rem));
EXPECT_EQ(-sec_max - absl::Milliseconds(kint64min), rem);
rem = any_dur;
EXPECT_EQ(kint64min,
absl::IDivDuration(sec_max, -absl::Milliseconds(1), &rem));
EXPECT_EQ(sec_max + absl::Milliseconds(kint64min), rem);
//
// operator/(Duration, Duration) is a wrapper for IDivDuration().
//
// IEEE 754 says inf / inf should be nan, but int64_t doesn't have
// nan so we'll return kint64max/kint64min instead.
EXPECT_TRUE(isnan(dbl_inf / dbl_inf));
EXPECT_EQ(kint64max, inf / inf);
EXPECT_EQ(kint64max, -inf / -inf);
EXPECT_EQ(kint64min, -inf / inf);
EXPECT_EQ(kint64min, inf / -inf);
EXPECT_TRUE(isinf(dbl_inf / 2.0));
EXPECT_EQ(kint64max, inf / any_dur);
EXPECT_EQ(kint64max, -inf / -any_dur);
EXPECT_EQ(kint64min, -inf / any_dur);
EXPECT_EQ(kint64min, inf / -any_dur);
EXPECT_EQ(0.0, 2.0 / dbl_inf);
EXPECT_EQ(0, any_dur / inf);
EXPECT_EQ(0, any_dur / -inf);
EXPECT_EQ(0, -any_dur / inf);
EXPECT_EQ(0, -any_dur / -inf);
EXPECT_EQ(0, absl::ZeroDuration() / inf);
// Division of Duration by a Duration overflow/underflow
EXPECT_EQ(kint64max, sec_max / absl::Milliseconds(1));
EXPECT_EQ(kint64max, -sec_max / -absl::Milliseconds(1));
EXPECT_EQ(kint64min, -sec_max / absl::Milliseconds(1));
EXPECT_EQ(kint64min, sec_max / -absl::Milliseconds(1));
}
TEST(Duration, InfinityFDiv) {
const absl::Duration any_dur = absl::Seconds(1);
const absl::Duration inf = absl::InfiniteDuration();
const double dbl_inf = std::numeric_limits<double>::infinity();
EXPECT_EQ(dbl_inf, absl::FDivDuration(inf, inf));
EXPECT_EQ(dbl_inf, absl::FDivDuration(-inf, -inf));
EXPECT_EQ(dbl_inf, absl::FDivDuration(inf, any_dur));
EXPECT_EQ(0.0, absl::FDivDuration(any_dur, inf));
EXPECT_EQ(dbl_inf, absl::FDivDuration(-inf, -any_dur));
EXPECT_EQ(0.0, absl::FDivDuration(-any_dur, -inf));
EXPECT_EQ(-dbl_inf, absl::FDivDuration(-inf, inf));
EXPECT_EQ(-dbl_inf, absl::FDivDuration(inf, -inf));
EXPECT_EQ(-dbl_inf, absl::FDivDuration(-inf, any_dur));
EXPECT_EQ(0.0, absl::FDivDuration(-any_dur, inf));
EXPECT_EQ(-dbl_inf, absl::FDivDuration(inf, -any_dur));
EXPECT_EQ(0.0, absl::FDivDuration(any_dur, -inf));
}
TEST(Duration, DivisionByZero) {
const absl::Duration zero = absl::ZeroDuration();
const absl::Duration inf = absl::InfiniteDuration();
const absl::Duration any_dur = absl::Seconds(1);
const double dbl_inf = std::numeric_limits<double>::infinity();
const double dbl_denorm = std::numeric_limits<double>::denorm_min();
// IEEE 754 behavior
double z = 0.0, two = 2.0;
EXPECT_TRUE(isinf(two / z));
EXPECT_TRUE(isnan(z / z)); // We'll return inf
// Operator/(Duration, double)
EXPECT_EQ(inf, zero / 0.0);
EXPECT_EQ(-inf, zero / -0.0);
EXPECT_EQ(inf, any_dur / 0.0);
EXPECT_EQ(-inf, any_dur / -0.0);
EXPECT_EQ(-inf, -any_dur / 0.0);
EXPECT_EQ(inf, -any_dur / -0.0);
// Tests dividing by a number very close to, but not quite zero.
EXPECT_EQ(zero, zero / dbl_denorm);
EXPECT_EQ(zero, zero / -dbl_denorm);
EXPECT_EQ(inf, any_dur / dbl_denorm);
EXPECT_EQ(-inf, any_dur / -dbl_denorm);
EXPECT_EQ(-inf, -any_dur / dbl_denorm);
EXPECT_EQ(inf, -any_dur / -dbl_denorm);
// IDiv
absl::Duration rem = zero;
EXPECT_EQ(kint64max, absl::IDivDuration(zero, zero, &rem));
EXPECT_EQ(inf, rem);
rem = zero;
EXPECT_EQ(kint64max, absl::IDivDuration(any_dur, zero, &rem));
EXPECT_EQ(inf, rem);
rem = zero;
EXPECT_EQ(kint64min, absl::IDivDuration(-any_dur, zero, &rem));
EXPECT_EQ(-inf, rem);
// Operator/(Duration, Duration)
EXPECT_EQ(kint64max, zero / zero);
EXPECT_EQ(kint64max, any_dur / zero);
EXPECT_EQ(kint64min, -any_dur / zero);
// FDiv
EXPECT_EQ(dbl_inf, absl::FDivDuration(zero, zero));
EXPECT_EQ(dbl_inf, absl::FDivDuration(any_dur, zero));
EXPECT_EQ(-dbl_inf, absl::FDivDuration(-any_dur, zero));
}
TEST(Duration, Range) {
const absl::Duration range = ApproxYears(100 * 1e9);
const absl::Duration range_future = range;
const absl::Duration range_past = -range;
EXPECT_LT(range_future, absl::InfiniteDuration());
EXPECT_GT(range_past, -absl::InfiniteDuration());
const absl::Duration full_range = range_future - range_past;
EXPECT_GT(full_range, absl::ZeroDuration());
EXPECT_LT(full_range, absl::InfiniteDuration());
const absl::Duration neg_full_range = range_past - range_future;
EXPECT_LT(neg_full_range, absl::ZeroDuration());
EXPECT_GT(neg_full_range, -absl::InfiniteDuration());
EXPECT_LT(neg_full_range, full_range);
EXPECT_EQ(neg_full_range, -full_range);
}
TEST(Duration, RelationalOperators) {
#define TEST_REL_OPS(UNIT) \
static_assert(UNIT(2) == UNIT(2), ""); \
static_assert(UNIT(1) != UNIT(2), ""); \
static_assert(UNIT(1) < UNIT(2), ""); \
static_assert(UNIT(3) > UNIT(2), ""); \
static_assert(UNIT(1) <= UNIT(2), ""); \
static_assert(UNIT(2) <= UNIT(2), ""); \
static_assert(UNIT(3) >= UNIT(2), ""); \
static_assert(UNIT(2) >= UNIT(2), "");
TEST_REL_OPS(absl::Nanoseconds);
TEST_REL_OPS(absl::Microseconds);
TEST_REL_OPS(absl::Milliseconds);
TEST_REL_OPS(absl::Seconds);
TEST_REL_OPS(absl::Minutes);
TEST_REL_OPS(absl::Hours);
#undef TEST_REL_OPS
}
TEST(Duration, Addition) {
#define TEST_ADD_OPS(UNIT) \
do { \
EXPECT_EQ(UNIT(2), UNIT(1) + UNIT(1)); \
EXPECT_EQ(UNIT(1), UNIT(2) - UNIT(1)); \
EXPECT_EQ(UNIT(0), UNIT(2) - UNIT(2)); \
EXPECT_EQ(UNIT(-1), UNIT(1) - UNIT(2)); \
EXPECT_EQ(UNIT(-2), UNIT(0) - UNIT(2)); \
EXPECT_EQ(UNIT(-2), UNIT(1) - UNIT(3)); \
absl::Duration a = UNIT(1); \
a += UNIT(1); \
EXPECT_EQ(UNIT(2), a); \
a -= UNIT(1); \
EXPECT_EQ(UNIT(1), a); \
} while (0)
TEST_ADD_OPS(absl::Nanoseconds);
TEST_ADD_OPS(absl::Microseconds);
TEST_ADD_OPS(absl::Milliseconds);
TEST_ADD_OPS(absl::Seconds);
TEST_ADD_OPS(absl::Minutes);
TEST_ADD_OPS(absl::Hours);
#undef TEST_ADD_OPS
EXPECT_EQ(absl::Seconds(2), absl::Seconds(3) - 2 * absl::Milliseconds(500));
EXPECT_EQ(absl::Seconds(2) + absl::Milliseconds(500),
absl::Seconds(3) - absl::Milliseconds(500));
EXPECT_EQ(absl::Seconds(1) + absl::Milliseconds(998),
absl::Milliseconds(999) + absl::Milliseconds(999));
EXPECT_EQ(absl::Milliseconds(-1),
absl::Milliseconds(998) - absl::Milliseconds(999));
// Tests fractions of a nanoseconds. These are implementation details only.
EXPECT_GT(absl::Nanoseconds(1), absl::Nanoseconds(1) / 2);
EXPECT_EQ(absl::Nanoseconds(1),
absl::Nanoseconds(1) / 2 + absl::Nanoseconds(1) / 2);
EXPECT_GT(absl::Nanoseconds(1) / 4, absl::Nanoseconds(0));
EXPECT_EQ(absl::Nanoseconds(1) / 8, absl::Nanoseconds(0));
// Tests subtraction that will cause wrap around of the rep_lo_ bits.
absl::Duration d_7_5 = absl::Seconds(7) + absl::Milliseconds(500);
absl::Duration d_3_7 = absl::Seconds(3) + absl::Milliseconds(700);
absl::Duration ans_3_8 = absl::Seconds(3) + absl::Milliseconds(800);
EXPECT_EQ(ans_3_8, d_7_5 - d_3_7);
// Subtracting min_duration
absl::Duration min_dur = absl::Seconds(kint64min);
EXPECT_EQ(absl::Seconds(0), min_dur - min_dur);
EXPECT_EQ(absl::Seconds(kint64max), absl::Seconds(-1) - min_dur);
}
TEST(Duration, Negation) {
// By storing negations of various values in constexpr variables we
// verify that the initializers are constant expressions.
constexpr absl::Duration negated_zero_duration = -absl::ZeroDuration();
EXPECT_EQ(negated_zero_duration, absl::ZeroDuration());
constexpr absl::Duration negated_infinite_duration =
-absl::InfiniteDuration();
EXPECT_NE(negated_infinite_duration, absl::InfiniteDuration());
EXPECT_EQ(-negated_infinite_duration, absl::InfiniteDuration());
// The public APIs to check if a duration is infinite depend on using
// -InfiniteDuration(), but we're trying to test operator- here, so we
// need to use the lower-level internal query IsInfiniteDuration.
EXPECT_TRUE(
absl::time_internal::IsInfiniteDuration(negated_infinite_duration));
// The largest Duration is kint64max seconds and kTicksPerSecond - 1 ticks.
// Using the absl::time_internal::MakeDuration API is the cleanest way to
// construct that Duration.
constexpr absl::Duration max_duration = absl::time_internal::MakeDuration(
kint64max, absl::time_internal::kTicksPerSecond - 1);
constexpr absl::Duration negated_max_duration = -max_duration;
// The largest negatable value is one tick above the minimum representable;
// it's the negation of max_duration.
constexpr absl::Duration nearly_min_duration =
absl::time_internal::MakeDuration(kint64min, int64_t{1});
constexpr absl::Duration negated_nearly_min_duration = -nearly_min_duration;
EXPECT_EQ(negated_max_duration, nearly_min_duration);
EXPECT_EQ(negated_nearly_min_duration, max_duration);
EXPECT_EQ(-(-max_duration), max_duration);
constexpr absl::Duration min_duration =
absl::time_internal::MakeDuration(kint64min);
constexpr absl::Duration negated_min_duration = -min_duration;
EXPECT_EQ(negated_min_duration, absl::InfiniteDuration());
}
TEST(Duration, AbsoluteValue) {
EXPECT_EQ(absl::ZeroDuration(), AbsDuration(absl::ZeroDuration()));
EXPECT_EQ(absl::Seconds(1), AbsDuration(absl::Seconds(1)));
EXPECT_EQ(absl::Seconds(1), AbsDuration(absl::Seconds(-1)));
EXPECT_EQ(absl::InfiniteDuration(), AbsDuration(absl::InfiniteDuration()));
EXPECT_EQ(absl::InfiniteDuration(), AbsDuration(-absl::InfiniteDuration()));
absl::Duration max_dur =
absl::Seconds(kint64max) + (absl::Seconds(1) - absl::Nanoseconds(1) / 4);
EXPECT_EQ(max_dur, AbsDuration(max_dur));
absl::Duration min_dur = absl::Seconds(kint64min);
EXPECT_EQ(absl::InfiniteDuration(), AbsDuration(min_dur));
EXPECT_EQ(max_dur, AbsDuration(min_dur + absl::Nanoseconds(1) / 4));
}
TEST(Duration, Multiplication) {
#define TEST_MUL_OPS(UNIT) \
do { \
EXPECT_EQ(UNIT(5), UNIT(2) * 2.5); \
EXPECT_EQ(UNIT(2), UNIT(5) / 2.5); \
EXPECT_EQ(UNIT(-5), UNIT(-2) * 2.5); \
EXPECT_EQ(UNIT(-5), -UNIT(2) * 2.5); \
EXPECT_EQ(UNIT(-5), UNIT(2) * -2.5); \
EXPECT_EQ(UNIT(-2), UNIT(-5) / 2.5); \
EXPECT_EQ(UNIT(-2), -UNIT(5) / 2.5); \
EXPECT_EQ(UNIT(-2), UNIT(5) / -2.5); \
EXPECT_EQ(UNIT(2), UNIT(11) % UNIT(3)); \
absl::Duration a = UNIT(2); \
a *= 2.5; \
EXPECT_EQ(UNIT(5), a); \
a /= 2.5; \
EXPECT_EQ(UNIT(2), a); \
a %= UNIT(1); \
EXPECT_EQ(UNIT(0), a); \
absl::Duration big = UNIT(1000000000); \
big *= 3; \
big /= 3; \
EXPECT_EQ(UNIT(1000000000), big); \
EXPECT_EQ(-UNIT(2), -UNIT(2)); \
EXPECT_EQ(-UNIT(2), UNIT(2) * -1); \
EXPECT_EQ(-UNIT(2), -1 * UNIT(2)); \
EXPECT_EQ(-UNIT(-2), UNIT(2)); \
EXPECT_EQ(2, UNIT(2) / UNIT(1)); \
absl::Duration rem; \
EXPECT_EQ(2, absl::IDivDuration(UNIT(2), UNIT(1), &rem)); \
EXPECT_EQ(2.0, absl::FDivDuration(UNIT(2), UNIT(1))); \
} while (0)
TEST_MUL_OPS(absl::Nanoseconds);
TEST_MUL_OPS(absl::Microseconds);
TEST_MUL_OPS(absl::Milliseconds);
TEST_MUL_OPS(absl::Seconds);
TEST_MUL_OPS(absl::Minutes);
TEST_MUL_OPS(absl::Hours);
#undef TEST_MUL_OPS
// Ensures that multiplication and division by 1 with a maxed-out durations
// doesn't lose precision.
absl::Duration max_dur =
absl::Seconds(kint64max) + (absl::Seconds(1) - absl::Nanoseconds(1) / 4);
absl::Duration min_dur = absl::Seconds(kint64min);
EXPECT_EQ(max_dur, max_dur * 1);
EXPECT_EQ(max_dur, max_dur / 1);
EXPECT_EQ(min_dur, min_dur * 1);
EXPECT_EQ(min_dur, min_dur / 1);
// Tests division on a Duration with a large number of significant digits.
// Tests when the digits span hi and lo as well as only in hi.
absl::Duration sigfigs = absl::Seconds(2000000000) + absl::Nanoseconds(3);
EXPECT_EQ(absl::Seconds(666666666) + absl::Nanoseconds(666666667) +
absl::Nanoseconds(1) / 2,
sigfigs / 3);
sigfigs = absl::Seconds(7000000000LL);
EXPECT_EQ(absl::Seconds(2333333333) + absl::Nanoseconds(333333333) +
absl::Nanoseconds(1) / 4,
sigfigs / 3);
EXPECT_EQ(absl::Seconds(7) + absl::Milliseconds(500), absl::Seconds(3) * 2.5);
EXPECT_EQ(absl::Seconds(8) * -1 + absl::Milliseconds(300),
(absl::Seconds(2) + absl::Milliseconds(200)) * -3.5);
EXPECT_EQ(-absl::Seconds(8) + absl::Milliseconds(300),
(absl::Seconds(2) + absl::Milliseconds(200)) * -3.5);
EXPECT_EQ(absl::Seconds(1) + absl::Milliseconds(875),
(absl::Seconds(7) + absl::Milliseconds(500)) / 4);
EXPECT_EQ(absl::Seconds(30),
(absl::Seconds(7) + absl::Milliseconds(500)) / 0.25);
EXPECT_EQ(absl::Seconds(3),
(absl::Seconds(7) + absl::Milliseconds(500)) / 2.5);
// Tests division remainder.
EXPECT_EQ(absl::Nanoseconds(0), absl::Nanoseconds(7) % absl::Nanoseconds(1));
EXPECT_EQ(absl::Nanoseconds(0), absl::Nanoseconds(0) % absl::Nanoseconds(10));
EXPECT_EQ(absl::Nanoseconds(2), absl::Nanoseconds(7) % absl::Nanoseconds(5));
EXPECT_EQ(absl::Nanoseconds(2), absl::Nanoseconds(2) % absl::Nanoseconds(5));
EXPECT_EQ(absl::Nanoseconds(1), absl::Nanoseconds(10) % absl::Nanoseconds(3));
EXPECT_EQ(absl::Nanoseconds(1),
absl::Nanoseconds(10) % absl::Nanoseconds(-3));
EXPECT_EQ(absl::Nanoseconds(-1),
absl::Nanoseconds(-10) % absl::Nanoseconds(3));
EXPECT_EQ(absl::Nanoseconds(-1),
absl::Nanoseconds(-10) % absl::Nanoseconds(-3));
EXPECT_EQ(absl::Milliseconds(100),
absl::Seconds(1) % absl::Milliseconds(300));
EXPECT_EQ(
absl::Milliseconds(300),
(absl::Seconds(3) + absl::Milliseconds(800)) % absl::Milliseconds(500));
EXPECT_EQ(absl::Nanoseconds(1), absl::Nanoseconds(1) % absl::Seconds(1));
EXPECT_EQ(absl::Nanoseconds(-1), absl::Nanoseconds(-1) % absl::Seconds(1));
EXPECT_EQ(0, absl::Nanoseconds(-1) / absl::Seconds(1)); // Actual -1e-9
// Tests identity a = (a/b)*b + a%b
#define TEST_MOD_IDENTITY(a, b) \
EXPECT_EQ((a), ((a) / (b))*(b) + ((a)%(b)))
TEST_MOD_IDENTITY(absl::Seconds(0), absl::Seconds(2));
TEST_MOD_IDENTITY(absl::Seconds(1), absl::Seconds(1));
TEST_MOD_IDENTITY(absl::Seconds(1), absl::Seconds(2));
TEST_MOD_IDENTITY(absl::Seconds(2), absl::Seconds(1));
TEST_MOD_IDENTITY(absl::Seconds(-2), absl::Seconds(1));
TEST_MOD_IDENTITY(absl::Seconds(2), absl::Seconds(-1));
TEST_MOD_IDENTITY(absl::Seconds(-2), absl::Seconds(-1));
TEST_MOD_IDENTITY(absl::Nanoseconds(0), absl::Nanoseconds(2));
TEST_MOD_IDENTITY(absl::Nanoseconds(1), absl::Nanoseconds(1));
TEST_MOD_IDENTITY(absl::Nanoseconds(1), absl::Nanoseconds(2));
TEST_MOD_IDENTITY(absl::Nanoseconds(2), absl::Nanoseconds(1));
TEST_MOD_IDENTITY(absl::Nanoseconds(-2), absl::Nanoseconds(1));
TEST_MOD_IDENTITY(absl::Nanoseconds(2), absl::Nanoseconds(-1));
TEST_MOD_IDENTITY(absl::Nanoseconds(-2), absl::Nanoseconds(-1));
// Mixed seconds + subseconds
absl::Duration mixed_a = absl::Seconds(1) + absl::Nanoseconds(2);
absl::Duration mixed_b = absl::Seconds(1) + absl::Nanoseconds(3);
TEST_MOD_IDENTITY(absl::Seconds(0), mixed_a);
TEST_MOD_IDENTITY(mixed_a, mixed_a);
TEST_MOD_IDENTITY(mixed_a, mixed_b);
TEST_MOD_IDENTITY(mixed_b, mixed_a);
TEST_MOD_IDENTITY(-mixed_a, mixed_b);
TEST_MOD_IDENTITY(mixed_a, -mixed_b);
TEST_MOD_IDENTITY(-mixed_a, -mixed_b);
#undef TEST_MOD_IDENTITY
}
TEST(Duration, Truncation) {
const absl::Duration d = absl::Nanoseconds(1234567890);
const absl::Duration inf = absl::InfiniteDuration();
for (int unit_sign : {1, -1}) { // sign shouldn't matter
EXPECT_EQ(absl::Nanoseconds(1234567890),
Trunc(d, unit_sign * absl::Nanoseconds(1)));
EXPECT_EQ(absl::Microseconds(1234567),
Trunc(d, unit_sign * absl::Microseconds(1)));
EXPECT_EQ(absl::Milliseconds(1234),
Trunc(d, unit_sign * absl::Milliseconds(1)));
EXPECT_EQ(absl::Seconds(1), Trunc(d, unit_sign * absl::Seconds(1)));
EXPECT_EQ(inf, Trunc(inf, unit_sign * absl::Seconds(1)));
EXPECT_EQ(absl::Nanoseconds(-1234567890),
Trunc(-d, unit_sign * absl::Nanoseconds(1)));
EXPECT_EQ(absl::Microseconds(-1234567),
Trunc(-d, unit_sign * absl::Microseconds(1)));
EXPECT_EQ(absl::Milliseconds(-1234),
Trunc(-d, unit_sign * absl::Milliseconds(1)));
EXPECT_EQ(absl::Seconds(-1), Trunc(-d, unit_sign * absl::Seconds(1)));
EXPECT_EQ(-inf, Trunc(-inf, unit_sign * absl::Seconds(1)));
}
}
TEST(Duration, Flooring) {
const absl::Duration d = absl::Nanoseconds(1234567890);
const absl::Duration inf = absl::InfiniteDuration();
for (int unit_sign : {1, -1}) { // sign shouldn't matter
EXPECT_EQ(absl::Nanoseconds(1234567890),
absl::Floor(d, unit_sign * absl::Nanoseconds(1)));
EXPECT_EQ(absl::Microseconds(1234567),
absl::Floor(d, unit_sign * absl::Microseconds(1)));
EXPECT_EQ(absl::Milliseconds(1234),
absl::Floor(d, unit_sign * absl::Milliseconds(1)));
EXPECT_EQ(absl::Seconds(1), absl::Floor(d, unit_sign * absl::Seconds(1)));
EXPECT_EQ(inf, absl::Floor(inf, unit_sign * absl::Seconds(1)));
EXPECT_EQ(absl::Nanoseconds(-1234567890),
absl::Floor(-d, unit_sign * absl::Nanoseconds(1)));
EXPECT_EQ(absl::Microseconds(-1234568),
absl::Floor(-d, unit_sign * absl::Microseconds(1)));
EXPECT_EQ(absl::Milliseconds(-1235),
absl::Floor(-d, unit_sign * absl::Milliseconds(1)));
EXPECT_EQ(absl::Seconds(-2), absl::Floor(-d, unit_sign * absl::Seconds(1)));
EXPECT_EQ(-inf, absl::Floor(-inf, unit_sign * absl::Seconds(1)));
}
}
TEST(Duration, Ceiling) {
const absl::Duration d = absl::Nanoseconds(1234567890);
const absl::Duration inf = absl::InfiniteDuration();
for (int unit_sign : {1, -1}) { // // sign shouldn't matter
EXPECT_EQ(absl::Nanoseconds(1234567890),
absl::Ceil(d, unit_sign * absl::Nanoseconds(1)));
EXPECT_EQ(absl::Microseconds(1234568),
absl::Ceil(d, unit_sign * absl::Microseconds(1)));
EXPECT_EQ(absl::Milliseconds(1235),
absl::Ceil(d, unit_sign * absl::Milliseconds(1)));
EXPECT_EQ(absl::Seconds(2), absl::Ceil(d, unit_sign * absl::Seconds(1)));
EXPECT_EQ(inf, absl::Ceil(inf, unit_sign * absl::Seconds(1)));
EXPECT_EQ(absl::Nanoseconds(-1234567890),
absl::Ceil(-d, unit_sign * absl::Nanoseconds(1)));
EXPECT_EQ(absl::Microseconds(-1234567),
absl::Ceil(-d, unit_sign * absl::Microseconds(1)));
EXPECT_EQ(absl::Milliseconds(-1234),
absl::Ceil(-d, unit_sign * absl::Milliseconds(1)));
EXPECT_EQ(absl::Seconds(-1), absl::Ceil(-d, unit_sign * absl::Seconds(1)));
EXPECT_EQ(-inf, absl::Ceil(-inf, unit_sign * absl::Seconds(1)));
}
}
TEST(Duration, RoundTripUnits) {
const int kRange = 100000;
#define ROUND_TRIP_UNIT(U, LOW, HIGH) \
do { \
for (int64_t i = LOW; i < HIGH; ++i) { \
absl::Duration d = absl::U(i); \
if (d == absl::InfiniteDuration()) \
EXPECT_EQ(kint64max, d / absl::U(1)); \
else if (d == -absl::InfiniteDuration()) \
EXPECT_EQ(kint64min, d / absl::U(1)); \
else \
EXPECT_EQ(i, absl::U(i) / absl::U(1)); \
} \
} while (0)
ROUND_TRIP_UNIT(Nanoseconds, kint64min, kint64min + kRange);
ROUND_TRIP_UNIT(Nanoseconds, -kRange, kRange);
ROUND_TRIP_UNIT(Nanoseconds, kint64max - kRange, kint64max);
ROUND_TRIP_UNIT(Microseconds, kint64min, kint64min + kRange);
ROUND_TRIP_UNIT(Microseconds, -kRange, kRange);
ROUND_TRIP_UNIT(Microseconds, kint64max - kRange, kint64max);
ROUND_TRIP_UNIT(Milliseconds, kint64min, kint64min + kRange);
ROUND_TRIP_UNIT(Milliseconds, -kRange, kRange);
ROUND_TRIP_UNIT(Milliseconds, kint64max - kRange, kint64max);
ROUND_TRIP_UNIT(Seconds, kint64min, kint64min + kRange);
ROUND_TRIP_UNIT(Seconds, -kRange, kRange);
ROUND_TRIP_UNIT(Seconds, kint64max - kRange, kint64max);
ROUND_TRIP_UNIT(Minutes, kint64min / 60, kint64min / 60 + kRange);
ROUND_TRIP_UNIT(Minutes, -kRange, kRange);
ROUND_TRIP_UNIT(Minutes, kint64max / 60 - kRange, kint64max / 60);
ROUND_TRIP_UNIT(Hours, kint64min / 3600, kint64min / 3600 + kRange);
ROUND_TRIP_UNIT(Hours, -kRange, kRange);
ROUND_TRIP_UNIT(Hours, kint64max / 3600 - kRange, kint64max / 3600);
#undef ROUND_TRIP_UNIT
}
TEST(Duration, TruncConversions) {
// Tests ToTimespec()/DurationFromTimespec()
const struct {
absl::Duration d;
timespec ts;
} to_ts[] = {
{absl::Seconds(1) + absl::Nanoseconds(1), {1, 1}},
{absl::Seconds(1) + absl::Nanoseconds(1) / 2, {1, 0}},
{absl::Seconds(1) + absl::Nanoseconds(0), {1, 0}},
{absl::Seconds(0) + absl::Nanoseconds(0), {0, 0}},
{absl::Seconds(0) - absl::Nanoseconds(1) / 2, {0, 0}},
{absl::Seconds(0) - absl::Nanoseconds(1), {-1, 999999999}},
{absl::Seconds(-1) + absl::Nanoseconds(1), {-1, 1}},
{absl::Seconds(-1) + absl::Nanoseconds(1) / 2, {-1, 1}},
{absl::Seconds(-1) + absl::Nanoseconds(0), {-1, 0}},
{absl::Seconds(-1) - absl::Nanoseconds(1) / 2, {-1, 0}},
};
for (const auto& test : to_ts) {
EXPECT_THAT(absl::ToTimespec(test.d), TimespecMatcher(test.ts));
}
const struct {
timespec ts;
absl::Duration d;
} from_ts[] = {
{{1, 1}, absl::Seconds(1) + absl::Nanoseconds(1)},
{{1, 0}, absl::Seconds(1) + absl::Nanoseconds(0)},
{{0, 0}, absl::Seconds(0) + absl::Nanoseconds(0)},
{{0, -1}, absl::Seconds(0) - absl::Nanoseconds(1)},
{{-1, 999999999}, absl::Seconds(0) - absl::Nanoseconds(1)},
{{-1, 1}, absl::Seconds(-1) + absl::Nanoseconds(1)},
{{-1, 0}, absl::Seconds(-1) + absl::Nanoseconds(0)},
{{-1, -1}, absl::Seconds(-1) - absl::Nanoseconds(1)},
{{-2, 999999999}, absl::Seconds(-1) - absl::Nanoseconds(1)},
};
for (const auto& test : from_ts) {
EXPECT_EQ(test.d, absl::DurationFromTimespec(test.ts));
}
// Tests ToTimeval()/DurationFromTimeval() (same as timespec above)
const struct {
absl::Duration d;
timeval tv;
} to_tv[] = {
{absl::Seconds(1) + absl::Microseconds(1), {1, 1}},
{absl::Seconds(1) + absl::Microseconds(1) / 2, {1, 0}},
{absl::Seconds(1) + absl::Microseconds(0), {1, 0}},
{absl::Seconds(0) + absl::Microseconds(0), {0, 0}},
{absl::Seconds(0) - absl::Microseconds(1) / 2, {0, 0}},
{absl::Seconds(0) - absl::Microseconds(1), {-1, 999999}},
{absl::Seconds(-1) + absl::Microseconds(1), {-1, 1}},
{absl::Seconds(-1) + absl::Microseconds(1) / 2, {-1, 1}},
{absl::Seconds(-1) + absl::Microseconds(0), {-1, 0}},
{absl::Seconds(-1) - absl::Microseconds(1) / 2, {-1, 0}},
};
for (const auto& test : to_tv) {
EXPECT_THAT(absl::ToTimeval(test.d), TimevalMatcher(test.tv));
}
const struct {
timeval tv;
absl::Duration d;
} from_tv[] = {
{{1, 1}, absl::Seconds(1) + absl::Microseconds(1)},
{{1, 0}, absl::Seconds(1) + absl::Microseconds(0)},
{{0, 0}, absl::Seconds(0) + absl::Microseconds(0)},
{{0, -1}, absl::Seconds(0) - absl::Microseconds(1)},
{{-1, 999999}, absl::Seconds(0) - absl::Microseconds(1)},
{{-1, 1}, absl::Seconds(-1) + absl::Microseconds(1)},
{{-1, 0}, absl::Seconds(-1) + absl::Microseconds(0)},
{{-1, -1}, absl::Seconds(-1) - absl::Microseconds(1)},
{{-2, 999999}, absl::Seconds(-1) - absl::Microseconds(1)},
};
for (const auto& test : from_tv) {
EXPECT_EQ(test.d, absl::DurationFromTimeval(test.tv));
}
}
TEST(Duration, SmallConversions) {
// Special tests for conversions of small durations.
EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(0));
// TODO(bww): Is the next one OK?
EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(0.124999999e-9));
EXPECT_EQ(absl::Nanoseconds(1) / 4, absl::Seconds(0.125e-9));
EXPECT_EQ(absl::Nanoseconds(1) / 4, absl::Seconds(0.250e-9));
EXPECT_EQ(absl::Nanoseconds(1) / 2, absl::Seconds(0.375e-9));
EXPECT_EQ(absl::Nanoseconds(1) / 2, absl::Seconds(0.500e-9));
EXPECT_EQ(absl::Nanoseconds(3) / 4, absl::Seconds(0.625e-9));
EXPECT_EQ(absl::Nanoseconds(3) / 4, absl::Seconds(0.750e-9));
EXPECT_EQ(absl::Nanoseconds(1), absl::Seconds(0.875e-9));
EXPECT_EQ(absl::Nanoseconds(1), absl::Seconds(1.000e-9));
timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 0;
EXPECT_THAT(ToTimespec(absl::Nanoseconds(0)), TimespecMatcher(ts));
// TODO(bww): Are the next three OK?
EXPECT_THAT(ToTimespec(absl::Nanoseconds(1) / 4), TimespecMatcher(ts));
EXPECT_THAT(ToTimespec(absl::Nanoseconds(2) / 4), TimespecMatcher(ts));
EXPECT_THAT(ToTimespec(absl::Nanoseconds(3) / 4), TimespecMatcher(ts));
ts.tv_nsec = 1;
EXPECT_THAT(ToTimespec(absl::Nanoseconds(4) / 4), TimespecMatcher(ts));
EXPECT_THAT(ToTimespec(absl::Nanoseconds(5) / 4), TimespecMatcher(ts));
EXPECT_THAT(ToTimespec(absl::Nanoseconds(6) / 4), TimespecMatcher(ts));
EXPECT_THAT(ToTimespec(absl::Nanoseconds(7) / 4), TimespecMatcher(ts));
ts.tv_nsec = 2;
EXPECT_THAT(ToTimespec(absl::Nanoseconds(8) / 4), TimespecMatcher(ts));
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
EXPECT_THAT(ToTimeval(absl::Nanoseconds(0)), TimevalMatcher(tv));
// TODO(bww): Is the next one OK?
EXPECT_THAT(ToTimeval(absl::Nanoseconds(999)), TimevalMatcher(tv));
tv.tv_usec = 1;
EXPECT_THAT(ToTimeval(absl::Nanoseconds(1000)), TimevalMatcher(tv));
EXPECT_THAT(ToTimeval(absl::Nanoseconds(1999)), TimevalMatcher(tv));
tv.tv_usec = 2;
EXPECT_THAT(ToTimeval(absl::Nanoseconds(2000)), TimevalMatcher(tv));
}
TEST(Duration, ConversionSaturation) {
absl::Duration d;
const auto max_timeval_sec =
std::numeric_limits<decltype(timeval::tv_sec)>::max();
const auto min_timeval_sec =
std::numeric_limits<decltype(timeval::tv_sec)>::min();
timeval tv;
tv.tv_sec = max_timeval_sec;
tv.tv_usec = 999998;
d = absl::DurationFromTimeval(tv);
tv = ToTimeval(d);
EXPECT_EQ(max_timeval_sec, tv.tv_sec);
EXPECT_EQ(999998, tv.tv_usec);
d += absl::Microseconds(1);
tv = ToTimeval(d);
EXPECT_EQ(max_timeval_sec, tv.tv_sec);
EXPECT_EQ(999999, tv.tv_usec);
d += absl::Microseconds(1); // no effect
tv = ToTimeval(d);
EXPECT_EQ(max_timeval_sec, tv.tv_sec);
EXPECT_EQ(999999, tv.tv_usec);
tv.tv_sec = min_timeval_sec;
tv.tv_usec = 1;
d = absl::DurationFromTimeval(tv);
tv = ToTimeval(d);
EXPECT_EQ(min_timeval_sec, tv.tv_sec);
EXPECT_EQ(1, tv.tv_usec);
d -= absl::Microseconds(1);
tv = ToTimeval(d);
EXPECT_EQ(min_timeval_sec, tv.tv_sec);
EXPECT_EQ(0, tv.tv_usec);
d -= absl::Microseconds(1); // no effect
tv = ToTimeval(d);
EXPECT_EQ(min_timeval_sec, tv.tv_sec);
EXPECT_EQ(0, tv.tv_usec);
const auto max_timespec_sec =
std::numeric_limits<decltype(timespec::tv_sec)>::max();
const auto min_timespec_sec =
std::numeric_limits<decltype(timespec::tv_sec)>::min();
timespec ts;
ts.tv_sec = max_timespec_sec;
ts.tv_nsec = 999999998;
d = absl::DurationFromTimespec(ts);
ts = absl::ToTimespec(d);
EXPECT_EQ(max_timespec_sec, ts.tv_sec);
EXPECT_EQ(999999998, ts.tv_nsec);
d += absl::Nanoseconds(1);
ts = absl::ToTimespec(d);
EXPECT_EQ(max_timespec_sec, ts.tv_sec);
EXPECT_EQ(999999999, ts.tv_nsec);
d += absl::Nanoseconds(1); // no effect
ts = absl::ToTimespec(d);
EXPECT_EQ(max_timespec_sec, ts.tv_sec);
EXPECT_EQ(999999999, ts.tv_nsec);
ts.tv_sec = min_timespec_sec;
ts.tv_nsec = 1;
d = absl::DurationFromTimespec(ts);
ts = absl::ToTimespec(d);
EXPECT_EQ(min_timespec_sec, ts.tv_sec);
EXPECT_EQ(1, ts.tv_nsec);
d -= absl::Nanoseconds(1);
ts = absl::ToTimespec(d);
EXPECT_EQ(min_timespec_sec, ts.tv_sec);
EXPECT_EQ(0, ts.tv_nsec);
d -= absl::Nanoseconds(1); // no effect
ts = absl::ToTimespec(d);
EXPECT_EQ(min_timespec_sec, ts.tv_sec);
EXPECT_EQ(0, ts.tv_nsec);
}
TEST(Duration, FormatDuration) {
// Example from Go's docs.
EXPECT_EQ("72h3m0.5s",
absl::FormatDuration(absl::Hours(72) + absl::Minutes(3) +
absl::Milliseconds(500)));
// Go's largest time: 2540400h10m10.000000000s
EXPECT_EQ("2540400h10m10s",
absl::FormatDuration(absl::Hours(2540400) + absl::Minutes(10) +
absl::Seconds(10)));
EXPECT_EQ("0", absl::FormatDuration(absl::ZeroDuration()));
EXPECT_EQ("0", absl::FormatDuration(absl::Seconds(0)));
EXPECT_EQ("0", absl::FormatDuration(absl::Nanoseconds(0)));
EXPECT_EQ("1ns", absl::FormatDuration(absl::Nanoseconds(1)));
EXPECT_EQ("1us", absl::FormatDuration(absl::Microseconds(1)));
EXPECT_EQ("1ms", absl::FormatDuration(absl::Milliseconds(1)));
EXPECT_EQ("1s", absl::FormatDuration(absl::Seconds(1)));
EXPECT_EQ("1m", absl::FormatDuration(absl::Minutes(1)));
EXPECT_EQ("1h", absl::FormatDuration(absl::Hours(1)));
EXPECT_EQ("1h1m", absl::FormatDuration(absl::Hours(1) + absl::Minutes(1)));
EXPECT_EQ("1h1s", absl::FormatDuration(absl::Hours(1) + absl::Seconds(1)));
EXPECT_EQ("1m1s", absl::FormatDuration(absl::Minutes(1) + absl::Seconds(1)));
EXPECT_EQ("1h0.25s",
absl::FormatDuration(absl::Hours(1) + absl::Milliseconds(250)));
EXPECT_EQ("1m0.25s",
absl::FormatDuration(absl::Minutes(1) + absl::Milliseconds(250)));
EXPECT_EQ("1h1m0.25s",
absl::FormatDuration(absl::Hours(1) + absl::Minutes(1) +
absl::Milliseconds(250)));
EXPECT_EQ("1h0.0005s",
absl::FormatDuration(absl::Hours(1) + absl::Microseconds(500)));
EXPECT_EQ("1h0.0000005s",
absl::FormatDuration(absl::Hours(1) + absl::Nanoseconds(500)));
// Subsecond special case.
EXPECT_EQ("1.5ns", absl::FormatDuration(absl::Nanoseconds(1) +
absl::Nanoseconds(1) / 2));
EXPECT_EQ("1.25ns", absl::FormatDuration(absl::Nanoseconds(1) +
absl::Nanoseconds(1) / 4));
EXPECT_EQ("1ns", absl::FormatDuration(absl::Nanoseconds(1) +
absl::Nanoseconds(1) / 9));
EXPECT_EQ("1.2us", absl::FormatDuration(absl::Microseconds(1) +
absl::Nanoseconds(200)));
EXPECT_EQ("1.2ms", absl::FormatDuration(absl::Milliseconds(1) +
absl::Microseconds(200)));
EXPECT_EQ("1.0002ms", absl::FormatDuration(absl::Milliseconds(1) +
absl::Nanoseconds(200)));
EXPECT_EQ("1.00001ms", absl::FormatDuration(absl::Milliseconds(1) +
absl::Nanoseconds(10)));
EXPECT_EQ("1.000001ms",
absl::FormatDuration(absl::Milliseconds(1) + absl::Nanoseconds(1)));
// Negative durations.
EXPECT_EQ("-1ns", absl::FormatDuration(absl::Nanoseconds(-1)));
EXPECT_EQ("-1us", absl::FormatDuration(absl::Microseconds(-1)));
EXPECT_EQ("-1ms", absl::FormatDuration(absl::Milliseconds(-1)));
EXPECT_EQ("-1s", absl::FormatDuration(absl::Seconds(-1)));
EXPECT_EQ("-1m", absl::FormatDuration(absl::Minutes(-1)));
EXPECT_EQ("-1h", absl::FormatDuration(absl::Hours(-1)));
EXPECT_EQ("-1h1m",
absl::FormatDuration(-(absl::Hours(1) + absl::Minutes(1))));
EXPECT_EQ("-1h1s",
absl::FormatDuration(-(absl::Hours(1) + absl::Seconds(1))));
EXPECT_EQ("-1m1s",
absl::FormatDuration(-(absl::Minutes(1) + absl::Seconds(1))));
EXPECT_EQ("-1ns", absl::FormatDuration(absl::Nanoseconds(-1)));
EXPECT_EQ("-1.2us", absl::FormatDuration(
-(absl::Microseconds(1) + absl::Nanoseconds(200))));
EXPECT_EQ("-1.2ms", absl::FormatDuration(
-(absl::Milliseconds(1) + absl::Microseconds(200))));
EXPECT_EQ("-1.0002ms", absl::FormatDuration(-(absl::Milliseconds(1) +
absl::Nanoseconds(200))));
EXPECT_EQ("-1.00001ms", absl::FormatDuration(-(absl::Milliseconds(1) +
absl::Nanoseconds(10))));
EXPECT_EQ("-1.000001ms", absl::FormatDuration(-(absl::Milliseconds(1) +
absl::Nanoseconds(1))));
//
// Interesting corner cases.
//
const absl::Duration qns = absl::Nanoseconds(1) / 4;
const absl::Duration max_dur =
absl::Seconds(kint64max) + (absl::Seconds(1) - qns);
const absl::Duration min_dur = absl::Seconds(kint64min);
EXPECT_EQ("0.25ns", absl::FormatDuration(qns));
EXPECT_EQ("-0.25ns", absl::FormatDuration(-qns));
EXPECT_EQ("2562047788015215h30m7.99999999975s",
absl::FormatDuration(max_dur));
EXPECT_EQ("-2562047788015215h30m8s", absl::FormatDuration(min_dur));
// Tests printing full precision from units that print using FDivDuration
EXPECT_EQ("55.00000000025s", absl::FormatDuration(absl::Seconds(55) + qns));
EXPECT_EQ("55.00000025ms",
absl::FormatDuration(absl::Milliseconds(55) + qns));
EXPECT_EQ("55.00025us", absl::FormatDuration(absl::Microseconds(55) + qns));
EXPECT_EQ("55.25ns", absl::FormatDuration(absl::Nanoseconds(55) + qns));
// Formatting infinity
EXPECT_EQ("inf", absl::FormatDuration(absl::InfiniteDuration()));
EXPECT_EQ("-inf", absl::FormatDuration(-absl::InfiniteDuration()));
// Formatting approximately +/- 100 billion years
const absl::Duration huge_range = ApproxYears(100000000000);
EXPECT_EQ("876000000000000h", absl::FormatDuration(huge_range));
EXPECT_EQ("-876000000000000h", absl::FormatDuration(-huge_range));
EXPECT_EQ("876000000000000h0.999999999s",
absl::FormatDuration(huge_range +
(absl::Seconds(1) - absl::Nanoseconds(1))));
EXPECT_EQ("876000000000000h0.9999999995s",
absl::FormatDuration(
huge_range + (absl::Seconds(1) - absl::Nanoseconds(1) / 2)));
EXPECT_EQ("876000000000000h0.99999999975s",
absl::FormatDuration(
huge_range + (absl::Seconds(1) - absl::Nanoseconds(1) / 4)));
EXPECT_EQ("-876000000000000h0.999999999s",
absl::FormatDuration(-huge_range -
(absl::Seconds(1) - absl::Nanoseconds(1))));
EXPECT_EQ("-876000000000000h0.9999999995s",
absl::FormatDuration(
-huge_range - (absl::Seconds(1) - absl::Nanoseconds(1) / 2)));
EXPECT_EQ("-876000000000000h0.99999999975s",
absl::FormatDuration(
-huge_range - (absl::Seconds(1) - absl::Nanoseconds(1) / 4)));
}
TEST(Duration, ParseDuration) {
absl::Duration d;
// No specified unit. Should only work for zero and infinity.
EXPECT_TRUE(absl::ParseDuration("0", &d));
EXPECT_EQ(absl::ZeroDuration(), d);
EXPECT_TRUE(absl::ParseDuration("+0", &d));
EXPECT_EQ(absl::ZeroDuration(), d);
EXPECT_TRUE(absl::ParseDuration("-0", &d));
EXPECT_EQ(absl::ZeroDuration(), d);
EXPECT_TRUE(absl::ParseDuration("inf", &d));
EXPECT_EQ(absl::InfiniteDuration(), d);
EXPECT_TRUE(absl::ParseDuration("+inf", &d));
EXPECT_EQ(absl::InfiniteDuration(), d);
EXPECT_TRUE(absl::ParseDuration("-inf", &d));
EXPECT_EQ(-absl::InfiniteDuration(), d);
EXPECT_FALSE(absl::ParseDuration("infBlah", &d));
// Illegal input forms.
EXPECT_FALSE(absl::ParseDuration("", &d));
EXPECT_FALSE(absl::ParseDuration("0.0", &d));
EXPECT_FALSE(absl::ParseDuration(".0", &d));
EXPECT_FALSE(absl::ParseDuration(".", &d));
EXPECT_FALSE(absl::ParseDuration("01", &d));
EXPECT_FALSE(absl::ParseDuration("1", &d));
EXPECT_FALSE(absl::ParseDuration("-1", &d));
EXPECT_FALSE(absl::ParseDuration("2", &d));
EXPECT_FALSE(absl::ParseDuration("2 s", &d));
EXPECT_FALSE(absl::ParseDuration(".s", &d));
EXPECT_FALSE(absl::ParseDuration("-.s", &d));
EXPECT_FALSE(absl::ParseDuration("s", &d));
EXPECT_FALSE(absl::ParseDuration(" 2s", &d));
EXPECT_FALSE(absl::ParseDuration("2s ", &d));
EXPECT_FALSE(absl::ParseDuration(" 2s ", &d));
EXPECT_FALSE(absl::ParseDuration("2mt", &d));
// One unit type.
EXPECT_TRUE(absl::ParseDuration("1ns", &d));
EXPECT_EQ(absl::Nanoseconds(1), d);
EXPECT_TRUE(absl::ParseDuration("1us", &d));
EXPECT_EQ(absl::Microseconds(1), d);
EXPECT_TRUE(absl::ParseDuration("1ms", &d));
EXPECT_EQ(absl::Milliseconds(1), d);
EXPECT_TRUE(absl::ParseDuration("1s", &d));
EXPECT_EQ(absl::Seconds(1), d);
EXPECT_TRUE(absl::ParseDuration("2m", &d));
EXPECT_EQ(absl::Minutes(2), d);
EXPECT_TRUE(absl::ParseDuration("2h", &d));
EXPECT_EQ(absl::Hours(2), d);
// Multiple units.
EXPECT_TRUE(absl::ParseDuration("2h3m4s", &d));
EXPECT_EQ(absl::Hours(2) + absl::Minutes(3) + absl::Seconds(4), d);
EXPECT_TRUE(absl::ParseDuration("3m4s5us", &d));
EXPECT_EQ(absl::Minutes(3) + absl::Seconds(4) + absl::Microseconds(5), d);
EXPECT_TRUE(absl::ParseDuration("2h3m4s5ms6us7ns", &d));
EXPECT_EQ(absl::Hours(2) + absl::Minutes(3) + absl::Seconds(4) +
absl::Milliseconds(5) + absl::Microseconds(6) +
absl::Nanoseconds(7),
d);
// Multiple units out of order.
EXPECT_TRUE(absl::ParseDuration("2us3m4s5h", &d));
EXPECT_EQ(absl::Hours(5) + absl::Minutes(3) + absl::Seconds(4) +
absl::Microseconds(2),
d);
// Fractional values of units.
EXPECT_TRUE(absl::ParseDuration("1.5ns", &d));
EXPECT_EQ(1.5 * absl::Nanoseconds(1), d);
EXPECT_TRUE(absl::ParseDuration("1.5us", &d));
EXPECT_EQ(1.5 * absl::Microseconds(1), d);
EXPECT_TRUE(absl::ParseDuration("1.5ms", &d));
EXPECT_EQ(1.5 * absl::Milliseconds(1), d);
EXPECT_TRUE(absl::ParseDuration("1.5s", &d));
EXPECT_EQ(1.5 * absl::Seconds(1), d);
EXPECT_TRUE(absl::ParseDuration("1.5m", &d));
EXPECT_EQ(1.5 * absl::Minutes(1), d);
EXPECT_TRUE(absl::ParseDuration("1.5h", &d));
EXPECT_EQ(1.5 * absl::Hours(1), d);
// Negative durations.
EXPECT_TRUE(absl::ParseDuration("-1s", &d));
EXPECT_EQ(absl::Seconds(-1), d);
EXPECT_TRUE(absl::ParseDuration("-1m", &d));
EXPECT_EQ(absl::Minutes(-1), d);
EXPECT_TRUE(absl::ParseDuration("-1h", &d));
EXPECT_EQ(absl::Hours(-1), d);
EXPECT_TRUE(absl::ParseDuration("-1h2s", &d));
EXPECT_EQ(-(absl::Hours(1) + absl::Seconds(2)), d);
EXPECT_FALSE(absl::ParseDuration("1h-2s", &d));
EXPECT_FALSE(absl::ParseDuration("-1h-2s", &d));
EXPECT_FALSE(absl::ParseDuration("-1h -2s", &d));
}
TEST(Duration, FormatParseRoundTrip) {
#define TEST_PARSE_ROUNDTRIP(d) \
do { \
std::string s = absl::FormatDuration(d); \
absl::Duration dur; \
EXPECT_TRUE(absl::ParseDuration(s, &dur)); \
EXPECT_EQ(d, dur); \
} while (0)
TEST_PARSE_ROUNDTRIP(absl::Nanoseconds(1));
TEST_PARSE_ROUNDTRIP(absl::Microseconds(1));
TEST_PARSE_ROUNDTRIP(absl::Milliseconds(1));
TEST_PARSE_ROUNDTRIP(absl::Seconds(1));
TEST_PARSE_ROUNDTRIP(absl::Minutes(1));
TEST_PARSE_ROUNDTRIP(absl::Hours(1));
TEST_PARSE_ROUNDTRIP(absl::Hours(1) + absl::Nanoseconds(2));
TEST_PARSE_ROUNDTRIP(absl::Nanoseconds(-1));
TEST_PARSE_ROUNDTRIP(absl::Microseconds(-1));
TEST_PARSE_ROUNDTRIP(absl::Milliseconds(-1));
TEST_PARSE_ROUNDTRIP(absl::Seconds(-1));
TEST_PARSE_ROUNDTRIP(absl::Minutes(-1));
TEST_PARSE_ROUNDTRIP(absl::Hours(-1));
TEST_PARSE_ROUNDTRIP(absl::Hours(-1) + absl::Nanoseconds(2));
TEST_PARSE_ROUNDTRIP(absl::Hours(1) + absl::Nanoseconds(-2));
TEST_PARSE_ROUNDTRIP(absl::Hours(-1) + absl::Nanoseconds(-2));
TEST_PARSE_ROUNDTRIP(absl::Nanoseconds(1) +
absl::Nanoseconds(1) / 4); // 1.25ns
const absl::Duration huge_range = ApproxYears(100000000000);
TEST_PARSE_ROUNDTRIP(huge_range);
TEST_PARSE_ROUNDTRIP(huge_range + (absl::Seconds(1) - absl::Nanoseconds(1)));
#undef TEST_PARSE_ROUNDTRIP
}
Changes imported from Abseil "staging" branch: - 06c8c67f5a564d00696e023060f05a5c34e7e164 IWYU | absl/base by Juemin Yang <jueminyang@google.com> - 2b1a054a09bda55843b449843b2a125741e936e7 Internal refactoring by Greg Miller <jgm@google.com> - f43f7f1f91bee26b5ddcd0c5bbbc47cb977aef77 Make std::hash<absl::optional<T>> to be standard compliant: by Xiaoyi Zhang <zhangxy@google.com> - 539bad2ebc22e610e1f292285a30a87945bc663e Update utility.h to Abseil standards by Tom Manshreck <shreck@google.com> - d05ec10a5f16a5d6640e0db91ecc7ab3ea971fd4 Add a test for absl::Barrier. by Derek Mauro <dmauro@google.com> - d707e27acb3c06f0d74c5f7ad7861e3841a5471f Run leak-checking tool over all outbound code. by Daniel Katz <katzdm@google.com> - 55f07f482a50422b8f99f7176374a19d0d473c5f Add alignas(16) to uint128. by Alex Strelnikov <strel@google.com> - 94999b7edde82308f736fb939501537ee9edbca6 Update attributes.h to Abseil standards by Tom Manshreck <shreck@google.com> - 321bed0061c41b53d0206ad4865528c00dd6d825 Test git merge + piper cl process by Juemin Yang <jueminyang@google.com> - 69920e7351a1053a7f4940bbde1768e839ce84bc Adds support for "/etc/localtime" as an embedded time zon... by Greg Miller <jgm@google.com> - 6839c06bf232903d3a9cbffa6eb2c960db78e67b Add copyright notices to inlined_vector code. by Greg Falcon <gfalcon@google.com> - 4e2714f6266263515cdfd31675c30c6ed6f98e1a Adding Apache 2.0 License by Gennadiy Civil <misterg@google.com> - 7402e7594016a4cd0a8b823fe6bc1bad1874bb85 IWYU | absl/utility by Juemin Yang <jueminyang@google.com> - 271a3812337eed97c412042738482688a80e19bd IWYU | absl/memory by Juemin Yang <jueminyang@google.com> - 32bda13a8098c2b06e25a5cf7bb782d6b79eb006 IWYU | absl/numeric by Juemin Yang <jueminyang@google.com> - 62d375cedc133108904bc06e340e303091a565df Remove "no_test"-annotations on span_test_noexceptions. by Daniel Katz <katzdm@google.com> - ebcbae9a55a93a7f1bb6862edc2715a6d9877206 Move CI-testing support files out of public-facing reposi... by Daniel Katz <katzdm@google.com> - d3f05eff4daa6030bfacb31cca0f9213fb702247 Fixes ToInt64Minutes() and ToInt64Hours() to properly sat... by Greg Miller <jgm@google.com> - b8dfae3facb6bb002622f083a10d14448f19e6e0 Fix typo. by Abseil Team <absl-team@google.com> - 150f03baa0afa231c2fc01597ea2321da586caba Update README.md by Yilei Yang <yileiyang@google.com> - 05276aa837dd081686518fd27bda4bd206ac4443 Adding Apache 2.0 License by Gennadiy Civil <misterg@google.com> - 37bf8e223e79ad06a195e28db9499e0c3d140f73 IWYU | absl/container by Juemin Yang <jueminyang@google.com> - 49164928f220978a32f88d16a55549bdf871daef IWYU | absl/algorithm by Juemin Yang <jueminyang@google.com> - a6804734e129039f9580a4fcd0f66425d0d0ac30 Move throw delegate wrappers to an internal namespace. by Greg Falcon <gfalcon@google.com> - ac83e73f67f593e2aff957b2be0b28e59c552a71 Fix error in comment stripping directives. by Greg Falcon <gfalcon@google.com> - e018a24185a984e787fb81a75fc35b74ad3a4d3d Update copyright headers all BUILD files by Gennadiy Civil <misterg@google.com> - a3be0990bfd76b0dec76bd85cecfa4dcec68b3ea Fix closing namespace comment typo. by Abseil Team <absl-team@google.com> - be3e3c4327e4f83949e0f29fd7a190d7eaa8b50b Update TODO by Abseil Team <absl-team@google.com> - f56a5d6f72685d92bb9c2905841b950d8177210c Add test-coverage for leak-sanitizer. by Daniel Katz <katzdm@google.com> - 7694bf161c7e00fdd08bfadc2aaf8e0fb09335f8 span.h: further touch up wording around the std::initiali... by Abseil Team <absl-team@google.com> - 3a12e081c0f8b359973e020d1e91f65356548ebc Update time.h to Abseil standards by Tom Manshreck <shreck@google.com> - 48d28f6468129420f4b20d451dca8e08012a7a77 Remove references to google from comments in Abseil. by Greg Falcon <gfalcon@google.com> - 773e34402d15fcad6370d5ed2430482d17db910d Rename the ExpectTime macro to match Abseil naming conven... by Greg Falcon <gfalcon@google.com> - 774d2ff1fe26c7313b301ff203e83e1aaac86627 Internal change. by Daniel Katz <katzdm@google.com> - 2e8a5830e95c8a1b839721bb2f1d4f5c85b9fb60 Fix typo in comment (missing '*' on a pointer). by Abseil Team <absl-team@google.com> - 458106feb707cf9609dd243713bde44aa9679e2a Correct capitalization: github -> GitHub by Yilei Yang <yileiyang@google.com> - af440725f02c2a83ca5cbaf176e1142f9e9d9b2f Update copyright headers by Gennadiy Civil <misterg@google.com> - 05b1118cce4ab87d23c33d48e64a96bcfec08761 Update copyright headers by Gennadiy Civil <misterg@google.com> - d5c6669a62d047156bb77055c5da03ee1b3c61b9 Update Abseil README to include descriptions of the inclu... by Tom Manshreck <shreck@google.com> - 3cd7e4663dddc840087469a6495f6cf433bfad8d Update copyright headers in //base by Tom Manshreck <shreck@google.com> - 7a876da657cd6698c5da2008a582d52eedc85dd1 Update strings overview with robust string library docume... by Tom Manshreck <shreck@google.com> - d9e3d0768d6f1c77d30992bdbef7b47ec92994bb Update copyright headers all BUILD files by Abseil Team <absl-team@google.com> - 6fe942728bceb0625f7c79b2840c4a6154d076b3 Make InlinedVector, FixedArray, and Span's at() throw on ... by Jon Cohen <cohenjon@google.com> - 5b52d5ec6cb9fbb07fc2e2fa020bd3eeb48c4953 Update clock.h to Abseil standards by Tom Manshreck <shreck@google.com> - c03c1ca3aee8bb7e40aa0315f6c432d31a72c30c Update //algorithm copyright headers by Tom Manshreck <shreck@google.com> - d46f40ddc596aaacb0459351d0e4aa6871289fa2 Temporarily prevent running mutex_test on crosstool17, wh... by Jon Cohen <cohenjon@google.com> - 61f11476189df68edfb9908308d677a91f03ff67 Update copyright headers in //container by Tom Manshreck <shreck@google.com> - 91832c00948954edf0b3dda12219c9a0202421ac Update copyright headers for //synchronization by Tom Manshreck <shreck@google.com> - 4e09100264b4585af6b4508ff35b9c627ac1f1ce Update copyright headers all BUILD files by Gennadiy Civil <misterg@google.com> - 13a0e8aebedec0f95b33750cbcd6b5548619b2a5 Update copyright headers in //memory by Tom Manshreck <shreck@google.com> - 63e1b9d4fdbcdf097e5276050ad1f76f0053e553 Update copyright headers for //strings (+ one from //nume... by Tom Manshreck <shreck@google.com> - 0108e7cfc50777a94c56d00e9c305161364df341 Convert ASSERT and EXPECT to ABSL_RAW_CHECK in helper fun... by Derek Mauro <dmauro@google.com> - 0122306fe47a3093248254a1b475c3a1d82abec5 Internal change by Abseil Team <absl-team@google.com> - 89c0c2698c98a12cd63172eeb02063b2f67e7c81 #absl Fix comment. by Abseil Team <absl-team@google.com> - 6621cc1ff54800e0aadb5e3071dbaa84b2077ceb Publishing contributing guidelines. by Gennadiy Civil <misterg@google.com> - e48c5be3c75e794b3e3827d40915b01fe1a1afc5 Avoid PRIdPTR. Cast to long long and use %lld insted. by Abseil Team <absl-team@google.com> - 2640ea4a260d89b94b07a3142660327e47db33fd No algorithmic changes. by Abseil Team <absl-team@google.com> - 1bc6c1bad17754f5d84963bf1d0db279402a0a1d Internal change. by Derek Mauro <dmauro@google.com> - 6845d24733e8c95bebde825ba78a2abfd9e35bdb span.h: fix up incorrect wording around lvalues. by Abseil Team <absl-team@google.com> - d8f5caee721e252e5f9b1080fb996363f498ac28 Add more exaustive Mutex testing. by Derek Mauro <dmauro@google.com> - e8b4cb053eb98858eef10cc53280b6ed5d6815a7 Change Span::subspan to not call into a deprecated constr... by Jon Cohen <cohenjon@google.com> - 49c36a82b3114926390557670aaaf0ea25b5760c s/std::size_t/size_t/g by Jon Cohen <cohenjon@google.com> - e17487c3c4d4a99f2fd8bc3e42176fc3171614d1 Account for the case of timeval::tv_sec being smaller than by Abseil Team <absl-team@google.com> - ecbb89d5fb98483e777c03d97ac02d7b7b54985e Alias absl::string_view to std::string_view when C++17 st... by Xiaoyi Zhang <zhangxy@google.com> - 6820e5a51459cdbb6a423cbae25a0cc839c85d44 Internal cleanup. by Xiaoyi Zhang <zhangxy@google.com> - 6976469b76a6faaf4111a24ddb37f40211ffadae More Span constexpr by Jon Cohen <cohenjon@google.com> - 8521c8956eee1125b7759eb272ec4a5a86fcefc5 #absl Fix comment. by Abseil Team <absl-team@google.com> - 20eae7a67fde5dd809aa47e5f7de8a493701645e Embed enough zoneinfo data to make time:time_test (under ... by Abseil Team <absl-team@google.com> - 841f5d98ceef4a423839ea73ee06c2f47a9b9680 Clean up macros in attributes.h | ATTRIBUTE_INITIAL_EXEC by Juemin Yang <jueminyang@google.com> - 83d8b36656e47919b5d0bac82eece897e195697e Update any.h comments to Abseil standards by Tom Manshreck <shreck@google.com> - bb3fae11d3459eeae2f63bfd22e65d3193187cc8 Update type_traits.h comments to Abseil standards by Tom Manshreck <shreck@google.com> - 992e1b07c0dec64271f8c44f22fd8df3734d0c47 Renamespace CycleClock code. by Greg Falcon <gfalcon@google.com> - 08d6fb0594098493ffbc0e737405182638122e7e Eliminate more existing lint warnings by Gennadiy Rozental <rogeeff@google.com> - 1cc6fdc71eb777497239f8c3e9168e6c9d40ea53 Update optional.h to Abseil standards by Tom Manshreck <shreck@google.com> - baa91747aa55009a9eb31b6072e33db06cfce2d2 Enforce internal namespace symbol reference policy by Gennadiy Rozental <rogeeff@google.com> - 939251e39342ce559e5d23fe43799671581f7cf5 Add CycleClock scaling shift to mitigate a possible overf... by Derek Mauro <dmauro@google.com> - c6dfdeecea0c7470938bed47c99ea2b2a95889d8 Add constexpr tests for absl::make_optional(). by Xiaoyi Zhang <zhangxy@google.com> - 509e949b992db33041d840746fbd05cc01cb206e Alias absl::optional to std::optional when C++17 std::opt... by Xiaoyi Zhang <zhangxy@google.com> - a1ae6d96a8826ba75281cac8632a766b5856acaf Remove no_test_* tags from span_test to increase test cov... by Xiaoyi Zhang <zhangxy@google.com> - 3c2a43cc09791723c8a324836629644ac44cb9c8 Remove accidental bits of Google-internal code and short ... by Greg Falcon <gfalcon@google.com> - 4874d49d496ac0b6ec36f4280a14b2159e7af930 Replaces the macro-generated Duration factory functions e... by Greg Miller <jgm@google.com> - 90e62695e03cb4a57e137ca0c3e116b1d802db57 Fix namespacing for a couple files in base/internal, and ... by Greg Falcon <gfalcon@google.com> - b0e6e00e34f967924849aaf8c123bba068f093e3 Publishing contributing guidelines. by Gennadiy Civil <misterg@google.com> - d74eafbccc3dffa6c25f9b6a2219425a24b5a959 Internal change by Abseil Team <absl-team@google.com> - 27477badbbf720265f5b9509b6c0e01913dc0a9f Update escaping.h comments to Abseil standards by Tom Manshreck <shreck@google.com> - 67002f55738319c2875197c3b6282de215ec250d adds absl namespace to debugging/stacktrace.h by Behzad Nouri <bnouri@google.com> - e608018f7faa384d5b202ac0a4c7a0d5166f4d9c Update string_view.h comments to Abseil standards by Tom Manshreck <shreck@google.com> - e884f04d4c648e01ed7dcde2fda80c24e8452047 Exclude strings/ files we are not releasing from OSS univ... by Gennadiy Rozental <rogeeff@google.com> - 3f4c4032ed520f2dd10a81d58ef4f399c001c5cc Strip out eventmanager reference from release. by Gennadiy Rozental <rogeeff@google.com> - fb0f1c204793c3792bad101dbaa734e7c2a35887 Fix copybara strip comments by Gennadiy Rozental <rogeeff@google.com> - 3eaaac942f77c3d41d63d414630403bfd0f6b70c Strip out style guide waivers. by Gennadiy Rozental <rogeeff@google.com> - 020e045058173178b51266b99a2a5dc9ed921960 substitute_test portability | MUST_USE_RESULT cast-to-voi... by Juemin Yang <jueminyang@google.com> - 86c093bf81d80ff537ed5e8b89225ce75a636220 Internal change. by Derek Mauro <dmauro@google.com> - 330375eb952fe78276e75631a28e750d5bfdb198 Prefer absl::FixedTimeZone() over loading "Etc/GMT[-+]<N>". by Abseil Team <absl-team@google.com> - 2e07ebee46a8201adc0dfd2c4ddb3df76e524357 Internal change. by Derek Mauro <dmauro@google.com> - 1f0c8b78c8ebd66f14cdf39fcba9f4c9986dcdca ::absl -> absl by Gennadiy Rozental <rogeeff@google.com> - ad163566d12ea08f1da2c23931eeacfffc564139 Avoid old style loops where possible. by Gennadiy Rozental <rogeeff@google.com> - bce2108818fe57b5617ce0090ddd4f753808f0a1 Update comments in str_cat.h in line with recent changes. by Abseil Team <absl-team@google.com> - cfd593a80f4897256f2ce1ea0be55dc14e3fcad4 Copybara-out gtl aliases. by Gennadiy Rozental <rogeeff@google.com> - 584f1524d717993c1a16093caccd9ed2b1e5409e Fix a warning for Windows/Kokoro time_test.cc. by Daniel Katz <katzdm@google.com> (And 562 more changes) GitOrigin-RevId: 06c8c67f5a564d00696e023060f05a5c34e7e164 Change-Id: I89907a6188fe7de05da400bf49ddfeba242aff8e
2017-09-20 02:15:26 +02:00
2017-09-19 22:54:40 +02:00
} // namespace