1 /*
2 * Copyright (c) 2021 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 #include <gtest/gtest.h>
16 #include <securec.h>
17 #include <surface.h>
18 #include <surface_buffer_impl.h>
19 #include <buffer_manager.h>
20
21 using namespace testing;
22 using namespace testing::ext;
23
24 namespace OHOS::Rosen {
25 class BufferManagerTest : public testing::Test {
26 public:
27 static void SetUpTestCase();
28 static void TearDownTestCase();
29
30 static inline BufferRequestConfig requestConfig = {
31 .width = 0x100,
32 .height = 0x100,
33 .strideAlignment = 0x8,
34 .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
35 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
36 .timeout = 0,
37 };
38 static inline sptr<SurfaceBuffer> buffer = nullptr;
39 };
40
SetUpTestCase()41 void BufferManagerTest::SetUpTestCase()
42 {
43 buffer = new SurfaceBufferImpl();
44 }
45
TearDownTestCase()46 void BufferManagerTest::TearDownTestCase()
47 {
48 buffer = nullptr;
49 }
50
51 /*
52 * Function: GetInstance
53 * Type: Function
54 * Rank: Important(2)
55 * EnvConditions: N/A
56 * CaseDescription: 1. call GetInstance
57 */
58 HWTEST_F(BufferManagerTest, GetInstance001, Function | MediumTest | Level2)
59 {
60 ASSERT_NE(BufferManager::GetInstance(), nullptr);
61 }
62
63 /*
64 * Function: Alloc
65 * Type: Function
66 * Rank: Important(2)
67 * EnvConditions: N/A
68 * CaseDescription: 1. call GetBufferHandle
69 * 2. call GetInstance and Alloc
70 * 3. call GetBufferHandle
71 * 4. check ret and handle
72 */
73 HWTEST_F(BufferManagerTest, Alloc001, Function | MediumTest | Level2)
74 {
75 ASSERT_EQ(buffer->GetBufferHandle(), nullptr);
76
77 GSError ret = BufferManager::GetInstance()->Alloc(requestConfig, buffer);
78 ASSERT_EQ(ret, OHOS::GSERROR_OK);
79
80 BufferHandle *handle = buffer->GetBufferHandle();
81
82 ASSERT_NE(handle, nullptr);
83 ASSERT_EQ(handle->virAddr, nullptr);
84 }
85
86 /*
87 * Function: Map
88 * Type: Function
89 * Rank: Important(2)
90 * EnvConditions: N/A
91 * CaseDescription: 1. call GetBufferHandle
92 * 2. call GetInstance and Map
93 * 3. call GetBufferHandle
94 * 4. check ret and handle
95 */
96 HWTEST_F(BufferManagerTest, Map001, Function | MediumTest | Level2)
97 {
98 BufferHandle *handle;
99
100 handle = buffer->GetBufferHandle();
101 ASSERT_NE(handle, nullptr);
102 ASSERT_EQ(handle->virAddr, nullptr);
103
104 GSError ret = BufferManager::GetInstance()->Map(buffer);
105 ASSERT_EQ(ret, OHOS::GSERROR_OK);
106
107 handle = buffer->GetBufferHandle();
108 ASSERT_NE(handle, nullptr);
109 ASSERT_NE(handle->virAddr, nullptr);
110 }
111
112 /*
113 * Function: FlushCache before Unmap
114 * Type: Function
115 * Rank: Important(2)
116 * EnvConditions: N/A
117 * CaseDescription: 1. call GetBufferHandle
118 * 2. call GetInstance and FlushCache
119 * 3. call GetBufferHandle
120 * 4. check ret and handle
121 */
122 HWTEST_F(BufferManagerTest, FlushBufferBeforeUnmap001, Function | MediumTest | Level2)
123 {
124 BufferHandle *handle;
125
126 handle = buffer->GetBufferHandle();
127 ASSERT_NE(handle, nullptr);
128 ASSERT_NE(handle->virAddr, nullptr);
129
130 GSError ret = BufferManager::GetInstance()->FlushCache(buffer);
131 ASSERT_EQ(ret, OHOS::GSERROR_OK);
132
133 handle = buffer->GetBufferHandle();
134 ASSERT_NE(handle, nullptr);
135 ASSERT_NE(handle->virAddr, nullptr);
136 }
137
138 /*
139 * Function: Unmap
140 * Type: Function
141 * Rank: Important(2)
142 * EnvConditions: N/A
143 * CaseDescription: 1. call GetBufferHandle
144 * 2. call GetInstance and Unmap
145 * 3. call GetBufferHandle
146 * 4. check ret and handle
147 */
148 HWTEST_F(BufferManagerTest, Unmap001, Function | MediumTest | Level2)
149 {
150 BufferHandle *handle = buffer->GetBufferHandle();
151 ASSERT_NE(handle, nullptr);
152 ASSERT_NE(handle->virAddr, nullptr);
153
154 GSError ret = BufferManager::GetInstance()->Unmap(buffer);
155 ASSERT_EQ(ret, OHOS::GSERROR_OK);
156
157 handle = buffer->GetBufferHandle();
158 ASSERT_NE(handle, nullptr);
159 ASSERT_EQ(handle->virAddr, nullptr);
160 }
161
162 /*
163 * Function: FlushCache after Unmap
164 * Type: Function
165 * Rank: Important(2)
166 * EnvConditions: N/A
167 * CaseDescription: 1. call GetBufferHandle
168 * 2. call GetInstance and FlushCache
169 * 3. call GetBufferHandle
170 * 4. check ret and handle
171 */
172 HWTEST_F(BufferManagerTest, FlushBufferAfterUnmap001, Function | MediumTest | Level2)
173 {
174 BufferHandle *handle;
175
176 handle = buffer->GetBufferHandle();
177 ASSERT_NE(handle, nullptr);
178 ASSERT_EQ(handle->virAddr, nullptr);
179
180 BufferManager::GetInstance()->FlushCache(buffer);
181
182 handle = buffer->GetBufferHandle();
183 ASSERT_NE(handle, nullptr);
184 ASSERT_EQ(handle->virAddr, nullptr);
185 }
186
187 /*
188 * Function: Free
189 * Type: Function
190 * Rank: Important(2)
191 * EnvConditions: N/A
192 * CaseDescription: 1. call GetBufferHandle
193 * 2. call GetInstance and Free
194 * 3. call GetBufferHandle
195 * 4. check ret and handle
196 */
197 HWTEST_F(BufferManagerTest, Free001, Function | MediumTest | Level2)
198 {
199 BufferHandle *handle;
200
201 handle = buffer->GetBufferHandle();
202 ASSERT_NE(handle, nullptr);
203 ASSERT_EQ(handle->virAddr, nullptr);
204
205 GSError ret = BufferManager::GetInstance()->Free(buffer);
206 ASSERT_EQ(ret, OHOS::GSERROR_OK);
207
208 handle = buffer->GetBufferHandle();
209 ASSERT_EQ(handle, nullptr);
210 }
211
212 /*
213 * Function: cma leak
214 * Type: Function
215 * Rank: Important(2)
216 * EnvConditions: N/A
217 * CaseDescription: 1. get cma free
218 * 2. alloc
219 * 3. free
220 * 4. get cma free again
221 * 5. diff should less then 1000KB
222 */
223 HWTEST_F(BufferManagerTest, CMALeak001, Function | MediumTest | Level2)
224 {
225 // 0. buffer size = 1024KB
226 constexpr uint32_t width = 1024 * 3;
227 constexpr uint32_t height = 1024 / 4;
228 constexpr uint32_t strideAlignment = 8;
229 BufferRequestConfig requestConfig = {
230 .width = width,
231 .height = height,
232 .strideAlignment = strideAlignment,
233 .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
234 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
235 .timeout = 0,
236 };
237
238 // 1. get cma free
__anon4ece14ec0102() 239 auto getCmaFree = []() -> uint32_t {
240 FILE *fp = fopen("/proc/meminfo", "r");
241 if (fp == nullptr) {
242 GTEST_LOG_(INFO) << "fopen return " << errno << std::endl;
243 return 0;
244 }
245
246 constexpr int keyLength = 32;
247 char key[keyLength];
248 int cmaFree = 0;
249 while (fscanf_s(fp, "%s%d%*s", key, sizeof(key), &cmaFree) > 0) {
250 if (strcmp(key, "CmaFree:") == 0) {
251 return cmaFree;
252 }
253 }
254
255 fclose(fp);
256 return 0;
257 };
258
259 int32_t first = getCmaFree();
260
261 // 2. alloc
262 sptr<SurfaceBuffer> buffer = new SurfaceBufferImpl();
263 GSError ret = BufferManager::GetInstance()->Alloc(requestConfig, buffer);
264 ASSERT_EQ(ret, OHOS::GSERROR_OK);
265
266 auto handle = buffer->GetBufferHandle();
267 ASSERT_NE(handle, nullptr);
268 ASSERT_EQ(handle->virAddr, nullptr);
269
270 // 3. free
271 ret = BufferManager::GetInstance()->Free(buffer);
272 ASSERT_EQ(ret, OHOS::GSERROR_OK);
273
274 handle = buffer->GetBufferHandle();
275 ASSERT_EQ(handle, nullptr);
276
277 // 4. get cma free again
278 int32_t third = getCmaFree();
279
280 // 5. diff should less then 1000KB
281 GTEST_LOG_(INFO) << "diff: " << first - third;
282 ASSERT_LT(first - third, 1000);
283 }
284 }
285