1 #include <sdbusplus/async.hpp>
2
3 #include <filesystem>
4 #include <fstream>
5
6 #include <gtest/gtest.h>
7
8 using namespace std::literals;
9
10 namespace fs = std::filesystem;
11
12 class FdioTest : public ::testing::Test
13 {
14 protected:
15 const fs::path path = "/tmp";
16 constexpr static auto testIterations = 5;
17
FdioTest()18 FdioTest()
19 {
20 auto fd = inotify_init1(IN_NONBLOCK);
21 EXPECT_NE(fd, -1) << "Error occurred during the inotify_init1, error: "
22 << errno;
23
24 auto wd = inotify_add_watch(fd, path.c_str(), IN_CLOSE_WRITE);
25 EXPECT_NE(wd, -1)
26 << "Error occurred during the inotify_add_watch, error: " << errno;
27 fdioInstance = std::make_unique<sdbusplus::async::fdio>(*ctx, fd);
28 }
29
~FdioTest()30 ~FdioTest() noexcept override
31 {
32 if (fd != -1)
33 {
34 if (wd != -1)
35 {
36 inotify_rm_watch(fd, wd);
37 }
38 close(fd);
39 }
40 ctx.reset();
41 }
42
writeToFile()43 auto writeToFile() -> sdbusplus::async::task<>
44 {
45 std::ofstream outfile((path / "test_fdio.txt").native());
46 EXPECT_TRUE(outfile.is_open())
47 << "Error occurred during file open, error: " << errno;
48 outfile << "Test fdio!" << std::endl;
49 outfile.close();
50 co_return;
51 }
52
testFdEvents(bool & ran,bool sleepBeforeWrite)53 auto testFdEvents(bool& ran, bool sleepBeforeWrite)
54 -> sdbusplus::async::task<>
55 {
56 for (int i = 0; i < testIterations; i++)
57 {
58 if (sleepBeforeWrite)
59 {
60 ctx->spawn(sdbusplus::async::sleep_for(*ctx, 1s) |
61 stdexec::then([&]() { ctx->spawn(writeToFile()); }));
62 }
63 else
64 {
65 co_await writeToFile();
66 }
67 co_await fdioInstance->next();
68 }
69 ran = true;
70 co_return;
71 }
72
73 std::unique_ptr<sdbusplus::async::fdio> fdioInstance;
74 std::optional<sdbusplus::async::context> ctx{std::in_place};
75
76 private:
77 int fd = -1;
78 int wd = -1;
79 };
80
TEST_F(FdioTest,TestFdEvents)81 TEST_F(FdioTest, TestFdEvents)
82 {
83 bool ran = false;
84 ctx->spawn(testFdEvents(ran, false));
85 ctx->spawn(
86 sdbusplus::async::sleep_for(*ctx, 1s) |
87 sdbusplus::async::execution::then([&]() { ctx->request_stop(); }));
88 ctx->run();
89 EXPECT_TRUE(ran);
90 }
91
TEST_F(FdioTest,TestFdEventsWithSleep)92 TEST_F(FdioTest, TestFdEventsWithSleep)
93 {
94 bool ran = false;
95 ctx->spawn(testFdEvents(ran, true));
96 ctx->spawn(
97 sdbusplus::async::sleep_for(*ctx, 5s) |
98 sdbusplus::async::execution::then([&]() { ctx->request_stop(); }));
99 ctx->run();
100 EXPECT_TRUE(ran);
101 }
102