1fb299fa2Sopenharmony_ci/* 2fb299fa2Sopenharmony_ci * Copyright (c) 2022 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 <climits> 17fb299fa2Sopenharmony_ci#include <cstring> 18fb299fa2Sopenharmony_ci#include <fcntl.h> 19fb299fa2Sopenharmony_ci#include <gtest/gtest.h> 20fb299fa2Sopenharmony_ci#include <iostream> 21fb299fa2Sopenharmony_ci#include <sys/mman.h> 22fb299fa2Sopenharmony_ci#include <sys/stat.h> 23fb299fa2Sopenharmony_ci#include <unistd.h> 24fb299fa2Sopenharmony_ci#include "hash_data_verifier.h" 25fb299fa2Sopenharmony_ci#include "log.h" 26fb299fa2Sopenharmony_ci#include "pkg_stream.h" 27fb299fa2Sopenharmony_ci#include "pkg_utils.h" 28fb299fa2Sopenharmony_ci#include "scope_guard.h" 29fb299fa2Sopenharmony_ci#include "script_instruction.h" 30fb299fa2Sopenharmony_ci#include "script_manager.h" 31fb299fa2Sopenharmony_ci#include "script/script_unittest.h" 32fb299fa2Sopenharmony_ci#include "script_utils.h" 33fb299fa2Sopenharmony_ci#include "unittest_comm.h" 34fb299fa2Sopenharmony_ci#include "utils.h" 35fb299fa2Sopenharmony_ci 36fb299fa2Sopenharmony_ciusing namespace std; 37fb299fa2Sopenharmony_ciusing namespace Hpackage; 38fb299fa2Sopenharmony_ciusing namespace Uscript; 39fb299fa2Sopenharmony_ciusing namespace Updater; 40fb299fa2Sopenharmony_ciusing namespace testing::ext; 41fb299fa2Sopenharmony_ci 42fb299fa2Sopenharmony_cinamespace { 43fb299fa2Sopenharmony_ciconstexpr int32_t SCRIPT_TEST_PRIORITY_NUM = 3; 44fb299fa2Sopenharmony_ciconstexpr int32_t SCRIPT_TEST_LAST_PRIORITY = 2; 45fb299fa2Sopenharmony_ci 46fb299fa2Sopenharmony_ciclass TestPkgManager : public TestScriptPkgManager { 47fb299fa2Sopenharmony_cipublic: 48fb299fa2Sopenharmony_ci const FileInfo *GetFileInfo(const std::string &fileId) override 49fb299fa2Sopenharmony_ci { 50fb299fa2Sopenharmony_ci static FileInfo fileInfo {}; 51fb299fa2Sopenharmony_ci static std::vector<std::string> testFileNames = { 52fb299fa2Sopenharmony_ci "loadScript.us", 53fb299fa2Sopenharmony_ci "registerCmd.us", 54fb299fa2Sopenharmony_ci "test_function.us", 55fb299fa2Sopenharmony_ci "test_if.us", 56fb299fa2Sopenharmony_ci "test_logic.us", 57fb299fa2Sopenharmony_ci "test_math.us", 58fb299fa2Sopenharmony_ci "test_native.us", 59fb299fa2Sopenharmony_ci "testscript.us", 60fb299fa2Sopenharmony_ci "Verse-script.us", 61fb299fa2Sopenharmony_ci "test_script.us" 62fb299fa2Sopenharmony_ci }; 63fb299fa2Sopenharmony_ci if (fileId == "hash_signed_data") { 64fb299fa2Sopenharmony_ci fileInfo.unpackedSize = GetFileSize(TEST_PATH_FROM + fileId); 65fb299fa2Sopenharmony_ci return &fileInfo; 66fb299fa2Sopenharmony_ci } 67fb299fa2Sopenharmony_ci if (std::find(testFileNames.begin(), testFileNames.end(), fileId) != testFileNames.end()) { 68fb299fa2Sopenharmony_ci return &fileInfo; 69fb299fa2Sopenharmony_ci } 70fb299fa2Sopenharmony_ci return nullptr; 71fb299fa2Sopenharmony_ci } 72fb299fa2Sopenharmony_ci int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName, const PkgBuffer &buffer) override 73fb299fa2Sopenharmony_ci { 74fb299fa2Sopenharmony_ci stream = new MemoryMapStream(this, fileName, buffer, PkgStream::PkgStreamType_Buffer); 75fb299fa2Sopenharmony_ci return PKG_SUCCESS; 76fb299fa2Sopenharmony_ci } 77fb299fa2Sopenharmony_ci int32_t ExtractFile(const std::string &fileId, StreamPtr output) override 78fb299fa2Sopenharmony_ci { 79fb299fa2Sopenharmony_ci if (fileId != "hash_signed_data") { 80fb299fa2Sopenharmony_ci return PKG_SUCCESS; 81fb299fa2Sopenharmony_ci } 82fb299fa2Sopenharmony_ci if (output == nullptr) { 83fb299fa2Sopenharmony_ci return PKG_INVALID_STREAM; 84fb299fa2Sopenharmony_ci } 85fb299fa2Sopenharmony_ci auto stream = static_cast<MemoryMapStream *>(output); 86fb299fa2Sopenharmony_ci auto fd = open((TEST_PATH_FROM + fileId).c_str(), O_RDWR); 87fb299fa2Sopenharmony_ci if (fd == -1) { 88fb299fa2Sopenharmony_ci PKG_LOGE("file %s not existed", (TEST_PATH_FROM + fileId).c_str()); 89fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 90fb299fa2Sopenharmony_ci } 91fb299fa2Sopenharmony_ci ON_SCOPE_EXIT(close) { 92fb299fa2Sopenharmony_ci close(fd); 93fb299fa2Sopenharmony_ci }; 94fb299fa2Sopenharmony_ci std::string content {}; 95fb299fa2Sopenharmony_ci if (!Utils::ReadFileToString(fd, content)) { 96fb299fa2Sopenharmony_ci PKG_LOGE("read file to string failed"); 97fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 98fb299fa2Sopenharmony_ci } 99fb299fa2Sopenharmony_ci PkgBuffer buffer {}; 100fb299fa2Sopenharmony_ci stream->GetBuffer(buffer); 101fb299fa2Sopenharmony_ci if (content.size() + 1 != buffer.length) { 102fb299fa2Sopenharmony_ci PKG_LOGE("content size is not valid, %u != %u", content.size(), buffer.data.size()); 103fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 104fb299fa2Sopenharmony_ci } 105fb299fa2Sopenharmony_ci std::copy(content.begin(), content.end(), buffer.buffer); 106fb299fa2Sopenharmony_ci return PKG_SUCCESS; 107fb299fa2Sopenharmony_ci } 108fb299fa2Sopenharmony_ci int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName, 109fb299fa2Sopenharmony_ci size_t size, int32_t type) override 110fb299fa2Sopenharmony_ci { 111fb299fa2Sopenharmony_ci FILE *file = nullptr; 112fb299fa2Sopenharmony_ci std::string fileNameReal = fileName; 113fb299fa2Sopenharmony_ci auto pos = fileName.rfind('/'); 114fb299fa2Sopenharmony_ci if (pos != std::string::npos) { 115fb299fa2Sopenharmony_ci fileNameReal = fileName.substr(pos + 1); 116fb299fa2Sopenharmony_ci } 117fb299fa2Sopenharmony_ci char realPath[PATH_MAX + 1] = {}; 118fb299fa2Sopenharmony_ci if (realpath((TEST_PATH_FROM + fileNameReal).c_str(), realPath) == nullptr) { 119fb299fa2Sopenharmony_ci LOG(ERROR) << (TEST_PATH_FROM + fileNameReal) << " realpath failed"; 120fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 121fb299fa2Sopenharmony_ci } 122fb299fa2Sopenharmony_ci file = fopen(realPath, "rb"); 123fb299fa2Sopenharmony_ci if (file == nullptr) { 124fb299fa2Sopenharmony_ci PKG_LOGE("Fail to open file %s ", fileNameReal.c_str()); 125fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 126fb299fa2Sopenharmony_ci } 127fb299fa2Sopenharmony_ci stream = new FileStream(this, fileNameReal, file, PkgStream::PkgStreamType_Read); 128fb299fa2Sopenharmony_ci return USCRIPT_SUCCESS; 129fb299fa2Sopenharmony_ci } 130fb299fa2Sopenharmony_ci void ClosePkgStream(StreamPtr &stream) override 131fb299fa2Sopenharmony_ci { 132fb299fa2Sopenharmony_ci delete stream; 133fb299fa2Sopenharmony_ci } 134fb299fa2Sopenharmony_ci}; 135fb299fa2Sopenharmony_ci 136fb299fa2Sopenharmony_ci 137fb299fa2Sopenharmony_ciclass TestScriptInstructionSparseImageWrite : public Uscript::UScriptInstruction { 138fb299fa2Sopenharmony_cipublic: 139fb299fa2Sopenharmony_ci TestScriptInstructionSparseImageWrite() {} 140fb299fa2Sopenharmony_ci virtual ~TestScriptInstructionSparseImageWrite() {} 141fb299fa2Sopenharmony_ci int32_t Execute(Uscript::UScriptEnv &env, Uscript::UScriptContext &context) override 142fb299fa2Sopenharmony_ci { 143fb299fa2Sopenharmony_ci // 从参数中获取分区信息 144fb299fa2Sopenharmony_ci std::string partitionName; 145fb299fa2Sopenharmony_ci int32_t ret = context.GetParam(0, partitionName); 146fb299fa2Sopenharmony_ci if (ret != USCRIPT_SUCCESS) { 147fb299fa2Sopenharmony_ci LOG(ERROR) << "Error to get param"; 148fb299fa2Sopenharmony_ci return ret; 149fb299fa2Sopenharmony_ci } 150fb299fa2Sopenharmony_ci LOG(INFO) << "UScriptInstructionSparseImageWrite::Execute " << partitionName; 151fb299fa2Sopenharmony_ci if (env.GetPkgManager() == nullptr) { 152fb299fa2Sopenharmony_ci LOG(ERROR) << "Error to get pkg manager"; 153fb299fa2Sopenharmony_ci return USCRIPT_ERROR_EXECUTE; 154fb299fa2Sopenharmony_ci } 155fb299fa2Sopenharmony_ci return ret; 156fb299fa2Sopenharmony_ci } 157fb299fa2Sopenharmony_ci}; 158fb299fa2Sopenharmony_ci 159fb299fa2Sopenharmony_ciclass TestScriptInstructionFactory : public UScriptInstructionFactory { 160fb299fa2Sopenharmony_cipublic: 161fb299fa2Sopenharmony_ci virtual int32_t CreateInstructionInstance(UScriptInstructionPtr& instr, const std::string& name) 162fb299fa2Sopenharmony_ci { 163fb299fa2Sopenharmony_ci if (name == "sparse_image_write") { 164fb299fa2Sopenharmony_ci instr = new TestScriptInstructionSparseImageWrite(); 165fb299fa2Sopenharmony_ci } 166fb299fa2Sopenharmony_ci return USCRIPT_SUCCESS; 167fb299fa2Sopenharmony_ci } 168fb299fa2Sopenharmony_ci virtual void DestoryInstructionInstance(UScriptInstructionPtr& instr) 169fb299fa2Sopenharmony_ci { 170fb299fa2Sopenharmony_ci delete instr; 171fb299fa2Sopenharmony_ci instr = nullptr; 172fb299fa2Sopenharmony_ci } 173fb299fa2Sopenharmony_ci TestScriptInstructionFactory() {} 174fb299fa2Sopenharmony_ci virtual ~TestScriptInstructionFactory() {} 175fb299fa2Sopenharmony_ci}; 176fb299fa2Sopenharmony_ci 177fb299fa2Sopenharmony_ciclass UTestScriptEnv : public UScriptEnv { 178fb299fa2Sopenharmony_cipublic: 179fb299fa2Sopenharmony_ci explicit UTestScriptEnv(Hpackage::PkgManager::PkgManagerPtr pkgManager) : UScriptEnv(pkgManager) {} 180fb299fa2Sopenharmony_ci ~UTestScriptEnv() 181fb299fa2Sopenharmony_ci { 182fb299fa2Sopenharmony_ci if (factory_ != nullptr) { 183fb299fa2Sopenharmony_ci delete factory_; 184fb299fa2Sopenharmony_ci factory_ = nullptr; 185fb299fa2Sopenharmony_ci } 186fb299fa2Sopenharmony_ci } 187fb299fa2Sopenharmony_ci 188fb299fa2Sopenharmony_ci virtual void PostMessage(const std::string &cmd, std::string content) {} 189fb299fa2Sopenharmony_ci 190fb299fa2Sopenharmony_ci virtual UScriptInstructionFactoryPtr GetInstructionFactory() 191fb299fa2Sopenharmony_ci { 192fb299fa2Sopenharmony_ci if (factory_ == nullptr) { 193fb299fa2Sopenharmony_ci factory_ = new TestScriptInstructionFactory(); 194fb299fa2Sopenharmony_ci } 195fb299fa2Sopenharmony_ci return factory_; 196fb299fa2Sopenharmony_ci } 197fb299fa2Sopenharmony_ci 198fb299fa2Sopenharmony_ci virtual const std::vector<std::string> GetInstructionNames() const 199fb299fa2Sopenharmony_ci { 200fb299fa2Sopenharmony_ci static std::vector<std::string> updaterCmds = {"sparse_image_write"}; 201fb299fa2Sopenharmony_ci return updaterCmds; 202fb299fa2Sopenharmony_ci } 203fb299fa2Sopenharmony_ci 204fb299fa2Sopenharmony_ci virtual bool IsRetry() const 205fb299fa2Sopenharmony_ci { 206fb299fa2Sopenharmony_ci return isRetry; 207fb299fa2Sopenharmony_ci } 208fb299fa2Sopenharmony_ci 209fb299fa2Sopenharmony_ci virtual PostMessageFunction GetPostmsgFunc() 210fb299fa2Sopenharmony_ci { 211fb299fa2Sopenharmony_ci return nullptr; 212fb299fa2Sopenharmony_ci } 213fb299fa2Sopenharmony_ci UScriptInstructionFactory *factory_ = nullptr; 214fb299fa2Sopenharmony_ciprivate: 215fb299fa2Sopenharmony_ci bool isRetry = false; 216fb299fa2Sopenharmony_ci}; 217fb299fa2Sopenharmony_ci 218fb299fa2Sopenharmony_ciclass UScriptTest : public ::testing::Test { 219fb299fa2Sopenharmony_cipublic: 220fb299fa2Sopenharmony_ci UScriptTest() {} 221fb299fa2Sopenharmony_ci 222fb299fa2Sopenharmony_ci ~UScriptTest() 223fb299fa2Sopenharmony_ci { 224fb299fa2Sopenharmony_ci ScriptManager::ReleaseScriptManager(); 225fb299fa2Sopenharmony_ci } 226fb299fa2Sopenharmony_ci 227fb299fa2Sopenharmony_ci int TestUscriptExecute() 228fb299fa2Sopenharmony_ci { 229fb299fa2Sopenharmony_ci int32_t ret {}; 230fb299fa2Sopenharmony_ci TestPkgManager packageManager; 231fb299fa2Sopenharmony_ci UTestScriptEnv *env = new UTestScriptEnv(&packageManager); 232fb299fa2Sopenharmony_ci HashDataVerifier verifier {&packageManager}; 233fb299fa2Sopenharmony_ci verifier.LoadHashDataAndPkcs7(TEST_PATH_FROM + "updater_fake_pkg.zip"); 234fb299fa2Sopenharmony_ci ScriptManager *manager = ScriptManager::GetScriptManager(env, &verifier); 235fb299fa2Sopenharmony_ci if (manager == nullptr) { 236fb299fa2Sopenharmony_ci USCRIPT_LOGI("create manager fail ret:%d", ret); 237fb299fa2Sopenharmony_ci delete env; 238fb299fa2Sopenharmony_ci return USCRIPT_INVALID_SCRIPT; 239fb299fa2Sopenharmony_ci } 240fb299fa2Sopenharmony_ci int32_t priority = SCRIPT_TEST_PRIORITY_NUM; 241fb299fa2Sopenharmony_ci ret = manager->ExecuteScript(priority); 242fb299fa2Sopenharmony_ci EXPECT_EQ(ret, USCRIPT_ABOART); 243fb299fa2Sopenharmony_ci USCRIPT_LOGI("ExecuteScript ret:%d", ret); 244fb299fa2Sopenharmony_ci priority = 0; 245fb299fa2Sopenharmony_ci ret = manager->ExecuteScript(priority); 246fb299fa2Sopenharmony_ci priority = 1; 247fb299fa2Sopenharmony_ci ret = manager->ExecuteScript(priority); 248fb299fa2Sopenharmony_ci priority = SCRIPT_TEST_LAST_PRIORITY; 249fb299fa2Sopenharmony_ci ret = manager->ExecuteScript(priority); 250fb299fa2Sopenharmony_ci delete env; 251fb299fa2Sopenharmony_ci ScriptManager::ReleaseScriptManager(); 252fb299fa2Sopenharmony_ci return ret; 253fb299fa2Sopenharmony_ci } 254fb299fa2Sopenharmony_ci 255fb299fa2Sopenharmony_ciprotected: 256fb299fa2Sopenharmony_ci void SetUp() {} 257fb299fa2Sopenharmony_ci void TearDown() {} 258fb299fa2Sopenharmony_ci void TestBody() {} 259fb299fa2Sopenharmony_ci 260fb299fa2Sopenharmony_ciprivate: 261fb299fa2Sopenharmony_ci std::vector<std::string> testFileNames_ = { 262fb299fa2Sopenharmony_ci "loadScript.us", 263fb299fa2Sopenharmony_ci "registerCmd.us", 264fb299fa2Sopenharmony_ci "test_function.us", 265fb299fa2Sopenharmony_ci "test_if.us", 266fb299fa2Sopenharmony_ci "test_logic.us", 267fb299fa2Sopenharmony_ci "test_math.us", 268fb299fa2Sopenharmony_ci "test_native.us", 269fb299fa2Sopenharmony_ci "testscript.us", 270fb299fa2Sopenharmony_ci "Verse-script.us", 271fb299fa2Sopenharmony_ci "test_script.us" 272fb299fa2Sopenharmony_ci }; 273fb299fa2Sopenharmony_ci}; 274fb299fa2Sopenharmony_ci 275fb299fa2Sopenharmony_ciHWTEST_F(UScriptTest, TestUscriptExecute, TestSize.Level1) 276fb299fa2Sopenharmony_ci{ 277fb299fa2Sopenharmony_ci UScriptTest test; 278fb299fa2Sopenharmony_ci EXPECT_EQ(0, test.TestUscriptExecute()); 279fb299fa2Sopenharmony_ci} 280fb299fa2Sopenharmony_ci} 281