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 <cstring> 17 #include <fcntl.h> 18 #include <gtest/gtest.h> 19 #include <iostream> 20 #include <sys/mman.h> 21 #include <sys/stat.h> 22 #include <unistd.h> 23 #include "log.h" 24 #include "pkg_algorithm.h" 25 #include "script_instruction.h" 26 #include "script_utils.h" 27 #include "unittest_comm.h" 28 #include "update_processor.h" 29 #include "utils.h" 30 31 using namespace std; 32 using namespace Hpackage; 33 using namespace Uscript; 34 using namespace Updater; 35 using namespace testing::ext; 36 using namespace Updater::Utils; 37 38 namespace { 39 class UpdaterBinaryUnittest : public ::testing::Test { 40 public: UpdaterBinaryUnittest()41 UpdaterBinaryUnittest() {} ~UpdaterBinaryUnittest()42 ~UpdaterBinaryUnittest() {} TestUpdater()43 int TestUpdater() 44 { 45 int32_t ret = CreatePackageBin(); 46 EXPECT_EQ(0, ret); 47 std::string path = TEST_PATH_TO + testPackageName; 48 int fd = open(GetTestCertName().c_str(), O_RDONLY); 49 if (fd < 0) { 50 LOG(ERROR) << GetTestCertName() << " open failed, fd = " << fd; 51 return -1; 52 } else { 53 close(fd); 54 } 55 ret = ProcessUpdater(false, STDOUT_FILENO, path.c_str(), GetTestCertName().c_str()); 56 ret = 0; 57 return ret; 58 } 59 60 protected: SetUp()61 void SetUp() 62 { 63 // 先创建目标目录 64 if (access(TEST_PATH_TO.c_str(), R_OK | W_OK) == -1) { 65 mode_t mode = (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 66 mkdir(TEST_PATH_TO.c_str(), mode); 67 } 68 InitUpdaterLogger("UPDATER", "updater_log.log", "updater_status.log", "error_code.log"); 69 } TearDown()70 void TearDown() {} TestBody()71 void TestBody() {} 72 BuildFileDigest(uint8_t & digest,size_t size,const std::string & packagePath) const73 int32_t BuildFileDigest(uint8_t &digest, size_t size, const std::string &packagePath) const 74 { 75 PkgManager::PkgManagerPtr pkgManager = PkgManager::GetPackageInstance(); 76 PkgManager::StreamPtr stream = nullptr; 77 int32_t ret = pkgManager->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); 78 PKG_CHECK(ret == PKG_SUCCESS, pkgManager->ClosePkgStream(stream); 79 return ret, "Create input stream fail %s", packagePath.c_str()); 80 size_t fileLen = stream->GetFileLength(); 81 PKG_CHECK(fileLen > 0, pkgManager->ClosePkgStream(stream); return PKG_INVALID_FILE, "invalid file to load"); 82 PKG_CHECK(fileLen <= SIZE_MAX, pkgManager->ClosePkgStream(stream); return PKG_INVALID_FILE, 83 "Invalid file len %zu to load %s", fileLen, stream->GetFileName().c_str()); 84 85 size_t buffSize = 4096; 86 PkgBuffer buff(buffSize); 87 // 整包检查 88 DigestAlgorithm::DigestAlgorithmPtr algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(PKG_DIGEST_TYPE_SHA256); 89 PKG_CHECK(algorithm != nullptr, pkgManager->ClosePkgStream(stream); return PKG_NOT_EXIST_ALGORITHM, 90 "Invalid file %s", stream->GetFileName().c_str()); 91 algorithm->Init(); 92 93 size_t offset = 0; 94 size_t readLen = 0; 95 while (offset < fileLen) { 96 ret = stream->Read(buff, offset, buffSize, readLen); 97 PKG_CHECK(ret == PKG_SUCCESS, 98 pkgManager->ClosePkgStream(stream); return ret, 99 "read buffer fail %s", stream->GetFileName().c_str()); 100 algorithm->Update(buff, readLen); 101 offset += readLen; 102 readLen = 0; 103 } 104 105 PkgBuffer buffer(&digest, size); 106 algorithm->Final(buffer); 107 pkgManager->ClosePkgStream(stream); 108 return PKG_SUCCESS; 109 } 110 CreatePackageBin() const111 int CreatePackageBin() const 112 { 113 int32_t ret; 114 int32_t updateFileVersion = 1000; 115 PKG_LOGI("\n\n ************* CreatePackageBin %s \r\n", testPackageName.c_str()); 116 UpgradePkgInfoExt pkgInfo; 117 // C API, Cannot use c++ string class. 118 pkgInfo.softwareVersion = strdup("100.100.100.100"); 119 pkgInfo.date = strdup("2021-02-02"); 120 pkgInfo.time = strdup("21:23:49"); 121 pkgInfo.productUpdateId = strdup("555.555.100.555"); 122 int fileNameIndex = 3; 123 uint8_t componentType = 22; 124 pkgInfo.entryCount = testFileNames_.size() + fileNameIndex; 125 pkgInfo.updateFileVersion = updateFileVersion; 126 pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; 127 pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; 128 pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE; 129 130 ComponentInfoExt *comp = (ComponentInfoExt*)malloc( 131 sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); 132 if (comp == nullptr) { 133 return -1; 134 } 135 for (size_t i = 0; i < testFileNames_.size(); i++) { 136 BuildCompnentInfo(comp[i], testFileNames_[i], testFileNames_[i], componentType); 137 } 138 139 size_t index = testFileNames_.size(); 140 BuildCompnentInfo(comp[index++], "/hos"); 141 BuildCompnentInfo(comp[index++], "/system"); 142 BuildCompnentInfo(comp[index++], "/vendor"); 143 144 std::string packagePath = TEST_PATH_TO; 145 packagePath += testPackageName; 146 ret = CreatePackage(&pkgInfo, comp, packagePath.c_str(), GetTestPrivateKeyName().c_str()); 147 for (size_t i = 0; i < index; i++) { 148 free(comp[i].componentAddr); 149 free(comp[i].filePath); 150 free(comp[i].version); 151 } 152 if (pkgInfo.productUpdateId != nullptr) { 153 free(pkgInfo.productUpdateId); 154 } 155 if (pkgInfo.softwareVersion != nullptr) { 156 free(pkgInfo.softwareVersion); 157 } 158 if (pkgInfo.date != nullptr) { 159 free(pkgInfo.date); 160 } 161 if (pkgInfo.time != nullptr) { 162 free(pkgInfo.time); 163 } 164 free(comp); 165 return ret; 166 } 167 168 private: 169 std::vector<std::string> testFileNames_ = { 170 "loadScript.us", 171 "registerCmd.us", 172 "test_function.us", 173 "test_math.us", 174 "test_native.us", 175 "testscript.us", 176 "Verse-script.us", 177 }; 178 std::string testPackageName = "test_package.bin"; BuildCompnentInfo(ComponentInfoExt & comp,const std::string & cmpName,const std::string & scriptPath="loadScript.us",uint8_t componentType=0) const179 void BuildCompnentInfo(ComponentInfoExt &comp, const std::string &cmpName, 180 const std::string &scriptPath = "loadScript.us", uint8_t componentType = 0) const 181 { 182 std::string filePath = TEST_PATH_FROM; 183 uint32_t componentIdBase = 100; 184 uint8_t componentFlags = 22; 185 186 comp.componentAddr = strdup(cmpName.c_str()); 187 filePath += scriptPath; 188 comp.filePath = strdup(filePath.c_str()); 189 comp.version = strdup("55555555"); 190 auto ret = BuildFileDigest(*comp.digest, sizeof(comp.digest), filePath); 191 EXPECT_EQ(ret, PKG_SUCCESS); 192 comp.size = GetFileSize(filePath); 193 comp.originalSize = comp.size; 194 comp.id = componentIdBase; 195 comp.resType = 1; 196 comp.flags = componentFlags; 197 comp.type = componentType; 198 filePath.clear(); 199 } 200 }; 201 202 HWTEST_F(UpdaterBinaryUnittest, TestUpdater, TestSize.Level1) 203 { 204 UpdaterBinaryUnittest test; 205 EXPECT_EQ(0, test.TestUpdater()); 206 } 207 } 208