blob: a7e5a1511367435bc3e61801898b24ab2e142181 [file] [log] [blame]
Patrick Williams2f58b792022-08-26 14:07:04 -05001#include <sdbusplus/async/execution.hpp>
2#include <sdbusplus/async/task.hpp>
3
4#include <gtest/gtest.h>
5
6using namespace sdbusplus::async;
7
8TEST(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.
Patrick Williams5e7ef082023-01-05 11:08:53 -060020 stdexec::this_thread::sync_wait(t());
Patrick Williams2f58b792022-08-26 14:07:04 -050021 EXPECT_TRUE(value);
22}
23
24TEST(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;
Patrick Williams5e7ef082023-01-05 11:08:53 -060044 stdexec::this_thread::sync_wait(_::two(executed));
Patrick Williams2f58b792022-08-26 14:07:04 -050045 EXPECT_TRUE(executed);
46}
47
48TEST(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.
Patrick Williams5e7ef082023-01-05 11:08:53 -060072 EXPECT_THROW(stdexec::this_thread::sync_wait(_::one()), std::logic_error);
Patrick Williams2f58b792022-08-26 14:07:04 -050073
74 // Ensure throws can be caught inside a co-routine.
75 bool caught = false;
Patrick Williams5e7ef082023-01-05 11:08:53 -060076 stdexec::this_thread::sync_wait(_::two(caught));
Patrick Williams2f58b792022-08-26 14:07:04 -050077 EXPECT_TRUE(caught);
78}
Patrick Williamsd6b05cc2022-09-23 09:38:38 -050079
80TEST(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 }
Patrick Williams5e7ef082023-01-05 11:08:53 -060091 co_return co_await stdexec::just(0);
Patrick Williamsd6b05cc2022-09-23 09:38:38 -050092 }
93 };
94
95 static constexpr size_t count = 100;
96 size_t executed = 0;
97
Patrick Williams5e7ef082023-01-05 11:08:53 -060098 stdexec::this_thread::sync_wait(
Patrick Williamsd6b05cc2022-09-23 09:38:38 -050099 _::one(count, executed) |
Patrick Williams5e7ef082023-01-05 11:08:53 -0600100 stdexec::then([=](auto result) { EXPECT_EQ(result, count); }));
Patrick Williamsd6b05cc2022-09-23 09:38:38 -0500101
102 EXPECT_EQ(executed, count);
103}