]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/TestTimers.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / test / TestTimers.cc
CommitLineData
7c673cae 1#include "common/ceph_argparse.h"
9f95a23c 2#include "common/ceph_mutex.h"
7c673cae
FG
3#include "common/Timer.h"
4#include "global/global_init.h"
9f95a23c 5#include "include/Context.h"
7c673cae
FG
6
7#include <iostream>
8
9/*
10 * TestTimers
11 *
12 * Tests the timer classes
13 */
14#define MAX_TEST_CONTEXTS 5
15
16class TestContext;
17
18namespace
19{
20 int test_array[MAX_TEST_CONTEXTS];
21 int array_idx;
22 TestContext* test_contexts[MAX_TEST_CONTEXTS];
23
9f95a23c 24 ceph::mutex array_lock = ceph::make_mutex("test_timers_mutex");
7c673cae
FG
25}
26
27class TestContext : public Context
28{
29public:
30 explicit TestContext(int num_)
31 : num(num_)
32 {
33 }
34
35 void finish(int r) override
36 {
9f95a23c 37 std::lock_guard locker{array_lock};
7c673cae
FG
38 cout << "TestContext " << num << std::endl;
39 test_array[array_idx++] = num;
7c673cae
FG
40 }
41
42 ~TestContext() override
43 {
44 }
45
46protected:
47 int num;
48};
49
50class StrictOrderTestContext : public TestContext
51{
52public:
53 explicit StrictOrderTestContext (int num_)
54 : TestContext(num_)
55 {
56 }
57
58 void finish(int r) override
59 {
9f95a23c 60 std::lock_guard locker{array_lock};
7c673cae
FG
61 cout << "StrictOrderTestContext " << num << std::endl;
62 test_array[num] = num;
7c673cae
FG
63 }
64
65 ~StrictOrderTestContext() override
66 {
67 }
68};
69
70static void print_status(const char *str, int ret)
71{
72 cout << str << ": ";
73 cout << ((ret == 0) ? "SUCCESS" : "FAILURE");
74 cout << std::endl;
75}
76
77template <typename T>
9f95a23c 78static int basic_timer_test(T &timer, ceph::mutex *lock)
7c673cae
FG
79{
80 int ret = 0;
81 memset(&test_array, 0, sizeof(test_array));
82 array_idx = 0;
83 memset(&test_contexts, 0, sizeof(test_contexts));
84
85 cout << __PRETTY_FUNCTION__ << std::endl;
86
87 for (int i = 0; i < MAX_TEST_CONTEXTS; ++i) {
88 test_contexts[i] = new TestContext(i);
89 }
90
91
92 for (int i = 0; i < MAX_TEST_CONTEXTS; ++i) {
93 if (lock)
9f95a23c
TL
94 lock->lock();
95 auto t = ceph::real_clock::now() + std::chrono::seconds(2 * i);
7c673cae
FG
96 timer.add_event_at(t, test_contexts[i]);
97 if (lock)
9f95a23c 98 lock->unlock();
7c673cae
FG
99 }
100
101 bool done = false;
102 do {
103 sleep(1);
9f95a23c 104 std::lock_guard locker{array_lock};
7c673cae 105 done = (array_idx == MAX_TEST_CONTEXTS);
7c673cae
FG
106 } while (!done);
107
108 for (int i = 0; i < MAX_TEST_CONTEXTS; ++i) {
109 if (test_array[i] != i) {
110 ret = 1;
111 cout << "error: expected test_array[" << i << "] = " << i
112 << "; got " << test_array[i] << " instead." << std::endl;
113 }
114 }
115
116 return ret;
117}
118
9f95a23c 119static int test_out_of_order_insertion(SafeTimer &timer, ceph::mutex *lock)
7c673cae
FG
120{
121 int ret = 0;
122 memset(&test_array, 0, sizeof(test_array));
123 array_idx = 0;
124 memset(&test_contexts, 0, sizeof(test_contexts));
125
126 cout << __PRETTY_FUNCTION__ << std::endl;
127
128 test_contexts[0] = new StrictOrderTestContext(0);
129 test_contexts[1] = new StrictOrderTestContext(1);
130
131 {
9f95a23c
TL
132 auto t = ceph::real_clock::now() + 100s;
133 std::lock_guard locker{*lock};
7c673cae 134 timer.add_event_at(t, test_contexts[0]);
7c673cae
FG
135 }
136
137 {
9f95a23c
TL
138 auto t = ceph::real_clock::now() + 2s;
139 std::lock_guard locker{*lock};
7c673cae 140 timer.add_event_at(t, test_contexts[1]);
7c673cae
FG
141 }
142
143 int secs = 0;
144 for (; secs < 100 ; ++secs) {
145 sleep(1);
9f95a23c 146 array_lock.lock();
7c673cae 147 int a = test_array[1];
9f95a23c 148 array_lock.unlock();
7c673cae
FG
149 if (a == 1)
150 break;
151 }
152
153 if (secs == 100) {
154 ret = 1;
155 cout << "error: expected test_array[" << 1 << "] = " << 1
156 << "; got " << test_array[1] << " instead." << std::endl;
157 }
158
159 return ret;
160}
161
9f95a23c
TL
162static int safe_timer_cancel_all_test(SafeTimer &safe_timer,
163 ceph::mutex& safe_timer_lock)
7c673cae
FG
164{
165 cout << __PRETTY_FUNCTION__ << std::endl;
166
167 int ret = 0;
168 memset(&test_array, 0, sizeof(test_array));
169 array_idx = 0;
170 memset(&test_contexts, 0, sizeof(test_contexts));
171
172 for (int i = 0; i < MAX_TEST_CONTEXTS; ++i) {
173 test_contexts[i] = new TestContext(i);
174 }
175
9f95a23c 176 safe_timer_lock.lock();
7c673cae 177 for (int i = 0; i < MAX_TEST_CONTEXTS; ++i) {
9f95a23c 178 auto t = ceph::real_clock::now() + std::chrono::seconds(4 * i);
7c673cae
FG
179 safe_timer.add_event_at(t, test_contexts[i]);
180 }
9f95a23c 181 safe_timer_lock.unlock();
7c673cae
FG
182
183 sleep(10);
184
9f95a23c 185 safe_timer_lock.lock();
7c673cae 186 safe_timer.cancel_all_events();
9f95a23c 187 safe_timer_lock.unlock();
7c673cae
FG
188
189 for (int i = 0; i < array_idx; ++i) {
190 if (test_array[i] != i) {
191 ret = 1;
192 cout << "error: expected test_array[" << i << "] = " << i
193 << "; got " << test_array[i] << " instead." << std::endl;
194 }
195 }
196
197 return ret;
198}
199
9f95a23c
TL
200static int safe_timer_cancellation_test(SafeTimer &safe_timer,
201 ceph::mutex& safe_timer_lock)
7c673cae
FG
202{
203 cout << __PRETTY_FUNCTION__ << std::endl;
204
205 int ret = 0;
206 memset(&test_array, 0, sizeof(test_array));
207 array_idx = 0;
208 memset(&test_contexts, 0, sizeof(test_contexts));
209
210 for (int i = 0; i < MAX_TEST_CONTEXTS; ++i) {
211 test_contexts[i] = new StrictOrderTestContext(i);
212 }
213
9f95a23c 214 safe_timer_lock.lock();
7c673cae 215 for (int i = 0; i < MAX_TEST_CONTEXTS; ++i) {
9f95a23c 216 auto t = ceph::real_clock::now() + std::chrono::seconds(4 * i);
7c673cae
FG
217 safe_timer.add_event_at(t, test_contexts[i]);
218 }
9f95a23c 219 safe_timer_lock.unlock();
7c673cae
FG
220
221 // cancel the even-numbered events
222 for (int i = 0; i < MAX_TEST_CONTEXTS; i += 2) {
9f95a23c 223 safe_timer_lock.lock();
7c673cae 224 safe_timer.cancel_event(test_contexts[i]);
9f95a23c 225 safe_timer_lock.unlock();
7c673cae
FG
226 }
227
228 sleep(20);
229
9f95a23c 230 safe_timer_lock.lock();
7c673cae 231 safe_timer.cancel_all_events();
9f95a23c 232 safe_timer_lock.unlock();
7c673cae
FG
233
234 for (int i = 1; i < array_idx; i += 2) {
235 if (test_array[i] != i) {
236 ret = 1;
237 cout << "error: expected test_array[" << i << "] = " << i
238 << "; got " << test_array[i] << " instead." << std::endl;
239 }
240 }
241
242 return ret;
243}
244
245int main(int argc, const char **argv)
246{
247 vector<const char*> args;
248 argv_to_vec(argc, argv, args);
7c673cae
FG
249
250 auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT,
11fdf7f2
TL
251 CODE_ENVIRONMENT_UTILITY,
252 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
7c673cae
FG
253 common_init_finish(g_ceph_context);
254
255 int ret;
9f95a23c 256 ceph::mutex safe_timer_lock = ceph::make_mutex("safe_timer_lock");
7c673cae
FG
257 SafeTimer safe_timer(g_ceph_context, safe_timer_lock);
258
259 ret = basic_timer_test <SafeTimer>(safe_timer, &safe_timer_lock);
260 if (ret)
261 goto done;
262
263 ret = safe_timer_cancel_all_test(safe_timer, safe_timer_lock);
264 if (ret)
265 goto done;
266
267 ret = safe_timer_cancellation_test(safe_timer, safe_timer_lock);
268 if (ret)
269 goto done;
270
271 ret = test_out_of_order_insertion(safe_timer, &safe_timer_lock);
272 if (ret)
273 goto done;
274
275done:
276 print_status(argv[0], ret);
277 return ret;
278}