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 #ifndef PKG_TEST
17 #define PKG_TEST
18 
19 #include <cstring>
20 #include <fcntl.h>
21 #include <gtest/gtest.h>
22 #include <iostream>
23 #include <sys/mman.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include "log.h"
27 #include "pkg_algorithm.h"
28 #include "pkg_manager.h"
29 #include "pkg_manager_impl.h"
30 #include "pkg_utils.h"
31 #include "unittest_comm.h"
32 #include "utils.h"
33 
34 using Hpackage::PkgManager;
35 using Hpackage::PkgManagerImpl;
36 using Hpackage::PkgStream;
37 using Hpackage::PkgAlgorithmFactory;
38 using Hpackage::DigestAlgorithm;
39 using Hpackage::ComponentInfo;
40 using Hpackage::FileInfo;
41 using Hpackage::ZipFileInfo;
42 using Hpackage::PkgInfo;
43 using Updater::InitUpdaterLogger;
44 
45 namespace UpdaterUt {
46 class PkgTest : public ::testing::Test {
47 public:
PkgTest()48     PkgTest()
49     {
50         pkgManager_ = static_cast<PkgManagerImpl*>(PkgManager::CreatePackageInstance());
51     }
~PkgTest()52     virtual ~PkgTest()
53     {
54         PkgManager::ReleasePackageInstance(pkgManager_);
55         pkgManager_ = nullptr;
56     }
57 
58 protected:
SetUp()59     void SetUp()
60     {
61         // 先创建目标目录
62         if (access(TEST_PATH_TO.c_str(), R_OK | W_OK) == -1) {
63             mkdir(TEST_PATH_TO.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
64         }
65         InitUpdaterLogger("UPDATER ", "updater_log.log", "updater_status.log", "error_code.log");
66     }
TearDown()67     void TearDown() {}
TestBody()68     void TestBody() {}
69 
BuildFileDigest(uint8_t & digest,size_t size,const std::string & packagePath)70     int32_t BuildFileDigest(uint8_t &digest, size_t size, const std::string &packagePath)
71     {
72         PkgManager::StreamPtr stream = nullptr;
73         int32_t ret = pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read);
74         if (ret != 0) {
75             PKG_LOGE("Create input stream fail %s", packagePath.c_str());
76             return ret;
77         }
78         size_t fileLen = stream->GetFileLength();
79         if (fileLen <= 0 || fileLen > SIZE_MAX) {
80             PKG_LOGE("Invalid file len %zu to load %s", fileLen, stream->GetFileName().c_str());
81             pkgManager_->ClosePkgStream(stream);
82             return -1;
83         }
84 
85         size_t buffSize = 4096;
86         Hpackage::PkgBuffer buff(buffSize);
87         // 整包检查
88         DigestAlgorithm::DigestAlgorithmPtr algorithm =
89             PkgAlgorithmFactory::GetDigestAlgorithm(PKG_DIGEST_TYPE_SHA256);
90         if (algorithm == nullptr) {
91             PKG_LOGE("Invalid file %s", stream->GetFileName().c_str());
92             pkgManager_->ClosePkgStream(stream);
93             return -1;
94         }
95         algorithm->Init();
96 
97         size_t offset = 0;
98         size_t readLen = 0;
99         while (offset < fileLen) {
100             ret = stream->Read(buff, offset, buffSize, readLen);
101             if (ret != 0) {
102                 PKG_LOGE("read buffer fail %s", stream->GetFileName().c_str());
103                 pkgManager_->ClosePkgStream(stream);
104                 return ret;
105             }
106             algorithm->Update(buff, readLen);
107 
108             offset += readLen;
109             readLen = 0;
110         }
111         Hpackage::PkgBuffer buffer(&digest, size);
112         algorithm->Final(buffer);
113         pkgManager_->ClosePkgStream(stream);
114         return 0;
115     }
116 
ExtractFile(PkgManager::PkgManagerPtr manager,std::vector<std::string> components,size_t i)117     void ExtractFile(PkgManager::PkgManagerPtr manager, std::vector<std::string> components, size_t i)
118     {
119         PkgManager::StreamPtr outStream = nullptr;
120         PKG_LOGI("comp [%zu] file name: %s \r\n", i, (TEST_PATH_TO + components[i]).c_str());
121         manager->CreatePkgStream(outStream, TEST_PATH_TO + components[i], 0, PkgStream::PkgStreamType_Write);
122         EXPECT_NE(nullptr, outStream);
123         if (outStream == nullptr) {
124             return;
125         }
126         int ret = manager->ExtractFile(components[i], outStream);
127         EXPECT_EQ(ret, 0);
128         manager->ClosePkgStream(outStream);
129         const FileInfo *info = manager->GetFileInfo(components[i]);
130         ASSERT_NE(info, nullptr);
131         if (info->packMethod == PKG_COMPRESS_METHOD_NONE) {
132             const ComponentInfo* compInfo = (const ComponentInfo*)manager->GetFileInfo(components[i]);
133             if (compInfo != nullptr) {
134                 PKG_LOGI("comp [%zu] componentAddr: %s \n", i, (*compInfo).fileInfo.identity.c_str());
135                 PKG_LOGI("comp [%zu] version: %s \n", i, (*compInfo).version.c_str());
136                 PKG_LOGI("comp [%zu] originalSize: %zu \n", i, (*compInfo).originalSize);
137                 PKG_LOGI("comp [%zu] size: %zu \n", i, (*compInfo).fileInfo.unpackedSize);
138                 PKG_LOGI("comp [%zu] id: %d \n", i, (*compInfo).id);
139                 PKG_LOGI("comp [%zu] resType: %d \n", i, (*compInfo).resType);
140                 PKG_LOGI("comp [%zu] flags: %d \n", i, (*compInfo).compFlags);
141                 PKG_LOGI("comp [%zu] type: %d \n", i, (*compInfo).type);
142             }
143         } else {
144             PKG_LOGI("FileInfo [%zu] id: %s \n", i, info->identity.c_str());
145             PKG_LOGI("FileInfo [%zu] unpackedSize: %zu \n", i, info->unpackedSize);
146             PKG_LOGI("FileInfo [%zu] packedSize: %zu \n", i, info->packedSize);
147             PKG_LOGI("FileInfo [%zu] packMethod: %d \n", i, info->packMethod);
148             PKG_LOGI("FileInfo [%zu] digestMethod: %d \n", i, info->digestMethod);
149             PKG_LOGI("FileInfo [%zu] flags: %d \n", i, info->flags);
150         }
151     }
152 
CreateZipPackage(const std::vector<std::string> & testFileNames,const std::string packageName,const std::string & base,int digestMethod)153     int CreateZipPackage(const std::vector<std::string> &testFileNames,
154         const std::string packageName, const std::string &base, int digestMethod)
155     {
156         PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance();
157         EXPECT_NE(pkgManager, nullptr);
158         std::vector<std::pair<std::string, ZipFileInfo>> files;
159         // 构建要打包的zip文件
160         for (auto name : testFileNames) {
161             ZipFileInfo file;
162             file.fileInfo.identity = name;
163             file.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP;
164             file.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC;
165             std::string fileName = base + name;
166             files.push_back(std::pair<std::string, ZipFileInfo>(fileName, file));
167         }
168 
169         PkgInfo pkgInfo;
170         pkgInfo.signMethod = PKG_SIGN_METHOD_RSA;
171         pkgInfo.digestMethod = digestMethod;
172         pkgInfo.pkgType = PKG_PACK_TYPE_ZIP;
173         int32_t ret = pkgManager->CreatePackage(packageName, GetTestPrivateKeyName(digestMethod), &pkgInfo, files);
174         EXPECT_EQ(ret, 0);
175         PkgManager::ReleasePackageInstance(pkgManager);
176         return ret;
177     }
178     std::vector<std::string> testFileNames_ = {
179         "loadScript.us",
180         "registerCmd.us",
181         "test_function.us",
182         "test_if.us",
183         "test_logic.us",
184         "test_math.us",
185         "test_native.us",
186         "testscript.us",
187         "Verse-script.us",
188         "libcrypto.a",
189         "ggg.zip"
190     };
191     PkgManagerImpl* pkgManager_ = nullptr;
192     std::string testPackageName = "test_package.bin";
193     std::string testZipPackageName = "test_package.zip";
194     std::string testLz4PackageName = "test_package.lz4";
195     std::string testGZipPackageName = "test_package.gz";
196     std::string testCombinePkgName = "test_CombinePackage.zip";
197     std::string testPackagePath = "/data/updater/package/";
198 };
199 }
200 #endif // PKG_TEST
201