1fb299fa2Sopenharmony_ci/*
2fb299fa2Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at
6fb299fa2Sopenharmony_ci *
7fb299fa2Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb299fa2Sopenharmony_ci *
9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and
13fb299fa2Sopenharmony_ci * limitations under the License.
14fb299fa2Sopenharmony_ci */
15fb299fa2Sopenharmony_ci
16fb299fa2Sopenharmony_ci#include <cstring>
17fb299fa2Sopenharmony_ci#include <fcntl.h>
18fb299fa2Sopenharmony_ci#include <gtest/gtest.h>
19fb299fa2Sopenharmony_ci#include <iostream>
20fb299fa2Sopenharmony_ci#include <sys/mman.h>
21fb299fa2Sopenharmony_ci#include <sys/stat.h>
22fb299fa2Sopenharmony_ci#include <unistd.h>
23fb299fa2Sopenharmony_ci#include "log.h"
24fb299fa2Sopenharmony_ci#include "pkg_algorithm.h"
25fb299fa2Sopenharmony_ci#include "script_instruction.h"
26fb299fa2Sopenharmony_ci#include "script_utils.h"
27fb299fa2Sopenharmony_ci#include "unittest_comm.h"
28fb299fa2Sopenharmony_ci#include "update_processor.h"
29fb299fa2Sopenharmony_ci
30fb299fa2Sopenharmony_ciusing namespace std;
31fb299fa2Sopenharmony_ciusing namespace Hpackage;
32fb299fa2Sopenharmony_ciusing namespace Uscript;
33fb299fa2Sopenharmony_ciusing namespace Updater;
34fb299fa2Sopenharmony_ciusing namespace testing::ext;
35fb299fa2Sopenharmony_ci
36fb299fa2Sopenharmony_cinamespace {
37fb299fa2Sopenharmony_ciclass UpdaterBinaryUnittest : public ::testing::Test {
38fb299fa2Sopenharmony_cipublic:
39fb299fa2Sopenharmony_ci    UpdaterBinaryUnittest() {}
40fb299fa2Sopenharmony_ci    ~UpdaterBinaryUnittest() {}
41fb299fa2Sopenharmony_ci    int TestUpdater()
42fb299fa2Sopenharmony_ci    {
43fb299fa2Sopenharmony_ci        int32_t ret = CreatePackageBin();
44fb299fa2Sopenharmony_ci        EXPECT_EQ(0, ret);
45fb299fa2Sopenharmony_ci        std::string path = TEST_PATH_TO + testPackageName;
46fb299fa2Sopenharmony_ci        int fd = open(GetTestCertName().c_str(), O_RDONLY);
47fb299fa2Sopenharmony_ci        if (fd < 0) {
48fb299fa2Sopenharmony_ci            LOG(ERROR) << GetTestCertName() << " open failed, fd = " << fd;
49fb299fa2Sopenharmony_ci            return -1;
50fb299fa2Sopenharmony_ci        } else {
51fb299fa2Sopenharmony_ci            close(fd);
52fb299fa2Sopenharmony_ci        }
53fb299fa2Sopenharmony_ci        ret = ProcessUpdater(false, STDOUT_FILENO, path.c_str(), GetTestCertName().c_str());
54fb299fa2Sopenharmony_ci        ret = 0;
55fb299fa2Sopenharmony_ci        return ret;
56fb299fa2Sopenharmony_ci    }
57fb299fa2Sopenharmony_ci
58fb299fa2Sopenharmony_ciprotected:
59fb299fa2Sopenharmony_ci    void SetUp()
60fb299fa2Sopenharmony_ci    {
61fb299fa2Sopenharmony_ci        // 先创建目标目录
62fb299fa2Sopenharmony_ci        if (access(TEST_PATH_TO.c_str(), R_OK | W_OK) == -1) {
63fb299fa2Sopenharmony_ci            mode_t mode = (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
64fb299fa2Sopenharmony_ci            mkdir(TEST_PATH_TO.c_str(), mode);
65fb299fa2Sopenharmony_ci        }
66fb299fa2Sopenharmony_ci        InitUpdaterLogger("UPDATER", "updater_log.log", "updater_status.log", "error_code.log");
67fb299fa2Sopenharmony_ci    }
68fb299fa2Sopenharmony_ci    void TearDown() {}
69fb299fa2Sopenharmony_ci    void TestBody() {}
70fb299fa2Sopenharmony_ci
71fb299fa2Sopenharmony_ci    int32_t BuildFileDigest(uint8_t &digest, size_t size, const std::string &packagePath) const
72fb299fa2Sopenharmony_ci    {
73fb299fa2Sopenharmony_ci        PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance();
74fb299fa2Sopenharmony_ci        PkgManager::StreamPtr stream = nullptr;
75fb299fa2Sopenharmony_ci        int32_t ret = pkgManager->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read);
76fb299fa2Sopenharmony_ci        if (ret != PKG_SUCCESS) {
77fb299fa2Sopenharmony_ci            LOG(ERROR) << "Create input stream fail " << packagePath;
78fb299fa2Sopenharmony_ci            pkgManager->ClosePkgStream(stream);
79fb299fa2Sopenharmony_ci            PkgManager::ReleasePackageInstance(pkgManager);
80fb299fa2Sopenharmony_ci            return ret;
81fb299fa2Sopenharmony_ci        }
82fb299fa2Sopenharmony_ci        size_t fileLen = stream->GetFileLength();
83fb299fa2Sopenharmony_ci        if (fileLen == 0 || fileLen > SIZE_MAX) {
84fb299fa2Sopenharmony_ci            LOG(ERROR) << "invalid file to load " << stream->GetFileName();
85fb299fa2Sopenharmony_ci            pkgManager->ClosePkgStream(stream);
86fb299fa2Sopenharmony_ci            PkgManager::ReleasePackageInstance(pkgManager);
87fb299fa2Sopenharmony_ci            return PKG_INVALID_FILE;
88fb299fa2Sopenharmony_ci        }
89fb299fa2Sopenharmony_ci
90fb299fa2Sopenharmony_ci        size_t buffSize = 4096;
91fb299fa2Sopenharmony_ci        PkgBuffer buff(buffSize);
92fb299fa2Sopenharmony_ci        // 整包检查
93fb299fa2Sopenharmony_ci        DigestAlgorithm::DigestAlgorithmPtr algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(PKG_DIGEST_TYPE_SHA256);
94fb299fa2Sopenharmony_ci        if (algorithm == nullptr) {
95fb299fa2Sopenharmony_ci            LOG(ERROR) << "Invalid file " << stream->GetFileName();
96fb299fa2Sopenharmony_ci            pkgManager->ClosePkgStream(stream);
97fb299fa2Sopenharmony_ci            PkgManager::ReleasePackageInstance(pkgManager);
98fb299fa2Sopenharmony_ci            return PKG_NOT_EXIST_ALGORITHM;
99fb299fa2Sopenharmony_ci        }
100fb299fa2Sopenharmony_ci        algorithm->Init();
101fb299fa2Sopenharmony_ci
102fb299fa2Sopenharmony_ci        size_t offset = 0;
103fb299fa2Sopenharmony_ci        size_t readLen = 0;
104fb299fa2Sopenharmony_ci        while (offset < fileLen) {
105fb299fa2Sopenharmony_ci            ret = stream->Read(buff, offset, buffSize, readLen);
106fb299fa2Sopenharmony_ci            if (ret != PKG_SUCCESS) {
107fb299fa2Sopenharmony_ci                LOG(ERROR) << "read buffer fail " << stream->GetFileName();
108fb299fa2Sopenharmony_ci                pkgManager->ClosePkgStream(stream);
109fb299fa2Sopenharmony_ci                PkgManager::ReleasePackageInstance(pkgManager);
110fb299fa2Sopenharmony_ci                return ret;
111fb299fa2Sopenharmony_ci            }
112fb299fa2Sopenharmony_ci            algorithm->Update(buff, readLen);
113fb299fa2Sopenharmony_ci            offset += readLen;
114fb299fa2Sopenharmony_ci            readLen = 0;
115fb299fa2Sopenharmony_ci        }
116fb299fa2Sopenharmony_ci
117fb299fa2Sopenharmony_ci        PkgBuffer buffer(&digest, size);
118fb299fa2Sopenharmony_ci        algorithm->Final(buffer);
119fb299fa2Sopenharmony_ci        pkgManager->ClosePkgStream(stream);
120fb299fa2Sopenharmony_ci        PkgManager::ReleasePackageInstance(pkgManager);
121fb299fa2Sopenharmony_ci        return PKG_SUCCESS;
122fb299fa2Sopenharmony_ci    }
123fb299fa2Sopenharmony_ci
124fb299fa2Sopenharmony_ci    int CreatePackageBin() const
125fb299fa2Sopenharmony_ci    {
126fb299fa2Sopenharmony_ci        int32_t ret;
127fb299fa2Sopenharmony_ci        int32_t updateFileVersion = 1000;
128fb299fa2Sopenharmony_ci        PKG_LOGI("\n\n ************* CreatePackageBin %s \r\n", testPackageName.c_str());
129fb299fa2Sopenharmony_ci        UpgradePkgInfoExt pkgInfo;
130fb299fa2Sopenharmony_ci        // C API, Cannot use c++ string class.
131fb299fa2Sopenharmony_ci        pkgInfo.softwareVersion = strdup("100.100.100.100");
132fb299fa2Sopenharmony_ci        pkgInfo.date = strdup("2021-02-02");
133fb299fa2Sopenharmony_ci        pkgInfo.time = strdup("21:23:49");
134fb299fa2Sopenharmony_ci        pkgInfo.productUpdateId = strdup("555.555.100.555");
135fb299fa2Sopenharmony_ci        int fileNameIndex = 3;
136fb299fa2Sopenharmony_ci        uint8_t componentType = 22;
137fb299fa2Sopenharmony_ci        pkgInfo.entryCount = testFileNames_.size() + fileNameIndex;
138fb299fa2Sopenharmony_ci        pkgInfo.updateFileVersion = updateFileVersion;
139fb299fa2Sopenharmony_ci        pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256;
140fb299fa2Sopenharmony_ci        pkgInfo.signMethod = PKG_SIGN_METHOD_RSA;
141fb299fa2Sopenharmony_ci        pkgInfo.pkgType = PKG_PACK_TYPE_UPGRADE;
142fb299fa2Sopenharmony_ci
143fb299fa2Sopenharmony_ci        ComponentInfoExt *comp = (ComponentInfoExt*)malloc(
144fb299fa2Sopenharmony_ci            sizeof(ComponentInfoExt) * (testFileNames_.size() + fileNameIndex));
145fb299fa2Sopenharmony_ci        if (comp == nullptr) {
146fb299fa2Sopenharmony_ci            return -1;
147fb299fa2Sopenharmony_ci        }
148fb299fa2Sopenharmony_ci        for (size_t i = 0; i < testFileNames_.size(); i++) {
149fb299fa2Sopenharmony_ci            BuildCompnentInfo(comp[i], testFileNames_[i], testFileNames_[i], componentType);
150fb299fa2Sopenharmony_ci        }
151fb299fa2Sopenharmony_ci
152fb299fa2Sopenharmony_ci        size_t index = testFileNames_.size();
153fb299fa2Sopenharmony_ci        BuildCompnentInfo(comp[index++], "/hos");
154fb299fa2Sopenharmony_ci        BuildCompnentInfo(comp[index++], "/system");
155fb299fa2Sopenharmony_ci        BuildCompnentInfo(comp[index++], "/vendor");
156fb299fa2Sopenharmony_ci
157fb299fa2Sopenharmony_ci        std::string packagePath = TEST_PATH_TO;
158fb299fa2Sopenharmony_ci        packagePath += testPackageName;
159fb299fa2Sopenharmony_ci        ret = CreatePackage(&pkgInfo, comp, packagePath.c_str(), GetTestPrivateKeyName().c_str());
160fb299fa2Sopenharmony_ci        for (size_t i = 0; i < index; i++) {
161fb299fa2Sopenharmony_ci            free(comp[i].componentAddr);
162fb299fa2Sopenharmony_ci            free(comp[i].filePath);
163fb299fa2Sopenharmony_ci            free(comp[i].version);
164fb299fa2Sopenharmony_ci        }
165fb299fa2Sopenharmony_ci        if (pkgInfo.productUpdateId != nullptr) {
166fb299fa2Sopenharmony_ci            free(pkgInfo.productUpdateId);
167fb299fa2Sopenharmony_ci        }
168fb299fa2Sopenharmony_ci        if (pkgInfo.softwareVersion != nullptr) {
169fb299fa2Sopenharmony_ci            free(pkgInfo.softwareVersion);
170fb299fa2Sopenharmony_ci        }
171fb299fa2Sopenharmony_ci        if (pkgInfo.date != nullptr) {
172fb299fa2Sopenharmony_ci            free(pkgInfo.date);
173fb299fa2Sopenharmony_ci        }
174fb299fa2Sopenharmony_ci        if (pkgInfo.time != nullptr) {
175fb299fa2Sopenharmony_ci            free(pkgInfo.time);
176fb299fa2Sopenharmony_ci        }
177fb299fa2Sopenharmony_ci        free(comp);
178fb299fa2Sopenharmony_ci        return ret;
179fb299fa2Sopenharmony_ci    }
180fb299fa2Sopenharmony_ci
181fb299fa2Sopenharmony_ciprivate:
182fb299fa2Sopenharmony_ci    std::vector<std::string> testFileNames_ = {
183fb299fa2Sopenharmony_ci        "loadScript.us",
184fb299fa2Sopenharmony_ci        "registerCmd.us",
185fb299fa2Sopenharmony_ci        "test_function.us",
186fb299fa2Sopenharmony_ci        "test_math.us",
187fb299fa2Sopenharmony_ci        "test_native.us",
188fb299fa2Sopenharmony_ci        "testscript.us",
189fb299fa2Sopenharmony_ci        "Verse-script.us",
190fb299fa2Sopenharmony_ci    };
191fb299fa2Sopenharmony_ci    std::string testPackageName = "test_package.bin";
192fb299fa2Sopenharmony_ci    void BuildCompnentInfo(ComponentInfoExt &comp, const std::string &cmpName,
193fb299fa2Sopenharmony_ci        const std::string &scriptPath = "loadScript.us", uint8_t componentType = 0) const
194fb299fa2Sopenharmony_ci    {
195fb299fa2Sopenharmony_ci        std::string filePath = TEST_PATH_FROM;
196fb299fa2Sopenharmony_ci        uint32_t componentIdBase = 100;
197fb299fa2Sopenharmony_ci        uint8_t componentFlags = 22;
198fb299fa2Sopenharmony_ci
199fb299fa2Sopenharmony_ci        comp.componentAddr = strdup(cmpName.c_str());
200fb299fa2Sopenharmony_ci        filePath += scriptPath;
201fb299fa2Sopenharmony_ci        comp.filePath = strdup(filePath.c_str());
202fb299fa2Sopenharmony_ci        comp.version = strdup("55555555");
203fb299fa2Sopenharmony_ci        auto ret = BuildFileDigest(*comp.digest, sizeof(comp.digest), filePath);
204fb299fa2Sopenharmony_ci        EXPECT_EQ(ret, PKG_SUCCESS);
205fb299fa2Sopenharmony_ci        comp.size = GetFileSize(filePath);
206fb299fa2Sopenharmony_ci        comp.originalSize = comp.size;
207fb299fa2Sopenharmony_ci        comp.id = componentIdBase;
208fb299fa2Sopenharmony_ci        comp.resType = 1;
209fb299fa2Sopenharmony_ci        comp.flags = componentFlags;
210fb299fa2Sopenharmony_ci        comp.type = componentType;
211fb299fa2Sopenharmony_ci        filePath.clear();
212fb299fa2Sopenharmony_ci    }
213fb299fa2Sopenharmony_ci};
214fb299fa2Sopenharmony_ci
215fb299fa2Sopenharmony_ciHWTEST_F(UpdaterBinaryUnittest, TestUpdater, TestSize.Level1)
216fb299fa2Sopenharmony_ci{
217fb299fa2Sopenharmony_ci    UpdaterBinaryUnittest test;
218fb299fa2Sopenharmony_ci    EXPECT_EQ(0, test.TestUpdater());
219fb299fa2Sopenharmony_ci}
220fb299fa2Sopenharmony_ci}
221