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