]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/tests/unit/timer_test.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / seastar / tests / unit / timer_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) 2014 Cloudius Systems, Ltd.
20 */
21
22 #include <seastar/core/app-template.hh>
23 #include <seastar/core/timer.hh>
24 #include <seastar/core/reactor.hh>
25 #include <seastar/core/print.hh>
26 #include <seastar/core/thread.hh>
27 #include <seastar/core/sleep.hh>
28 #include <chrono>
29 #include <iostream>
30
31 using namespace seastar;
32 using namespace std::chrono_literals;
33
34 #define BUG() do { \
35 std::cerr << "ERROR @ " << __FILE__ << ":" << __LINE__ << std::endl; \
36 throw std::runtime_error("test failed"); \
37 } while (0)
38
39 #define OK() do { \
40 std::cerr << "OK @ " << __FILE__ << ":" << __LINE__ << std::endl; \
41 } while (0)
42
43 template <typename Clock>
44 struct timer_test {
45 timer<Clock> t1;
46 timer<Clock> t2;
47 timer<Clock> t3;
48 timer<Clock> t4;
49 timer<Clock> t5;
50 promise<> pr1;
51 promise<> pr2;
52
53 future<> run() {
54 t1.set_callback([this] {
55 OK();
56 fmt::print(" 500ms timer expired\n");
57 if (!t4.cancel()) {
58 BUG();
59 }
60 if (!t5.cancel()) {
61 BUG();
62 }
63 t5.arm(1100ms);
64 });
65 t2.set_callback([] { OK(); fmt::print(" 900ms timer expired\n"); });
66 t3.set_callback([] { OK(); fmt::print("1000ms timer expired\n"); });
67 t4.set_callback([] { OK(); fmt::print(" BAD cancelled timer expired\n"); });
68 t5.set_callback([this] { OK(); fmt::print("1600ms rearmed timer expired\n"); pr1.set_value(); });
69
70 t1.arm(500ms);
71 t2.arm(900ms);
72 t3.arm(1000ms);
73 t4.arm(700ms);
74 t5.arm(800ms);
75
76 return pr1.get_future().then([this] { return test_timer_cancelling(); }).then([this] {
77 return test_timer_with_scheduling_groups();
78 });
79 }
80
81 future<> test_timer_cancelling() {
82 timer<Clock>& t1 = *new timer<Clock>();
83 t1.set_callback([] { BUG(); });
84 t1.arm(100ms);
85 t1.cancel();
86
87 t1.arm(100ms);
88 t1.cancel();
89
90 t1.set_callback([this] { OK(); pr2.set_value(); });
91 t1.arm(100ms);
92 return pr2.get_future().then([&t1] { delete &t1; });
93 }
94
95 future<> test_timer_with_scheduling_groups() {
96 return async([] {
97 auto sg1 = create_scheduling_group("sg1", 100).get0();
98 auto sg2 = create_scheduling_group("sg2", 100).get0();
99 thread_attributes t1attr;
100 t1attr.sched_group = sg1;
101 auto expirations = 0;
102 async(t1attr, [&] {
103 auto make_callback_checking_sg = [&] (scheduling_group sg_to_check) {
104 return [sg_to_check, &expirations] {
105 ++expirations;
106 if (current_scheduling_group() != sg_to_check) {
107 BUG();
108 }
109 };
110 };
111 timer<Clock> t1(make_callback_checking_sg(sg1));
112 t1.arm(10ms);
113 timer<Clock> t2(sg2, make_callback_checking_sg(sg2));
114 t2.arm(10ms);
115 sleep(500ms).get();
116 if (expirations != 2) {
117 BUG();
118 }
119 OK();
120 }).get();
121 destroy_scheduling_group(sg1).get();
122 destroy_scheduling_group(sg2).get();
123 });
124 }
125 };
126
127 int main(int ac, char** av) {
128 app_template app;
129 timer_test<steady_clock_type> t1;
130 timer_test<lowres_clock> t2;
131 return app.run_deprecated(ac, av, [&t1, &t2] {
132 fmt::print("=== Start High res clock test\n");
133 return t1.run().then([&t2] {
134 fmt::print("=== Start Low res clock test\n");
135 return t2.run();
136 }).then([] {
137 fmt::print("Done\n");
138 engine().exit(0);
139 });
140 });
141 }