• 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 #ifndef ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_HEAPDUMP_LOOP_TEST_H
17 #define ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_HEAPDUMP_LOOP_TEST_H
18 
19 #include "tooling/test/client_utils/test_util.h"
20 
21 namespace panda::ecmascript::tooling::test {
22 class JsHeapdumpLoopTest : public TestActions {
23 public:
JsHeapdumpLoopTest()24     JsHeapdumpLoopTest()
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 
36             // break on start
37             {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
38 
39             {SocketAction::SEND, "heapprofiler-enable"},
40             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
41 
42             // set breakpoint
43             {SocketAction::SEND, "b " DEBUGGER_JS_DIR "common_func.js 64"},
44             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
45             {SocketAction::SEND, "b " DEBUGGER_JS_DIR "common_func.js 65"},
46             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
47 
48             // hit breakpoint after resume
49             {SocketAction::SEND, "resume"},
50             {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
51             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
52             {SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
53 
54             // hit breakpoint after resume
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::STRING_CONTAIN},
59 
60             {SocketAction::SEND, "heapdump"},
61             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
62                 [this](auto recv, auto, auto) -> bool { return RecvReportProgress(recv); }},
63             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
64                 [this](auto recv, auto, bool &needMoreMsg) -> bool {
65                     return RecvReportProgressFinished(recv, needMoreMsg);
66                 }},
67             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE,
68                 [this](auto recv, auto, bool &needMoreMsg) -> bool {
69                     return RecvReportProgressChunk(recv, needMoreMsg);
70                 }},
71             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
72 
73             {SocketAction::SEND, "heapprofiler-disable"},
74             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
75 
76             // hit breakpoint after resume
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             // reply success and run
83             {SocketAction::SEND, "success"},
84             {SocketAction::SEND, "resume"},
85             {SocketAction::RECV, "Debugger.resumed", ActionRule::STRING_CONTAIN},
86             {SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
87         };
88     }
89 
RecvReportProgress(std::string recv)90     bool RecvReportProgress(std::string recv)
91     {
92         std::unique_ptr<PtJson> json = PtJson::Parse(recv);
93         Result ret;
94         std::string method = "";
95         ret = json->GetString("method", &method);
96         if (ret != Result::SUCCESS) {
97             return false;
98         }
99 
100         if (method != "HeapProfiler.reportHeapSnapshotProgress") {
101             return false;
102         }
103 
104         std::unique_ptr<PtJson> params = nullptr;
105         ret = json->GetObject("params", &params);
106         if (ret != Result::SUCCESS) {
107             return false;
108         }
109 
110         int done = 0;
111         ret = params->GetInt("done", &done);
112         if (ret != Result::SUCCESS) {
113             return false;
114         }
115 
116         if (done != 0) {
117             return false;
118         }
119         return true;
120     }
121 
RecvReportProgressFinished(std::string recv,bool & needMoreMsg)122     bool RecvReportProgressFinished(std::string recv, bool &needMoreMsg)
123     {
124         needMoreMsg = false;
125         std::unique_ptr<PtJson> json = PtJson::Parse(recv);
126         Result ret;
127         std::string method = "";
128         ret = json->GetString("method", &method);
129         if (ret != Result::SUCCESS) {
130             return false;
131         }
132 
133         if (method != "HeapProfiler.reportHeapSnapshotProgress") {
134             return false;
135         }
136 
137         std::unique_ptr<PtJson> params = nullptr;
138         ret = json->GetObject("params", &params);
139         if (ret != Result::SUCCESS) {
140             return false;
141         }
142 
143         int done = 0;
144         ret = params->GetInt("done", &done);
145         if (ret != Result::SUCCESS) {
146             return false;
147         }
148 
149         bool finished = 0;
150         ret = params->GetBool("finished", &finished);
151         if (ret != Result::SUCCESS) {
152             needMoreMsg = true;
153         }
154         return true;
155     }
156 
RecvReportProgressChunk(std::string recv,bool & needMoreMsg)157     bool RecvReportProgressChunk(std::string recv, bool &needMoreMsg)
158     {
159         static std::string content = "";
160         needMoreMsg = false;
161         std::unique_ptr<PtJson> json = PtJson::Parse(recv);
162         Result ret;
163         std::string method = "";
164         ret = json->GetString("method", &method);
165         if (ret != Result::SUCCESS) {
166             return false;
167         }
168 
169         if (method != "HeapProfiler.addHeapSnapshotChunk") {
170             return false;
171         }
172 
173         std::unique_ptr<PtJson> params = nullptr;
174         ret = json->GetObject("params", &params);
175         if (ret != Result::SUCCESS) {
176             return false;
177         }
178 
179         std::string chunk = "";
180         ret = params->GetString("chunk", &chunk);
181         if (ret != Result::SUCCESS) {
182             return false;
183         }
184 
185         content += chunk;
186         std::unique_ptr<PtJson> contentJson = PtJson::Parse(content);
187         if (contentJson == nullptr || contentJson->Stringify().empty()) {
188             needMoreMsg = true;
189         }
190         return true;
191     }
192 
GetEntryPoint()193     std::pair<std::string, std::string> GetEntryPoint() override
194     {
195         return {pandaFile_, entryPoint_};
196     }
197     ~JsHeapdumpLoopTest() = default;
198 
199 private:
200     std::string pandaFile_ = DEBUGGER_ABC_DIR "common_func.abc";
201     std::string sourceFile_ = DEBUGGER_JS_DIR "common_func.js";
202     std::string entryPoint_ = "_GLOBAL::func_main_0";
203 };
204 
GetJsHeapdumpLoopTest()205 std::unique_ptr<TestActions> GetJsHeapdumpLoopTest()
206 {
207     return std::make_unique<JsHeapdumpLoopTest>();
208 }
209 }  // namespace panda::ecmascript::tooling::test
210 
211 #endif // ECMASCRIPT_TOOLING_TEST_TESTCASES_JS_HEAPDUMP_LOOP_TEST_H
212