blob: 9054783e80ea2d0fa28e2daf89d820941481645d [file] [log] [blame]
Jagpal Singh Gillbd04c3b2025-07-07 16:34:20 -07001#include <sdbusplus/async.hpp>
2
3#include <filesystem>
4#include <fstream>
5
6#include <gtest/gtest.h>
7
8using namespace std::literals;
9
10namespace fs = std::filesystem;
11
12class MutexTest : public ::testing::Test
13{
14 protected:
Jayanth Othayoth45d04062025-12-22 23:04:56 -060015 ~MutexTest() noexcept override = default;
Jagpal Singh Gillbd04c3b2025-07-07 16:34:20 -070016 constexpr static std::string testMutex = "TestMutex";
17 const fs::path path = "/tmp";
18
19 MutexTest() : mutex(testMutex)
20 {
21 auto fd = inotify_init1(IN_NONBLOCK);
22 EXPECT_NE(fd, -1) << "Error occurred during the inotify_init1, error: "
23 << errno;
24
25 auto wd = inotify_add_watch(fd, path.c_str(), IN_CLOSE_WRITE);
26 EXPECT_NE(wd, -1)
27 << "Error occurred during the inotify_add_watch, error: " << errno;
28 fdioInstance = std::make_unique<sdbusplus::async::fdio>(*ctx, fd);
29 }
30
31 std::optional<sdbusplus::async::context> ctx{std::in_place};
32
33 auto testAsyncAddition(int val = 1) -> sdbusplus::async::task<>
34 {
35 sdbusplus::async::lock_guard lg{mutex};
36 co_await lg.lock();
37
38 sharedVar += val;
39 }
40
41 auto testAsyncSubtraction(int val = 1) -> sdbusplus::async::task<>
42 {
43 sdbusplus::async::lock_guard lg{mutex};
44 co_await lg.lock();
45
46 sharedVar -= val;
47 }
48
49 auto writeToFile() -> sdbusplus::async::task<>
50 {
51 std::ofstream outfile((path / testMutex).native());
52 EXPECT_TRUE(outfile.is_open())
53 << "Error occurred during file open, error: " << errno;
54
55 outfile << testMutex << std::endl;
56 outfile.close();
57
58 co_return;
59 }
60
61 auto readFromFile() -> sdbusplus::async::task<>
62 {
63 std::ifstream infile((path / testMutex).native());
64 EXPECT_TRUE(infile.is_open())
65 << "Error occurred during file open, error: " << errno;
66
67 std::string line;
68 std::getline(infile, line);
69 EXPECT_EQ(line, testMutex);
70 infile.close();
71
72 co_return;
73 }
74
75 auto testFdEvents() -> sdbusplus::async::task<>
76 {
77 sdbusplus::async::lock_guard lg{mutex};
78 co_await lg.lock();
79
80 ctx->spawn(writeToFile());
81 co_await fdioInstance->next();
82 co_await readFromFile();
83 ran++;
84
85 co_return;
86 }
87
88 int sharedVar = 0;
89 int ran = 0;
90 sdbusplus::async::mutex mutex;
91
92 private:
93 std::unique_ptr<sdbusplus::async::fdio> fdioInstance;
Jagpal Singh Gillbd04c3b2025-07-07 16:34:20 -070094};
95
96TEST_F(MutexTest, TestAsyncAddition)
97{
98 constexpr auto testIterations = 10;
99 for (auto i = 0; i < testIterations; i++)
100 {
101 ctx->spawn(testAsyncAddition());
102 }
103
104 ctx->spawn(
105 sdbusplus::async::sleep_for(*ctx, 1s) |
106 sdbusplus::async::execution::then([&]() { ctx->request_stop(); }));
107
108 ctx->run();
109
110 EXPECT_EQ(sharedVar, testIterations);
111}
112
113TEST_F(MutexTest, TestAsyncMixed)
114{
115 constexpr auto testIterations = 10;
116 for (auto i = 0; i < testIterations; i++)
117 {
118 ctx->spawn(testAsyncAddition());
119 ctx->spawn(testAsyncSubtraction(2));
120 }
121
122 ctx->spawn(
123 sdbusplus::async::sleep_for(*ctx, 1s) |
124 sdbusplus::async::execution::then([&]() { ctx->request_stop(); }));
125
126 ctx->run();
127
128 EXPECT_EQ(sharedVar, -testIterations);
129}
130
131TEST_F(MutexTest, TestFdEvents)
132{
133 constexpr static auto testIterations = 5;
134
135 for (auto i = 0; i < testIterations; i++)
136 {
137 ctx->spawn(testFdEvents());
138 }
139 ctx->spawn(
140 sdbusplus::async::sleep_for(*ctx, 3s) |
141 sdbusplus::async::execution::then([&]() { ctx->request_stop(); }));
142 ctx->run();
143 EXPECT_EQ(ran, testIterations);
144}
145
146TEST_F(MutexTest, TestLockGuardNoLock)
147{
148 sdbusplus::async::lock_guard lg{mutex};
149}