]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/tests/unit/lowres_clock_test.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / seastar / tests / unit / lowres_clock_test.cc
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>
26 #include <seastar/core/sleep.hh>
27 #include <seastar/core/loop.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 }