1 /* 2 * Copyright (c) 2022 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 <gmock/gmock.h> 20 #include <iostream> 21 #include <memory> 22 #include <sys/mman.h> 23 #include <sys/stat.h> 24 #include <type_traits> 25 #include <unistd.h> 26 #include "log.h" 27 #include "script_context.h" 28 #include "script_basicinstruction.h" 29 #include "script_instruction.h" 30 #include "script_manager.h" 31 #include "script/script_unittest.h" 32 #include "script_utils.h" 33 #include "thread_pool.h" 34 35 using namespace std; 36 using namespace Hpackage; 37 using namespace Uscript; 38 using namespace BasicInstruction; 39 using namespace Updater; 40 using namespace testing::ext; 41 42 namespace { 43 class MockUScriptEnv : public UScriptEnv { 44 public: MockUScriptEnv(Hpackage::PkgManager::PkgManagerPtr pkgManager)45 explicit MockUScriptEnv(Hpackage::PkgManager::PkgManagerPtr pkgManager) : UScriptEnv(pkgManager) {} GetPostmsgFunc()46 virtual PostMessageFunction GetPostmsgFunc() 47 { 48 return nullptr; 49 } 50 MOCK_CONST_METHOD0(IsRetry, bool()); 51 MOCK_METHOD2(PostMessage, void(const std::string &cmd, std::string content)); 52 MOCK_METHOD0(GetInstructionFactory, UScriptInstructionFactoryPtr()); 53 MOCK_CONST_METHOD0(GetInstructionNames, const std::vector<std::string>()); 54 }; 55 56 class BasicInstructionUnittest : public ::testing::Test { 57 public: BasicInstructionUnittest()58 BasicInstructionUnittest() {} ~BasicInstructionUnittest()59 ~BasicInstructionUnittest() {} 60 template<typename ... Args> AddInputParam(UScriptInstructionContext & ctx,Args &&...args)61 static void AddInputParam(UScriptInstructionContext &ctx, Args && ... args) 62 { 63 [[maybe_unused]] auto li = { AddInputParamImpl(ctx, args)...}; 64 } AddInputParamImpl(UScriptInstructionContext & ctx,const std::string & v)65 static int32_t AddInputParamImpl(UScriptInstructionContext &ctx, const std::string &v) 66 { 67 return ctx.AddInputParam(std::make_shared<StringValue>(v)); 68 } 69 template<typename T, std::enable_if_t<std::is_floating_point_v<T>, void *> = nullptr> AddInputParamImpl(UScriptInstructionContext & ctx,T v)70 static int32_t AddInputParamImpl(UScriptInstructionContext &ctx, T v) 71 { 72 return ctx.AddInputParam(std::make_shared<FloatValue>(v)); 73 } AddInputParamImpl(UScriptInstructionContext & ctx,int32_t v)74 static int32_t AddInputParamImpl(UScriptInstructionContext &ctx, int32_t v) 75 { 76 return ctx.AddInputParam(std::make_shared<IntegerValue>(v)); 77 } TestBasicInstructionIsSubString01() const78 void TestBasicInstructionIsSubString01() const 79 { 80 { 81 MockUScriptEnv env {nullptr}; 82 UScriptInstructionContext context {}; 83 AddInputParam(context, "this is a test", "this is a test for is sub string"); 84 auto instruction = std::make_unique<UScriptInstructionIsSubString>(); 85 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_SUCCESS); 86 std::vector<UScriptValuePtr> output = context.GetOutVar(); 87 ASSERT_EQ(output.size(), 1); 88 EXPECT_EQ(output[0]->GetValueType(), UScriptValue::VALUE_TYPE_INTEGER); 89 EXPECT_EQ(output[0]->ToString(), "0"); 90 } 91 { 92 MockUScriptEnv env {nullptr}; 93 UScriptInstructionContext context {}; 94 AddInputParam(context, "this is a test for is sub string", "this is a test"); 95 auto instruction = std::make_unique<UScriptInstructionIsSubString>(); 96 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_SUCCESS); 97 std::vector<UScriptValuePtr> output = context.GetOutVar(); 98 ASSERT_EQ(output.size(), 1); 99 EXPECT_EQ(output[0]->GetValueType(), UScriptValue::VALUE_TYPE_INTEGER); 100 EXPECT_EQ(output[0]->ToString(), "1"); 101 } 102 } TestBasicInstructionIsSubString02() const103 void TestBasicInstructionIsSubString02() const 104 { 105 { 106 MockUScriptEnv env {nullptr}; 107 UScriptInstructionContext context {}; 108 context.AddInputParam(std::make_shared<StringValue>("this is a test")); 109 auto instruction = std::make_unique<UScriptInstructionIsSubString>(); 110 EXPECT_EQ(instruction->Execute(env, context), UScriptContext::PARAM_TYPE_INVALID); 111 std::vector<UScriptValuePtr> output = context.GetOutVar(); 112 EXPECT_EQ(output.size(), 0); 113 } 114 { 115 MockUScriptEnv env {nullptr}; 116 UScriptInstructionContext context {}; 117 AddInputParam(context, "this is a test", 1); 118 auto instruction = std::make_unique<UScriptInstructionIsSubString>(); 119 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_INVALID_PARAM); 120 std::vector<UScriptValuePtr> output = context.GetOutVar(); 121 EXPECT_EQ(output.size(), 0); 122 } 123 } TestBasicInstructionStdout() const124 void TestBasicInstructionStdout() const 125 { 126 MockUScriptEnv env {nullptr}; 127 UScriptInstructionContext context {}; 128 auto input = std::make_tuple("string1", 1, 1.0, 1.0001, 1.00000001); 129 auto instruction = std::make_unique<UScriptInstructionStdout>(); 130 std::stringstream buffer; 131 std::streambuf* old = std::cout.rdbuf(buffer.rdbuf()); 132 std::stringstream tgt; 133 std::apply([&tgt] (auto && ... args) { 134 ((tgt << args << " "), ...); 135 tgt << std::endl; 136 }, input); 137 std::apply([&context] (auto && ... args) { 138 AddInputParam(context, args...); 139 }, input); 140 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_SUCCESS); 141 std::vector<UScriptValuePtr> output = context.GetOutVar(); 142 EXPECT_EQ(output.size(), 0); 143 EXPECT_EQ(buffer.str(), tgt.str()); 144 std::cout.rdbuf(old); 145 } TestBasicInstructionConcat() const146 void TestBasicInstructionConcat() const 147 { 148 MockUScriptEnv env {nullptr}; 149 { 150 UScriptInstructionContext context {}; 151 auto input = std::make_tuple("this is a test", "test2", 1, 1.0, 1.0001, 1.00000001); 152 auto instruction = std::make_unique<UScriptInstructionConcat>(); 153 std::stringstream tgt; 154 auto toString = [] (auto &&arg) -> std::string { 155 using T = std::remove_cv_t<std::remove_reference_t<decltype(arg)>>; 156 if constexpr (std::is_same_v<std::string, T> || 157 std::is_same_v<const char *, T> || 158 std::is_same_v<char *, T>) { 159 return arg; 160 } else { 161 return std::to_string(arg); 162 } 163 }; 164 std::apply([&toString, &tgt] (auto && ... args) { 165 ((tgt << toString(args)), ...); 166 }, input); 167 std::apply([&context] (auto && ... args) { 168 AddInputParam(context, args...); 169 }, input); 170 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_SUCCESS); 171 std::vector<UScriptValuePtr> output = context.GetOutVar(); 172 ASSERT_EQ(output.size(), 1); 173 EXPECT_EQ(output[0]->GetValueType(), UScriptValue::VALUE_TYPE_STRING); 174 EXPECT_EQ(output[0]->ToString(), tgt.str()); 175 } 176 { 177 UScriptInstructionContext context {}; 178 auto instruction = std::make_unique<UScriptInstructionConcat>(); 179 EXPECT_EQ(instruction->Execute(env, context), UScriptContext::PARAM_TYPE_INVALID); 180 } 181 { 182 UScriptInstructionContext context1 {}; 183 AddInputParam(context1, 1); 184 auto instruction1 = std::make_unique<UScriptInstructionConcat>(); 185 EXPECT_EQ(instruction1->Execute(env, context1), USCRIPT_INVALID_PARAM); 186 UScriptInstructionContext context2 {}; 187 AddInputParam(context2, "test"); 188 auto instruction2 = std::make_unique<UScriptInstructionConcat>(); 189 EXPECT_EQ(instruction2->Execute(env, context2), USCRIPT_SUCCESS); 190 std::vector<UScriptValuePtr> output = context2.GetOutVar(); 191 ASSERT_EQ(output.size(), 1); 192 EXPECT_EQ(output[0]->GetValueType(), UScriptValue::VALUE_TYPE_STRING); 193 EXPECT_EQ(output[0]->ToString(), "test"); 194 } 195 } TestBasicInstructionAbort() const196 void TestBasicInstructionAbort() const 197 { 198 MockUScriptEnv env {nullptr}; 199 { 200 UScriptInstructionContext context {}; 201 auto instruction = std::make_unique<UScriptInstructionAbort>(); 202 EXPECT_EQ(instruction->Execute(env, context), UScriptContext::PARAM_TYPE_INVALID); 203 } 204 { 205 UScriptInstructionContext context {}; 206 AddInputParam(context, 1.0); 207 auto instruction = std::make_unique<UScriptInstructionSleep>(); 208 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_INVALID_PARAM); 209 } 210 { 211 UScriptInstructionContext context {}; 212 AddInputParam(context, 1); 213 auto instruction = std::make_unique<UScriptInstructionAbort>(); 214 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_SUCCESS); 215 } 216 { 217 UScriptInstructionContext context {}; 218 AddInputParam(context, 0); 219 auto instruction = std::make_unique<UScriptInstructionAbort>(); 220 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_ABOART); 221 } 222 } TestBasicInstructionAssert() const223 void TestBasicInstructionAssert() const 224 { 225 MockUScriptEnv env {nullptr}; 226 { 227 UScriptInstructionContext context {}; 228 auto instruction = std::make_unique<UScriptInstructionAssert>(); 229 EXPECT_EQ(instruction->Execute(env, context), UScriptContext::PARAM_TYPE_INVALID); 230 } 231 { 232 UScriptInstructionContext context {}; 233 AddInputParam(context, 1); 234 auto instruction = std::make_unique<UScriptInstructionAssert>(); 235 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_SUCCESS); 236 } 237 { 238 UScriptInstructionContext context {}; 239 AddInputParam(context, 0); 240 auto instruction = std::make_unique<UScriptInstructionAssert>(); 241 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_ASSERT); 242 } 243 } TestBasicInstructionSleep() const244 void TestBasicInstructionSleep() const 245 { 246 MockUScriptEnv env {nullptr}; 247 { 248 UScriptInstructionContext context {}; 249 auto instruction = std::make_unique<UScriptInstructionSleep>(); 250 EXPECT_EQ(instruction->Execute(env, context), UScriptContext::PARAM_TYPE_INVALID); 251 } 252 { 253 UScriptInstructionContext context {}; 254 AddInputParam(context, 0); 255 auto instruction = std::make_unique<UScriptInstructionSleep>(); 256 EXPECT_EQ(instruction->Execute(env, context), USCRIPT_SUCCESS); 257 } 258 } 259 protected: SetUp()260 void SetUp() {} TearDown()261 void TearDown() {} TestBody()262 void TestBody() {} 263 }; 264 265 HWTEST_F(BasicInstructionUnittest, TestBasicInstructionIsSubString01, TestSize.Level1) 266 { 267 BasicInstructionUnittest test; 268 test.TestBasicInstructionIsSubString01(); 269 } 270 271 HWTEST_F(BasicInstructionUnittest, TestBasicInstructionIsSubString02, TestSize.Level1) 272 { 273 BasicInstructionUnittest test; 274 test.TestBasicInstructionIsSubString02(); 275 } 276 277 HWTEST_F(BasicInstructionUnittest, TestBasicInstructionStdout, TestSize.Level1) 278 { 279 BasicInstructionUnittest test; 280 test.TestBasicInstructionStdout(); 281 } 282 283 HWTEST_F(BasicInstructionUnittest, TestBasicInstructionConcat, TestSize.Level1) 284 { 285 BasicInstructionUnittest test; 286 test.TestBasicInstructionConcat(); 287 } 288 289 HWTEST_F(BasicInstructionUnittest, TestBasicInstructionAbort, TestSize.Level1) 290 { 291 BasicInstructionUnittest test; 292 test.TestBasicInstructionAbort(); 293 } 294 295 HWTEST_F(BasicInstructionUnittest, TestBasicInstructionAssert, TestSize.Level1) 296 { 297 BasicInstructionUnittest test; 298 test.TestBasicInstructionAssert(); 299 } 300 301 HWTEST_F(BasicInstructionUnittest, TestBasicInstructionSleep, TestSize.Level1) 302 { 303 BasicInstructionUnittest test; 304 test.TestBasicInstructionSleep(); 305 } 306 } 307