clock_test.cc (4306B)
1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "absl/time/clock.h" 16 17 #include "absl/base/config.h" 18 #if defined(ABSL_HAVE_ALARM) 19 #include <signal.h> 20 #include <unistd.h> 21 #ifdef _AIX 22 // sig_t is not defined in AIX. 23 typedef void (*sig_t)(int); 24 #endif 25 #elif defined(__linux__) || defined(__APPLE__) 26 #error all known Linux and Apple targets have alarm 27 #endif 28 29 #include "gtest/gtest.h" 30 #include "absl/time/time.h" 31 32 namespace { 33 34 TEST(Time, Now) { 35 const absl::Time before = absl::FromUnixNanos(absl::GetCurrentTimeNanos()); 36 const absl::Time now = absl::Now(); 37 const absl::Time after = absl::FromUnixNanos(absl::GetCurrentTimeNanos()); 38 EXPECT_GE(now, before); 39 EXPECT_GE(after, now); 40 } 41 42 enum class AlarmPolicy { kWithoutAlarm, kWithAlarm }; 43 44 #if defined(ABSL_HAVE_ALARM) 45 bool alarm_handler_invoked = false; 46 47 void AlarmHandler(int signo) { 48 ASSERT_EQ(signo, SIGALRM); 49 alarm_handler_invoked = true; 50 } 51 #endif 52 53 // Does SleepFor(d) take between lower_bound and upper_bound at least 54 // once between now and (now + timeout)? If requested (and supported), 55 // add an alarm for the middle of the sleep period and expect it to fire. 56 bool SleepForBounded(absl::Duration d, absl::Duration lower_bound, 57 absl::Duration upper_bound, absl::Duration timeout, 58 AlarmPolicy alarm_policy, int* attempts) { 59 const absl::Time deadline = absl::Now() + timeout; 60 while (absl::Now() < deadline) { 61 #if defined(ABSL_HAVE_ALARM) 62 sig_t old_alarm = SIG_DFL; 63 if (alarm_policy == AlarmPolicy::kWithAlarm) { 64 alarm_handler_invoked = false; 65 old_alarm = signal(SIGALRM, AlarmHandler); 66 alarm(absl::ToInt64Seconds(d / 2)); 67 } 68 #else 69 EXPECT_EQ(alarm_policy, AlarmPolicy::kWithoutAlarm); 70 #endif 71 ++*attempts; 72 absl::Time start = absl::Now(); 73 absl::SleepFor(d); 74 absl::Duration actual = absl::Now() - start; 75 #if defined(ABSL_HAVE_ALARM) 76 if (alarm_policy == AlarmPolicy::kWithAlarm) { 77 signal(SIGALRM, old_alarm); 78 if (!alarm_handler_invoked) continue; 79 } 80 #endif 81 if (lower_bound <= actual && actual <= upper_bound) { 82 return true; // yes, the SleepFor() was correctly bounded 83 } 84 } 85 return false; 86 } 87 88 testing::AssertionResult AssertSleepForBounded(absl::Duration d, 89 absl::Duration early, 90 absl::Duration late, 91 absl::Duration timeout, 92 AlarmPolicy alarm_policy) { 93 const absl::Duration lower_bound = d - early; 94 const absl::Duration upper_bound = d + late; 95 int attempts = 0; 96 if (SleepForBounded(d, lower_bound, upper_bound, timeout, alarm_policy, 97 &attempts)) { 98 return testing::AssertionSuccess(); 99 } 100 return testing::AssertionFailure() 101 << "SleepFor(" << d << ") did not return within [" << lower_bound 102 << ":" << upper_bound << "] in " << attempts << " attempt" 103 << (attempts == 1 ? "" : "s") << " over " << timeout 104 << (alarm_policy == AlarmPolicy::kWithAlarm ? " with" : " without") 105 << " an alarm"; 106 } 107 108 // Tests that SleepFor() returns neither too early nor too late. 109 TEST(SleepFor, Bounded) { 110 const absl::Duration d = absl::Milliseconds(2500); 111 const absl::Duration early = absl::Milliseconds(100); 112 const absl::Duration late = absl::Milliseconds(300); 113 const absl::Duration timeout = 48 * d; 114 EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout, 115 AlarmPolicy::kWithoutAlarm)); 116 #if defined(ABSL_HAVE_ALARM) 117 EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout, 118 AlarmPolicy::kWithAlarm)); 119 #endif 120 } 121 122 } // namespace