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, &notifier]() {
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