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