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 <gtest/gtest.h>
18#include <iostream>
19#include <memory>
20#include "log.h"
21#include "packages_info.h"
22#include "pkg_algorithm.h"
23#include "pkg_gzipfile.h"
24#include "pkg_lz4file.h"
25#include "pkg_manager.h"
26#include "pkg_manager_impl.h"
27#include "pkg_test.h"
28#include "pkg_upgradefile.h"
29#include "pkg_utils.h"
30#include "pkg_zipfile.h"
31#include "securec.h"
32
33using namespace std;
34using namespace Hpackage;
35using namespace Updater;
36using namespace testing::ext;
37
38namespace UpdaterUt {
39constexpr uint32_t MAX_FILE_NAME = 256;
40constexpr uint32_t CENTRAL_SIGNATURE = 0x02014b50;
41
42class TestFile : public PkgFileImpl {
43public:
44    explicit TestFile(PkgManager::PkgManagerPtr pkgManager, PkgStreamPtr stream)
45        : PkgFileImpl(pkgManager, stream, PKG_TYPE_MAX) {}
46
47    virtual ~TestFile() {}
48
49    virtual int32_t AddEntry(const PkgManager::FileInfoPtr file, const PkgStreamPtr inStream)
50    {
51        PkgFileImpl::GetPkgInfo();
52        PkgFileImpl::AddPkgEntry(inStream->GetFileName());
53        return 0;
54    }
55
56    virtual int32_t SavePackage(size_t &offset)
57    {
58        return 0;
59    }
60
61    virtual int32_t LoadPackage(std::vector<std::string>& fileNames, VerifyFunction verify = nullptr)
62    {
63        return 0;
64    }
65};
66
67class PkgPackageTest : public PkgTest {
68public:
69    PkgPackageTest() {}
70    ~PkgPackageTest() override {}
71
72    int TestPkgFile()
73    {
74        if (pkgManager_ == nullptr) {
75            return PKG_SUCCESS;
76        }
77        PkgManager::StreamPtr stream = nullptr;
78        std::string packagePath = TEST_PATH_TO;
79        packagePath += testPackageName;
80        int ret = pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read);
81        auto file = std::make_unique<Lz4PkgFile>(pkgManager_, PkgStreamImpl::ConvertPkgStream(stream));
82        EXPECT_NE(file, nullptr);
83        constexpr uint32_t lz4NodeId = 100;
84        auto entry = std::make_unique<Lz4FileEntry>(file.get(), lz4NodeId);
85        EXPECT_NE(entry, nullptr);
86
87        EXPECT_NE(((PkgEntryPtr)entry.get())->GetPkgFile(), nullptr);
88        Lz4FileInfo fileInfo {};
89        ret = entry->Init(&fileInfo.fileInfo, PkgStreamImpl::ConvertPkgStream(stream));
90        EXPECT_EQ(ret, 0);
91        return 0;
92    }
93
94    int TestPkgFileInvalid()
95    {
96        if (pkgManager_ == nullptr) {
97            return PKG_SUCCESS;
98        }
99        PkgManager::StreamPtr stream = nullptr;
100        std::string packagePath = TEST_PATH_TO;
101        packagePath += testPackageName;
102        int ret = pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read);
103        FileInfo fileInfo;
104        std::unique_ptr<TestFile> file = std::make_unique<TestFile>(pkgManager_,
105            PkgStreamImpl::ConvertPkgStream(stream));
106        EXPECT_NE(file, nullptr);
107        ret = file->AddEntry(&fileInfo, PkgStreamImpl::ConvertPkgStream(stream));
108        EXPECT_EQ(ret, 0);
109        size_t offset = 0;
110        ret = file->SavePackage(offset);
111        EXPECT_EQ(ret, 0);
112        return 0;
113    }
114
115    int TestBigZipEntry()
116    {
117        EXPECT_NE(pkgManager_, nullptr);
118        PkgManager::StreamPtr stream = nullptr;
119        std::string packagePath = TEST_PATH_TO;
120        uint32_t zipNodeId = 100;
121        packagePath += testPackageName;
122        pkgManager_->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read);
123        EXPECT_NE(stream, nullptr);
124        std::unique_ptr<TestFile> file = std::make_unique<TestFile>(pkgManager_,
125            PkgStreamImpl::ConvertPkgStream(stream));
126        EXPECT_NE(file, nullptr);
127        std::unique_ptr<ZipFileEntry> entry = std::make_unique<ZipFileEntry>(file.get(), zipNodeId);
128        EXPECT_NE(entry, nullptr);
129
130        string name = "TestBigZip";
131        uint16_t extraSize = 20;
132        size_t offsetHalfWord = 2;
133        size_t offsetWord = 4;
134        size_t offset4Words = 16;
135        size_t offset3Words = 12;
136        int32_t buffLen = MAX_FILE_NAME + sizeof(LocalFileHeader) + sizeof(DataDescriptor) +
137            sizeof(CentralDirEntry) + offsetWord + offset4Words;
138        std::vector<uint8_t> buff(buffLen);
139        CentralDirEntry* centralDir = (CentralDirEntry *)buff.data();
140        (void)memset_s(centralDir, sizeof(CentralDirEntry), 0, sizeof(CentralDirEntry));
141        centralDir->signature = CENTRAL_SIGNATURE;
142        centralDir->compressionMethod = PKG_COMPRESS_METHOD_ZIP;
143        centralDir->compressedSize = UINT_MAX;
144        centralDir->uncompressedSize = UINT_MAX;
145        centralDir->nameSize = name.length();
146        centralDir->extraSize = extraSize;
147        int ret = memcpy_s(buff.data() + sizeof(CentralDirEntry), name.length(), name.c_str(), name.length());
148        EXPECT_EQ(ret, 0);
149        WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length(), 1);
150        WriteLE16(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetHalfWord, offset4Words);
151        size_t giantNumber = 100000;
152        size_t size = UINT_MAX + giantNumber;
153        WriteLE64(buff.data() + sizeof(CentralDirEntry) + name.length() + offsetWord, size);
154        WriteLE64(buff.data() + sizeof(CentralDirEntry) + name.length() + offset3Words, size);
155        size_t decodeLen = 0;
156        PkgBuffer buffer(buff);
157        entry->DecodeCentralDirEntry(nullptr, buffer, 0, decodeLen);
158        return 0;
159    }
160
161    void WriteLE64(uint8_t *buff, size_t size) const
162    {
163        *reinterpret_cast<size_t *>(buff) = size;
164    }
165
166    int TestPackageInfoFail()
167    {
168        PkgManager::PkgManagerPtr manager = PkgManager::CreatePackageInstance();
169        PackagesInfoPtr pkginfomanager = PackagesInfo::GetPackagesInfoInstance();
170        std::vector<std::string> target;
171        std::vector<std::string> tmp;
172
173        target = pkginfomanager->GetOTAVersion(nullptr, "", "");
174        EXPECT_EQ(target, tmp);
175        target = pkginfomanager->GetOTAVersion(manager, "", "");
176        EXPECT_EQ(target, tmp);
177        target = pkginfomanager->GetBoardID(nullptr, "", "");
178        EXPECT_EQ(target, tmp);
179        target = pkginfomanager->GetBoardID(manager, "", "");
180        EXPECT_EQ(target, tmp);
181
182        bool ret = pkginfomanager->IsAllowRollback();
183        EXPECT_EQ(ret, false);
184        PackagesInfo::ReleasePackagesInfoInstance(pkginfomanager);
185        PkgManager::ReleasePackageInstance(manager);
186        return 0;
187    }
188
189    int TestUpdaterPreProcess()
190    {
191        PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance();
192        std::string packagePath = testPackagePath + "test_package.zip";
193        std::vector<std::string> components;
194        int32_t ret = pkgManager->LoadPackage(packagePath, Utils::GetCertName(), components);
195        EXPECT_EQ(ret, PKG_SUCCESS);
196
197        PackagesInfoPtr pkginfomanager = PackagesInfo::GetPackagesInfoInstance();
198        std::vector<std::string> result;
199        std::vector<std::string> targetVersions = pkginfomanager->GetOTAVersion(
200            pkgManager, "/version_list", testPackagePath);
201        EXPECT_NE(targetVersions, result);
202
203        std::vector<std::string> boardIdList = pkginfomanager->GetBoardID(pkgManager, "/board_list", "");
204        EXPECT_NE(boardIdList, result);
205        PackagesInfo::ReleasePackagesInfoInstance(pkginfomanager);
206        PkgManager::ReleasePackageInstance(pkgManager);
207        return 0;
208    }
209};
210
211HWTEST_F(PkgPackageTest, TestUpdaterPreProcess, TestSize.Level1)
212{
213    PkgPackageTest test;
214    EXPECT_EQ(0, test.TestUpdaterPreProcess());
215}
216
217HWTEST_F(PkgPackageTest, TestPackageInfoFail, TestSize.Level1)
218{
219    PkgPackageTest test;
220    EXPECT_EQ(0, test.TestPackageInfoFail());
221}
222
223HWTEST_F(PkgPackageTest, TestPkgFile, TestSize.Level1)
224{
225    PkgPackageTest test;
226    EXPECT_EQ(0, test.TestPkgFile());
227}
228
229HWTEST_F(PkgPackageTest, TestPkgFileInvalid, TestSize.Level1)
230{
231    PkgPackageTest test;
232    EXPECT_EQ(0, test.TestPkgFileInvalid());
233}
234
235HWTEST_F(PkgPackageTest, TestBigZip, TestSize.Level1)
236{
237    PkgPackageTest test;
238    EXPECT_EQ(0, test.TestBigZipEntry());
239}
240}
241