1 #include "common/ceph_argparse.h"
2 #include "common/ceph_mutex.h"
3 #include "common/Timer.h"
4 #include "global/global_init.h"
5 #include "include/Context.h"
12 * Tests the timer classes
14 #define MAX_TEST_CONTEXTS 5
22 int test_array
[MAX_TEST_CONTEXTS
];
24 TestContext
* test_contexts
[MAX_TEST_CONTEXTS
];
26 ceph::mutex array_lock
= ceph::make_mutex("test_timers_mutex");
29 class TestContext
: public Context
32 explicit TestContext(int num_
)
37 void finish(int r
) override
39 std::lock_guard locker
{array_lock
};
40 cout
<< "TestContext " << num
<< std::endl
;
41 test_array
[array_idx
++] = num
;
44 ~TestContext() override
52 class StrictOrderTestContext
: public TestContext
55 explicit StrictOrderTestContext (int num_
)
60 void finish(int r
) override
62 std::lock_guard locker
{array_lock
};
63 cout
<< "StrictOrderTestContext " << num
<< std::endl
;
64 test_array
[num
] = num
;
67 ~StrictOrderTestContext() override
72 static void print_status(const char *str
, int ret
)
75 cout
<< ((ret
== 0) ? "SUCCESS" : "FAILURE");
80 static int basic_timer_test(T
&timer
, ceph::mutex
*lock
)
83 memset(&test_array
, 0, sizeof(test_array
));
85 memset(&test_contexts
, 0, sizeof(test_contexts
));
87 cout
<< __PRETTY_FUNCTION__
<< std::endl
;
89 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
90 test_contexts
[i
] = new TestContext(i
);
94 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
97 auto t
= ceph::real_clock::now() + std::chrono::seconds(2 * i
);
98 timer
.add_event_at(t
, test_contexts
[i
]);
106 std::lock_guard locker
{array_lock
};
107 done
= (array_idx
== MAX_TEST_CONTEXTS
);
110 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
111 if (test_array
[i
] != i
) {
113 cout
<< "error: expected test_array[" << i
<< "] = " << i
114 << "; got " << test_array
[i
] << " instead." << std::endl
;
121 static int test_out_of_order_insertion(SafeTimer
&timer
, ceph::mutex
*lock
)
124 memset(&test_array
, 0, sizeof(test_array
));
126 memset(&test_contexts
, 0, sizeof(test_contexts
));
128 cout
<< __PRETTY_FUNCTION__
<< std::endl
;
130 test_contexts
[0] = new StrictOrderTestContext(0);
131 test_contexts
[1] = new StrictOrderTestContext(1);
134 auto t
= ceph::real_clock::now() + 100s
;
135 std::lock_guard locker
{*lock
};
136 timer
.add_event_at(t
, test_contexts
[0]);
140 auto t
= ceph::real_clock::now() + 2s
;
141 std::lock_guard locker
{*lock
};
142 timer
.add_event_at(t
, test_contexts
[1]);
146 for (; secs
< 100 ; ++secs
) {
149 int a
= test_array
[1];
157 cout
<< "error: expected test_array[" << 1 << "] = " << 1
158 << "; got " << test_array
[1] << " instead." << std::endl
;
164 static int safe_timer_cancel_all_test(SafeTimer
&safe_timer
,
165 ceph::mutex
& safe_timer_lock
)
167 cout
<< __PRETTY_FUNCTION__
<< std::endl
;
170 memset(&test_array
, 0, sizeof(test_array
));
172 memset(&test_contexts
, 0, sizeof(test_contexts
));
174 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
175 test_contexts
[i
] = new TestContext(i
);
178 safe_timer_lock
.lock();
179 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
180 auto t
= ceph::real_clock::now() + std::chrono::seconds(4 * i
);
181 safe_timer
.add_event_at(t
, test_contexts
[i
]);
183 safe_timer_lock
.unlock();
187 safe_timer_lock
.lock();
188 safe_timer
.cancel_all_events();
189 safe_timer_lock
.unlock();
191 for (int i
= 0; i
< array_idx
; ++i
) {
192 if (test_array
[i
] != i
) {
194 cout
<< "error: expected test_array[" << i
<< "] = " << i
195 << "; got " << test_array
[i
] << " instead." << std::endl
;
202 static int safe_timer_cancellation_test(SafeTimer
&safe_timer
,
203 ceph::mutex
& safe_timer_lock
)
205 cout
<< __PRETTY_FUNCTION__
<< std::endl
;
208 memset(&test_array
, 0, sizeof(test_array
));
210 memset(&test_contexts
, 0, sizeof(test_contexts
));
212 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
213 test_contexts
[i
] = new StrictOrderTestContext(i
);
216 safe_timer_lock
.lock();
217 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
218 auto t
= ceph::real_clock::now() + std::chrono::seconds(4 * i
);
219 safe_timer
.add_event_at(t
, test_contexts
[i
]);
221 safe_timer_lock
.unlock();
223 // cancel the even-numbered events
224 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; i
+= 2) {
225 safe_timer_lock
.lock();
226 safe_timer
.cancel_event(test_contexts
[i
]);
227 safe_timer_lock
.unlock();
232 safe_timer_lock
.lock();
233 safe_timer
.cancel_all_events();
234 safe_timer_lock
.unlock();
236 for (int i
= 1; i
< array_idx
; i
+= 2) {
237 if (test_array
[i
] != i
) {
239 cout
<< "error: expected test_array[" << i
<< "] = " << i
240 << "; got " << test_array
[i
] << " instead." << std::endl
;
247 int main(int argc
, const char **argv
)
249 auto args
= argv_to_vec(argc
, argv
);
251 auto cct
= global_init(nullptr, args
, CEPH_ENTITY_TYPE_CLIENT
,
252 CODE_ENVIRONMENT_UTILITY
,
253 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE
);
254 common_init_finish(g_ceph_context
);
257 ceph::mutex safe_timer_lock
= ceph::make_mutex("safe_timer_lock");
258 SafeTimer
safe_timer(g_ceph_context
, safe_timer_lock
);
261 ret
= basic_timer_test
<SafeTimer
>(safe_timer
, &safe_timer_lock
);
265 ret
= safe_timer_cancel_all_test(safe_timer
, safe_timer_lock
);
269 ret
= safe_timer_cancellation_test(safe_timer
, safe_timer_lock
);
273 ret
= test_out_of_order_insertion(safe_timer
, &safe_timer_lock
);
278 safe_timer
.shutdown();
279 print_status(argv
[0], ret
);