File indexing completed on 2021-12-24 02:18:39
0001
0002
0003
0004
0005
0006
0007
0008 #define CATCH_CONFIG_MAIN
0009 #include "catch.hpp"
0010
0011 #include "oneapi/tbb/global_control.h"
0012
0013 #include "FWCore/Concurrency/interface/chain_first.h"
0014
0015 TEST_CASE("Test chain::first", "[chain::first]") {
0016 oneapi::tbb::global_control control(oneapi::tbb::global_control::max_allowed_parallelism, 1);
0017
0018 SECTION("no explicit exception handling") {
0019 SECTION("first | lastTask") {
0020 std::atomic<int> count{0};
0021
0022 edm::FinalWaitingTask waitTask;
0023 oneapi::tbb::task_group group;
0024 {
0025 using namespace edm::waiting_task::chain;
0026 auto h = first([&count](edm::WaitingTaskHolder h) {
0027 ++count;
0028 REQUIRE(count.load() == 1);
0029 }) |
0030 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0031
0032 h.doneWaiting(std::exception_ptr());
0033 }
0034 group.wait();
0035 REQUIRE(count.load() == 1);
0036 REQUIRE(waitTask.done());
0037 REQUIRE(waitTask.exceptionPtr() == nullptr);
0038 }
0039
0040 SECTION("first | then | lastTask") {
0041 std::atomic<int> count{0};
0042
0043 edm::FinalWaitingTask waitTask;
0044 oneapi::tbb::task_group group;
0045 {
0046 using namespace edm::waiting_task::chain;
0047 auto h = first([&count](auto h) {
0048 ++count;
0049 REQUIRE(count.load() == 1);
0050 }) |
0051 then([&count](auto h) {
0052 ++count;
0053 REQUIRE(count.load() == 2);
0054 }) |
0055 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0056
0057 h.doneWaiting(std::exception_ptr());
0058 }
0059 group.wait();
0060 REQUIRE(count.load() == 2);
0061 REQUIRE(waitTask.done());
0062 REQUIRE(waitTask.exceptionPtr() == nullptr);
0063 }
0064
0065 SECTION("first | then | then | lastTask") {
0066 std::atomic<int> count{0};
0067
0068 edm::FinalWaitingTask waitTask;
0069 oneapi::tbb::task_group group;
0070 {
0071 using namespace edm::waiting_task::chain;
0072 auto h = first([&count](auto h) {
0073 ++count;
0074 REQUIRE(count.load() == 1);
0075 }) |
0076 then([&count](auto h) {
0077 ++count;
0078 REQUIRE(count.load() == 2);
0079 }) |
0080 then([&count](auto h) {
0081 ++count;
0082 REQUIRE(count.load() == 3);
0083 }) |
0084 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0085
0086 h.doneWaiting(std::exception_ptr());
0087 }
0088 group.wait();
0089 REQUIRE(count.load() == 3);
0090 REQUIRE(waitTask.done());
0091 REQUIRE(waitTask.exceptionPtr() == nullptr);
0092 }
0093
0094 SECTION("first | then | then | runLast") {
0095 std::atomic<int> count{0};
0096
0097 edm::FinalWaitingTask waitTask;
0098 oneapi::tbb::task_group group;
0099 {
0100 using namespace edm::waiting_task::chain;
0101 first([&count](auto h) {
0102 ++count;
0103 REQUIRE(count.load() == 1);
0104 }) | then([&count](auto h) {
0105 ++count;
0106 REQUIRE(count.load() == 2);
0107 }) | then([&count](auto h) {
0108 ++count;
0109 REQUIRE(count.load() == 3);
0110 }) | runLast(edm::WaitingTaskHolder(group, &waitTask));
0111 }
0112 group.wait();
0113 REQUIRE(count.load() == 3);
0114 REQUIRE(waitTask.done());
0115 REQUIRE(waitTask.exceptionPtr() == nullptr);
0116 }
0117
0118 SECTION("exception -> first | lastTask") {
0119 std::atomic<int> count{0};
0120
0121 edm::FinalWaitingTask waitTask;
0122 oneapi::tbb::task_group group;
0123 {
0124 using namespace edm::waiting_task::chain;
0125 auto h = first([&count](edm::WaitingTaskHolder h) {
0126 ++count;
0127 REQUIRE(false);
0128 }) |
0129 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0130
0131 h.doneWaiting(std::make_exception_ptr(std::exception()));
0132 }
0133 group.wait();
0134 REQUIRE(count.load() == 0);
0135 REQUIRE(waitTask.done());
0136 REQUIRE(waitTask.exceptionPtr() != nullptr);
0137 }
0138
0139 SECTION("first(exception) | lastTask") {
0140 std::atomic<int> count{0};
0141
0142 edm::FinalWaitingTask waitTask;
0143 oneapi::tbb::task_group group;
0144 {
0145 using namespace edm::waiting_task::chain;
0146 auto h = first([&count](edm::WaitingTaskHolder h) {
0147 ++count;
0148 REQUIRE(count.load() == 1);
0149 throw std::exception();
0150 }) |
0151 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0152
0153 h.doneWaiting(std::exception_ptr());
0154 }
0155 group.wait();
0156 REQUIRE(count.load() == 1);
0157 REQUIRE(waitTask.done());
0158 REQUIRE(waitTask.exceptionPtr() != nullptr);
0159 }
0160
0161 SECTION("first(exception) | then | then | lastTask") {
0162 std::atomic<int> count{0};
0163
0164 edm::FinalWaitingTask waitTask;
0165 oneapi::tbb::task_group group;
0166 {
0167 using namespace edm::waiting_task::chain;
0168 auto h = first([&count](auto h) {
0169 ++count;
0170 REQUIRE(count.load() == 1);
0171 throw std::exception();
0172 }) |
0173 then([&count](auto h) {
0174 ++count;
0175 REQUIRE(false);
0176 }) |
0177 then([&count](auto h) {
0178 ++count;
0179 REQUIRE(false);
0180 }) |
0181 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0182
0183 h.doneWaiting(std::exception_ptr());
0184 }
0185 group.wait();
0186 REQUIRE(count.load() == 1);
0187 REQUIRE(waitTask.done());
0188 REQUIRE(waitTask.exceptionPtr() != nullptr);
0189 }
0190 }
0191
0192 SECTION("then with exception handler testing") {
0193 SECTION("first | lastTask") {
0194 std::atomic<int> count{0};
0195
0196 edm::FinalWaitingTask waitTask;
0197 oneapi::tbb::task_group group;
0198 {
0199 using namespace edm::waiting_task::chain;
0200 auto h = first([&count](std::exception_ptr const* iPtr, edm::WaitingTaskHolder h) {
0201 REQUIRE(iPtr == nullptr);
0202 ++count;
0203 REQUIRE(count.load() == 1);
0204 }) |
0205 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0206
0207 h.doneWaiting(std::exception_ptr());
0208 }
0209 group.wait();
0210 REQUIRE(count.load() == 1);
0211 REQUIRE(waitTask.done());
0212 REQUIRE(waitTask.exceptionPtr() == nullptr);
0213 }
0214
0215 SECTION("first | then | lastTask") {
0216 std::atomic<int> count{0};
0217
0218 edm::FinalWaitingTask waitTask;
0219 oneapi::tbb::task_group group;
0220 {
0221 using namespace edm::waiting_task::chain;
0222 auto h = first([&count](std::exception_ptr const* iPtr, auto h) {
0223 REQUIRE(iPtr == nullptr);
0224 ++count;
0225 REQUIRE(count.load() == 1);
0226 }) |
0227 then([&count](std::exception_ptr const* iPtr, auto h) {
0228 REQUIRE(iPtr == nullptr);
0229 ++count;
0230 REQUIRE(count.load() == 2);
0231 }) |
0232 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0233
0234 h.doneWaiting(std::exception_ptr());
0235 }
0236 group.wait();
0237 REQUIRE(count.load() == 2);
0238 REQUIRE(waitTask.done());
0239 REQUIRE(waitTask.exceptionPtr() == nullptr);
0240 }
0241
0242 SECTION("first | then | then | lastTask") {
0243 std::atomic<int> count{0};
0244
0245 edm::FinalWaitingTask waitTask;
0246 oneapi::tbb::task_group group;
0247 {
0248 using namespace edm::waiting_task::chain;
0249 auto h = first([&count](std::exception_ptr const* iPtr, auto h) {
0250 REQUIRE(iPtr == nullptr);
0251 ++count;
0252 REQUIRE(count.load() == 1);
0253 }) |
0254 then([&count](std::exception_ptr const* iPtr, auto h) {
0255 REQUIRE(iPtr == nullptr);
0256 ++count;
0257 REQUIRE(count.load() == 2);
0258 }) |
0259 then([&count](std::exception_ptr const* iPtr, auto h) {
0260 REQUIRE(iPtr == nullptr);
0261 ++count;
0262 REQUIRE(count.load() == 3);
0263 }) |
0264 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0265
0266 h.doneWaiting(std::exception_ptr());
0267 }
0268 group.wait();
0269 REQUIRE(count.load() == 3);
0270 REQUIRE(waitTask.done());
0271 REQUIRE(waitTask.exceptionPtr() == nullptr);
0272 }
0273
0274 SECTION("exception -> first | lastTask") {
0275 std::atomic<int> count{0};
0276
0277 edm::FinalWaitingTask waitTask;
0278 oneapi::tbb::task_group group;
0279 {
0280 using namespace edm::waiting_task::chain;
0281 auto h = first([&count](std::exception_ptr const* iPtr, edm::WaitingTaskHolder h) {
0282 REQUIRE(iPtr != nullptr);
0283 ++count;
0284 REQUIRE(count.load() == 1);
0285 }) |
0286 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0287
0288 h.doneWaiting(std::make_exception_ptr(std::exception()));
0289 }
0290 group.wait();
0291 REQUIRE(count.load() == 1);
0292 REQUIRE(waitTask.done());
0293 REQUIRE(waitTask.exceptionPtr() == nullptr);
0294 }
0295
0296 SECTION("exception -> first | then | lastTask") {
0297 std::atomic<int> count{0};
0298
0299 edm::FinalWaitingTask waitTask;
0300 oneapi::tbb::task_group group;
0301 {
0302 using namespace edm::waiting_task::chain;
0303 auto h = first([&count](std::exception_ptr const* iPtr, edm::WaitingTaskHolder h) {
0304 REQUIRE(iPtr != nullptr);
0305 ++count;
0306 REQUIRE(count.load() == 1);
0307 h.doneWaiting(*iPtr);
0308 }) |
0309 then([&count](std::exception_ptr const* iPtr, auto h) {
0310 REQUIRE(iPtr != nullptr);
0311 ++count;
0312 REQUIRE(count.load() == 2);
0313 }) |
0314 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0315
0316 h.doneWaiting(std::make_exception_ptr(std::exception()));
0317 }
0318 group.wait();
0319 REQUIRE(count.load() == 2);
0320 REQUIRE(waitTask.done());
0321 REQUIRE(waitTask.exceptionPtr() == nullptr);
0322 }
0323 }
0324
0325 SECTION("ifException.else testing") {
0326 SECTION("first | lastTask") {
0327 std::atomic<int> count{0};
0328 std::atomic<int> exceptCount{0};
0329
0330 edm::FinalWaitingTask waitTask;
0331 oneapi::tbb::task_group group;
0332 {
0333 using namespace edm::waiting_task::chain;
0334 auto h = first(ifException([&exceptCount](std::exception_ptr const& iPtr) {
0335 ++exceptCount;
0336 REQUIRE(false);
0337 }).else_([&count](edm::WaitingTaskHolder h) {
0338 ++count;
0339 REQUIRE(count.load() == 1);
0340 })) |
0341 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0342
0343 h.doneWaiting(std::exception_ptr());
0344 }
0345 group.wait();
0346 REQUIRE(exceptCount.load() == 0);
0347 REQUIRE(count.load() == 1);
0348 REQUIRE(waitTask.done());
0349 REQUIRE(waitTask.exceptionPtr() == nullptr);
0350 }
0351
0352 SECTION("first | then | lastTask") {
0353 std::atomic<int> count{0};
0354 std::atomic<int> exceptCount{0};
0355
0356 edm::FinalWaitingTask waitTask;
0357 oneapi::tbb::task_group group;
0358 {
0359 using namespace edm::waiting_task::chain;
0360 auto h = first(ifException([&exceptCount](std::exception_ptr const& iPtr) {
0361 ++exceptCount;
0362 REQUIRE(false);
0363 }).else_([&count](auto h) {
0364 ++count;
0365 REQUIRE(count.load() == 1);
0366 })) |
0367 then(ifException([&exceptCount](std::exception_ptr const& iPtr) {
0368 ++exceptCount;
0369 REQUIRE(false);
0370 }).else_([&count](auto h) {
0371 ++count;
0372 REQUIRE(count.load() == 2);
0373 })) |
0374 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0375
0376 h.doneWaiting(std::exception_ptr());
0377 }
0378 group.wait();
0379 REQUIRE(exceptCount.load() == 0);
0380 REQUIRE(count.load() == 2);
0381 REQUIRE(waitTask.done());
0382 REQUIRE(waitTask.exceptionPtr() == nullptr);
0383 }
0384
0385 SECTION("first | then | then | lastTask") {
0386 std::atomic<int> count{0};
0387 std::atomic<int> exceptCount{0};
0388
0389 edm::FinalWaitingTask waitTask;
0390 oneapi::tbb::task_group group;
0391 {
0392 using namespace edm::waiting_task::chain;
0393 auto h = first(ifException([&exceptCount](std::exception_ptr const& iPtr) {
0394 ++exceptCount;
0395 REQUIRE(false);
0396 }).else_([&count](auto h) {
0397 ++count;
0398 REQUIRE(count.load() == 1);
0399 })) |
0400 then(ifException([&exceptCount](std::exception_ptr const& iPtr) {
0401 ++exceptCount;
0402 REQUIRE(false);
0403 }).else_([&count](auto h) {
0404 ++count;
0405 REQUIRE(count.load() == 2);
0406 })) |
0407 then(ifException([&exceptCount](std::exception_ptr const& iPtr) {
0408 ++exceptCount;
0409 REQUIRE(false);
0410 }).else_([&count](auto h) {
0411 ++count;
0412 REQUIRE(count.load() == 3);
0413 })) |
0414 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0415
0416 h.doneWaiting(std::exception_ptr());
0417 }
0418 group.wait();
0419 REQUIRE(exceptCount.load() == 0);
0420 REQUIRE(count.load() == 3);
0421 REQUIRE(waitTask.done());
0422 REQUIRE(waitTask.exceptionPtr() == nullptr);
0423 }
0424
0425 SECTION("exception -> first | then | then | lastTask") {
0426 std::atomic<int> count{0};
0427 std::atomic<int> exceptCount{0};
0428
0429 edm::FinalWaitingTask waitTask;
0430 oneapi::tbb::task_group group;
0431 {
0432 using namespace edm::waiting_task::chain;
0433 auto h = first(ifException([&exceptCount](std::exception_ptr const& iPtr) {
0434 ++exceptCount;
0435 REQUIRE(exceptCount.load() == 1);
0436 }).else_([&count](auto h) {
0437 ++count;
0438 REQUIRE(false);
0439 })) |
0440 then(ifException([&exceptCount](std::exception_ptr const& iPtr) {
0441 ++exceptCount;
0442 REQUIRE(exceptCount.load() == 2);
0443 }).else_([&count](auto h) {
0444 ++count;
0445 REQUIRE(false);
0446 })) |
0447 then(ifException([&exceptCount](std::exception_ptr const& iPtr) {
0448 ++exceptCount;
0449 REQUIRE(exceptCount.load() == 3);
0450 }).else_([&count](auto h) {
0451 ++count;
0452 REQUIRE(false);
0453 })) |
0454 lastTask(edm::WaitingTaskHolder(group, &waitTask));
0455
0456 h.doneWaiting(std::make_exception_ptr(std::exception()));
0457 }
0458 group.wait();
0459 REQUIRE(exceptCount.load() == 3);
0460 REQUIRE(count.load() == 0);
0461 REQUIRE(waitTask.done());
0462 REQUIRE(waitTask.exceptionPtr() != nullptr);
0463 }
0464 }
0465
0466 SECTION("ifThen testing") {
0467 SECTION("first | ifThen(true) | then | runLast") {
0468 std::atomic<int> count{0};
0469
0470 edm::FinalWaitingTask waitTask;
0471 oneapi::tbb::task_group group;
0472 {
0473 using namespace edm::waiting_task::chain;
0474 first([&count](auto h) {
0475 ++count;
0476 REQUIRE(count.load() == 1);
0477 }) | ifThen(true, [&count](auto h) {
0478 ++count;
0479 REQUIRE(count.load() == 2);
0480 }) | then([&count](auto h) {
0481 ++count;
0482 REQUIRE(count.load() == 3);
0483 }) | runLast(edm::WaitingTaskHolder(group, &waitTask));
0484 }
0485 group.wait();
0486 REQUIRE(count.load() == 3);
0487 REQUIRE(waitTask.done());
0488 REQUIRE(waitTask.exceptionPtr() == nullptr);
0489 }
0490
0491 SECTION("first | ifThen(false) | then | runLast") {
0492 std::atomic<int> count{0};
0493
0494 edm::FinalWaitingTask waitTask;
0495 oneapi::tbb::task_group group;
0496 {
0497 using namespace edm::waiting_task::chain;
0498 first([&count](auto h) {
0499 ++count;
0500 REQUIRE(count.load() == 1);
0501 }) | ifThen(false, [&count](auto h) {
0502 ++count;
0503 REQUIRE(false);
0504 }) | then([&count](auto h) {
0505 ++count;
0506 REQUIRE(count.load() == 2);
0507 }) | runLast(edm::WaitingTaskHolder(group, &waitTask));
0508 }
0509 group.wait();
0510 REQUIRE(count.load() == 2);
0511 REQUIRE(waitTask.done());
0512 REQUIRE(waitTask.exceptionPtr() == nullptr);
0513 }
0514 }
0515 }