21 #define BOOST_TEST_MODULE libjmmcg_tests
22 #include <boost/test/included/unit_test.hpp>
24 #include <boost/mpl/list.hpp>
26 #include "core/thread_wrapper.hpp"
30 using namespace libjmmcg;
37 template<
bool exit_val,
class Mdl>
38 struct thread_wrapper
final :
public ppd::wrapper<ppd::platform_api, Mdl> {
47 this->exit_requested=
true;
48 base_t::wait_thread_exit();
60 BOOST_AUTO_TEST_SUITE(thread_wrapper_tests)
62 BOOST_AUTO_TEST_SUITE(generic)
64 BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor, Mdl, thread_types) {
65 typedef thread_wrapper<
true,Mdl> run_and_exit;
68 BOOST_CHECK_EQUAL(thr.i,0U);
71 BOOST_AUTO_TEST_CASE_TEMPLATE(start_thread, Mdl, thread_types) {
72 typedef thread_wrapper<
true,Mdl> run_and_exit;
75 BOOST_CHECK_EQUAL(thr.i,0U);
76 BOOST_CHECK_NO_THROW(thr.create_running());
77 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
78 BOOST_CHECK_GT(thr.i,0U);
81 BOOST_AUTO_TEST_CASE_TEMPLATE(create_suspended, Mdl, thread_types) {
82 typedef thread_wrapper<
true,Mdl> run_and_exit;
85 BOOST_CHECK_EQUAL(thr.i,0U);
87 BOOST_CHECK_EQUAL(thr.i,0U);
90 BOOST_AUTO_TEST_CASE_TEMPLATE(create_suspended_thread_then_resume, Mdl, thread_types) {
91 typedef thread_wrapper<
true,Mdl> run_and_exit;
94 BOOST_CHECK_EQUAL(thr.i,0U);
96 BOOST_CHECK_EQUAL(thr.i,0U);
98 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
101 BOOST_AUTO_TEST_CASE_TEMPLATE(create_running_thread_then_suspend, Mdl, thread_types) {
102 typedef thread_wrapper<
true,Mdl> run_and_exit;
105 BOOST_CHECK_EQUAL(thr.i,0U);
106 BOOST_CHECK_NO_THROW(thr.create_running());
107 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
109 BOOST_CHECK_GT(thr.i,0U);
112 BOOST_AUTO_TEST_CASE_TEMPLATE(create_running_thread_then_suspend_then_resume, Mdl, thread_types) {
113 typedef thread_wrapper<
true,Mdl> run_and_exit;
116 BOOST_CHECK_EQUAL(thr.i,0U);
117 BOOST_CHECK_NO_THROW(thr.create_running());
118 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
121 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
122 BOOST_CHECK_GT(thr.i,0U);
125 BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor_two_threads, Mdl, thread_types) {
126 typedef thread_wrapper<
true,Mdl> run_and_exit;
130 BOOST_CHECK_EQUAL(thr1.i,0U);
131 BOOST_CHECK_EQUAL(thr2.i,0U);
134 BOOST_AUTO_TEST_CASE_TEMPLATE(start_two_threads, Mdl, thread_types) {
135 typedef thread_wrapper<
true,Mdl> run_and_exit;
139 BOOST_CHECK_EQUAL(thr1.i,0U);
140 BOOST_CHECK_EQUAL(thr2.i,0U);
141 BOOST_CHECK_NO_THROW(thr1.create_running());
142 BOOST_CHECK_NO_THROW(thr2.create_running());
143 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
144 BOOST_CHECK_GT(thr1.i,0U);
145 BOOST_CHECK_GT(thr2.i,0U);
148 BOOST_AUTO_TEST_CASE_TEMPLATE(start_two_suspended_threads, Mdl, thread_types) {
149 typedef thread_wrapper<
true,Mdl> run_and_exit;
153 BOOST_CHECK_EQUAL(thr1.i,0U);
154 BOOST_CHECK_EQUAL(thr2.i,0U);
157 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
160 BOOST_AUTO_TEST_CASE_TEMPLATE(start_two_suspended_threads_then_resume_them, Mdl, thread_types) {
161 typedef thread_wrapper<
true,Mdl> run_and_exit;
165 BOOST_CHECK_EQUAL(thr1.i,0U);
166 BOOST_CHECK_EQUAL(thr2.i,0U);
169 BOOST_CHECK_EQUAL(thr1.i,0U);
170 BOOST_CHECK_EQUAL(thr2.i,0U);
173 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
176 BOOST_AUTO_TEST_CASE_TEMPLATE(create_two_running_threads_then_suspend_them, Mdl, thread_types) {
177 typedef thread_wrapper<
true,Mdl> run_and_exit;
181 BOOST_CHECK_EQUAL(thr1.i,0U);
182 BOOST_CHECK_EQUAL(thr2.i,0U);
183 BOOST_CHECK_NO_THROW(thr1.create_running());
184 BOOST_CHECK_NO_THROW(thr2.create_running());
185 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
188 BOOST_CHECK_GT(thr1.i,0U);
189 BOOST_CHECK_GT(thr2.i,0U);
192 BOOST_AUTO_TEST_CASE_TEMPLATE(create_two_running_threads_then_suspend_and_resume_them, Mdl, thread_types) {
193 typedef thread_wrapper<
true,Mdl> run_and_exit;
197 BOOST_CHECK_EQUAL(thr1.i,0U);
198 BOOST_CHECK_EQUAL(thr2.i,0U);
199 BOOST_CHECK_NO_THROW(thr1.create_running());
200 BOOST_CHECK_NO_THROW(thr2.create_running());
201 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
206 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
209 BOOST_AUTO_TEST_SUITE_END()
211 BOOST_AUTO_TEST_SUITE(stl_like)
213 BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor_functor, Mdl, thread_types) {
214 using run_and_exit=
ppd::thread<
ppd::platform_api, Mdl>;
216 struct increment_ref {
217 std::atomic<
unsigned int> &i_;
219 explicit increment_ref(
std::atomic<
unsigned int> &i)
noexcept(
true)
222 void operator()()
noexcept(
true) {
227 std::atomic<
unsigned int> i{0U};
229 BOOST_CHECK_NO_THROW(run_and_exit thr{increment_ref(i)});
231 BOOST_CHECK_GE(i, 0U);
232 BOOST_CHECK_LE(i, 1U);
235 BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor_stdbind, Mdl, thread_types) {
236 using run_and_exit=
ppd::thread<
ppd::platform_api, Mdl>;
238 struct increment_ref {
239 static void result(
std::atomic<
unsigned int> &i)
noexcept(
true) {
244 std::atomic<
unsigned int> i{0U};
246 BOOST_CHECK_NO_THROW(run_and_exit thr(std::bind(&increment_ref::result, std::ref(i))));
248 BOOST_CHECK_GE(i, 0U);
249 BOOST_CHECK_LE(i, 1U);
252 BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor_stdfn, Mdl, thread_types) {
253 using run_and_exit=
ppd::thread<
ppd::platform_api, Mdl>;
255 struct increment_ref {
256 void operator()(
std::atomic<
unsigned int> &i)
noexcept(
true) {
261 std::atomic<
unsigned int> i{0U};
262 std::function<
void ()> fn(std::bind(increment_ref(), std::ref(i)));
264 BOOST_CHECK_NO_THROW(run_and_exit thr(std::move(fn)));
266 BOOST_CHECK_GE(i, 0U);
267 BOOST_CHECK_LE(i, 1U);
270 BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor_lambda, Mdl, thread_types) {
271 using run_and_exit=
ppd::thread<
ppd::platform_api, Mdl>;
273 std::atomic<
unsigned int> i{0U};
275 BOOST_CHECK_NO_THROW(run_and_exit thr([&i]() {++i;}));
277 BOOST_CHECK_GE(i, 0U);
278 BOOST_CHECK_LE(i, 1U);
281 BOOST_AUTO_TEST_CASE_TEMPLATE(create_suspended_thread_then_resume, Mdl, thread_types) {
282 using run_and_exit=
ppd::thread<
ppd::platform_api, Mdl>;
284 std::atomic<
unsigned int> i{0U};
285 run_and_exit thr([&i]() {++i;});
287 BOOST_CHECK_GE(i, 0U);
288 BOOST_CHECK_LE(i, 1U);
290 ppd::api_threading_traits<
ppd::platform_api,Mdl>::sleep(100);
293 BOOST_AUTO_TEST_CASE_TEMPLATE(default_ctor_two_threads, Mdl, thread_types) {
294 using run_and_exit=
ppd::thread<
ppd::platform_api, Mdl>;
296 std::atomic<
unsigned int> i{0U};
298 BOOST_CHECK_NO_THROW(run_and_exit thr1([&i]() {++i;}));
299 BOOST_CHECK_NO_THROW(run_and_exit thr2([&i]() {++i;}));
301 BOOST_CHECK_GE(i, 0U);
302 BOOST_CHECK_LE(i, 2U);
305 BOOST_AUTO_TEST_SUITE_END()
307 BOOST_AUTO_TEST_SUITE(multi_threaded)
309 BOOST_AUTO_TEST_CASE(default_ctor) {
310 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
313 BOOST_CHECK_EQUAL(thr.i, 0U);
316 BOOST_AUTO_TEST_CASE(start_thread) {
317 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
320 BOOST_CHECK_EQUAL(thr.i, 0U);
321 BOOST_CHECK_NO_THROW(thr.create_running());
322 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
323 BOOST_CHECK_GT(thr.i,0U);
326 BOOST_AUTO_TEST_CASE(create_suspended) {
327 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
330 BOOST_CHECK_EQUAL(thr.i, 0U);
332 BOOST_CHECK_EQUAL(thr.i, 0U);
335 BOOST_AUTO_TEST_CASE(create_suspended_thread_then_resume) {
336 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
339 BOOST_CHECK_EQUAL(thr.i, 0U);
341 BOOST_CHECK_EQUAL(thr.i, 0U);
343 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
346 BOOST_AUTO_TEST_CASE(create_running_thread_then_suspend) {
347 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
350 BOOST_CHECK_EQUAL(thr.i,0U);
351 BOOST_CHECK_NO_THROW(thr.create_running());
352 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
356 BOOST_AUTO_TEST_CASE(create_running_thread_then_suspend_then_resume) {
357 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
360 BOOST_CHECK_EQUAL(thr.i,0U);
361 BOOST_CHECK_NO_THROW(thr.create_running());
362 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
365 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
366 BOOST_CHECK_GT(thr.i,0U);
369 BOOST_AUTO_TEST_CASE(default_ctor_two_threads) {
370 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
374 BOOST_CHECK_EQUAL(thr1.i,0U);
375 BOOST_CHECK_EQUAL(thr2.i,0U);
378 BOOST_AUTO_TEST_CASE(start_two_threads) {
379 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
383 BOOST_CHECK_EQUAL(thr1.i,0U);
384 BOOST_CHECK_EQUAL(thr2.i,0U);
385 BOOST_CHECK_NO_THROW(thr1.create_running());
386 BOOST_CHECK_NO_THROW(thr2.create_running());
387 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
388 BOOST_CHECK_GT(thr1.i,0U);
389 BOOST_CHECK_GT(thr2.i,0U);
392 BOOST_AUTO_TEST_CASE(start_two_suspended_threads) {
393 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
397 BOOST_CHECK_EQUAL(thr1.i,0U);
398 BOOST_CHECK_EQUAL(thr2.i,0U);
401 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
404 BOOST_AUTO_TEST_CASE(start_two_suspended_threads_then_resume_them) {
405 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
409 BOOST_CHECK_EQUAL(thr1.i,0U);
410 BOOST_CHECK_EQUAL(thr2.i,0U);
413 BOOST_CHECK_EQUAL(thr1.i,0U);
414 BOOST_CHECK_EQUAL(thr2.i,0U);
417 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
420 BOOST_AUTO_TEST_CASE(create_two_running_threads_then_suspend_them) {
421 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
425 BOOST_CHECK_EQUAL(thr1.i,0U);
426 BOOST_CHECK_EQUAL(thr2.i,0U);
427 BOOST_CHECK_NO_THROW(thr1.create_running());
428 BOOST_CHECK_NO_THROW(thr2.create_running());
429 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
432 BOOST_CHECK_GT(thr1.i,0U);
433 BOOST_CHECK_GT(thr2.i,0U);
436 BOOST_AUTO_TEST_CASE(create_two_running_threads_then_suspend_and_resume_them) {
437 typedef thread_wrapper<
false,
ppd::heavyweight_threading> run_forever;
441 BOOST_CHECK_EQUAL(thr1.i,0U);
442 BOOST_CHECK_EQUAL(thr2.i,0U);
443 BOOST_CHECK_NO_THROW(thr1.create_running());
444 BOOST_CHECK_NO_THROW(thr2.create_running());
445 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
450 ppd::api_threading_traits<ppd::platform_api, ppd::heavyweight_threading>::sleep(100);
451 BOOST_CHECK_GT(thr1.i,0U);
452 BOOST_CHECK_GT(thr2.i,0U);
455 BOOST_AUTO_TEST_SUITE_END()
457 BOOST_AUTO_TEST_SUITE_END()