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 "pkg_manager.h"
26#include "pkg_manager_impl.h"
27#include "pkg_test.h"
28#include "pkg_utils.h"
29
30using namespace std;
31using namespace Hpackage;
32using namespace Updater;
33using namespace testing::ext;
34
35namespace UpdaterUt {
36class PackageUnitTest : public PkgTest {
37public:
38    PackageUnitTest() {}
39    ~PackageUnitTest() override {}
40public:
41    int TestInvalidCreatePackage()
42    {
43        std::vector<ComponentInfoExt> compInfo;
44        uint8_t pkgType = PkgPackType::PKG_PACK_TYPE_UPGRADE;
45        int ret = CreatePackage(nullptr, compInfo, nullptr, GetTestPrivateKeyName(0).c_str());
46        EXPECT_EQ(ret, PKG_INVALID_PARAM);
47
48        UpgradePkgInfoExt pkgInfoExt {};
49        pkgInfoExt.pkgType = pkgType;
50        ret = CreatePackage(&pkgInfoExt, compInfo, nullptr, GetTestPrivateKeyName(0).c_str());
51        EXPECT_EQ(ret, PKG_INVALID_PARAM);
52
53        constexpr uint32_t digestLen = 32;
54        ret = VerifyPackage(nullptr, GetTestCertName(0).c_str(), nullptr, nullptr, digestLen);
55        EXPECT_EQ(ret, PKG_INVALID_PARAM);
56
57        std::string packagePath = TEST_PATH_TO + testPackageName;
58        pkgInfoExt.pkgType = pkgType;
59        ret = CreatePackage(&pkgInfoExt, compInfo, packagePath.c_str(), GetTestPrivateKeyName(0).c_str());
60        EXPECT_EQ(ret, PKG_INVALID_PARAM);
61
62        pkgType = PkgPackType::PKG_PACK_TYPE_ZIP;
63        pkgInfoExt.pkgType = pkgType;
64        ret = CreatePackage(&pkgInfoExt, compInfo, packagePath.c_str(), GetTestPrivateKeyName(0).c_str());
65        EXPECT_EQ(ret, PKG_INVALID_PARAM);
66
67        pkgType = PkgPackType::PKG_PACK_TYPE_LZ4;
68        pkgInfoExt.pkgType = pkgType;
69        ret = CreatePackage(&pkgInfoExt, compInfo, packagePath.c_str(), GetTestPrivateKeyName(0).c_str());
70        EXPECT_EQ(ret, PKG_INVALID_PARAM);
71
72        pkgType = PkgPackType::PKG_PACK_TYPE_GZIP;
73        pkgInfoExt.pkgType = pkgType;
74        ret = CreatePackage(&pkgInfoExt, compInfo, packagePath.c_str(), GetTestPrivateKeyName(0).c_str());
75        EXPECT_EQ(ret, PKG_INVALID_PARAM);
76
77        pkgType = PkgPackType::PKG_PACK_TYPE_NONE;
78        pkgInfoExt.pkgType = pkgType;
79        ret = CreatePackage(&pkgInfoExt, compInfo, packagePath.c_str(), GetTestPrivateKeyName(0).c_str());
80        EXPECT_EQ(ret, PKG_INVALID_PARAM);
81        return 0;
82    }
83
84    int TestPackagePack(int type = PKG_DIGEST_TYPE_SHA256)
85    {
86        int32_t ret;
87        uint32_t updateFileVersion = 1000;
88        UpgradePkgInfoExt pkgInfo;
89        pkgInfo.softwareVersion = strdup("100.100.100.100");
90        pkgInfo.date = strdup("2021-02-02");
91        pkgInfo.time = strdup("21:23:49");
92        pkgInfo.productUpdateId = strdup("555.555.100.555");
93        pkgInfo.entryCount = testFileNames_.size();
94        pkgInfo.digestMethod = type;
95        pkgInfo.signMethod = PKG_SIGN_METHOD_RSA;
96        pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE;
97        pkgInfo.updateFileVersion = updateFileVersion;
98        std::string filePath;
99        uint32_t componentIdBase = 100;
100        uint8_t componentFlags = 22;
101        std::vector<ComponentInfoExt> comp(testFileNames_.size());
102        for (size_t i = 0; i < testFileNames_.size(); i++) {
103            comp[i].componentAddr = strdup(testFileNames_[i].c_str());
104            filePath = TEST_PATH_FROM;
105            filePath += testFileNames_[i].c_str();
106            comp[i].filePath = strdup(filePath.c_str());
107            comp[i].version = strdup("55555555");
108            ret = BuildFileDigest(*comp[i].digest, sizeof(comp[i].digest), filePath);
109            EXPECT_EQ(ret, PKG_SUCCESS);
110            comp[i].size = GetFileSize(filePath);
111            comp[i].originalSize = comp[i].size;
112            comp[i].id = i + componentIdBase;
113            comp[i].resType = 1;
114            comp[i].type = 1;
115            comp[i].flags = componentFlags;
116            filePath.clear();
117        }
118        std::string packagePath = TEST_PATH_TO;
119        packagePath += testPackageName;
120        ret = CreatePackage(&pkgInfo, comp, packagePath.c_str(),
121            GetTestPrivateKeyName(pkgInfo.digestMethod).c_str());
122        EXPECT_EQ(ret, PKG_SUCCESS);
123        for (size_t i = 0; i < testFileNames_.size(); i++) {
124            free(comp[i].componentAddr);
125            free(comp[i].filePath);
126            free(comp[i].version);
127        }
128        free(pkgInfo.softwareVersion);
129        free(pkgInfo.date);
130        free(pkgInfo.time);
131        free(pkgInfo.productUpdateId);
132        return ret;
133    }
134
135    int TestPackageUnpack(int type)
136    {
137        EXPECT_NE(pkgManager_, nullptr);
138        std::vector<std::string> components;
139        // 使用上面打包的包进行解析
140        int32_t ret = pkgManager_->LoadPackage(
141            testPackagePath + "test_package.zip", GetTestCertName(type), components);
142        EXPECT_EQ(ret, PKG_SUCCESS);
143
144        for (size_t i = 0; i < components.size(); i++) {
145            PKG_LOGI("comp [%zu] file name: %s \r\n", i, (TEST_PATH_TO + components[i]).c_str());
146            ExtractFile(pkgManager_, components, i);
147        }
148        return PKG_SUCCESS;
149    }
150
151    int TestZipPkgCompress(int digestMethod)
152    {
153        return CreateZipPackage(testFileNames_, TEST_PATH_TO + testZipPackageName, TEST_PATH_FROM, digestMethod);
154    }
155
156    int TestZipPkgDecompress(int digestMethod)
157    {
158        EXPECT_NE(pkgManager_, nullptr);
159        std::vector<std::string> components;
160        int32_t ret = pkgManager_->LoadPackage(TEST_PATH_TO + testZipPackageName,
161            GetTestCertName(digestMethod), components);
162        EXPECT_EQ(ret, PKG_SUCCESS);
163
164        for (size_t i = 0; i < components.size(); i++) {
165            PKG_LOGI("file name: %s \r\n", (TEST_PATH_TO + components[i]).c_str());
166            ExtractFile(pkgManager_, components, i);
167        }
168        return ret;
169    }
170
171    int TestGZipPkgCompress()
172    {
173        int ret = TestPackagePack();
174        EXPECT_EQ(ret, PKG_SUCCESS);
175        EXPECT_NE(pkgManager_, nullptr);
176        std::vector<std::pair<std::string, ZipFileInfo>> files;
177        ZipFileInfo file;
178        file.fileInfo.identity = testPackageName;
179        file.fileInfo.packMethod = PKG_COMPRESS_METHOD_GZIP;
180        file.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC;
181        std::string fileName = TEST_PATH_TO + testPackageName;
182        files.push_back(std::pair<std::string, ZipFileInfo>(fileName, file));
183
184        PkgInfo pkgInfo;
185        pkgInfo.signMethod = PKG_SIGN_METHOD_RSA;
186        pkgInfo.digestMethod  = PKG_DIGEST_TYPE_SHA256;
187        pkgInfo.pkgType = PKG_PACK_TYPE_GZIP;
188        return pkgManager_->CreatePackage(TEST_PATH_TO + testGZipPackageName,
189            GetTestPrivateKeyName(pkgInfo.digestMethod), &pkgInfo, files);
190    }
191
192    int TestVerifyUpgradePackage()
193    {
194        constexpr size_t digestSize = 32;
195        std::vector<uint8_t> digest(digestSize);
196        std::string path = testPackagePath + "test_package.zip";
197        BuildFileDigest(*digest.data(), digest.capacity(), path.c_str());
198        int ret = VerifyPackage(path.c_str(), GetTestCertName(0).c_str(), "", digest.data(), digest.capacity());
199        EXPECT_EQ(0, ret);
200        ret = VerifyPackage(nullptr, nullptr, nullptr, nullptr, digest.capacity());
201        EXPECT_EQ(PKG_INVALID_PARAM, ret);
202        return 0;
203    }
204
205    int TestVerifyPackageWithCallback()
206    {
207        std::string path = testPackagePath + "test_package.zip";
208        int ret = VerifyPackageWithCallback(path.c_str(), GetTestCertName(0).c_str(),
209            [](int32_t result, uint32_t percent) { PKG_LOGI("current progress: %u\n", percent); });
210        EXPECT_EQ(0, ret);
211
212        std::string keyPath = "";
213        ret = VerifyPackageWithCallback(path.c_str(), keyPath.c_str(),
214            [](int32_t result, uint32_t percent) { PKG_LOGI("current progress: %u\n", percent); });
215        EXPECT_EQ(PKG_INVALID_PARAM, ret);
216
217        std::function<void(int32_t result, uint32_t percent)> cb = nullptr;
218        ret = VerifyPackageWithCallback(path.c_str(), GetTestCertName(0).c_str(), cb);
219        EXPECT_EQ(PKG_INVALID_PARAM, ret);
220
221        path = "";
222        ret = VerifyPackageWithCallback(path.c_str(), GetTestCertName(0).c_str(),
223            [](int32_t result, uint32_t percent) { PKG_LOGI("current progress: %u\n", percent); });
224        EXPECT_EQ(PKG_INVALID_PARAM, ret);
225        return 0;
226    }
227
228    int TestLz4PkgCompress()
229    {
230        int ret = TestPackagePack();
231        EXPECT_EQ(ret, PKG_SUCCESS);
232        EXPECT_NE(pkgManager_, nullptr);
233        std::vector<std::pair<std::string, Lz4FileInfo>> files;
234        Lz4FileInfo file;
235        int8_t compressionLevel = 14;
236        file.fileInfo.identity = testPackageName;
237        file.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4;
238        file.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC;
239        file.compressionLevel = compressionLevel;
240        file.blockSizeID = 0;
241        file.contentChecksumFlag = 0;
242        file.blockIndependence = 0;
243        std::string fileName = TEST_PATH_TO + testPackageName;
244        files.push_back(std::pair<std::string, Lz4FileInfo>(fileName, file));
245
246        PkgInfo pkgInfo;
247        pkgInfo.pkgType = PKG_PACK_TYPE_LZ4;
248        pkgInfo.signMethod = PKG_SIGN_METHOD_RSA;
249        pkgInfo.digestMethod  = PKG_DIGEST_TYPE_SHA256;
250        return pkgManager_->CreatePackage(TEST_PATH_TO + testLz4PackageName,
251            GetTestPrivateKeyName(pkgInfo.digestMethod), &pkgInfo, files);
252    }
253};
254
255HWTEST_F(PackageUnitTest, TestLz4Package, TestSize.Level1)
256{
257    PackageUnitTest test;
258    EXPECT_EQ(0, test.TestLz4PkgCompress());
259}
260
261HWTEST_F(PackageUnitTest, TestInvalidCreatePackage, TestSize.Level1)
262{
263    PackageUnitTest test;
264    EXPECT_EQ(0, test.TestInvalidCreatePackage());
265}
266
267HWTEST_F(PackageUnitTest, TestVerifyUpgradePackage, TestSize.Level1)
268{
269    PackageUnitTest test;
270    EXPECT_EQ(0, test.TestVerifyUpgradePackage());
271}
272
273HWTEST_F(PackageUnitTest, TestVerifyPackageWithCallback, TestSize.Level1)
274{
275    PackageUnitTest test;
276    EXPECT_EQ(0, test.TestVerifyPackageWithCallback());
277}
278
279HWTEST_F(PackageUnitTest, TestPackage, TestSize.Level1)
280{
281    PackageUnitTest test;
282    EXPECT_EQ(0, test.TestPackagePack(PKG_DIGEST_TYPE_SHA256));
283    EXPECT_EQ(0, test.TestPackageUnpack(PKG_DIGEST_TYPE_SHA256));
284}
285
286HWTEST_F(PackageUnitTest, TestZipPackage, TestSize.Level1)
287{
288    PackageUnitTest test;
289    EXPECT_EQ(0, test.TestZipPkgCompress(PKG_DIGEST_TYPE_SHA256));
290    EXPECT_EQ(0, test.TestZipPkgDecompress(PKG_DIGEST_TYPE_SHA256));
291}
292
293HWTEST_F(PackageUnitTest, TestGZipPkg, TestSize.Level1)
294{
295    PackageUnitTest test;
296    EXPECT_EQ(0, test.TestGZipPkgCompress());
297}
298}
299