• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #ifndef ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_SYMBOLICBREAKPOINT_LOOP_TEST_H
17 #define ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_SYMBOLICBREAKPOINT_LOOP_TEST_H
18 
19 #include "tooling/dynamic/test/client_utils/test_util.h"
20 
21 namespace panda::ecmascript::tooling::test {
22 class JsSymbolicBreakpointTest : public TestActions {
23 public:
JsSymbolicBreakpointTest()24     JsSymbolicBreakpointTest()
25     {
26         testAction = {
27             {SocketAction::SEND, "enable"},
28             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
29             {SocketAction::SEND, "runtime-enable"},
30             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
31             {SocketAction::SEND, "run"},
32             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
33             // load common_func.js
34             {SocketAction::RECV, "Debugger.scriptParsed", ActionRule::STRING_CONTAIN},
35             // break on start
36             {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
37             // set symbol breakpoints
38             {SocketAction::SEND, "setSymbolicBreakpoints " "common_func"},
39             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
40             {SocketAction::SEND, "setSymbolicBreakpoints " "for_loop"},
41             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
42 
43             // hit the common_func function
44             {SocketAction::SEND, "resume"},
45             {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
46             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
47             {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE,
48                 [this](auto recv, auto, auto) -> bool { return RecvBreakInfo(recv, "common_func", 16); }},
49 
50             // set symbol breakpoints
51             {SocketAction::SEND, "setSymbolicBreakpoints " "while_loop"},
52             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
53 
54             // hit the for_loop function
55             {SocketAction::SEND, "resume"},
56             {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
57             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
58             {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE,
59                 [this](auto recv, auto, auto) -> bool { return RecvBreakInfo(recv, "for_loop", 26); }},
60 
61             // set symbol breakpoints
62             {SocketAction::SEND, "setSymbolicBreakpoints " "while_loop"},
63             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
64 
65             // hit the while_loop function
66             {SocketAction::SEND, "resume"},
67             {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
68             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
69             {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE,
70                 [this](auto recv, auto, auto) -> bool { return RecvBreakInfo(recv, "while_loop", 34); }},
71 
72             // set symbol breakpoints
73             {SocketAction::SEND, "setSymbolicBreakpoints " "loop_switch"},
74             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
75 
76             // hit the loop_switch function
77             {SocketAction::SEND, "resume"},
78             {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
79             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
80             {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
81 
82             // set symbol breakpoints
83             {SocketAction::SEND, "setSymbolicBreakpoints " "factorial"},
84             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
85 
86             // firstly hit the factorial function
87             {SocketAction::SEND, "resume"},
88             {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
89             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
90             {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE,
91                 [this](auto recv, auto, auto) -> bool { return RecvBreakInfo(recv, "factorial", 57); }},
92 
93             // remove symbol breakpoints
94             {SocketAction::SEND, "removeSymbolicBreakpoints " "loop_switch"},
95             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
96 
97             // secondly hit the factorial function
98             {SocketAction::SEND, "resume"},
99             {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
100             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
101             {SocketAction::RECV, "Debugger.paused", ActionRule::CUSTOM_RULE,
102                 [this](auto recv, auto, auto) -> bool { return RecvBreakInfo(recv, "factorial", 57); }},
103 
104             // remove symbol breakpoints
105             {SocketAction::SEND, "removeSymbolicBreakpoints " "factorial"},
106             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
107 
108             // reply success and run
109             {SocketAction::SEND, "success"},
110             {SocketAction::SEND, "resume"},
111             {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
112             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
113         };
114     }
115 
RecvBreakInfo(std::string recv,std::string funcName,int lineNumber)116     bool RecvBreakInfo(std::string recv, std::string funcName, int lineNumber)
117     {
118         std::unique_ptr<PtJson> json = PtJson::Parse(recv);
119         Result ret;
120         std::string method = "";
121         ret = json->GetString("method", &method);
122         if (ret != Result::SUCCESS || method != "Debugger.paused") {
123             return false;
124         }
125 
126         std::unique_ptr<PtJson> params = nullptr;
127         ret = json->GetObject("params", &params);
128         if (ret != Result::SUCCESS) {
129             return false;
130         }
131 
132         std::unique_ptr<PtJson> callFrames = nullptr;
133         ret = params->GetArray("callFrames", &callFrames);
134         if (ret != Result::SUCCESS) {
135             return false;
136         }
137 
138         std::string functionName = "";
139         ret = callFrames->Get(0)->GetString("functionName", &functionName);
140         if (ret != Result::SUCCESS || functionName != funcName) {
141             return false;
142         }
143 
144         std::unique_ptr<PtJson> location = nullptr;
145         ret = callFrames->Get(0)->GetObject("location", &location);
146         if (ret != Result::SUCCESS) {
147             return false;
148         }
149 
150         int lineNum = 0;
151         ret = location->GetInt("lineNumber", &lineNum);
152         if (ret != Result::SUCCESS || lineNum != lineNumber) {
153             return false;
154         }
155 
156         DebuggerClient debuggerClient(0);
157         debuggerClient.PausedReply(std::move(json));
158         return true;
159     }
160 
GetEntryPoint()161     std::pair<std::string, std::string> GetEntryPoint() override
162     {
163         return {pandaFile_, entryPoint_};
164     }
165     ~JsSymbolicBreakpointTest() = default;
166 
167 private:
168     std::string pandaFile_ = DEBUGGER_ABC_DIR "common_func.abc";
169     std::string sourceFile_ = DEBUGGER_JS_DIR "common_func.js";
170     std::string entryPoint_ = "common_func";
171 };
172 
GetJsSymbolicBreakpointTest()173 std::unique_ptr<TestActions> GetJsSymbolicBreakpointTest()
174 {
175     return std::make_unique<JsSymbolicBreakpointTest>();
176 }
177 }  // namespace panda::ecmascript::tooling::test
178 
179 #endif // ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_SYMBOLICBREAKPOINT_LOOP_TEST_H