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