diff options
author | Vincent Ambo <tazjin@google.com> | 2020-05-20T01·32+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2020-05-20T01·32+0100 |
commit | fc8dc48020ac5b52731d0828a96ea4d2526c77ba (patch) | |
tree | 353204eea3268095a9ad3f5345720f32c2615c69 /third_party/abseil_cpp/absl/time/clock_test.cc | |
parent | ffb2ae54beb5796cd408fbe15d2d2da09ff37adf (diff) | |
parent | 768eb2ca2857342673fcd462792ce04b8bac3fa3 (diff) |
Add 'third_party/abseil_cpp/' from commit '768eb2ca2857342673fcd462792ce04b8bac3fa3' r/781
git-subtree-dir: third_party/abseil_cpp git-subtree-mainline: ffb2ae54beb5796cd408fbe15d2d2da09ff37adf git-subtree-split: 768eb2ca2857342673fcd462792ce04b8bac3fa3
Diffstat (limited to 'third_party/abseil_cpp/absl/time/clock_test.cc')
-rw-r--r-- | third_party/abseil_cpp/absl/time/clock_test.cc | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/third_party/abseil_cpp/absl/time/clock_test.cc b/third_party/abseil_cpp/absl/time/clock_test.cc new file mode 100644 index 000000000000..4bcfc6bc7272 --- /dev/null +++ b/third_party/abseil_cpp/absl/time/clock_test.cc @@ -0,0 +1,118 @@ +// 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 +// +// https://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 "absl/time/clock.h" + +#include "absl/base/config.h" +#if defined(ABSL_HAVE_ALARM) +#include <signal.h> +#include <unistd.h> +#elif defined(__linux__) || defined(__APPLE__) +#error all known Linux and Apple targets have alarm +#endif + +#include "gtest/gtest.h" +#include "absl/time/time.h" + +namespace { + +TEST(Time, Now) { + const absl::Time before = absl::FromUnixNanos(absl::GetCurrentTimeNanos()); + const absl::Time now = absl::Now(); + const absl::Time after = absl::FromUnixNanos(absl::GetCurrentTimeNanos()); + EXPECT_GE(now, before); + EXPECT_GE(after, now); +} + +enum class AlarmPolicy { kWithoutAlarm, kWithAlarm }; + +#if defined(ABSL_HAVE_ALARM) +bool alarm_handler_invoked = false; + +void AlarmHandler(int signo) { + ASSERT_EQ(signo, SIGALRM); + alarm_handler_invoked = true; +} +#endif + +// Does SleepFor(d) take between lower_bound and upper_bound at least +// once between now and (now + timeout)? If requested (and supported), +// add an alarm for the middle of the sleep period and expect it to fire. +bool SleepForBounded(absl::Duration d, absl::Duration lower_bound, + absl::Duration upper_bound, absl::Duration timeout, + AlarmPolicy alarm_policy, int* attempts) { + const absl::Time deadline = absl::Now() + timeout; + while (absl::Now() < deadline) { +#if defined(ABSL_HAVE_ALARM) + sig_t old_alarm = SIG_DFL; + if (alarm_policy == AlarmPolicy::kWithAlarm) { + alarm_handler_invoked = false; + old_alarm = signal(SIGALRM, AlarmHandler); + alarm(absl::ToInt64Seconds(d / 2)); + } +#else + EXPECT_EQ(alarm_policy, AlarmPolicy::kWithoutAlarm); +#endif + ++*attempts; + absl::Time start = absl::Now(); + absl::SleepFor(d); + absl::Duration actual = absl::Now() - start; +#if defined(ABSL_HAVE_ALARM) + if (alarm_policy == AlarmPolicy::kWithAlarm) { + signal(SIGALRM, old_alarm); + if (!alarm_handler_invoked) continue; + } +#endif + if (lower_bound <= actual && actual <= upper_bound) { + return true; // yes, the SleepFor() was correctly bounded + } + } + return false; +} + +testing::AssertionResult AssertSleepForBounded(absl::Duration d, + absl::Duration early, + absl::Duration late, + absl::Duration timeout, + AlarmPolicy alarm_policy) { + const absl::Duration lower_bound = d - early; + const absl::Duration upper_bound = d + late; + int attempts = 0; + if (SleepForBounded(d, lower_bound, upper_bound, timeout, alarm_policy, + &attempts)) { + return testing::AssertionSuccess(); + } + return testing::AssertionFailure() + << "SleepFor(" << d << ") did not return within [" << lower_bound + << ":" << upper_bound << "] in " << attempts << " attempt" + << (attempts == 1 ? "" : "s") << " over " << timeout + << (alarm_policy == AlarmPolicy::kWithAlarm ? " with" : " without") + << " an alarm"; +} + +// Tests that SleepFor() returns neither too early nor too late. +TEST(SleepFor, Bounded) { + const absl::Duration d = absl::Milliseconds(2500); + const absl::Duration early = absl::Milliseconds(100); + const absl::Duration late = absl::Milliseconds(300); + const absl::Duration timeout = 48 * d; + EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout, + AlarmPolicy::kWithoutAlarm)); +#if defined(ABSL_HAVE_ALARM) + EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout, + AlarmPolicy::kWithAlarm)); +#endif +} + +} // namespace |