capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

time-test.c++ (5133B)


      1 // Copyright (c) 2019 Cloudflare, Inc. and contributors
      2 // Licensed under the MIT License:
      3 //
      4 // Permission is hereby granted, free of charge, to any person obtaining a copy
      5 // of this software and associated documentation files (the "Software"), to deal
      6 // in the Software without restriction, including without limitation the rights
      7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 // copies of the Software, and to permit persons to whom the Software is
      9 // furnished to do so, subject to the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included in
     12 // all copies or substantial portions of the Software.
     13 //
     14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 // THE SOFTWARE.
     21 
     22 #if _WIN32
     23 #include "win32-api-version.h"
     24 #endif
     25 
     26 #include "time.h"
     27 #include "debug.h"
     28 #include <kj/test.h>
     29 #include <time.h>
     30 
     31 #if _WIN32
     32 #include <windows.h>
     33 #include "windows-sanity.h"
     34 #else
     35 #include <unistd.h>
     36 #endif
     37 
     38 namespace kj {
     39 namespace {
     40 
     41 KJ_TEST("stringify times") {
     42   KJ_EXPECT(kj::str(50 * kj::SECONDS) == "50s");
     43   KJ_EXPECT(kj::str(5 * kj::SECONDS + 2 * kj::MILLISECONDS) == "5.002s");
     44   KJ_EXPECT(kj::str(256 * kj::MILLISECONDS) == "256ms");
     45   KJ_EXPECT(kj::str(5 * kj::MILLISECONDS + 2 * kj::NANOSECONDS) == "5.000002ms");
     46   KJ_EXPECT(kj::str(50 * kj::MICROSECONDS) == "50μs");
     47   KJ_EXPECT(kj::str(5 * kj::MICROSECONDS + 300 * kj::NANOSECONDS) == "5.3μs");
     48   KJ_EXPECT(kj::str(50 * kj::NANOSECONDS) == "50ns");
     49 }
     50 
     51 #if _WIN32
     52 void delay(kj::Duration d) {
     53   Sleep(d / kj::MILLISECONDS);
     54 }
     55 #else
     56 void delay(kj::Duration d) {
     57   usleep(d / kj::MICROSECONDS);
     58 }
     59 #endif
     60 
     61 KJ_TEST("calendar clocks matches unix time") {
     62   // Check that the times returned by the calendar clock are within 1s of what time() returns.
     63 
     64   auto& coarse = systemCoarseCalendarClock();
     65   auto& precise = systemPreciseCalendarClock();
     66 
     67   Date p = precise.now();
     68   Date c = coarse.now();
     69   time_t t = time(nullptr);
     70 
     71   int64_t pi = (p - UNIX_EPOCH) / kj::SECONDS;
     72   int64_t ci = (c - UNIX_EPOCH) / kj::SECONDS;
     73 
     74   KJ_EXPECT(pi >= t - 1);
     75   KJ_EXPECT(pi <= t + 1);
     76   KJ_EXPECT(ci >= t - 1);
     77   KJ_EXPECT(ci <= t + 1);
     78 }
     79 
     80 KJ_TEST("monotonic clocks match each other") {
     81   // Check that the monotonic clocks return comparable times.
     82 
     83   auto& coarse = systemCoarseMonotonicClock();
     84   auto& precise = systemPreciseMonotonicClock();
     85 
     86   TimePoint p = precise.now();
     87   TimePoint c = coarse.now();
     88 
     89   // 40ms tolerance due to Windows timeslices being quite long, especially on GitHub Actions where
     90   // Windows is drunk and has completely lost track of time.
     91   KJ_EXPECT(p < c + 40 * kj::MILLISECONDS, p - c);
     92   KJ_EXPECT(p > c - 40 * kj::MILLISECONDS, c - p);
     93 }
     94 
     95 KJ_TEST("all clocks advance in real time") {
     96   Duration coarseCalDiff;
     97   Duration preciseCalDiff;
     98   Duration coarseMonoDiff;
     99   Duration preciseMonoDiff;
    100 
    101   for (uint retryCount KJ_UNUSED: kj::zeroTo(20)) {
    102     auto& coarseCal = systemCoarseCalendarClock();
    103     auto& preciseCal = systemPreciseCalendarClock();
    104     auto& coarseMono = systemCoarseMonotonicClock();
    105     auto& preciseMono = systemPreciseMonotonicClock();
    106 
    107     Date coarseCalBefore = coarseCal.now();
    108     Date preciseCalBefore = preciseCal.now();
    109     TimePoint coarseMonoBefore = coarseMono.now();
    110     TimePoint preciseMonoBefore = preciseMono.now();
    111 
    112     Duration delayTime = 150 * kj::MILLISECONDS;
    113     delay(delayTime);
    114 
    115     Date coarseCalAfter = coarseCal.now();
    116     Date preciseCalAfter = preciseCal.now();
    117     TimePoint coarseMonoAfter = coarseMono.now();
    118     TimePoint preciseMonoAfter = preciseMono.now();
    119 
    120     coarseCalDiff = coarseCalAfter - coarseCalBefore;
    121     preciseCalDiff = preciseCalAfter - preciseCalBefore;
    122     coarseMonoDiff = coarseMonoAfter - coarseMonoBefore;
    123     preciseMonoDiff = preciseMonoAfter - preciseMonoBefore;
    124 
    125     // 20ms tolerance due to Windows timeslices being quite long (and Windows sleeps being only
    126     // accurate to the timeslice).
    127     if (coarseCalDiff > delayTime - 20 * kj::MILLISECONDS &&
    128         coarseCalDiff < delayTime + 20 * kj::MILLISECONDS &&
    129         preciseCalDiff > delayTime - 20 * kj::MILLISECONDS &&
    130         preciseCalDiff < delayTime + 20 * kj::MILLISECONDS &&
    131         coarseMonoDiff > delayTime - 20 * kj::MILLISECONDS &&
    132         coarseMonoDiff < delayTime + 20 * kj::MILLISECONDS &&
    133         preciseMonoDiff > delayTime - 20 * kj::MILLISECONDS &&
    134         preciseMonoDiff < delayTime + 20 * kj::MILLISECONDS) {
    135       // success
    136       return;
    137     }
    138   }
    139 
    140   KJ_FAIL_EXPECT("clocks seem inaccurate even after 20 tries",
    141       coarseCalDiff / kj::MICROSECONDS, preciseCalDiff / kj::MICROSECONDS,
    142       coarseMonoDiff / kj::MICROSECONDS, preciseMonoDiff / kj::MICROSECONDS);
    143 }
    144 
    145 }  // namespace
    146 }  // namespace kj