• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
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 
16 #include <gtest/gtest.h>
17 
18 #include "native_fence.h"
19 
20 #include <chrono>
21 #include <cstring>
22 #include <cerrno>
23 #include <fcntl.h>
24 #include <iostream>
25 #include <linux/sync_file.h>
26 #include <csignal>
27 #include <sys/ioctl.h>
28 #include <sys/signalfd.h>
29 #include <thread>
30 #include <unistd.h>
31 
32 namespace OHOS {
33 namespace {
34     constexpr int INVALID_FD = -1;
35     constexpr uint32_t TIMEOUT_MS = 5000;
36 } // namespace
37 
38 class NativeFenceTest : public testing::Test {
39 public:
SetUpTestCase()40     static void SetUpTestCase() {}
TearDownTestCase()41     static void TearDownTestCase() {}
SetUp()42     void SetUp() {}
TearDown()43     void TearDown() {}
44 };
45 
46 /*
47  * Function: NativeFenceWaitTest
48  * Type: Function
49  * Rank: Important(2)
50  * EnvConditions: N/A
51  * CaseDescription: 1. preSetUp: open a valid fence fd.
52  *                  2. operation: call OH_NativeFence_Wait with valid fence fd and timeout.
53  *                  3. result: OH_NativeFence_Wait returns false because no event occurred after timeout.
54  */
TEST_F(NativeFenceTest,NativeFenceWaitTest)55 TEST_F(NativeFenceTest, NativeFenceWaitTest)
56 {
57     // Test invalid fence fd
58     bool result = OH_NativeFence_Wait(INVALID_FD, TIMEOUT_MS);
59     EXPECT_FALSE(result);
60 
61     // Test valid fence fd
62     int fd = open("/dev/GPIO_TEST", O_RDONLY);
63     ASSERT_GE(fd, 0);
64     bool result2 = false;
65     result2 = OH_NativeFence_Wait(fd, 0);
66     EXPECT_FALSE(result2);
67     auto startTime = std::chrono::steady_clock::now();
68     result2 = OH_NativeFence_Wait(fd, TIMEOUT_MS);
69     auto endTime = std::chrono::steady_clock::now();
70     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
71     std::cout << "OH_NativeFence_Wait cost time:   " << duration << "ms" << std::endl;
72     EXPECT_FALSE(result2);
73     OH_NativeFence_Close(fd);
74 }
75 
76 /*
77  * Function: NativeFenceWaitWithSignalTest
78  * Type: Function
79  * Rank: Important(2)
80  * EnvConditions: N/A
81  * CaseDescription: 1. preSetUp: create a valid fence fd by signalfd.
82  *                  2. operation: waitThread call OH_NativeFence_Wait with valid fence fd and timeout. \n
83  *                                mainThread call kill to send signal after 3 seconds.
84  *                  3. result: OH_NativeFence_Wait should return true because has event occurred after 3 seconds.
85  */
TEST_F(NativeFenceTest,NativeFenceWaitWithSignalTest)86 TEST_F(NativeFenceTest, NativeFenceWaitWithSignalTest)
87 {
88     // Test invalid fence fd
89     bool result = OH_NativeFence_Wait(INVALID_FD, TIMEOUT_MS);
90     EXPECT_FALSE(result);
91 
92     std::atomic<bool> signaled(false);
93     sigset_t mask;
94     sigemptyset(&mask);
95     sigaddset(&mask, SIGINT); // Monitor SIGINT signal (Ctrl C)
96     sigaddset(&mask, SIGTERM); // Monitor SIGTERM signal (kill command)
97     sigprocmask(SIG_BLOCK, &mask, nullptr);
98     int sfd = signalfd(-1, &mask, 0);
99     if (sfd == -1) {
100         perror("signalfd failed");
101         exit(1);
102     }
103 
104     std::thread waitThread([&]() {
105         bool result2 = false;
106         auto startTime = std::chrono::steady_clock::now();
107         result2 = OH_NativeFence_Wait(sfd, TIMEOUT_MS);
108         auto endTime = std::chrono::steady_clock::now();
109         auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
110         std::cout << "OH_NativeFence_Wait cost time:   " << duration << "ms" << std::endl;
111         EXPECT_TRUE(result2);
112         signaled.store(true);
113     });
114 
115     std::this_thread::sleep_for(std::chrono::seconds(3)); // 3 means main thread sleep 3 seconds.
116     pid_t target_pid = getpid();
117     int ret = kill(target_pid, SIGINT);
118     if (ret < 0) {
119         FAIL() << "kill failed: " << strerror(errno);
120     }
121 
122     // Waiting for waitThread to complete
123     waitThread.join();
124 
125     // checks the signaled variable to ensure that OH_NativeFence_Wait has returned
126     EXPECT_TRUE(signaled.load());
127     OH_NativeFence_Close(sfd);
128 }
129 
130 /*
131  * Function: NativeFenceIsValidTest
132  * Type: Function
133  * Rank: Important(2)
134  * EnvConditions: N/A
135  * CaseDescription: 1. preSetUp: create a valid and invalid fence fd.
136  *                  2. operation: call the OH_NativeFence_IsValid with a fence fd.
137  *                  3. result: legitimate ID returns true, illegal ID returns false.
138  */
TEST_F(NativeFenceTest,NativeFenceIsValidTest)139 TEST_F(NativeFenceTest, NativeFenceIsValidTest)
140 {
141     // Test invalid fence fd
142     bool result = OH_NativeFence_IsValid(INVALID_FD);
143     EXPECT_FALSE(result);
144 
145     OH_NativeFence_Close(INVALID_FD);
146 
147     // Test valid fence fd
148     int fd = open("/dev/GPIO_TEST", O_RDONLY);
149     ASSERT_GE(fd, 0);
150     result = OH_NativeFence_IsValid(fd);
151     EXPECT_TRUE(result);
152     OH_NativeFence_Close(fd);
153 }
154 
155 /*
156  * Function: NativeFenceLoopCallInterfaceTest
157  * Type: Function
158  * Rank: Important(2)
159  * EnvConditions: N/A
160  * CaseDescription: 1. preSetUp: create a valid fence fd.
161  *                  2. operation: call the OH_NativeFence_IsValid and OH_NativeFence_Close with 1000 times.
162  *                  3. result: Interface execution without crash.
163  */
TEST_F(NativeFenceTest,NativeFenceLoopCallInterfaceTest)164 TEST_F(NativeFenceTest, NativeFenceLoopCallInterfaceTest)
165 {
166     auto start = std::chrono::high_resolution_clock::now();
167     for (auto i = 0; i != 1000; i++) { // 1000 represents the number of cycles
168         bool result = OH_NativeFence_IsValid(INVALID_FD);
169         EXPECT_FALSE(result);
170     }
171     auto end = std::chrono::high_resolution_clock::now();
172     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
173     std::cout << "OH_NativeFence_IsValid cost time:   " << duration.count() << "ms" << std::endl;
174     ASSERT_GE(duration.count(), 0);
175 
176     start = std::chrono::high_resolution_clock::now();
177     for (auto i = 0; i != 1000; i++) { // 1000 represents the number of cycles
178         int fd = open("/dev/GPIO_TEST", O_RDONLY);
179         ASSERT_GE(fd, 0);
180         OH_NativeFence_Close(fd);
181     }
182     end = std::chrono::high_resolution_clock::now();
183     duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
184     std::cout << "OH_NativeFence_Close cost time:   " << duration.count() << "ms" << std::endl;
185     ASSERT_GE(duration.count(), 0);
186 }
187 
188 /*
189  * Function: NativeFenceWaitForeverWithSignalTest
190  * Type: Function
191  * Rank: Important(2)
192  * EnvConditions: N/A
193  * CaseDescription: 1. preSetUp: create a valid fence fd by signalfd.
194  *                  2. operation: waitThread call OH_NativeFence_WaitForever with valid fence fd and timeout. \n
195  *                                mainThread call kill to send signal after 3 seconds.
196  *                  3. result: OH_NativeFence_WaitForever should return true because has event occurred after 3 seconds.
197  */
TEST_F(NativeFenceTest,NativeFenceWaitForeverWithSignalTest)198 TEST_F(NativeFenceTest, NativeFenceWaitForeverWithSignalTest)
199 {
200     // Test invalid fence fd
201     bool result = OH_NativeFence_WaitForever(INVALID_FD);
202     EXPECT_FALSE(result);
203 
204     std::atomic<bool> signaled(false);
205     sigset_t mask;
206     sigemptyset(&mask);
207     sigaddset(&mask, SIGINT); // Monitor SIGINT signal (Ctrl C)
208     sigaddset(&mask, SIGTERM); // Monitor SIGTERM signal (kill command)
209     sigprocmask(SIG_BLOCK, &mask, nullptr);
210 
211     int sfd = signalfd(-1, &mask, 0);
212     if (sfd == -1) {
213         perror("signalfd failed");
214         exit(1);
215     }
216     std::thread waitThread([&]() {
217         bool result2 = false;
218         result2 = OH_NativeFence_WaitForever(sfd);
219         EXPECT_TRUE(result2);
220         signaled.store(true);
221     });
222     std::this_thread::sleep_for(std::chrono::seconds(3)); // 3 means main thread sleep 3 seconds.
223     pid_t target_pid = getpid();
224     int ret = kill(target_pid, SIGINT);
225     if (ret < 0) {
226         FAIL() << "kill failed: " << strerror(errno);
227     }
228 
229     // Waiting for waitThread to complete
230     waitThread.join();
231 
232     // checks the signaled variable to ensure that OH_NativeFence_WaitForever has returned
233     EXPECT_TRUE(signaled.load());
234     OH_NativeFence_Close(sfd);
235 }
236 } // namespace OHOS