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
HWTEST_F(UpdaterBinaryUnittest, TestUpdater, TestSize.Level1)215 HWTEST_F(UpdaterBinaryUnittest, TestUpdater, TestSize.Level1)
216 {
217 UpdaterBinaryUnittest test;
218 EXPECT_EQ(0, test.TestUpdater());
219 }
220 }
221