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 "gtest/gtest.h"
29 #include "securec.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
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
87 SetOwnerIdForHeapFlags(&buffer, DMA_OWNER_MEDIA_CODEC);
88
89 __u64 ownerId = get_owner_id_from_heap_flags(buffer.heapFlags);
90
91 ASSERT_EQ(DMA_OWNER_MEDIA_CODEC, ownerId);
92
93 ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
94
95 void *ptr = mmap(NULL, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
96 ASSERT_TRUE(ptr != NULL);
97
98 ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
99
100 ASSERT_GE(sprintf_s((char *)ptr, BUFFER_SIZE, "libdmabufheap"), 0);
101
102 ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
103
104 ASSERT_STREQ("libdmabufheap", (char *)ptr);
105
106 ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
107
108 ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
109
110 ASSERT_EQ(0, DmabufHeapClose(heapFd));
111 }
112
113 HWTEST_F(DmabufAllocTest, ShareBufferBetweenProcess, Function|MediumTest|Level1)
114 {
115 ASSERT_STRNE(heapName.c_str(), "");
116
117 int heapFd = DmabufHeapOpen(heapName.c_str());
118 ASSERT_GE(heapFd, 0);
119
120 DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
121 ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
122
123 void *ptr = mmap(NULL, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
124 ASSERT_TRUE(ptr != NULL);
125
126 ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
127
128 ASSERT_GE(sprintf_s((char *)ptr, BUFFER_SIZE, "parent"), 0);
129
130 ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
131
132 pid_t pid = fork();
133 ASSERT_GE(pid, 0);
134 /* child process */
135 if (pid == 0) {
136 ptr = mmap(NULL, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
137 ASSERT_TRUE(ptr != NULL);
138
139 ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
140
141 ASSERT_STREQ("parent", (char *)ptr);
142
143 ASSERT_GE(sprintf_s((char *)ptr, BUFFER_SIZE, "child"), 0);
144
145 ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
146
147 ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
148
149 ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
150
151 exit(EXIT_SUCCESS);
152 }
153 /* parent process */
154 waitpid(pid, nullptr, 0);
155
156 ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
157
158 ASSERT_STREQ("child", (char *)ptr);
159
160 ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
161
162 ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
163
164 ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
165
166 ASSERT_EQ(0, DmabufHeapClose(heapFd));
167 }
168
169 HWTEST_F(DmabufAllocTest, OpenInvalidNameHeap, Function|MediumTest|Level1)
170 {
171 int i;
172 std::string invalidName = "invalid";
173 int heapFd = DmabufHeapOpen(invalidName.c_str());
174 ASSERT_EQ(-EPERM, heapFd);
175
176 for (i = 0; i < 20; i++) {
177 invalidName += "invalid";
178 }
179 heapFd = DmabufHeapOpen(invalidName.c_str());
180 ASSERT_EQ(-EINVAL, heapFd);
181 }
182
183 HWTEST_F(DmabufAllocTest, AllocInvalidSizeBuffer, Function|MediumTest|Level1)
184 {
185 ASSERT_STRNE(heapName.c_str(), "");
186
187 int heapFd = DmabufHeapOpen(heapName.c_str());
188 ASSERT_GE(heapFd, 0);
189
190 DmabufHeapBuffer buffer = { .size = 0 };
191 ASSERT_EQ(-EINVAL, DmabufHeapBufferAlloc(heapFd, &buffer));
192
193 ASSERT_EQ(0, DmabufHeapClose(heapFd));
194 }
195
196 HWTEST_F(DmabufAllocTest, BufferSyncWithWrongFd, Function|MediumTest|Level1)
197 {
198 ASSERT_STRNE(heapName.c_str(), "");
199
200 const unsigned int WRONG_FD = UINT_MAX;
201
202 int heapFd = DmabufHeapOpen(heapName.c_str());
203 ASSERT_GE(heapFd, 0);
204
205 DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
206 ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
207
208 void *ptr = mmap(NULL, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
209 ASSERT_TRUE(ptr != NULL);
210
211 ASSERT_NE(0, DmabufHeapBufferSyncStart(WRONG_FD, DMA_BUF_HEAP_BUF_SYNC_RW));
212
213 ASSERT_NE(0, DmabufHeapBufferSyncEnd(WRONG_FD, DMA_BUF_HEAP_BUF_SYNC_RW));
214
215 ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
216
217 ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
218
219 ASSERT_EQ(0, DmabufHeapClose(heapFd));
220 }
221
222 HWTEST_F(DmabufAllocTest, BufferSyncWithWrongSyncType, Function|MediumTest|Level1)
223 {
224 ASSERT_STRNE(heapName.c_str(), "");
225
226 const unsigned int WRONG_SYNC_TYPE = UINT_MAX;
227
228 int heapFd = DmabufHeapOpen(heapName.c_str());
229 ASSERT_GE(heapFd, 0);
230
231 DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
232 ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
233
234 void *ptr = mmap(NULL, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
235 ASSERT_TRUE(ptr != NULL);
236
237 ASSERT_NE(0, DmabufHeapBufferSyncEnd(buffer.fd, (DmabufHeapBufferSyncType)WRONG_SYNC_TYPE));
238
239 ASSERT_NE(0, DmabufHeapBufferSyncStart(buffer.fd, (DmabufHeapBufferSyncType)WRONG_SYNC_TYPE));
240
241 ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
242
243 ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
244
245 ASSERT_EQ(0, DmabufHeapClose(heapFd));
246 }
247
248 HWTEST_F(DmabufAllocTest, SyncBufferTwice, Function|MediumTest|Level1)
249 {
250 ASSERT_STRNE(heapName.c_str(), "");
251
252 int heapFd = DmabufHeapOpen(heapName.c_str());
253 ASSERT_GE(heapFd, 0);
254
255 DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
256 ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
257
258 void *ptr = mmap(NULL, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
259 ASSERT_TRUE(ptr != NULL);
260
261 ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
262
263 ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
264
265 ASSERT_GE(sprintf_s((char *)ptr, BUFFER_SIZE, "libdmabufheap"), 0);
266
267 ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
268
269 ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
270
271 ASSERT_STREQ("libdmabufheap", (char *)ptr);
272
273 ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
274
275 ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
276
277 ASSERT_EQ(0, DmabufHeapClose(heapFd));
278 }
279
280 HWTEST_F(DmabufAllocTest, ExchangeBufferSyncOrder, Function|MediumTest|Level1)
281 {
282 ASSERT_STRNE(heapName.c_str(), "");
283
284 int heapFd = DmabufHeapOpen(heapName.c_str());
285 ASSERT_GE(heapFd, 0);
286
287 DmabufHeapBuffer buffer = { .size = BUFFER_SIZE, .heapFlags = 0 };
288 ASSERT_EQ(0, DmabufHeapBufferAlloc(heapFd, &buffer));
289
290 void *ptr = mmap(NULL, BUFFER_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, buffer.fd, 0);
291 ASSERT_TRUE(ptr != NULL);
292
293 ASSERT_EQ(0, DmabufHeapBufferSyncEnd(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
294
295 ASSERT_EQ(0, DmabufHeapBufferSyncStart(buffer.fd, DMA_BUF_HEAP_BUF_SYNC_RW));
296
297 ASSERT_EQ(0, munmap(ptr, BUFFER_SIZE));
298
299 ASSERT_EQ(0, DmabufHeapBufferFree(&buffer));
300
301 ASSERT_EQ(0, DmabufHeapClose(heapFd));
302 }
303 }