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