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
20 int test_array
[MAX_TEST_CONTEXTS
];
22 TestContext
* test_contexts
[MAX_TEST_CONTEXTS
];
24 ceph::mutex array_lock
= ceph::make_mutex("test_timers_mutex");
27 class TestContext
: public Context
30 explicit TestContext(int num_
)
35 void finish(int r
) override
37 std::lock_guard locker
{array_lock
};
38 cout
<< "TestContext " << num
<< std::endl
;
39 test_array
[array_idx
++] = num
;
42 ~TestContext() override
50 class StrictOrderTestContext
: public TestContext
53 explicit StrictOrderTestContext (int num_
)
58 void finish(int r
) override
60 std::lock_guard locker
{array_lock
};
61 cout
<< "StrictOrderTestContext " << num
<< std::endl
;
62 test_array
[num
] = num
;
65 ~StrictOrderTestContext() override
70 static void print_status(const char *str
, int ret
)
73 cout
<< ((ret
== 0) ? "SUCCESS" : "FAILURE");
78 static int basic_timer_test(T
&timer
, ceph::mutex
*lock
)
81 memset(&test_array
, 0, sizeof(test_array
));
83 memset(&test_contexts
, 0, sizeof(test_contexts
));
85 cout
<< __PRETTY_FUNCTION__
<< std::endl
;
87 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
88 test_contexts
[i
] = new TestContext(i
);
92 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
95 auto t
= ceph::real_clock::now() + std::chrono::seconds(2 * i
);
96 timer
.add_event_at(t
, test_contexts
[i
]);
104 std::lock_guard locker
{array_lock
};
105 done
= (array_idx
== MAX_TEST_CONTEXTS
);
108 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
109 if (test_array
[i
] != i
) {
111 cout
<< "error: expected test_array[" << i
<< "] = " << i
112 << "; got " << test_array
[i
] << " instead." << std::endl
;
119 static int test_out_of_order_insertion(SafeTimer
&timer
, ceph::mutex
*lock
)
122 memset(&test_array
, 0, sizeof(test_array
));
124 memset(&test_contexts
, 0, sizeof(test_contexts
));
126 cout
<< __PRETTY_FUNCTION__
<< std::endl
;
128 test_contexts
[0] = new StrictOrderTestContext(0);
129 test_contexts
[1] = new StrictOrderTestContext(1);
132 auto t
= ceph::real_clock::now() + 100s
;
133 std::lock_guard locker
{*lock
};
134 timer
.add_event_at(t
, test_contexts
[0]);
138 auto t
= ceph::real_clock::now() + 2s
;
139 std::lock_guard locker
{*lock
};
140 timer
.add_event_at(t
, test_contexts
[1]);
144 for (; secs
< 100 ; ++secs
) {
147 int a
= test_array
[1];
155 cout
<< "error: expected test_array[" << 1 << "] = " << 1
156 << "; got " << test_array
[1] << " instead." << std::endl
;
162 static int safe_timer_cancel_all_test(SafeTimer
&safe_timer
,
163 ceph::mutex
& safe_timer_lock
)
165 cout
<< __PRETTY_FUNCTION__
<< std::endl
;
168 memset(&test_array
, 0, sizeof(test_array
));
170 memset(&test_contexts
, 0, sizeof(test_contexts
));
172 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
173 test_contexts
[i
] = new TestContext(i
);
176 safe_timer_lock
.lock();
177 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
178 auto t
= ceph::real_clock::now() + std::chrono::seconds(4 * i
);
179 safe_timer
.add_event_at(t
, test_contexts
[i
]);
181 safe_timer_lock
.unlock();
185 safe_timer_lock
.lock();
186 safe_timer
.cancel_all_events();
187 safe_timer_lock
.unlock();
189 for (int i
= 0; i
< array_idx
; ++i
) {
190 if (test_array
[i
] != i
) {
192 cout
<< "error: expected test_array[" << i
<< "] = " << i
193 << "; got " << test_array
[i
] << " instead." << std::endl
;
200 static int safe_timer_cancellation_test(SafeTimer
&safe_timer
,
201 ceph::mutex
& safe_timer_lock
)
203 cout
<< __PRETTY_FUNCTION__
<< std::endl
;
206 memset(&test_array
, 0, sizeof(test_array
));
208 memset(&test_contexts
, 0, sizeof(test_contexts
));
210 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
211 test_contexts
[i
] = new StrictOrderTestContext(i
);
214 safe_timer_lock
.lock();
215 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; ++i
) {
216 auto t
= ceph::real_clock::now() + std::chrono::seconds(4 * i
);
217 safe_timer
.add_event_at(t
, test_contexts
[i
]);
219 safe_timer_lock
.unlock();
221 // cancel the even-numbered events
222 for (int i
= 0; i
< MAX_TEST_CONTEXTS
; i
+= 2) {
223 safe_timer_lock
.lock();
224 safe_timer
.cancel_event(test_contexts
[i
]);
225 safe_timer_lock
.unlock();
230 safe_timer_lock
.lock();
231 safe_timer
.cancel_all_events();
232 safe_timer_lock
.unlock();
234 for (int i
= 1; i
< array_idx
; i
+= 2) {
235 if (test_array
[i
] != i
) {
237 cout
<< "error: expected test_array[" << i
<< "] = " << i
238 << "; got " << test_array
[i
] << " instead." << std::endl
;
245 int main(int argc
, const char **argv
)
247 vector
<const char*> args
;
248 argv_to_vec(argc
, argv
, args
);
250 auto cct
= global_init(NULL
, args
, CEPH_ENTITY_TYPE_CLIENT
,
251 CODE_ENVIRONMENT_UTILITY
,
252 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE
);
253 common_init_finish(g_ceph_context
);
256 ceph::mutex safe_timer_lock
= ceph::make_mutex("safe_timer_lock");
257 SafeTimer
safe_timer(g_ceph_context
, safe_timer_lock
);
260 ret
= basic_timer_test
<SafeTimer
>(safe_timer
, &safe_timer_lock
);
264 ret
= safe_timer_cancel_all_test(safe_timer
, safe_timer_lock
);
268 ret
= safe_timer_cancellation_test(safe_timer
, safe_timer_lock
);
272 ret
= test_out_of_order_insertion(safe_timer
, &safe_timer_lock
);
277 safe_timer
.shutdown();
278 print_status(argv
[0], ret
);