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 "applypatch_unittest.h" 17#include <cerrno> 18#include <cstdio> 19#include <fcntl.h> 20#include <iostream> 21#include <libgen.h> 22#include <sys/mman.h> 23#include <sys/mount.h> 24#include <sys/stat.h> 25#include <unistd.h> 26#include <vector> 27#include "applypatch/data_writer.h" 28#include "fs_manager/mount.h" 29#include "log/log.h" 30#include "securec.h" 31#include "unittest_comm.h" 32#include "utils.h" 33 34namespace UpdaterUt { 35using namespace testing::ext; 36using namespace Updater; 37using namespace std; 38using namespace testing; 39constexpr unsigned int BUFFER_LEN = 12; 40 41void ApplyPatchUnitTest::SetUp() 42{ 43 unsigned long mountFlag = MS_REMOUNT; 44 std::string tmpPath = "/tmp"; 45 // mount rootfs to read-write. 46 std::string rootSource = "/dev/root"; 47 if (mount(rootSource.c_str(), "/", "ext4", mountFlag, nullptr) != 0) { 48 std::cout << "Cannot re-mount rootfs\n"; 49 } 50 auto ret = mkdir(tmpPath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 51 if (ret != 0) { 52 std::cout << "Cannot create \"/tmp\" directory: " << errno << "\n"; 53 } 54 55 // Load specific fstab for testing. 56 LoadSpecificFstab("/data/updater/applypatch/etc/fstab.ut.updater"); 57} 58 59void ApplyPatchUnitTest::TearDown() 60{ 61 std::string partitionName = "/rawwriter"; 62 auto devPath = GetBlockDeviceByMountPoint(partitionName); 63 unlink(devPath.c_str()); 64} 65 66HWTEST_F(ApplyPatchUnitTest, updater_RawWriter, TestSize.Level1) 67{ 68 WriteMode mode = WRITE_RAW; 69 uint8_t *addr = nullptr; 70 uint8_t buf[BUFFER_LEN + 1] = {0}; 71 72 std::string partitionName = "/rawwriter"; 73 std::string filePath = "/data/updater/ut/datawriter/rawwrite"; 74 std::unique_ptr<DataWriter> writer = DataWriter::CreateDataWriter(mode, filePath); 75 EXPECT_NE(writer, nullptr); 76 bool ret = writer->Write(addr, 0, nullptr); 77 EXPECT_FALSE(ret); 78 79 addr = buf; 80 ret = writer->Write(addr, 0, nullptr); 81 EXPECT_FALSE(ret); 82 83 ret = writer->Write(buf, BUFFER_LEN, nullptr); 84 EXPECT_FALSE(ret); 85 86 int mRet = memcpy_s(buf, BUFFER_LEN, "hello, world", BUFFER_LEN); 87 EXPECT_EQ(mRet, 0); 88 auto devPath = GetBlockDeviceByMountPoint(partitionName); 89 const std::string devDir = "/data/updater/ut/datawriter"; 90 Updater::Utils::MkdirRecursive(devDir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 91 close(open(devPath.c_str(), O_CREAT | O_WRONLY | O_EXCL, 0664)); 92 ret = writer->Write(buf, BUFFER_LEN, nullptr); 93 EXPECT_TRUE(ret); 94 95 int fd = open(devPath.c_str(), O_RDONLY); 96 EXPECT_GE(fd, 0); 97 98 uint8_t buffer[BUFFER_LEN + 1] = {0}; 99 size_t n = read(fd, buffer, BUFFER_LEN); 100 EXPECT_EQ(n, BUFFER_LEN); 101 102 auto result = memcmp(buf, buffer, BUFFER_LEN); 103 EXPECT_EQ(result, 0); 104 DataWriter::ReleaseDataWriter(writer); 105} 106 107HWTEST_F(ApplyPatchUnitTest, updater_CreateDataWriter, TestSize.Level1) 108{ 109 std::vector<WriteMode> modes = { WRITE_RAW, WRITE_DECRYPT }; 110 std::unique_ptr<DataWriter> writer = nullptr; 111 for (auto mode : modes) { 112 if (mode == WRITE_DECRYPT) { 113 EXPECT_EQ(writer, nullptr); 114 continue; 115 } 116 writer = DataWriter::CreateDataWriter(mode, "", DataWriter::GetUpdaterEnv()); 117 EXPECT_NE(writer, nullptr); 118 DataWriter::ReleaseDataWriter(writer); 119 writer = nullptr; 120 } 121} 122} // namespace updater_ut 123