1 #include "test.h" 2 3 TEST_CASE("value_task") { 4 auto t = tw::make_value_task(42); 5 REQUIRE(42 == t->get()); 6 REQUIRE(42 == t->future().get()); 7 REQUIRE(t->was_scheduled()); 8 REQUIRE(t->is_ready()); 9 REQUIRE(t->edges().empty()); 10 auto n = t; 11 REQUIRE(0u == n->id()); 12 REQUIRE(tw::task_type::root == n->type()); 13 REQUIRE(!n->name()); 14 REQUIRE(!n->executor()); 15 REQUIRE(n->parents().empty()); 16 REQUIRE(0 == n->priority()); 17 REQUIRE(!any_data_ok(n->custom_data())); 18 REQUIRE(!n->canceled()); 19 } 20 21 TEST_CASE("value_task_with_name") { 22 const std::string name = "albert"; 23 auto t = tw::make_value_task(42)->named(name); 24 REQUIRE(42 == t->get()); 25 REQUIRE(42 == t->future().get()); 26 REQUIRE(t->was_scheduled()); 27 REQUIRE(t->is_ready()); 28 REQUIRE(t->edges().empty()); 29 auto n = t; 30 REQUIRE(0u == n->id()); 31 REQUIRE(tw::task_type::root == n->type()); 32 #ifndef TRANSWARP_MINIMUM_TASK_SIZE 33 REQUIRE(name == *n->name()); 34 #else 35 REQUIRE(!n->name()); 36 #endif 37 REQUIRE(!n->executor()); 38 REQUIRE(n->parents().empty()); 39 REQUIRE(0 == n->priority()); 40 REQUIRE(!any_data_ok(n->custom_data())); 41 REQUIRE(!n->canceled()); 42 } 43 44 TEST_CASE("value_task_with_priority_and_custom_data") { 45 auto t = tw::make_value_task(42); 46 t->set_priority(13); 47 auto data = std::make_shared<double>(13.5); 48 t->set_custom_data(data); 49 auto n = t; 50 #ifndef TRANSWARP_DISABLE_TASK_PRIORITY 51 REQUIRE(13 == n->priority()); 52 #else 53 REQUIRE(0 == n->priority()); 54 #endif 55 #ifndef TRANSWARP_DISABLE_TASK_CUSTOM_DATA 56 REQUIRE(13.5 == *get_any_data<std::shared_ptr<double>>(n->custom_data())); 57 #else 58 REQUIRE(!any_data_ok(n->custom_data())); 59 #endif 60 t->remove_custom_data(); 61 t->reset_priority(); 62 REQUIRE(0 == n->priority()); 63 REQUIRE(!any_data_ok(n->custom_data())); 64 } 65 66 TEST_CASE("value_task_with_priority_all_and_custom_data_all") { 67 auto t = tw::make_value_task(42); 68 t->set_priority_all(13); 69 auto data = std::make_shared<double>(13.5); 70 t->set_custom_data_all(data); 71 auto n = t; 72 #ifndef TRANSWARP_DISABLE_TASK_PRIORITY 73 REQUIRE(13 == n->priority()); 74 #else 75 REQUIRE(0 == n->priority()); 76 #endif 77 #ifndef TRANSWARP_DISABLE_TASK_CUSTOM_DATA 78 REQUIRE(13.5 == *get_any_data<std::shared_ptr<double>>(n->custom_data())); 79 #else 80 REQUIRE(!any_data_ok(n->custom_data())); 81 #endif 82 t->remove_custom_data_all(); 83 t->reset_priority_all(); 84 REQUIRE(0 == n->priority()); 85 REQUIRE(!any_data_ok(n->custom_data())); 86 } 87 88 TEST_CASE("value_task_in_a_graph") { 89 auto t1 = tw::make_value_task(42); 90 REQUIRE(42 == t1->get()); 91 auto t2 = tw::make_value_task(13.3); 92 REQUIRE(13.3 == t2->get()); __anonb62a17580102(int x, double y) 93 auto t3 = tw::make_task(tw::consume, [](int x, double y) { return x + y; }, t1, t2); 94 t3->schedule(); 95 REQUIRE(55.3 == t3->get()); 96 } 97 98 TEST_CASE("value_task_and_executor") { 99 auto t = tw::make_value_task(42); 100 REQUIRE(42 == t->get()); 101 auto exec = std::make_shared<tw::sequential>(); 102 t->set_executor(exec); 103 REQUIRE(!t->executor()); 104 t->remove_executor(); 105 REQUIRE(!t->executor()); 106 REQUIRE(42 == t->get()); 107 } 108 109 TEST_CASE("value_task_and_executor_all") { 110 auto t = tw::make_value_task(42); 111 REQUIRE(42 == t->get()); 112 auto exec = std::make_shared<tw::sequential>(); 113 t->set_executor_all(exec); 114 REQUIRE(!t->executor()); 115 t->remove_executor_all(); 116 REQUIRE(!t->executor()); 117 REQUIRE(42 == t->get()); 118 } 119 120 TEST_CASE("value_task_and_schedule") { 121 auto t = tw::make_value_task(42); 122 REQUIRE(42 == t->get()); 123 tw::sequential exec; 124 t->schedule(true); 125 t->schedule(exec, true); 126 REQUIRE(42 == t->get()); 127 } 128 129 TEST_CASE("value_task_and_schedule_all") { 130 auto t = tw::make_value_task(42); 131 REQUIRE(42 == t->get()); 132 tw::sequential exec; 133 t->schedule_all(true); 134 t->schedule_all(exec, true); 135 REQUIRE(42 == t->get()); 136 } 137 138 TEST_CASE("value_task_and_wait") { 139 auto t = tw::make_value_task(42); 140 REQUIRE(42 == t->get()); 141 t->wait(); 142 REQUIRE(42 == t->get()); 143 } 144 145 TEST_CASE("value_task_and_reset_and_cancel") { 146 auto t = tw::make_value_task(42); 147 REQUIRE(42 == t->get()); 148 t->reset(); 149 t->cancel(true); 150 REQUIRE(42 == t->get()); 151 } 152 153 TEST_CASE("value_task_and_reset_all_and_cancel_all") { 154 auto t = tw::make_value_task(42); 155 REQUIRE(42 == t->get()); 156 t->reset_all(); 157 t->cancel_all(true); 158 REQUIRE(42 == t->get()); 159 } 160 161 TEST_CASE("value_task_with_lvalue_reference") { 162 const int x = 42; 163 auto t = tw::make_value_task(x); 164 REQUIRE(x == t->get()); 165 } 166 167 TEST_CASE("value_task_with_rvalue_reference") { 168 int x = 42; 169 auto t = tw::make_value_task(std::move(x)); 170 REQUIRE(42 == t->get()); 171 } 172 173 TEST_CASE("value_task_with_changing_value") { 174 int x = 42; 175 auto t = tw::make_value_task(x); 176 x = 43; 177 REQUIRE(42 == t->get()); 178 } 179 180 TEST_CASE("make_ready_future_with_value") { 181 const int x = 42; 182 auto future = tw::detail::make_future_with_value<int>(x); 183 REQUIRE(x == future.get()); 184 } 185 186 TEST_CASE("make_ready_future") { 187 auto future = tw::detail::make_ready_future(); 188 REQUIRE(future.valid()); 189 } 190 191 TEST_CASE("make_ready_future_with_exception") { 192 std::runtime_error e{"42"}; 193 auto future = tw::detail::make_future_with_exception<int>(std::make_exception_ptr(e)); 194 try { 195 future.get(); 196 } catch (std::runtime_error& e) { 197 REQUIRE(std::string{"42"} == e.what()); 198 return; 199 } 200 throw std::runtime_error{"shouldn't get here"}; 201 } 202 203 TEST_CASE("make_ready_future_with_invalid_exception") { 204 REQUIRE_THROWS_AS(tw::detail::make_future_with_exception<int>(std::exception_ptr{}), tw::transwarp_error); 205 } 206 207 TEST_CASE("task_set_value_and_remove_value") { 208 const int x = 42; 209 const int y = 55; __anonb62a17580202null210 auto t = tw::make_task(tw::root, [x]{ return x; }); 211 t->schedule(); 212 REQUIRE(x == t->get()); 213 t->set_value(y); 214 REQUIRE(t->is_ready()); 215 REQUIRE(y == t->get()); 216 t->reset(); 217 REQUIRE_THROWS_AS(t->is_ready(), tw::transwarp_error); 218 t->schedule(); 219 REQUIRE(t->is_ready()); 220 REQUIRE(x == t->get()); 221 } 222 223 TEST_CASE("task_set_value_and_remove_value_for_mutable_ref") { 224 int x = 42; 225 int y = 55; __anonb62a17580302null226 auto t = tw::make_task(tw::root, [x]{ return x; }); 227 t->schedule(); 228 REQUIRE(x == t->get()); 229 t->set_value(y); 230 REQUIRE(t->is_ready()); 231 REQUIRE(y == t->get()); 232 t->reset(); 233 REQUIRE_THROWS_AS(t->is_ready(), tw::transwarp_error); 234 t->schedule(); 235 REQUIRE(t->is_ready()); 236 REQUIRE(x == t->get()); 237 } 238 239 TEST_CASE("task_set_value_and_remove_value_for_void") { __anonb62a17580402null240 auto t = tw::make_task(tw::root, []{}); 241 t->schedule(); 242 t->reset(); 243 REQUIRE_THROWS_AS(t->is_ready(), tw::transwarp_error); 244 t->set_value(); 245 REQUIRE(t->is_ready()); 246 t->reset(); 247 REQUIRE_THROWS_AS(t->is_ready(), tw::transwarp_error); 248 t->schedule(); 249 REQUIRE(t->is_ready()); 250 } 251 252 TEST_CASE("task_set_exception_and_remove_exception") { 253 const int x = 42; __anonb62a17580502null254 auto t = tw::make_task(tw::root, [x]{ return x; }); 255 std::runtime_error e{"blah"}; 256 t->set_exception(std::make_exception_ptr(e)); 257 REQUIRE(t->is_ready()); 258 REQUIRE_THROWS_AS(t->get(), std::runtime_error); 259 t->reset(); 260 REQUIRE_THROWS_AS(t->is_ready(), tw::transwarp_error); 261 t->schedule(); 262 REQUIRE(t->is_ready()); 263 REQUIRE(x == t->get()); 264 } 265 266 TEST_CASE("task_pass_exception_to_set_value") { __anonb62a17580602null267 auto t = tw::make_task(tw::root, []{ return std::make_exception_ptr(std::runtime_error{"foo"}); }); 268 std::runtime_error e{"blah"}; 269 t->set_value(std::make_exception_ptr(e)); 270 const auto result = t->get(); 271 try { 272 std::rethrow_exception(result); 273 } catch (const std::runtime_error& re) { 274 REQUIRE(std::string(e.what()) == std::string(re.what())); 275 return; 276 } 277 throw std::runtime_error{"shouldn't get here"}; 278 } 279 280 TEST_CASE("has_result") { __anonb62a17580702null281 auto t = tw::make_task(tw::root, []{}); 282 REQUIRE(!t->has_result()); 283 t->schedule(); 284 REQUIRE(t->has_result()); 285 } 286 287 TEST_CASE("has_result_for_value_task") { 288 auto t = tw::make_value_task(42); 289 REQUIRE(t->has_result()); 290 } 291 292 TEST_CASE("value_task_with_volatile_int") { 293 volatile int x = 42; 294 auto t = tw::make_value_task(x); 295 REQUIRE(x == t->get()); 296 t->set_value(43); 297 REQUIRE(43 == t->get()); 298 x *= 2; 299 t->set_value(x); 300 REQUIRE(x == t->get()); 301 } 302