1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <atomic>
16 #include <chrono>
17 #include <cinttypes>
18 #include <fcntl.h>
19 #include <gtest/gtest.h>
20 #include <memory>
21 #include <sys/eventfd.h>
22 #include <sys/types.h>
23 #include <sys/wait.h>
24 #include <thread>
25 #include <unistd.h>
26
27 #include "epoll_event_poller.h"
28 #include "event_notifier.h"
29 #include "logging.h"
30
31 using namespace testing::ext;
32
33 namespace {
34 constexpr int DEFAULT_POLL_INTERVAL = 1000;
35 }
36
37 namespace {
38 class EpollEventPollerTest : public testing::Test {
39 protected:
40 std::unique_ptr<EpollEventPoller> eventPoller;
41 void SetUp() override
42 {
43 eventPoller = std::make_unique<EpollEventPoller>(DEFAULT_POLL_INTERVAL);
44 }
45
46 void TearDown() override {}
47 };
48
49 /**
50 * @tc.name: EpollEventPollerTest
51 * @tc.desc: CtorDtor.
52 * @tc.type: FUNC
53 */
HWTEST_F(EpollEventPollerTest, CtorDtor, TestSize.Level1)54 HWTEST_F(EpollEventPollerTest, CtorDtor, TestSize.Level1)
55 {
56 ASSERT_NE(eventPoller, nullptr);
57 }
58
59 /**
60 * @tc.name: EpollEventPollerTest
61 * @tc.desc: InitFinalize.
62 * @tc.type: FUNC
63 */
HWTEST_F(EpollEventPollerTest, InitFinalize, TestSize.Level1)64 HWTEST_F(EpollEventPollerTest, InitFinalize, TestSize.Level1)
65 {
66 ASSERT_NE(eventPoller, nullptr);
67
68 PROFILER_LOG_INFO(LOG_CORE, "EpollEventPollerTest.InitFinalize start!");
69 EXPECT_TRUE(eventPoller->Init());
70 EXPECT_TRUE(eventPoller->Finalize());
71 }
72
73 /**
74 * @tc.name: EpollEventPollerTest
75 * @tc.desc: InitFinalize.
76 * @tc.type: FUNC
77 */
HWTEST_F(EpollEventPollerTest, InitOnly, TestSize.Level1)78 HWTEST_F(EpollEventPollerTest, InitOnly, TestSize.Level1)
79 {
80 ASSERT_NE(eventPoller, nullptr);
81 PROFILER_LOG_INFO(LOG_CORE, "EpollEventPollerTest.InitOnly start!");
82 EXPECT_TRUE(eventPoller->Init());
83 }
84
85 /**
86 * @tc.name: EpollEventPollerTest
87 * @tc.desc: Init 2 times Finalize 1 time.
88 * @tc.type: FUNC
89 */
HWTEST_F(EpollEventPollerTest, Init2Finalize1, TestSize.Level1)90 HWTEST_F(EpollEventPollerTest, Init2Finalize1, TestSize.Level1)
91 {
92 ASSERT_NE(eventPoller, nullptr);
93
94 PROFILER_LOG_INFO(LOG_CORE, "EpollEventPollerTest.Init2Finalize1 start!");
95 EXPECT_TRUE(eventPoller->Init());
96 EXPECT_FALSE(eventPoller->Init());
97 EXPECT_TRUE(eventPoller->Finalize());
98 }
99
100 /**
101 * @tc.name: EpollEventPollerTest
102 * @tc.desc: InitStartStopFinalize.
103 * @tc.type: FUNC
104 */
HWTEST_F(EpollEventPollerTest, InitStartStopFinalize, TestSize.Level1)105 HWTEST_F(EpollEventPollerTest, InitStartStopFinalize, TestSize.Level1)
106 {
107 ASSERT_NE(eventPoller, nullptr);
108
109 PROFILER_LOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartStopFinalize start!");
110 EXPECT_TRUE(eventPoller->Init());
111 EXPECT_TRUE(eventPoller->Start());
112 EXPECT_TRUE(eventPoller->Stop());
113 EXPECT_TRUE(eventPoller->Finalize());
114 }
115
116 /**
117 * @tc.name: EpollEventPollerTest
118 * @tc.desc: InitStartStop.
119 * @tc.type: FUNC
120 */
HWTEST_F(EpollEventPollerTest, InitStartStop, TestSize.Level1)121 HWTEST_F(EpollEventPollerTest, InitStartStop, TestSize.Level1)
122 {
123 ASSERT_NE(eventPoller, nullptr);
124
125 PROFILER_LOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartStop start!");
126 EXPECT_TRUE(eventPoller->Init());
127 EXPECT_TRUE(eventPoller->Start());
128 EXPECT_TRUE(eventPoller->Stop());
129 }
130
131 /**
132 * @tc.name: EpollEventPollerTest
133 * @tc.desc: InitStart.
134 * @tc.type: FUNC
135 */
HWTEST_F(EpollEventPollerTest, InitStart, TestSize.Level1)136 HWTEST_F(EpollEventPollerTest, InitStart, TestSize.Level1)
137 {
138 ASSERT_NE(eventPoller, nullptr);
139
140 PROFILER_LOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStart start!");
141 EXPECT_TRUE(eventPoller->Init());
142 EXPECT_TRUE(eventPoller->Start());
143 }
144
145 /**
146 * @tc.name: EpollEventPollerTest
147 * @tc.desc: AddFd.
148 * @tc.type: FUNC
149 */
HWTEST_F(EpollEventPollerTest, InitStartAddFd, TestSize.Level1)150 HWTEST_F(EpollEventPollerTest, InitStartAddFd, TestSize.Level1)
151 {
152 ASSERT_NE(eventPoller, nullptr);
153
154 PROFILER_LOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartAddFd start!");
155 EXPECT_TRUE(eventPoller->Init());
156 EXPECT_TRUE(eventPoller->Start());
157
158 int eventFd = eventfd(0, O_CLOEXEC | O_NONBLOCK);
159 uint64_t readValue = 0;
160 auto onReadable = [&readValue, &eventFd]() {
161 read(eventFd, &readValue, sizeof(readValue));
162 PROFILER_LOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartAddFd read %" PRIu64, readValue);
163 };
164 EXPECT_TRUE(eventPoller->AddFileDescriptor(eventFd, onReadable));
165
166 uint64_t writeValue = 1234;
167 int writeSize = sizeof(writeValue); // run -t UT -ss developtools
168 EXPECT_EQ(write(eventFd, &writeValue, writeSize), writeSize);
169
170 std::this_thread::yield();
171 usleep(15 * 1000);
172 EXPECT_EQ(readValue, writeValue);
173 eventPoller->RemoveFileDescriptor(eventFd);
174 EXPECT_TRUE(eventPoller->Stop());
175 EXPECT_TRUE(eventPoller->Finalize());
176
177 close(eventFd);
178 }
179
HWTEST_F(EpollEventPollerTest, InitStartAddEventFd, TestSize.Level1)180 HWTEST_F(EpollEventPollerTest, InitStartAddEventFd, TestSize.Level1)
181 {
182 ASSERT_NE(eventPoller, nullptr);
183
184 PROFILER_LOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartAddFd start!");
185 EXPECT_TRUE(eventPoller->Init());
186 EXPECT_TRUE(eventPoller->Start());
187
188 auto notifier = EventNotifier::Create(0, EventNotifier::NONBLOCK);
189 uint64_t readValue = 0;
190 auto onReadable = [&readValue, ¬ifier]() {
191 readValue = notifier->Take();
192 PROFILER_LOG_INFO(LOG_CORE, "EpollEventPollerTest.InitStartAddFd read %" PRIu64, readValue);
193 };
194 EXPECT_TRUE(eventPoller->AddFileDescriptor(notifier->GetFd(), onReadable));
195
196 uint64_t writeValue = 1234;
197 pid_t pid = fork();
198 EXPECT_GE(pid, 0);
199 if (pid == 0) {
200 int evFd = dup(notifier->GetFd());
201 auto evNotifier = EventNotifier::CreateWithFd(evFd);
202 evNotifier->Post(writeValue);
203 _exit(0);
204 } else if (pid > 0) {
205 int wstatus = 0;
206 waitpid(pid, &wstatus, 0);
207 }
208
209 std::this_thread::yield();
210 usleep(15 * 1000);
211 EXPECT_EQ(readValue, writeValue);
212
213 EXPECT_TRUE(eventPoller->Stop());
214 EXPECT_TRUE(eventPoller->Finalize());
215 }
216 } // namespace