Check TaskGroup behaviour with some successful and some failing tasks
| 74 | |
| 75 | // Check TaskGroup behaviour with some successful and some failing tasks |
| 76 | void TestTaskGroupErrors(std::shared_ptr<TaskGroup> task_group) { |
| 77 | const int NSUCCESSES = 2; |
| 78 | const int NERRORS = 20; |
| 79 | |
| 80 | std::atomic<int> count(0); |
| 81 | |
| 82 | auto task_group_was_ok = false; |
| 83 | task_group->Append([&]() -> Status { |
| 84 | for (int i = 0; i < NSUCCESSES; ++i) { |
| 85 | task_group->Append([&]() { |
| 86 | count++; |
| 87 | return Status::OK(); |
| 88 | }); |
| 89 | } |
| 90 | task_group_was_ok = task_group->ok(); |
| 91 | for (int i = 0; i < NERRORS; ++i) { |
| 92 | task_group->Append([&]() { |
| 93 | SleepFor(1e-2); |
| 94 | count++; |
| 95 | return Status::Invalid("some message"); |
| 96 | }); |
| 97 | } |
| 98 | |
| 99 | return Status::OK(); |
| 100 | }); |
| 101 | |
| 102 | // Task error is propagated |
| 103 | ASSERT_RAISES(Invalid, task_group->Finish()); |
| 104 | ASSERT_TRUE(task_group_was_ok); |
| 105 | ASSERT_FALSE(task_group->ok()); |
| 106 | if (task_group->parallelism() == 1) { |
| 107 | // Serial: exactly two successes and an error |
| 108 | ASSERT_EQ(count.load(), 3); |
| 109 | } else { |
| 110 | // Parallel: at least two successes and an error |
| 111 | ASSERT_GE(count.load(), 3); |
| 112 | ASSERT_LE(count.load(), 2 * task_group->parallelism()); |
| 113 | } |
| 114 | // Finish() is idempotent |
| 115 | ASSERT_RAISES(Invalid, task_group->Finish()); |
| 116 | } |
| 117 | |
| 118 | void TestTaskGroupCancel(std::shared_ptr<TaskGroup> task_group, StopSource* stop_source) { |
| 119 | const int NSUCCESSES = 2; |