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::CreatePackageInstance(); 76 PkgManager::StreamPtr stream = nullptr; 77 int32_t ret = pkgManager->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); 78 if (ret != PKG_SUCCESS) { 79 LOG(ERROR) << "Create input stream fail " << packagePath; 80 pkgManager->ClosePkgStream(stream); 81 PkgManager::ReleasePackageInstance(pkgManager); 82 return ret; 83 } 84 size_t fileLen = stream->GetFileLength(); 85 if (fileLen == 0 || fileLen > SIZE_MAX) { 86 LOG(ERROR) << "invalid file to load " << stream->GetFileName(); 87 pkgManager->ClosePkgStream(stream); 88 PkgManager::ReleasePackageInstance(pkgManager); 89 return PKG_INVALID_FILE; 90 } 91 92 size_t buffSize = 4096; 93 PkgBuffer buff(buffSize); 94 // 整包检查 95 DigestAlgorithm::DigestAlgorithmPtr algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(PKG_DIGEST_TYPE_SHA256); 96 if (algorithm == nullptr) { 97 LOG(ERROR) << "Invalid file " << stream->GetFileName(); 98 pkgManager->ClosePkgStream(stream); 99 PkgManager::ReleasePackageInstance(pkgManager); 100 return PKG_NOT_EXIST_ALGORITHM; 101 } 102 algorithm->Init(); 103 104 size_t offset = 0; 105 size_t readLen = 0; 106 while (offset < fileLen) { 107 ret = stream->Read(buff, offset, buffSize, readLen); 108 if (ret != PKG_SUCCESS) { 109 LOG(ERROR) << "read buffer fail " << stream->GetFileName(); 110 pkgManager->ClosePkgStream(stream); 111 PkgManager::ReleasePackageInstance(pkgManager); 112 return ret; 113 } 114 algorithm->Update(buff, readLen); 115 offset += readLen; 116 readLen = 0; 117 } 118 119 PkgBuffer buffer(&digest, size); 120 algorithm->Final(buffer); 121 pkgManager->ClosePkgStream(stream); 122 PkgManager::ReleasePackageInstance(pkgManager); 123 return PKG_SUCCESS; 124 } 125 CreatePackageBin() const126 int CreatePackageBin() const 127 { 128 int32_t ret; 129 int32_t updateFileVersion = 1000; 130 PKG_LOGI("\n\n ************* CreatePackageBin %s \r\n", testPackageName.c_str()); 131 UpgradePkgInfoExt pkgInfo; 132 // C API, Cannot use c++ string class. 133 pkgInfo.softwareVersion = strdup("100.100.100.100"); 134 pkgInfo.date = strdup("2021-02-02"); 135 pkgInfo.time = strdup("21:23:49"); 136 pkgInfo.productUpdateId = strdup("555.555.100.555"); 137 int fileNameIndex = 3; 138 uint8_t componentType = 22; 139 pkgInfo.entryCount = testFileNames_.size() + fileNameIndex; 140 pkgInfo.updateFileVersion = updateFileVersion; 141 pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; 142 pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; 143 pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE; 144 145 ComponentInfoExt *comp = (ComponentInfoExt*)malloc( 146 sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex)); 147 if (comp == nullptr) { 148 return -1; 149 } 150 for (size_t i = 0; i < testFileNames_.size(); i++) { 151 BuildCompnentInfo(comp[i], testFileNames_[i], testFileNames_[i], componentType); 152 } 153 154 size_t index = testFileNames_.size(); 155 BuildCompnentInfo(comp[index++], "/hos"); 156 BuildCompnentInfo(comp[index++], "/system"); 157 BuildCompnentInfo(comp[index++], "/vendor"); 158 159 std::string packagePath = TEST_PATH_TO; 160 packagePath += testPackageName; 161 ret = CreatePackage(&pkgInfo, comp, packagePath.c_str(), GetTestPrivateKeyName().c_str()); 162 for (size_t i = 0; i < index; i++) { 163 free(comp[i].componentAddr); 164 free(comp[i].filePath); 165 free(comp[i].version); 166 } 167 if (pkgInfo.productUpdateId != nullptr) { 168 free(pkgInfo.productUpdateId); 169 } 170 if (pkgInfo.softwareVersion != nullptr) { 171 free(pkgInfo.softwareVersion); 172 } 173 if (pkgInfo.date != nullptr) { 174 free(pkgInfo.date); 175 } 176 if (pkgInfo.time != nullptr) { 177 free(pkgInfo.time); 178 } 179 free(comp); 180 return ret; 181 } 182 183 private: 184 std::vector<std::string> testFileNames_ = { 185 "loadScript.us", 186 "registerCmd.us", 187 "test_function.us", 188 "test_math.us", 189 "test_native.us", 190 "testscript.us", 191 "Verse-script.us", 192 }; 193 std::string testPackageName = "test_package.bin"; BuildCompnentInfo(ComponentInfoExt & comp,const std::string & cmpName,const std::string & scriptPath="loadScript.us",uint8_t componentType=0) const194 void BuildCompnentInfo(ComponentInfoExt &comp, const std::string &cmpName, 195 const std::string &scriptPath = "loadScript.us", uint8_t componentType = 0) const 196 { 197 std::string filePath = TEST_PATH_FROM; 198 uint32_t componentIdBase = 100; 199 uint8_t componentFlags = 22; 200 201 comp.componentAddr = strdup(cmpName.c_str()); 202 filePath += scriptPath; 203 comp.filePath = strdup(filePath.c_str()); 204 comp.version = strdup("55555555"); 205 auto ret = BuildFileDigest(*comp.digest, sizeof(comp.digest), filePath); 206 EXPECT_EQ(ret, PKG_SUCCESS); 207 comp.size = GetFileSize(filePath); 208 comp.originalSize = comp.size; 209 comp.id = componentIdBase; 210 comp.resType = 1; 211 comp.flags = componentFlags; 212 comp.type = componentType; 213 filePath.clear(); 214 } 215 }; 216 217 HWTEST_F(UpdaterBinaryUnittest, TestUpdater, TestSize.Level1) 218 { 219 UpdaterBinaryUnittest test; 220 EXPECT_EQ(0, test.TestUpdater()); 221 } 222 } 223