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