• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 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 "libabckit/include/c/abckit.h"
17 #include "libabckit/include/c/metadata_core.h"
18 #include "libabckit/include/c/ir_core.h"
19 
20 #include "helpers/helpers.h"
21 #include "helpers/helpers_runtime.h"
22 
23 #include <gtest/gtest.h>
24 #include <cstddef>
25 
26 // NOTE:
27 // * Printed filename is "NOTE", should be real name
28 // * Use actual stdlib calls (instead of user's DateGetTime, ConsoleLogNum, ConsoleLogStr)
29 // * There are several issues related to SaveState in this test:
30 //   * Start calls are inserted after first SaveState (not at the beginning of function)
31 //   * SaveStates are manipulated by user explicitly
32 //   * SaveStates are "INVALID" operations in validation schema
33 
34 namespace libabckit::test {
35 
36 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
37 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
38 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
39 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
40 static auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
41 
42 struct UserData {
43     AbckitString *str1 = nullptr;
44     AbckitString *str2 = nullptr;
45     AbckitCoreFunction *consoleLogStr = nullptr;
46     AbckitCoreFunction *consoleLogNum = nullptr;
47     AbckitCoreFunction *dateGetTime = nullptr;
48     AbckitInst *startTime = nullptr;
49 };
50 
TransformIr(AbckitGraph * graph,UserData * userData)51 static void TransformIr(AbckitGraph *graph, UserData *userData)
52 {
53     AbckitInst *callOp = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC);
54 
55     // console.log("file: FileName; function: FunctionName")
56     AbckitInst *loadString = g_statG->iCreateLoadString(graph, userData->str1);
57     g_implG->iInsertBefore(loadString, callOp);
58     AbckitInst *log1 = g_statG->iCreateCallStatic(graph, userData->consoleLogStr, 1, loadString);
59     g_implG->iInsertAfter(log1, loadString);
60 
61     // const start = Date().getTime()
62     userData->startTime = g_statG->iCreateCallStatic(graph, userData->dateGetTime, 0);
63     g_implG->iInsertAfter(userData->startTime, log1);
64 
65     g_implG->gVisitBlocksRpo(graph, userData, [](AbckitBasicBlock *bb, void *data) {
66         auto *inst = g_implG->bbGetFirstInst(bb);
67         auto *userData = reinterpret_cast<UserData *>(data);
68         auto *graph = g_implG->bbGetGraph(bb);
69         while (inst != nullptr) {
70             if (g_statG->iGetOpcode(inst) == ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID) {
71                 // const end = Date().getTime()
72                 AbckitInst *endTime = g_statG->iCreateCallStatic(graph, userData->dateGetTime, 0);
73                 g_implG->iInsertBefore(endTime, inst);
74 
75                 // console.log("Elapsed time:")
76                 auto *loadString = g_statG->iCreateLoadString(graph, userData->str2);
77                 g_implG->iInsertAfter(loadString, endTime);
78                 AbckitInst *log = g_statG->iCreateCallStatic(graph, userData->consoleLogStr, 1, loadString);
79                 g_implG->iInsertAfter(log, loadString);
80 
81                 // console.log(end - start)
82                 AbckitInst *sub = g_statG->iCreateSub(graph, endTime, userData->startTime);
83                 g_implG->iInsertAfter(sub, log);
84                 AbckitInst *log2 = g_statG->iCreateCallStatic(graph, userData->consoleLogNum, 1, sub);
85                 g_implG->iInsertAfter(log2, sub);
86             }
87             inst = g_implG->iGetNext(inst);
88         }
89         return true;
90     });
91 }
92 
93 class AbckitScenarioTest : public ::testing::Test {};
94 
95 // Test: test-kind=scenario, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(AbckitScenarioTest,LibAbcKitTestStaticAddLog)96 TEST_F(AbckitScenarioTest, LibAbcKitTestStaticAddLog)
97 {
98     auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "scenarios/add_log/add_log_static.abc",
99                                             "add_log_static/ETSGLOBAL", "main");
100     EXPECT_TRUE(helpers::Match(output, "buisiness logic...\n"));
101 
102     helpers::TransformMethod(
103         ABCKIT_ABC_DIR "scenarios/add_log/add_log_static.abc",
104         ABCKIT_ABC_DIR "scenarios/add_log/add_log_static_modified.abc", "handle",
105         []([[maybe_unused]] AbckitFile *file, [[maybe_unused]] AbckitCoreFunction *method,
106            [[maybe_unused]] AbckitGraph *graph) {
107             UserData userData;
108             userData.consoleLogStr = helpers::FindMethodByName(file, "ConsoleLogStr");
109             userData.consoleLogNum = helpers::FindMethodByName(file, "ConsoleLogNum");
110             userData.dateGetTime = helpers::FindMethodByName(file, "DateGetTime");
111             auto mname = g_implI->functionGetName(method);
112             auto methodName = helpers::GetCropFuncName(helpers::AbckitStringToString(mname).data());
113             std::string startMsg = "file: NOTE; function: " + methodName;
114             userData.str1 = g_implM->createString(file, startMsg.c_str(), startMsg.size());
115             userData.str2 = g_implM->createString(file, "Elapsed time:", strlen("Elapsed time:"));
116 
117             TransformIr(graph, &userData);
118         },
119         [](AbckitGraph *graph) {
120             // NOLINTBEGIN(readability-magic-numbers)
121             std::vector<helpers::BBSchema<AbckitIsaApiStaticOpcode>> bbSchemas(
122                 {{{}, {1}, {{0, ABCKIT_ISA_API_STATIC_OPCODE_PARAMETER, {}}}},
123                  {{0},
124                   {2},
125                   {
126                       {3, ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING, {}},
127                       {5, ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING, {}},
128                       {8, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {5}},
129                       {11, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {}},
130                       {14, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {3}},
131                       {17, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {}},
132                       {19, ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING, {}},
133                       {22, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {19}},
134                       {23, ABCKIT_ISA_API_STATIC_OPCODE_SUB, {17, 11}},
135                       {26, ABCKIT_ISA_API_STATIC_OPCODE_CALL_STATIC, {23}},
136                       {27, ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID, {}},
137                   }},
138                  {{1}, {}, {}}});
139             // NOLINTEND(readability-magic-numbers)
140             helpers::VerifyGraph(graph, bbSchemas);
141         });
142 
143     output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "scenarios/add_log/add_log_static_modified.abc",
144                                        "add_log_static/ETSGLOBAL", "main");
145     EXPECT_TRUE(helpers::Match(output,
146                                "file: NOTE; function: handle\n"
147                                "buisiness logic...\n"
148                                "Elapsed time:\n"
149                                "\\d+\n"));
150 }
151 
152 }  // namespace libabckit::test
153