xref: /aosp_15_r20/external/angle/third_party/abseil-cpp/absl/time/clock_test.cc (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 
TEST(Time,Now)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 
AlarmHandler(int signo)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.
SleepForBounded(absl::Duration d,absl::Duration lower_bound,absl::Duration upper_bound,absl::Duration timeout,AlarmPolicy alarm_policy,int * attempts)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 
AssertSleepForBounded(absl::Duration d,absl::Duration early,absl::Duration late,absl::Duration timeout,AlarmPolicy alarm_policy)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.
TEST(SleepFor,Bounded)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
123