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 }