]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/tests/unit/lowres_clock_test.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / seastar / tests / unit / lowres_clock_test.cc
CommitLineData
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
35using namespace seastar;
36
37//
38// Sanity check the accuracy of the steady low-resolution clock.
39//
40SEASTAR_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//
59SEASTAR_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//
109SEASTAR_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}