xref: /openbmc/sdbusplus/test/async/fdio.cpp (revision 36137e09614746b13603b5fbae79e6f70819c46b)
12a12ae12SJagpal Singh Gill #include <sdbusplus/async.hpp>
22a12ae12SJagpal Singh Gill 
32a12ae12SJagpal Singh Gill #include <filesystem>
42a12ae12SJagpal Singh Gill #include <fstream>
52a12ae12SJagpal Singh Gill 
62a12ae12SJagpal Singh Gill #include <gtest/gtest.h>
72a12ae12SJagpal Singh Gill 
82a12ae12SJagpal Singh Gill using namespace std::literals;
92a12ae12SJagpal Singh Gill 
102a12ae12SJagpal Singh Gill namespace fs = std::filesystem;
112a12ae12SJagpal Singh Gill 
122a12ae12SJagpal Singh Gill class FdioTest : public ::testing::Test
132a12ae12SJagpal Singh Gill {
142a12ae12SJagpal Singh Gill   protected:
152a12ae12SJagpal Singh Gill     const fs::path path = "/tmp";
162a12ae12SJagpal Singh Gill     constexpr static auto testIterations = 5;
172a12ae12SJagpal Singh Gill 
FdioTest()182a12ae12SJagpal Singh Gill     FdioTest()
192a12ae12SJagpal Singh Gill     {
202a12ae12SJagpal Singh Gill         auto fd = inotify_init1(IN_NONBLOCK);
212a12ae12SJagpal Singh Gill         EXPECT_NE(fd, -1) << "Error occurred during the inotify_init1, error: "
222a12ae12SJagpal Singh Gill                           << errno;
232a12ae12SJagpal Singh Gill 
242a12ae12SJagpal Singh Gill         auto wd = inotify_add_watch(fd, path.c_str(), IN_CLOSE_WRITE);
252a12ae12SJagpal Singh Gill         EXPECT_NE(wd, -1)
262a12ae12SJagpal Singh Gill             << "Error occurred during the inotify_add_watch, error: " << errno;
272a12ae12SJagpal Singh Gill         fdioInstance = std::make_unique<sdbusplus::async::fdio>(*ctx, fd);
282a12ae12SJagpal Singh Gill     }
292a12ae12SJagpal Singh Gill 
~FdioTest()304638a2e9SJayanth Othayoth     ~FdioTest() noexcept override
312a12ae12SJagpal Singh Gill     {
322a12ae12SJagpal Singh Gill         if (fd != -1)
332a12ae12SJagpal Singh Gill         {
342a12ae12SJagpal Singh Gill             if (wd != -1)
352a12ae12SJagpal Singh Gill             {
362a12ae12SJagpal Singh Gill                 inotify_rm_watch(fd, wd);
372a12ae12SJagpal Singh Gill             }
382a12ae12SJagpal Singh Gill             close(fd);
392a12ae12SJagpal Singh Gill         }
402a12ae12SJagpal Singh Gill         ctx.reset();
412a12ae12SJagpal Singh Gill     }
422a12ae12SJagpal Singh Gill 
writeToFile()432a12ae12SJagpal Singh Gill     auto writeToFile() -> sdbusplus::async::task<>
442a12ae12SJagpal Singh Gill     {
452a12ae12SJagpal Singh Gill         std::ofstream outfile((path / "test_fdio.txt").native());
462a12ae12SJagpal Singh Gill         EXPECT_TRUE(outfile.is_open())
472a12ae12SJagpal Singh Gill             << "Error occurred during file open, error: " << errno;
482a12ae12SJagpal Singh Gill         outfile << "Test fdio!" << std::endl;
492a12ae12SJagpal Singh Gill         outfile.close();
502a12ae12SJagpal Singh Gill         co_return;
512a12ae12SJagpal Singh Gill     }
522a12ae12SJagpal Singh Gill 
testFdEvents(bool & ran,bool sleepBeforeWrite)53*36137e09SPatrick Williams     auto testFdEvents(bool& ran, bool sleepBeforeWrite)
54*36137e09SPatrick Williams         -> sdbusplus::async::task<>
552a12ae12SJagpal Singh Gill     {
562a12ae12SJagpal Singh Gill         for (int i = 0; i < testIterations; i++)
572a12ae12SJagpal Singh Gill         {
582a12ae12SJagpal Singh Gill             if (sleepBeforeWrite)
592a12ae12SJagpal Singh Gill             {
602a12ae12SJagpal Singh Gill                 ctx->spawn(sdbusplus::async::sleep_for(*ctx, 1s) |
612a12ae12SJagpal Singh Gill                            stdexec::then([&]() { ctx->spawn(writeToFile()); }));
622a12ae12SJagpal Singh Gill             }
632a12ae12SJagpal Singh Gill             else
642a12ae12SJagpal Singh Gill             {
652a12ae12SJagpal Singh Gill                 co_await writeToFile();
662a12ae12SJagpal Singh Gill             }
672a12ae12SJagpal Singh Gill             co_await fdioInstance->next();
682a12ae12SJagpal Singh Gill         }
692a12ae12SJagpal Singh Gill         ran = true;
702a12ae12SJagpal Singh Gill         co_return;
712a12ae12SJagpal Singh Gill     }
722a12ae12SJagpal Singh Gill 
732a12ae12SJagpal Singh Gill     std::unique_ptr<sdbusplus::async::fdio> fdioInstance;
742a12ae12SJagpal Singh Gill     std::optional<sdbusplus::async::context> ctx{std::in_place};
752a12ae12SJagpal Singh Gill 
762a12ae12SJagpal Singh Gill   private:
772a12ae12SJagpal Singh Gill     int fd = -1;
782a12ae12SJagpal Singh Gill     int wd = -1;
792a12ae12SJagpal Singh Gill };
802a12ae12SJagpal Singh Gill 
TEST_F(FdioTest,TestFdEvents)812a12ae12SJagpal Singh Gill TEST_F(FdioTest, TestFdEvents)
822a12ae12SJagpal Singh Gill {
832a12ae12SJagpal Singh Gill     bool ran = false;
842a12ae12SJagpal Singh Gill     ctx->spawn(testFdEvents(ran, false));
852a12ae12SJagpal Singh Gill     ctx->spawn(
862a12ae12SJagpal Singh Gill         sdbusplus::async::sleep_for(*ctx, 1s) |
872a12ae12SJagpal Singh Gill         sdbusplus::async::execution::then([&]() { ctx->request_stop(); }));
882a12ae12SJagpal Singh Gill     ctx->run();
892a12ae12SJagpal Singh Gill     EXPECT_TRUE(ran);
902a12ae12SJagpal Singh Gill }
912a12ae12SJagpal Singh Gill 
TEST_F(FdioTest,TestFdEventsWithSleep)922a12ae12SJagpal Singh Gill TEST_F(FdioTest, TestFdEventsWithSleep)
932a12ae12SJagpal Singh Gill {
942a12ae12SJagpal Singh Gill     bool ran = false;
952a12ae12SJagpal Singh Gill     ctx->spawn(testFdEvents(ran, true));
962a12ae12SJagpal Singh Gill     ctx->spawn(
972a12ae12SJagpal Singh Gill         sdbusplus::async::sleep_for(*ctx, 5s) |
982a12ae12SJagpal Singh Gill         sdbusplus::async::execution::then([&]() { ctx->request_stop(); }));
992a12ae12SJagpal Singh Gill     ctx->run();
1002a12ae12SJagpal Singh Gill     EXPECT_TRUE(ran);
1012a12ae12SJagpal Singh Gill }
102