| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 | // 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
 |