1 #include <sdbusplus/async/execution.hpp> 2 #include <sdbusplus/async/task.hpp> 3 4 #include <gtest/gtest.h> 5 6 using namespace sdbusplus::async; 7 8 TEST(Task, CoAwaitVoid) 9 { 10 bool value = false; 11 auto t = [&]() -> task<> { 12 value = true; 13 co_return; 14 }; 15 16 // Check to ensure the co-routine hasn't started executing yet. 17 EXPECT_FALSE(value); 18 19 // Run it and confirm the value is updated. 20 std::this_thread::sync_wait(t()); 21 EXPECT_TRUE(value); 22 } 23 24 TEST(Task, CoAwaitInt) 25 { 26 struct _ 27 { 28 static auto one() -> task<int> 29 { 30 co_return 42; 31 } 32 static auto two(bool& executed) -> task<> 33 { 34 auto r = co_await one(); 35 EXPECT_EQ(r, 42); 36 executed = true; 37 co_return; 38 } 39 }; 40 41 // Add boolean to confirm that co-routine actually executed by the 42 // end. 43 bool executed = false; 44 std::this_thread::sync_wait(_::two(executed)); 45 EXPECT_TRUE(executed); 46 } 47 48 TEST(Task, CoAwaitThrow) 49 { 50 struct _ 51 { 52 static auto one() -> task<> 53 { 54 throw std::logic_error("Failed"); 55 co_return; 56 } 57 58 static auto two(bool& caught) -> task<> 59 { 60 try 61 { 62 co_await (one()); 63 } 64 catch (const std::logic_error&) 65 { 66 caught = true; 67 } 68 } 69 }; 70 71 // Ensure throws surface up. 72 EXPECT_THROW(std::this_thread::sync_wait(_::one()), std::logic_error); 73 74 // Ensure throws can be caught inside a co-routine. 75 bool caught = false; 76 std::this_thread::sync_wait(_::two(caught)); 77 EXPECT_TRUE(caught); 78 } 79 80 TEST(Task, RecursiveTask) 81 { 82 struct _ 83 { 84 static auto one(size_t count, size_t& executed) -> task<size_t> 85 { 86 if (count) 87 { 88 ++executed; 89 co_return (co_await one(count - 1, executed)) + 1; 90 } 91 co_return co_await std::execution::just(0); 92 } 93 }; 94 95 static constexpr size_t count = 100; 96 size_t executed = 0; 97 98 std::this_thread::sync_wait( 99 _::one(count, executed) | 100 std::execution::then([=](auto result) { EXPECT_EQ(result, count); })); 101 102 EXPECT_EQ(executed, count); 103 } 104