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
16 #include <algorithm>
17 #include <fstream>
18 #include <iostream>
19 #include <unistd.h>
20 #include <sys/mman.h>
21 #include <gtest/gtest.h>
22 #include "directory_ex.h"
23 #include "securec.h"
24 #include "hilog/log.h"
25 #include "parcel.h"
26 #include "refbase.h"
27 #include "ashmem.h"
28
29 using namespace testing::ext;
30 using namespace OHOS;
31 using namespace std;
32
33 const int MAX_PARCEL_SIZE = 1000;
34 char g_data[MAX_PARCEL_SIZE];
35 const int32_t MEMORY_SIZE = 1024;
36 const std::string MEMORY_CONTENT = "HelloWorld2020\0";
37 const std::string MEMORY_NAME = "Test SharedMemory\0";
38 static constexpr HiviewDFX::HiLogLabel label = { LOG_CORE, 0xD003D00, "UtilsAshmemTest" };
39 #define UTILS_LOGF(...) (void)OHOS::HiviewDFX::HiLog::Fatal(label, __VA_ARGS__)
40 #define UTILS_LOGE(...) (void)OHOS::HiviewDFX::HiLog::Error(label, __VA_ARGS__)
41 #define UTILS_LOGW(...) (void)OHOS::HiviewDFX::HiLog::Warn(label, __VA_ARGS__)
42 #define UTILS_LOGI(...) (void)OHOS::HiviewDFX::HiLog::Info(label, __VA_ARGS__)
43 #define UTILS_LOGD(...) (void)OHOS::HiviewDFX::HiLog::Debug(label, __VA_ARGS__)
44
45 class UtilsAshmemTest : public testing::Test {
46 public:
47 static void TearDownTestCase(void);
48 };
49
TearDownTestCase(void)50 void UtilsAshmemTest::TearDownTestCase(void)
51 {
52 for (int i = 0; i < MAX_PARCEL_SIZE; i++) {
53 g_data[i] = 0;
54 }
55 }
56
57 /**
58 * @tc.name: test_ashmem_WriteAndRead_001
59 * @tc.desc: create and map ashmem
60 * @tc.type: FUNC
61 */
62 HWTEST_F(UtilsAshmemTest, test_ashmem_WriteAndRead_001, TestSize.Level0)
63 {
64 UTILS_LOGI("test_ashmem_WriteAndRead_001");
65
66 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE);
67 ASSERT_TRUE(ashmem != nullptr);
68 ASSERT_TRUE(ashmem->GetAshmemSize() == MEMORY_SIZE);
69
70 bool ret = ashmem->MapAshmem(PROT_READ | PROT_WRITE);
71 ASSERT_TRUE(ret);
72
73 ashmem->UnmapAshmem();
74 ashmem->CloseAshmem();
75 }
76
77 /**
78 * @tc.name: test_ashmem_WriteAndRead_002
79 * @tc.desc: write to and read from ashmem
80 * @tc.type: FUNC
81 */
82 HWTEST_F(UtilsAshmemTest, test_ashmem_WriteAndRead_002, TestSize.Level0)
83 {
84 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE);
85 ASSERT_TRUE(ashmem != nullptr);
86
87 bool ret = ashmem->MapReadAndWriteAshmem();
88 ASSERT_TRUE(ret);
89
90 ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0);
91 ASSERT_TRUE(ret);
92
93 ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), sizeof(MEMORY_CONTENT));
94 ASSERT_TRUE(ret);
95
96 auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0);
97 ASSERT_TRUE(readData != nullptr);
98
99 const char *readContent = reinterpret_cast<const char *>(readData);
100 EXPECT_EQ(memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)), 0);
101
102 readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), sizeof(MEMORY_CONTENT));
103 ASSERT_TRUE(readData != nullptr);
104
105 readContent = reinterpret_cast<const char *>(readData);
106 EXPECT_EQ(memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)), 0);
107
108 ashmem->UnmapAshmem();
109 ashmem->CloseAshmem();
110 }
111
112 /**
113 * @tc.name: test_ashmem_WriteAndRead_003
114 * @tc.desc: test read-only ashmem
115 * @tc.type: FUNC
116 */
117 HWTEST_F(UtilsAshmemTest, test_ashmem_WriteAndRead_003, TestSize.Level0)
118 {
119 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE);
120 ASSERT_TRUE(ashmem != nullptr);
121
122 bool ret = ashmem->MapReadAndWriteAshmem();
123 ASSERT_TRUE(ret);
124
125 ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0);
126 ASSERT_TRUE(ret);
127
128 ashmem->UnmapAshmem();
129
130 ret = ashmem->MapReadOnlyAshmem();
131 ASSERT_TRUE(ret);
132
133 ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), sizeof(MEMORY_CONTENT));
134 ASSERT_FALSE(ret);
135
136 auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0);
137 ASSERT_TRUE(readData != nullptr);
138
139 const char *readContent = reinterpret_cast<const char *>(readData);
140 EXPECT_EQ(memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)), 0);
141
142 ashmem->UnmapAshmem();
143 ashmem->CloseAshmem();
144 }
145
146 /**
147 * @tc.name: test_ashmem_WriteAndRead_004
148 * @tc.desc: set read-only protection and map again
149 * @tc.type: FUNC
150 */
151 HWTEST_F(UtilsAshmemTest, test_ashmem_WriteAndRead_004, TestSize.Level0)
152 {
153 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE);
154 ASSERT_TRUE(ashmem != nullptr);
155
156 bool ret = ashmem->MapReadAndWriteAshmem();
157 ASSERT_TRUE(ret);
158
159 ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0);
160 ASSERT_TRUE(ret);
161
162 ashmem->UnmapAshmem();
163
164 ret = ashmem->SetProtection(PROT_READ);
165 ASSERT_TRUE(ret);
166
167 ret = ashmem->MapReadAndWriteAshmem();
168 ASSERT_FALSE(ret);
169
170 ret = ashmem->MapReadOnlyAshmem();
171 ASSERT_TRUE(ret);
172
173 auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0);
174 ASSERT_TRUE(readData != nullptr);
175
176 const char *readContent = reinterpret_cast<const char *>(readData);
177 EXPECT_EQ(memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)), 0);
178
179 ashmem->UnmapAshmem();
180 ashmem->CloseAshmem();
181 }
182
183 /**
184 * @tc.name: test_ashmem_WriteAndRead_005
185 * @tc.desc: set read-only protection without mapping again
186 * @tc.type: FUNC
187 */
188 HWTEST_F(UtilsAshmemTest, test_ashmem_WriteAndRead_005, TestSize.Level0)
189 {
190 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE);
191 ASSERT_TRUE(ashmem != nullptr);
192
193 bool ret = ashmem->MapReadAndWriteAshmem();
194 ASSERT_TRUE(ret);
195
196 ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0);
197 ASSERT_TRUE(ret);
198
199 ret = ashmem->SetProtection(PROT_READ);
200 ASSERT_TRUE(ret);
201
202 ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0);
203 ASSERT_FALSE(ret);
204
205 auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0);
206 ASSERT_TRUE(readData != nullptr);
207
208 const char *readContent = reinterpret_cast<const char *>(readData);
209 EXPECT_EQ(memcmp(MEMORY_CONTENT.c_str(), readContent, sizeof(MEMORY_CONTENT)), 0);
210
211 ashmem->UnmapAshmem();
212 ashmem->CloseAshmem();
213 }
214
215 /**
216 * @tc.name: test_ashmem_InvalidOperation_001
217 * @tc.desc: create invalid-size ashmem or set invalid protection type
218 * @tc.type: FUNC
219 */
220 HWTEST_F(UtilsAshmemTest, test_ashmem_InvalidOperation_001, TestSize.Level0)
221 {
222 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), -1);
223 ASSERT_TRUE(ashmem == nullptr);
224
225 ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE);
226 ASSERT_TRUE(ashmem != nullptr);
227
228 bool ret = ashmem->SetProtection(-1);
229 ASSERT_FALSE(ret);
230
231 ashmem->CloseAshmem();
232 }
233
234 /**
235 * @tc.name: test_ashmem_InvalidOperation_002
236 * @tc.desc: map after closing ashmem
237 * @tc.type: FUNC
238 */
239 HWTEST_F(UtilsAshmemTest, test_ashmem_InvalidOperation_002, TestSize.Level0)
240 {
241 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE);
242 ASSERT_TRUE(ashmem != nullptr);
243
244 ashmem->CloseAshmem();
245
246 bool ret = ashmem->MapReadAndWriteAshmem();
247 ASSERT_FALSE(ret);
248 }
249
250 /**
251 * @tc.name: test_ashmem_InvalidOperation_003
252 * @tc.desc: write or read after closing ashmem
253 * @tc.type: FUNC
254 */
255 HWTEST_F(UtilsAshmemTest, test_ashmem_InvalidOperation_003, TestSize.Level0)
256 {
257 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE);
258 ASSERT_TRUE(ashmem != nullptr);
259
260 bool ret = ashmem->MapReadAndWriteAshmem();
261 ASSERT_TRUE(ret);
262
263 ashmem->CloseAshmem();
264
265 ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0);
266 ASSERT_FALSE(ret);
267
268 auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0);
269 ASSERT_TRUE(readData == nullptr);
270 }
271
272 /**
273 * @tc.name: test_ashmem_InvalidOperation_004
274 * @tc.desc: write or read after unmapping ashmem
275 * @tc.type: FUNC
276 */
277 HWTEST_F(UtilsAshmemTest, test_ashmem_InvalidOperation_004, TestSize.Level0)
278 {
279 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE);
280 ASSERT_TRUE(ashmem != nullptr);
281
282 bool ret = ashmem->MapReadAndWriteAshmem();
283 ASSERT_TRUE(ret);
284
285 ashmem->UnmapAshmem();
286
287 ret = ashmem->WriteToAshmem(MEMORY_CONTENT.c_str(), sizeof(MEMORY_CONTENT), 0);
288 ASSERT_FALSE(ret);
289
290 auto readData = ashmem->ReadFromAshmem(sizeof(MEMORY_CONTENT), 0);
291 ASSERT_TRUE(readData == nullptr);
292
293 ashmem->CloseAshmem();
294 }
295
296 /**
297 * @tc.name: test_ashmem_InvalidOperation_005
298 * @tc.desc: expand protection type
299 * @tc.type: FUNC
300 */
301 HWTEST_F(UtilsAshmemTest, test_ashmem_InvalidOperation_005, TestSize.Level0)
302 {
303 sptr<Ashmem> ashmem = Ashmem::CreateAshmem(MEMORY_NAME.c_str(), MEMORY_SIZE);
304 ASSERT_TRUE(ashmem != nullptr);
305
306 bool ret = ashmem->SetProtection(PROT_WRITE);
307 ASSERT_TRUE(ret);
308
309 ret = ashmem->SetProtection(PROT_READ);
310 ASSERT_FALSE(ret);
311
312 ret = ashmem->SetProtection(PROT_READ | PROT_WRITE);
313 ASSERT_FALSE(ret);
314
315 ret = ashmem->SetProtection(PROT_NONE);
316 ASSERT_TRUE(ret);
317
318 ret = ashmem->SetProtection(PROT_READ);
319 ASSERT_FALSE(ret);
320
321 ashmem->CloseAshmem();
322 }
323