1fb299fa2Sopenharmony_ci/* 2fb299fa2Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at 6fb299fa2Sopenharmony_ci * 7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb299fa2Sopenharmony_ci * 9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and 13fb299fa2Sopenharmony_ci * limitations under the License. 14fb299fa2Sopenharmony_ci */ 15fb299fa2Sopenharmony_ci 16fb299fa2Sopenharmony_ci#include <fcntl.h> 17fb299fa2Sopenharmony_ci#include <gmock/gmock.h> 18fb299fa2Sopenharmony_ci#include <gtest/gtest.h> 19fb299fa2Sopenharmony_ci#include <iostream> 20fb299fa2Sopenharmony_ci#include <string> 21fb299fa2Sopenharmony_ci#include "applypatch/block_set.h" 22fb299fa2Sopenharmony_ci#include "applypatch/store.h" 23fb299fa2Sopenharmony_ci#include "applypatch/transfer_manager.h" 24fb299fa2Sopenharmony_ci#include "log/log.h" 25fb299fa2Sopenharmony_ci#include "utils.h" 26fb299fa2Sopenharmony_ci 27fb299fa2Sopenharmony_ci 28fb299fa2Sopenharmony_ciusing namespace testing::ext; 29fb299fa2Sopenharmony_ciusing namespace Updater; 30fb299fa2Sopenharmony_ciusing namespace std; 31fb299fa2Sopenharmony_cinamespace UpdaterUt { 32fb299fa2Sopenharmony_ciclass AllCmdUnitTest : public testing::Test { 33fb299fa2Sopenharmony_cipublic: 34fb299fa2Sopenharmony_ci static void SetUpTestCase(void); 35fb299fa2Sopenharmony_ci static void TearDownTestCase(void) {}; 36fb299fa2Sopenharmony_ci void SetUp(); 37fb299fa2Sopenharmony_ci void TearDown(); 38fb299fa2Sopenharmony_ci bool WriteTestBin(int fd, const uint8_t &data, size_t size) const; 39fb299fa2Sopenharmony_ci bool GetTransferContents(const std::string &transferFile, std::string &contents) const; 40fb299fa2Sopenharmony_ci int AllCmdUnitTestMove(int &fd, std::vector<std::string> &allCmd, TransferManager &tm); 41fb299fa2Sopenharmony_ci void FillTransferHeader(std::vector<std::string> &command, const std::string &headerBuffer) const 42fb299fa2Sopenharmony_ci { 43fb299fa2Sopenharmony_ci std::vector<std::string> headInfos = Updater::Utils::SplitString(headerBuffer); 44fb299fa2Sopenharmony_ci for (const auto &headInfo : headInfos) { 45fb299fa2Sopenharmony_ci command.push_back(headInfo); 46fb299fa2Sopenharmony_ci } 47fb299fa2Sopenharmony_ci } 48fb299fa2Sopenharmony_ci}; 49fb299fa2Sopenharmony_ci 50fb299fa2Sopenharmony_civoid AllCmdUnitTest::SetUpTestCase() 51fb299fa2Sopenharmony_ci{ 52fb299fa2Sopenharmony_ci cout << "Updater Unit AllCmdUnitTest Setup!" << endl; 53fb299fa2Sopenharmony_ci} 54fb299fa2Sopenharmony_ci 55fb299fa2Sopenharmony_civoid AllCmdUnitTest::SetUp() 56fb299fa2Sopenharmony_ci{ 57fb299fa2Sopenharmony_ci cout << "Updater Unit AllCmdUnitTest Begin!" << endl; 58fb299fa2Sopenharmony_ci} 59fb299fa2Sopenharmony_ci 60fb299fa2Sopenharmony_civoid AllCmdUnitTest::TearDown() 61fb299fa2Sopenharmony_ci{ 62fb299fa2Sopenharmony_ci cout << "Updater Unit AllCmdUnitTest End!" << endl; 63fb299fa2Sopenharmony_ci} 64fb299fa2Sopenharmony_ci 65fb299fa2Sopenharmony_cibool AllCmdUnitTest::GetTransferContents(const std::string &transferFile, std::string &contents) const 66fb299fa2Sopenharmony_ci{ 67fb299fa2Sopenharmony_ci int fd = open(transferFile.c_str(), O_RDONLY | O_CLOEXEC); 68fb299fa2Sopenharmony_ci if (fd < 0) { 69fb299fa2Sopenharmony_ci return false; 70fb299fa2Sopenharmony_ci } 71fb299fa2Sopenharmony_ci contents.clear(); 72fb299fa2Sopenharmony_ci bool rc = Updater::Utils::ReadFileToString(fd, contents); 73fb299fa2Sopenharmony_ci close(fd); 74fb299fa2Sopenharmony_ci return rc; 75fb299fa2Sopenharmony_ci} 76fb299fa2Sopenharmony_ci 77fb299fa2Sopenharmony_cibool AllCmdUnitTest::WriteTestBin(int fd, const uint8_t &data, size_t size) const 78fb299fa2Sopenharmony_ci{ 79fb299fa2Sopenharmony_ci ssize_t written = 0; 80fb299fa2Sopenharmony_ci size_t rest = size; 81fb299fa2Sopenharmony_ci size_t count = 4096; 82fb299fa2Sopenharmony_ci 83fb299fa2Sopenharmony_ci const uint8_t *p = &data; 84fb299fa2Sopenharmony_ci while (rest > 0) { 85fb299fa2Sopenharmony_ci do { 86fb299fa2Sopenharmony_ci written = write(fd, p, count); 87fb299fa2Sopenharmony_ci } while (written < 0 && errno == EINTR); 88fb299fa2Sopenharmony_ci 89fb299fa2Sopenharmony_ci if (written < 0) { 90fb299fa2Sopenharmony_ci return false; 91fb299fa2Sopenharmony_ci } 92fb299fa2Sopenharmony_ci rest -= written; 93fb299fa2Sopenharmony_ci } 94fb299fa2Sopenharmony_ci return true; 95fb299fa2Sopenharmony_ci} 96fb299fa2Sopenharmony_ci 97fb299fa2Sopenharmony_ci// Testcase for testing all commands without "new" command. 98fb299fa2Sopenharmony_ci// new command is not easy to simulate, it depends on 99fb299fa2Sopenharmony_ci// compression and other condition. 100fb299fa2Sopenharmony_ci// Leave new command to be covered by update_image_block test. 101fb299fa2Sopenharmony_ciHWTEST_F(AllCmdUnitTest, allCmd_test_001, TestSize.Level1) 102fb299fa2Sopenharmony_ci{ 103fb299fa2Sopenharmony_ci std::unique_ptr<TransferManager> tm = std::make_unique<TransferManager>(); 104fb299fa2Sopenharmony_ci // Read source 105fb299fa2Sopenharmony_ci 106fb299fa2Sopenharmony_ci char filename[] = {"/data/updater/updater/allCmdUnitTest.bin"}; 107fb299fa2Sopenharmony_ci int fd = open(filename, O_RDWR); 108fb299fa2Sopenharmony_ci if (fd == -1) { 109fb299fa2Sopenharmony_ci std::cout << "Failed to open test data allCmdUnitTest.bin : " << errno << std::endl; 110fb299fa2Sopenharmony_ci return; 111fb299fa2Sopenharmony_ci } 112fb299fa2Sopenharmony_ci 113fb299fa2Sopenharmony_ci std::string transferContents = ""; 114fb299fa2Sopenharmony_ci // Read transfer list then run all commands. 115fb299fa2Sopenharmony_ci // Cover all correct transfer data, expect all commands return correctly. 116fb299fa2Sopenharmony_ci bool rc = GetTransferContents("/data/updater/applypatch/cmd_001_correct.transfer.list", transferContents); 117fb299fa2Sopenharmony_ci EXPECT_TRUE(rc); 118fb299fa2Sopenharmony_ci std::vector<std::string> transferLines = Updater::Utils::SplitString(transferContents, "\n"); 119fb299fa2Sopenharmony_ci std::cout << "Dump transfer lines: " << std::endl; 120fb299fa2Sopenharmony_ci for (const auto &line : transferLines) { 121fb299fa2Sopenharmony_ci std::cout << line << std::endl; 122fb299fa2Sopenharmony_ci } 123fb299fa2Sopenharmony_ci std::cout << "Dump transfer line done." << std::endl; 124fb299fa2Sopenharmony_ci tm->GetTransferParams()->storeBase = "/data/updater/update_tmp"; 125fb299fa2Sopenharmony_ci std::string storePath = "/data/updater/update_tmp"; 126fb299fa2Sopenharmony_ci Store::CreateNewSpace(storePath, false); 127fb299fa2Sopenharmony_ci rc = tm->CommandsParser(fd, transferLines); 128fb299fa2Sopenharmony_ci EXPECT_TRUE(rc); 129fb299fa2Sopenharmony_ci} 130fb299fa2Sopenharmony_ci 131fb299fa2Sopenharmony_ciint AllCmdUnitTest::AllCmdUnitTestMove(int &fd, std::vector<std::string> &allCmd, TransferManager &tm) 132fb299fa2Sopenharmony_ci{ 133fb299fa2Sopenharmony_ci size_t bufferSize = 4096; 134fb299fa2Sopenharmony_ci size_t count = 10; 135fb299fa2Sopenharmony_ci std::vector<uint8_t> buffer1(bufferSize, 1); 136fb299fa2Sopenharmony_ci lseek64(fd, 0, SEEK_SET); 137fb299fa2Sopenharmony_ci auto res = WriteTestBin(fd, *buffer1.data(), bufferSize * count); 138fb299fa2Sopenharmony_ci if (!res) { 139fb299fa2Sopenharmony_ci printf("Write to bin error\n"); 140fb299fa2Sopenharmony_ci } 141fb299fa2Sopenharmony_ci 142fb299fa2Sopenharmony_ci std::string baseBlockPair = "2,1,2"; 143fb299fa2Sopenharmony_ci BlockSet baseBlock; 144fb299fa2Sopenharmony_ci baseBlock.ParserAndInsert(baseBlockPair); 145fb299fa2Sopenharmony_ci if (baseBlock.WriteZeroToBlock(fd, false) != 0) { 146fb299fa2Sopenharmony_ci std::cout << "Write 0 to bin error: " << errno << std::endl; 147fb299fa2Sopenharmony_ci } 148fb299fa2Sopenharmony_ci 149fb299fa2Sopenharmony_ci allCmd.pop_back(); 150fb299fa2Sopenharmony_ci allCmd.push_back("move ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7 2,0,1 1 2,1,2"); 151fb299fa2Sopenharmony_ci bool result = tm.CommandsParser(fd, allCmd); 152fb299fa2Sopenharmony_ci LOG(INFO) << "CommandsParser result:" << result; 153fb299fa2Sopenharmony_ci 154fb299fa2Sopenharmony_ci lseek64(fd, 0, SEEK_SET); 155fb299fa2Sopenharmony_ci res = WriteTestBin(fd, *buffer1.data(), bufferSize * count); 156fb299fa2Sopenharmony_ci if (!res) { 157fb299fa2Sopenharmony_ci std::cout << "Write to bin error" << std::endl; 158fb299fa2Sopenharmony_ci } 159fb299fa2Sopenharmony_ci if (baseBlock.WriteZeroToBlock(fd, false) != 0) { 160fb299fa2Sopenharmony_ci std::cout << "Write 0 to bin error: " << errno << std::endl; 161fb299fa2Sopenharmony_ci } 162fb299fa2Sopenharmony_ci 163fb299fa2Sopenharmony_ci close(fd); 164fb299fa2Sopenharmony_ci return 0; 165fb299fa2Sopenharmony_ci} 166fb299fa2Sopenharmony_ci 167fb299fa2Sopenharmony_ciHWTEST_F(AllCmdUnitTest, allCmd_test_002, TestSize.Level1) 168fb299fa2Sopenharmony_ci{ 169fb299fa2Sopenharmony_ci std::unique_ptr<TransferManager> tm = std::make_unique<TransferManager>(); 170fb299fa2Sopenharmony_ci std::string filePath = "/tmp/test.bin"; 171fb299fa2Sopenharmony_ci size_t bufferSize = 4096; 172fb299fa2Sopenharmony_ci size_t count = 10; 173fb299fa2Sopenharmony_ci mode_t dirMode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 174fb299fa2Sopenharmony_ci tm->GetTransferParams()->storeBase = "/tmp/cmdtest"; 175fb299fa2Sopenharmony_ci Store::DoFreeSpace(tm->GetTransferParams()->storeBase); 176fb299fa2Sopenharmony_ci Utils::MkdirRecursive(tm->GetTransferParams()->storeBase, dirMode); 177fb299fa2Sopenharmony_ci std::vector<uint8_t> buffer(bufferSize, 0); 178fb299fa2Sopenharmony_ci int fd = open(filePath.c_str(), O_RDWR | O_CREAT, dirMode); 179fb299fa2Sopenharmony_ci if (fd < 0) { 180fb299fa2Sopenharmony_ci printf("Failed to open block %s, errno: %d\n", filePath.c_str(), errno); 181fb299fa2Sopenharmony_ci return; 182fb299fa2Sopenharmony_ci } 183fb299fa2Sopenharmony_ci lseek64(fd, 0, SEEK_SET); 184fb299fa2Sopenharmony_ci auto res = WriteTestBin(fd, *buffer.data(), bufferSize * count); 185fb299fa2Sopenharmony_ci if (!res) { 186fb299fa2Sopenharmony_ci printf("Write to bin error\n"); 187fb299fa2Sopenharmony_ci } 188fb299fa2Sopenharmony_ci 189fb299fa2Sopenharmony_ci bool result = false; 190fb299fa2Sopenharmony_ci mode_t mode = (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 191fb299fa2Sopenharmony_ci // 192fb299fa2Sopenharmony_ci // 构造命令 193fb299fa2Sopenharmony_ci std::vector<std::string> allCmd; 194fb299fa2Sopenharmony_ci FillTransferHeader(allCmd, "4 27280 0 3616"); 195fb299fa2Sopenharmony_ci allCmd.push_back("stash ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7 2,0,1"); // 清第一块 196fb299fa2Sopenharmony_ci result = tm->CommandsParser(fd, allCmd); 197fb299fa2Sopenharmony_ci EXPECT_TRUE(result); 198fb299fa2Sopenharmony_ci Store::DoFreeSpace(tm->GetTransferParams()->storeBase); 199fb299fa2Sopenharmony_ci Utils::MkdirRecursive(tm->GetTransferParams()->storeBase, mode); 200fb299fa2Sopenharmony_ci 201fb299fa2Sopenharmony_ci EXPECT_EQ(AllCmdUnitTestMove(fd, allCmd, *tm), 0); 202fb299fa2Sopenharmony_ci unlink(filePath.c_str()); 203fb299fa2Sopenharmony_ci} 204fb299fa2Sopenharmony_ci} // updater_ut 205