1 /*
2  * Copyright (c) 2022 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 <cstdio>
17 #include <cstdlib>
18 #include <fcntl.h>
19 #include <cerrno>
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <sys/mman.h>
24 #include <sys/wait.h>
25 #include <climits>
26 #include <dirent.h>
27 #include <string>
28 #include "securec.h"
29 #include "gtest/gtest.h"
30 #include "dmabuf_alloc.h"
31 
32 using namespace testing;
33 using namespace testing::ext;
34 
35 namespace {
36 const int BUFFER_SIZE = 128;
37 
38 class DmabufAllocTest : public testing::Test {
39 public:
40     static void SetUpTestCase();
41     static void TearDownTestCase();
42     void SetUp();
43     void TearDown();
44     std::string heapName;
45 };
46 
SetUpTestCase()47 void DmabufAllocTest::SetUpTestCase()
48 {
49 }
50 
TearDownTestCase()51 void DmabufAllocTest::TearDownTestCase()
52 {
53 }
54 
SetUp()55 void DmabufAllocTest::SetUp()
56 {
57     std::string rootDir = "/dev/dma_heap/";
58     DIR *dir = opendir(rootDir.c_str());
59     if (dir == nullptr) {
60         return;
61     }
62     struct dirent *ptr;
63     while ((ptr = readdir(dir)) != nullptr) {
64         std::string fileName = ptr->d_name;
65         std::string::size_type idx = fileName.find("system");
66         if (idx != std::string::npos) {
67             heapName = fileName;
68             break;
69         }
70     }
71     closedir(dir);
72 }
73 
TearDown()74 void DmabufAllocTest::TearDown()
75 {
76 }
77 
HWTEST_F(DmabufAllocTest, AllocSingleBuffer, TestSize.Level1)78 HWTEST_F(DmabufAllocTest, AllocSingleBuffer, TestSize.Level1)
79 {
80     ASSERT_STRNE(heapName.c_str(), "");
81 
82     int heapFd = DmabufHeapOpen(heapName.c_str());
83     ASSERT_GE(heapFd, 0);
84 
85     DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
86     ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
87 
88     void *ptr = mmap(nullptr, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
89     ASSERT_TRUE(ptr != nullptr);
90 
91     ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
92 
93     ASSERT_GE(sprintf_s((char *)ptr, BUFFER_SIZE, "libdmabufheap"), 0);
94 
95     ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
96 
97     ASSERT_STREQ("libdmabufheap", (char *)ptr);
98 
99     ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
100 
101     ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
102 
103     ASSERT_EQ(0, DmabufHeapClose(heapFd));
104 }
105 
HWTEST_F(DmabufAllocTest, ShareBufferBetweenProcess, Function|MediumTest|Level1)106 HWTEST_F(DmabufAllocTest, ShareBufferBetweenProcess, Function|MediumTest|Level1)
107 {
108     ASSERT_STRNE(heapName.c_str(), "");
109 
110     int heapFd = DmabufHeapOpen(heapName.c_str());
111     ASSERT_GE(heapFd, 0);
112 
113     DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
114     ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
115 
116     void *ptr = mmap(nullptr, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
117     ASSERT_TRUE(ptr != nullptr);
118 
119     ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
120 
121     ASSERT_GE(sprintf_s((char *)ptr, BUFFER_SIZE, "parent"), 0);
122 
123     ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
124 
125     pid_t pid = fork();
126     ASSERT_GE(pid, 0);
127     /* child process */
128     if (pid == 0) {
129         ptr = mmap(nullptr, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
130         ASSERT_TRUE(ptr != nullptr);
131 
132         ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
133 
134         ASSERT_STREQ("parent", (char *)ptr);
135 
136         ASSERT_GE(sprintf_s((char *)ptr, BUFFER_SIZE, "child"), 0);
137 
138         ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
139 
140         ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
141 
142         ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
143 
144         exit(EXIT_SUCCESS);
145     }
146     /* parent process */
147     waitpid(pid, nullptr, 0);
148 
149     ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
150 
151     ASSERT_STREQ("child", (char *)ptr);
152 
153     ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
154 
155     ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
156 
157     ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
158 
159     ASSERT_EQ(0, DmabufHeapClose(heapFd));
160 }
161 
HWTEST_F(DmabufAllocTest, OpenInvalidNameHeap, Function|MediumTest|Level1)162 HWTEST_F(DmabufAllocTest, OpenInvalidNameHeap, Function|MediumTest|Level1)
163 {
164     int i;
165     std::string invalidName = "invalid";
166     int heapFd = DmabufHeapOpen(invalidName.c_str());
167     ASSERT_EQ(-EPERM, heapFd);
168 
169     for (i = 0; i < 20; i++) {
170         invalidName += "invalid";
171     }
172     heapFd = DmabufHeapOpen(invalidName.c_str());
173     ASSERT_EQ(-EINVAL, heapFd);
174 }
175 
HWTEST_F(DmabufAllocTest, AllocInvalidSizeBuffer, Function|MediumTest|Level1)176 HWTEST_F(DmabufAllocTest, AllocInvalidSizeBuffer, Function|MediumTest|Level1)
177 {
178     ASSERT_STRNE(heapName.c_str(), "");
179 
180     int heapFd = DmabufHeapOpen(heapName.c_str());
181     ASSERT_GE(heapFd, 0);
182 
183     DmabufHeapBuffer buffer = { .size = 0 };
184     ASSERT_EQ(-EINVAL, DmabufHeapBufferAlloc(heapFd, &buffer));
185 
186     ASSERT_EQ(0, DmabufHeapClose(heapFd));
187 }
188 
HWTEST_F(DmabufAllocTest, BufferSyncWithWrongFd, Function|MediumTest|Level1)189 HWTEST_F(DmabufAllocTest, BufferSyncWithWrongFd, Function|MediumTest|Level1)
190 {
191     ASSERT_STRNE(heapName.c_str(), "");
192 
193     const unsigned int wrongFd = UINT_MAX;
194 
195     int heapFd = DmabufHeapOpen(heapName.c_str());
196     ASSERT_GE(heapFd, 0);
197 
198     DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
199     ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
200 
201     void *ptr = mmap(nullptr, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
202     ASSERT_TRUE(ptr != nullptr);
203 
204     ASSERT_NE(0, DmabufHeapBufferSyncStart(wrongFd, DMA_BUF_HEAP_BUF_SYNC_RW));
205 
206     ASSERT_NE(0, DmabufHeapBufferSyncEnd(wrongFd, DMA_BUF_HEAP_BUF_SYNC_RW));
207 
208     ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
209 
210     ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
211 
212     ASSERT_EQ(0, DmabufHeapClose(heapFd));
213 }
214 
HWTEST_F(DmabufAllocTest, BufferSyncWithWrongSyncType, Function|MediumTest|Level1)215 HWTEST_F(DmabufAllocTest, BufferSyncWithWrongSyncType, Function|MediumTest|Level1)
216 {
217     ASSERT_STRNE(heapName.c_str(), "");
218 
219     const unsigned int wrongSyncType = UINT_MAX;
220 
221     int heapFd = DmabufHeapOpen(heapName.c_str());
222     ASSERT_GE(heapFd, 0);
223 
224     DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
225     ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
226 
227     void *ptr = mmap(nullptr, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
228     ASSERT_TRUE(ptr != nullptr);
229 
230     ASSERT_NE(0, DmabufHeapBufferSyncEnd(buffer.fd, (DmabufHeapBufferSyncType)wrongSyncType));
231 
232     ASSERT_NE(0, DmabufHeapBufferSyncStart(buffer.fd, (DmabufHeapBufferSyncType)wrongSyncType));
233 
234     ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
235 
236     ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
237 
238     ASSERT_EQ(0, DmabufHeapClose(heapFd));
239 }
240 
HWTEST_F(DmabufAllocTest, SyncBufferTwice, Function|MediumTest|Level1)241 HWTEST_F(DmabufAllocTest, SyncBufferTwice, Function|MediumTest|Level1)
242 {
243     ASSERT_STRNE(heapName.c_str(), "");
244 
245     int heapFd = DmabufHeapOpen(heapName.c_str());
246     ASSERT_GE(heapFd, 0);
247 
248     DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
249     ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
250 
251     void *ptr = mmap(nullptr, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
252     ASSERT_TRUE(ptr != nullptr);
253 
254     ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
255 
256     ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
257 
258     ASSERT_GE(sprintf_s((char *)ptr, BUFFER_SIZE, "libdmabufheap"), 0);
259 
260     ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
261 
262     ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
263 
264     ASSERT_STREQ("libdmabufheap", (char *)ptr);
265 
266     ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
267 
268     ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
269 
270     ASSERT_EQ(0, DmabufHeapClose(heapFd));
271 }
272 
HWTEST_F(DmabufAllocTest, ExchangeBufferSyncOrder, Function|MediumTest|Level1)273 HWTEST_F(DmabufAllocTest, ExchangeBufferSyncOrder, Function|MediumTest|Level1)
274 {
275     ASSERT_STRNE(heapName.c_str(), "");
276 
277     int heapFd = DmabufHeapOpen(heapName.c_str());
278     ASSERT_GE(heapFd, 0);
279 
280     DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
281     ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
282 
283     void *ptr = mmap(nullptr, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
284     ASSERT_TRUE(ptr != nullptr);
285 
286     ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
287 
288     ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
289 
290     ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
291 
292     ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
293 
294     ASSERT_EQ(0, DmabufHeapClose(heapFd));
295 }
296 }