Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_chrono / system_clock_facade_test.cc
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // 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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include <chrono>
16
17 #include "gtest/gtest.h"
18 #include "pw_chrono/system_clock.h"
19 #include "pw_preprocessor/util.h"
20
21 using namespace std::chrono_literals;
22
23 namespace pw::chrono {
24 namespace {
25
26 extern "C" {
27
28 // Functions defined in system_clock_facade_test_c.c which call the API from C.
29 pw_chrono_SystemClock_TimePoint pw_chrono_SystemClock_CallNow();
30 pw_chrono_SystemClock_Duration pw_chrono_SystemClock_CallTimeElapsed(
31     pw_chrono_SystemClock_TimePoint last_time,
32     pw_chrono_SystemClock_TimePoint current_time);
33
34 pw_chrono_SystemClock_Nanoseconds pw_chrono_SystemClock_CallDurationToNsFloor(
35     pw_chrono_SystemClock_Duration ticks);
36
37 }  // extern "C"
38
39 // While testing that the clock ticks (i.e. moves forward) we want to ensure a
40 // failure can be reported instead of deadlocking the test until it passes.
41 // Given that there isn't really a good heuristic for this we instead make some
42 // wild assumptions to bound the maximum busy loop iterations.
43 // - Assume our clock is < 6Ghz
44 // - Assume we can check the clock in a single cycle
45 // - Wait for up to 1/10th of a second @ 6Ghz, this may be a long period on a
46 //   slower (i.e. real) machine.
47 constexpr uint64_t kMaxIterations = 6'000'000'000 / 10;
48
49 TEST(SystemClock, Now) {
50   const SystemClock::time_point start_time = SystemClock::now();
51   // Verify the clock moves forward.
52   bool clock_moved_forward = false;
53   for (uint64_t i = 0; i < kMaxIterations; ++i) {
54     if (SystemClock::now() > start_time) {
55       clock_moved_forward = true;
56       break;
57     }
58   }
59   EXPECT_TRUE(clock_moved_forward);
60 }
61
62 TEST(VirtualSystemClock, Now) {
63   auto& clock = VirtualSystemClock::RealClock();
64   const SystemClock::time_point start_time = clock.now();
65   // Verify the clock moves forward.
66   bool clock_moved_forward = false;
67   for (uint64_t i = 0; i < kMaxIterations; ++i) {
68     if (clock.now() > start_time) {
69       clock_moved_forward = true;
70       break;
71     }
72   }
73   EXPECT_TRUE(clock_moved_forward);
74 }
75
76 TEST(SystemClock, NowInC) {
77   const pw_chrono_SystemClock_TimePoint start_time =
78       pw_chrono_SystemClock_CallNow();
79   // Verify the clock moves forward.
80   bool clock_moved_forward = false;
81   for (uint64_t i = 0; i < kMaxIterations; ++i) {
82     if (pw_chrono_SystemClock_CallNow().duration_since_epoch.ticks >
83         start_time.duration_since_epoch.ticks) {
84       clock_moved_forward = true;
85       break;
86     }
87   }
88   EXPECT_TRUE(clock_moved_forward);
89 }
90
91 TEST(SystemClock, TimeElapsedInC) {
92   const pw_chrono_SystemClock_TimePoint first = pw_chrono_SystemClock_CallNow();
93   const pw_chrono_SystemClock_TimePoint last = pw_chrono_SystemClock_CallNow();
94   static_assert(SystemClock::is_monotonic);
95   EXPECT_GE(0, pw_chrono_SystemClock_CallTimeElapsed(last, first).ticks);
96 }
97
98 TEST(SystemClock, DurationCastInC) {
99   // We can't control the SystemClock's period configuration, so just in case
100   // 42 hours cannot be accurately expressed in integer ticks, round the
101   // duration w/ floor.
102   static constexpr auto kRoundedArbitraryDuration =
103       std::chrono::floor<SystemClock::duration>(42h);
104   static constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
105       PW_SYSTEM_CLOCK_H_FLOOR(42);
106   EXPECT_EQ(
107       std::chrono::floor<std::chrono::nanoseconds>(kRoundedArbitraryDuration)
108           .count(),
109       pw_chrono_SystemClock_CallDurationToNsFloor(
110           kRoundedArbitraryDurationInC));
111 }
112
113 }  // namespace
114 }  // namespace pw::chrono