• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }