]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /* |
2 | * This file is open source software, licensed to you under the terms | |
3 | * of the Apache License, Version 2.0 (the "License"). See the NOTICE file | |
4 | * distributed with this work for additional information regarding copyright | |
5 | * ownership. You may not use this file except in compliance with the License. | |
6 | * | |
7 | * You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, | |
12 | * software distributed under the License is distributed on an | |
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
14 | * KIND, either express or implied. See the License for the | |
15 | * specific language governing permissions and limitations | |
16 | * under the License. | |
17 | */ | |
18 | /* | |
19 | * Copyright (C) 2017 ScyllaDB | |
20 | */ | |
21 | ||
22 | #include <seastar/testing/test_case.hh> | |
23 | ||
24 | #include <seastar/core/do_with.hh> | |
25 | #include <seastar/core/lowres_clock.hh> | |
9f95a23c | 26 | #include <seastar/core/reactor.hh> |
11fdf7f2 TL |
27 | #include <seastar/core/sleep.hh> |
28 | ||
29 | #include <ctime> | |
30 | ||
31 | #include <algorithm> | |
32 | #include <array> | |
33 | #include <chrono> | |
34 | ||
35 | using namespace seastar; | |
36 | ||
37 | // | |
38 | // Sanity check the accuracy of the steady low-resolution clock. | |
39 | // | |
40 | SEASTAR_TEST_CASE(steady_clock_sanity) { | |
41 | return do_with(lowres_clock::now(), [](auto &&t1) { | |
42 | static constexpr auto sleep_duration = std::chrono::milliseconds(100); | |
43 | ||
44 | return ::seastar::sleep(sleep_duration).then([&t1] { | |
45 | auto const elapsed = lowres_clock::now() - t1; | |
46 | auto const minimum_elapsed = 0.9 * sleep_duration; | |
47 | ||
48 | BOOST_REQUIRE(elapsed >= minimum_elapsed); | |
49 | ||
50 | return make_ready_future<>(); | |
51 | }); | |
52 | }); | |
53 | } | |
54 | ||
55 | // | |
56 | // At the very least, we can verify that the low-resolution system clock is within a second of the | |
57 | // high-resolution system clock. | |
58 | // | |
59 | SEASTAR_TEST_CASE(system_clock_sanity) { | |
60 | static const auto check_matching = [] { | |
61 | auto const system_time = std::chrono::system_clock::now(); | |
62 | auto const lowres_time = lowres_system_clock::now(); | |
63 | ||
64 | auto const t1 = std::chrono::system_clock::to_time_t(system_time); | |
65 | auto const t2 = lowres_system_clock::to_time_t(lowres_time); | |
66 | ||
67 | std::tm *lt1 = std::localtime(&t1); | |
68 | std::tm *lt2 = std::localtime(&t2); | |
69 | ||
70 | return (lt1->tm_isdst == lt2->tm_isdst) && | |
71 | (lt1->tm_year == lt2->tm_year) && | |
72 | (lt1->tm_mon == lt2->tm_mon) && | |
73 | (lt1->tm_yday == lt2->tm_yday) && | |
74 | (lt1->tm_mday == lt2->tm_mday) && | |
75 | (lt1->tm_wday == lt2->tm_wday) && | |
76 | (lt1->tm_hour == lt2->tm_hour) && | |
77 | (lt1->tm_min == lt2->tm_min) && | |
78 | (lt1->tm_sec == lt2->tm_sec); | |
79 | }; | |
80 | ||
81 | // | |
82 | // Check two out of three samples in order to account for the possibility that the high-resolution clock backing | |
83 | // the low-resoltuion clock was captured in the range of the 990th to 999th millisecond of the second. This would | |
84 | // make the low-resolution clock and the high-resolution clock disagree on the current second. | |
85 | // | |
86 | ||
87 | return do_with(0ul, 0ul, [](std::size_t& index, std::size_t& success_count) { | |
88 | return repeat([&index, &success_count] { | |
89 | if (index >= 3) { | |
90 | BOOST_REQUIRE_GE(success_count, 2u); | |
91 | return make_ready_future<stop_iteration>(stop_iteration::yes); | |
92 | } | |
93 | ||
94 | return ::seastar::sleep(std::chrono::milliseconds(10)).then([&index, &success_count] { | |
95 | if (check_matching()) { | |
96 | ++success_count; | |
97 | } | |
98 | ||
99 | ++index; | |
100 | return stop_iteration::no; | |
101 | }); | |
102 | }); | |
103 | }); | |
104 | } | |
105 | ||
106 | // | |
107 | // Verify that the low-resolution clock updates its reported time point over time. | |
108 | // | |
109 | SEASTAR_TEST_CASE(system_clock_dynamic) { | |
110 | return do_with(lowres_system_clock::now(), [](auto &&t1) { | |
111 | return seastar::sleep(std::chrono::milliseconds(100)).then([&t1] { | |
112 | auto const t2 = lowres_system_clock::now(); | |
113 | BOOST_REQUIRE_NE(t1.time_since_epoch().count(), t2.time_since_epoch().count()); | |
114 | ||
115 | return make_ready_future<>(); | |
116 | }); | |
117 | }); | |
118 | } |