tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

kernel_timeout_test.cc (16683B)


      1 // Copyright 2023 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/synchronization/internal/kernel_timeout.h"
     16 
     17 #include <ctime>
     18 #include <chrono>  // NOLINT(build/c++11)
     19 #include <limits>
     20 
     21 #include "absl/base/config.h"
     22 #include "absl/random/random.h"
     23 #include "absl/time/clock.h"
     24 #include "absl/time/time.h"
     25 #include "gtest/gtest.h"
     26 
     27 // Test go/btm support by randomizing the value of clock_gettime() for
     28 // CLOCK_MONOTONIC. This works by overriding a weak symbol in glibc.
     29 // We should be resistant to this randomization when !SupportsSteadyClock().
     30 #if defined(__GOOGLE_GRTE_VERSION__) &&      \
     31    !defined(ABSL_HAVE_ADDRESS_SANITIZER) && \
     32    !defined(ABSL_HAVE_MEMORY_SANITIZER) &&  \
     33    !defined(ABSL_HAVE_THREAD_SANITIZER)
     34 extern "C" int __clock_gettime(clockid_t c, struct timespec* ts);
     35 
     36 extern "C" int clock_gettime(clockid_t c, struct timespec* ts) {
     37  if (c == CLOCK_MONOTONIC &&
     38      !absl::synchronization_internal::KernelTimeout::SupportsSteadyClock()) {
     39    thread_local absl::BitGen gen;  // NOLINT
     40    ts->tv_sec = absl::Uniform(gen, 0, 1'000'000'000);
     41    ts->tv_nsec = absl::Uniform(gen, 0, 1'000'000'000);
     42    return 0;
     43  }
     44  return __clock_gettime(c, ts);
     45 }
     46 #endif
     47 
     48 namespace {
     49 
     50 #if defined(ABSL_HAVE_ADDRESS_SANITIZER) ||                        \
     51    defined(ABSL_HAVE_MEMORY_SANITIZER) ||                         \
     52    defined(ABSL_HAVE_THREAD_SANITIZER) || defined(__ANDROID__) || \
     53    defined(__APPLE__) || defined(_WIN32) || defined(_WIN64)
     54 constexpr absl::Duration kTimingBound = absl::Milliseconds(5);
     55 #else
     56 constexpr absl::Duration kTimingBound = absl::Microseconds(250);
     57 #endif
     58 
     59 using absl::synchronization_internal::KernelTimeout;
     60 
     61 // TODO(b/348224897): re-enabled when the flakiness is fixed.
     62 TEST(KernelTimeout, DISABLED_FiniteTimes) {
     63  constexpr absl::Duration kDurationsToTest[] = {
     64    absl::ZeroDuration(),
     65    absl::Nanoseconds(1),
     66    absl::Microseconds(1),
     67    absl::Milliseconds(1),
     68    absl::Seconds(1),
     69    absl::Minutes(1),
     70    absl::Hours(1),
     71    absl::Hours(1000),
     72    -absl::Nanoseconds(1),
     73    -absl::Microseconds(1),
     74    -absl::Milliseconds(1),
     75    -absl::Seconds(1),
     76    -absl::Minutes(1),
     77    -absl::Hours(1),
     78    -absl::Hours(1000),
     79  };
     80 
     81  for (auto duration : kDurationsToTest) {
     82    const absl::Time now = absl::Now();
     83    const absl::Time when = now + duration;
     84    SCOPED_TRACE(duration);
     85    KernelTimeout t(when);
     86    EXPECT_TRUE(t.has_timeout());
     87    EXPECT_TRUE(t.is_absolute_timeout());
     88    EXPECT_FALSE(t.is_relative_timeout());
     89    EXPECT_EQ(absl::TimeFromTimespec(t.MakeAbsTimespec()), when);
     90 #ifndef _WIN32
     91    EXPECT_LE(
     92        absl::AbsDuration(absl::Now() + duration -
     93                          absl::TimeFromTimespec(
     94                              t.MakeClockAbsoluteTimespec(CLOCK_REALTIME))),
     95        absl::Milliseconds(10));
     96 #endif
     97    EXPECT_LE(
     98        absl::AbsDuration(absl::DurationFromTimespec(t.MakeRelativeTimespec()) -
     99                          std::max(duration, absl::ZeroDuration())),
    100        kTimingBound);
    101    EXPECT_EQ(absl::FromUnixNanos(t.MakeAbsNanos()), when);
    102    EXPECT_LE(absl::AbsDuration(absl::Milliseconds(t.InMillisecondsFromNow()) -
    103                                std::max(duration, absl::ZeroDuration())),
    104              absl::Milliseconds(5));
    105    EXPECT_LE(absl::AbsDuration(absl::FromChrono(t.ToChronoTimePoint()) - when),
    106              absl::Microseconds(1));
    107    EXPECT_LE(absl::AbsDuration(absl::FromChrono(t.ToChronoDuration()) -
    108                                std::max(duration, absl::ZeroDuration())),
    109              kTimingBound);
    110  }
    111 }
    112 
    113 TEST(KernelTimeout, InfiniteFuture) {
    114  KernelTimeout t(absl::InfiniteFuture());
    115  EXPECT_FALSE(t.has_timeout());
    116  // Callers are expected to check has_timeout() instead of using the methods
    117  // below, but we do try to do something reasonable if they don't. We may not
    118  // be able to round-trip back to absl::InfiniteDuration() or
    119  // absl::InfiniteFuture(), but we should return a very large value.
    120  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
    121            absl::Now() + absl::Hours(100000));
    122 #ifndef _WIN32
    123  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
    124            absl::Now() + absl::Hours(100000));
    125 #endif
    126  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
    127            absl::Hours(100000));
    128  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
    129            absl::Now() + absl::Hours(100000));
    130  EXPECT_EQ(t.InMillisecondsFromNow(),
    131            std::numeric_limits<KernelTimeout::DWord>::max());
    132  EXPECT_EQ(t.ToChronoTimePoint(),
    133            std::chrono::time_point<std::chrono::system_clock>::max());
    134  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
    135 }
    136 
    137 TEST(KernelTimeout, DefaultConstructor) {
    138  // The default constructor is equivalent to absl::InfiniteFuture().
    139  KernelTimeout t;
    140  EXPECT_FALSE(t.has_timeout());
    141  // Callers are expected to check has_timeout() instead of using the methods
    142  // below, but we do try to do something reasonable if they don't. We may not
    143  // be able to round-trip back to absl::InfiniteDuration() or
    144  // absl::InfiniteFuture(), but we should return a very large value.
    145  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
    146            absl::Now() + absl::Hours(100000));
    147 #ifndef _WIN32
    148  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
    149            absl::Now() + absl::Hours(100000));
    150 #endif
    151  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
    152            absl::Hours(100000));
    153  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
    154            absl::Now() + absl::Hours(100000));
    155  EXPECT_EQ(t.InMillisecondsFromNow(),
    156            std::numeric_limits<KernelTimeout::DWord>::max());
    157  EXPECT_EQ(t.ToChronoTimePoint(),
    158            std::chrono::time_point<std::chrono::system_clock>::max());
    159  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
    160 }
    161 
    162 TEST(KernelTimeout, TimeMaxNanos) {
    163  // Time >= kMaxNanos should behave as no timeout.
    164  KernelTimeout t(absl::FromUnixNanos(std::numeric_limits<int64_t>::max()));
    165  EXPECT_FALSE(t.has_timeout());
    166  // Callers are expected to check has_timeout() instead of using the methods
    167  // below, but we do try to do something reasonable if they don't. We may not
    168  // be able to round-trip back to absl::InfiniteDuration() or
    169  // absl::InfiniteFuture(), but we should return a very large value.
    170  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
    171            absl::Now() + absl::Hours(100000));
    172 #ifndef _WIN32
    173  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
    174            absl::Now() + absl::Hours(100000));
    175 #endif
    176  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
    177            absl::Hours(100000));
    178  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
    179            absl::Now() + absl::Hours(100000));
    180  EXPECT_EQ(t.InMillisecondsFromNow(),
    181            std::numeric_limits<KernelTimeout::DWord>::max());
    182  EXPECT_EQ(t.ToChronoTimePoint(),
    183            std::chrono::time_point<std::chrono::system_clock>::max());
    184  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
    185 }
    186 
    187 TEST(KernelTimeout, Never) {
    188  // KernelTimeout::Never() is equivalent to absl::InfiniteFuture().
    189  KernelTimeout t = KernelTimeout::Never();
    190  EXPECT_FALSE(t.has_timeout());
    191  // Callers are expected to check has_timeout() instead of using the methods
    192  // below, but we do try to do something reasonable if they don't. We may not
    193  // be able to round-trip back to absl::InfiniteDuration() or
    194  // absl::InfiniteFuture(), but we should return a very large value.
    195  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
    196            absl::Now() + absl::Hours(100000));
    197 #ifndef _WIN32
    198  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
    199            absl::Now() + absl::Hours(100000));
    200 #endif
    201  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
    202            absl::Hours(100000));
    203  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
    204            absl::Now() + absl::Hours(100000));
    205  EXPECT_EQ(t.InMillisecondsFromNow(),
    206            std::numeric_limits<KernelTimeout::DWord>::max());
    207  EXPECT_EQ(t.ToChronoTimePoint(),
    208            std::chrono::time_point<std::chrono::system_clock>::max());
    209  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
    210 }
    211 
    212 TEST(KernelTimeout, InfinitePast) {
    213  KernelTimeout t(absl::InfinitePast());
    214  EXPECT_TRUE(t.has_timeout());
    215  EXPECT_TRUE(t.is_absolute_timeout());
    216  EXPECT_FALSE(t.is_relative_timeout());
    217  EXPECT_LE(absl::TimeFromTimespec(t.MakeAbsTimespec()),
    218            absl::FromUnixNanos(1));
    219 #ifndef _WIN32
    220  EXPECT_LE(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
    221            absl::FromUnixSeconds(1));
    222 #endif
    223  EXPECT_EQ(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
    224            absl::ZeroDuration());
    225  EXPECT_LE(absl::FromUnixNanos(t.MakeAbsNanos()), absl::FromUnixNanos(1));
    226  EXPECT_EQ(t.InMillisecondsFromNow(), KernelTimeout::DWord{0});
    227  EXPECT_LT(t.ToChronoTimePoint(), std::chrono::system_clock::from_time_t(0) +
    228                                       std::chrono::seconds(1));
    229  EXPECT_EQ(t.ToChronoDuration(), std::chrono::nanoseconds(0));
    230 }
    231 
    232 // TODO(b/348224897): re-enabled when the flakiness is fixed.
    233 TEST(KernelTimeout, DISABLED_FiniteDurations) {
    234  constexpr absl::Duration kDurationsToTest[] = {
    235    absl::ZeroDuration(),
    236    absl::Nanoseconds(1),
    237    absl::Microseconds(1),
    238    absl::Milliseconds(1),
    239    absl::Seconds(1),
    240    absl::Minutes(1),
    241    absl::Hours(1),
    242    absl::Hours(1000),
    243  };
    244 
    245  for (auto duration : kDurationsToTest) {
    246    SCOPED_TRACE(duration);
    247    KernelTimeout t(duration);
    248    EXPECT_TRUE(t.has_timeout());
    249    EXPECT_FALSE(t.is_absolute_timeout());
    250    EXPECT_TRUE(t.is_relative_timeout());
    251    EXPECT_LE(absl::AbsDuration(absl::Now() + duration -
    252                                absl::TimeFromTimespec(t.MakeAbsTimespec())),
    253              absl::Milliseconds(5));
    254 #ifndef _WIN32
    255    EXPECT_LE(
    256        absl::AbsDuration(absl::Now() + duration -
    257                          absl::TimeFromTimespec(
    258                              t.MakeClockAbsoluteTimespec(CLOCK_REALTIME))),
    259        absl::Milliseconds(5));
    260 #endif
    261    EXPECT_LE(
    262        absl::AbsDuration(absl::DurationFromTimespec(t.MakeRelativeTimespec()) -
    263                          duration),
    264        kTimingBound);
    265    EXPECT_LE(absl::AbsDuration(absl::Now() + duration -
    266                                absl::FromUnixNanos(t.MakeAbsNanos())),
    267              absl::Milliseconds(5));
    268    EXPECT_LE(absl::Milliseconds(t.InMillisecondsFromNow()) - duration,
    269              absl::Milliseconds(5));
    270    EXPECT_LE(absl::AbsDuration(absl::Now() + duration -
    271                                absl::FromChrono(t.ToChronoTimePoint())),
    272              kTimingBound);
    273    EXPECT_LE(
    274        absl::AbsDuration(absl::FromChrono(t.ToChronoDuration()) - duration),
    275        kTimingBound);
    276  }
    277 }
    278 
    279 // TODO(b/348224897): re-enabled when the flakiness is fixed.
    280 TEST(KernelTimeout, DISABLED_NegativeDurations) {
    281  constexpr absl::Duration kDurationsToTest[] = {
    282    -absl::ZeroDuration(),
    283    -absl::Nanoseconds(1),
    284    -absl::Microseconds(1),
    285    -absl::Milliseconds(1),
    286    -absl::Seconds(1),
    287    -absl::Minutes(1),
    288    -absl::Hours(1),
    289    -absl::Hours(1000),
    290    -absl::InfiniteDuration(),
    291  };
    292 
    293  for (auto duration : kDurationsToTest) {
    294    // Negative durations should all be converted to zero durations or "now".
    295    SCOPED_TRACE(duration);
    296    KernelTimeout t(duration);
    297    EXPECT_TRUE(t.has_timeout());
    298    EXPECT_FALSE(t.is_absolute_timeout());
    299    EXPECT_TRUE(t.is_relative_timeout());
    300    EXPECT_LE(absl::AbsDuration(absl::Now() -
    301                                absl::TimeFromTimespec(t.MakeAbsTimespec())),
    302              absl::Milliseconds(5));
    303 #ifndef _WIN32
    304    EXPECT_LE(absl::AbsDuration(absl::Now() - absl::TimeFromTimespec(
    305                                                  t.MakeClockAbsoluteTimespec(
    306                                                      CLOCK_REALTIME))),
    307              absl::Milliseconds(5));
    308 #endif
    309    EXPECT_EQ(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
    310              absl::ZeroDuration());
    311    EXPECT_LE(
    312        absl::AbsDuration(absl::Now() - absl::FromUnixNanos(t.MakeAbsNanos())),
    313        absl::Milliseconds(5));
    314    EXPECT_EQ(t.InMillisecondsFromNow(), KernelTimeout::DWord{0});
    315    EXPECT_LE(absl::AbsDuration(absl::Now() -
    316                                absl::FromChrono(t.ToChronoTimePoint())),
    317              absl::Milliseconds(5));
    318    EXPECT_EQ(t.ToChronoDuration(), std::chrono::nanoseconds(0));
    319  }
    320 }
    321 
    322 TEST(KernelTimeout, InfiniteDuration) {
    323  KernelTimeout t(absl::InfiniteDuration());
    324  EXPECT_FALSE(t.has_timeout());
    325  // Callers are expected to check has_timeout() instead of using the methods
    326  // below, but we do try to do something reasonable if they don't. We may not
    327  // be able to round-trip back to absl::InfiniteDuration() or
    328  // absl::InfiniteFuture(), but we should return a very large value.
    329  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
    330            absl::Now() + absl::Hours(100000));
    331 #ifndef _WIN32
    332  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
    333            absl::Now() + absl::Hours(100000));
    334 #endif
    335  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
    336            absl::Hours(100000));
    337  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
    338            absl::Now() + absl::Hours(100000));
    339  EXPECT_EQ(t.InMillisecondsFromNow(),
    340            std::numeric_limits<KernelTimeout::DWord>::max());
    341  EXPECT_EQ(t.ToChronoTimePoint(),
    342            std::chrono::time_point<std::chrono::system_clock>::max());
    343  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
    344 }
    345 
    346 TEST(KernelTimeout, DurationMaxNanos) {
    347  // Duration >= kMaxNanos should behave as no timeout.
    348  KernelTimeout t(absl::Nanoseconds(std::numeric_limits<int64_t>::max()));
    349  EXPECT_FALSE(t.has_timeout());
    350  // Callers are expected to check has_timeout() instead of using the methods
    351  // below, but we do try to do something reasonable if they don't. We may not
    352  // be able to round-trip back to absl::InfiniteDuration() or
    353  // absl::InfiniteFuture(), but we should return a very large value.
    354  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
    355            absl::Now() + absl::Hours(100000));
    356 #ifndef _WIN32
    357  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
    358            absl::Now() + absl::Hours(100000));
    359 #endif
    360  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
    361            absl::Hours(100000));
    362  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
    363            absl::Now() + absl::Hours(100000));
    364  EXPECT_EQ(t.InMillisecondsFromNow(),
    365            std::numeric_limits<KernelTimeout::DWord>::max());
    366  EXPECT_EQ(t.ToChronoTimePoint(),
    367            std::chrono::time_point<std::chrono::system_clock>::max());
    368  EXPECT_GE(t.ToChronoDuration(), std::chrono::nanoseconds::max());
    369 }
    370 
    371 TEST(KernelTimeout, OverflowNanos) {
    372  // Test what happens when KernelTimeout is constructed with an absl::Duration
    373  // that would overflow now_nanos + duration.
    374  int64_t now_nanos = absl::ToUnixNanos(absl::Now());
    375  int64_t limit = std::numeric_limits<int64_t>::max() - now_nanos;
    376  absl::Duration duration = absl::Nanoseconds(limit) + absl::Seconds(1);
    377  KernelTimeout t(duration);
    378  // Timeouts should still be far in the future.
    379  EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
    380            absl::Now() + absl::Hours(100000));
    381 #ifndef _WIN32
    382  EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
    383            absl::Now() + absl::Hours(100000));
    384 #endif
    385  EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
    386            absl::Hours(100000));
    387  EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
    388            absl::Now() + absl::Hours(100000));
    389  EXPECT_LE(absl::Milliseconds(t.InMillisecondsFromNow()) - duration,
    390            absl::Milliseconds(5));
    391  EXPECT_GT(t.ToChronoTimePoint(),
    392            std::chrono::system_clock::now() + std::chrono::hours(100000));
    393  EXPECT_GT(t.ToChronoDuration(), std::chrono::hours(100000));
    394 }
    395 
    396 }  // namespace