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 #ifndef ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_STEP_OVER_TEST_H
17 #define ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_STEP_OVER_TEST_H
18
19 #include "test/utils/test_util.h"
20
21 namespace panda::ecmascript::tooling::test {
22 class JsStepOverTest : public TestEvents {
23 public:
JsStepOverTest()24 JsStepOverTest()
25 {
26 vmDeath = [this]() {
27 ASSERT_EQ(breakpointCounter_, pointerLocations_.size()); // size: break point counter
28 ASSERT_EQ(stepCompleteCounter_, stepLocations_.size()); // size: step complete counter
29 return true;
30 };
31
32 loadModule = [this](std::string_view moduleName) {
33 runtime_->Enable();
34 // 24、27: line number for breakpoint array
35 size_t breakpoint[8][2] = {{24, 0}, {27, 0}, {36, 0}, {50, 0}, {60, 0}, {90, 0}, {96, 0}, {54, 0}};
36 // 25、28: line number for stepinto array
37 size_t stepOver[7][2] = {{25, 5}, {28, 0}, {37, 0}, {51, 0}, {61, 0}, {91, 5}, {97, 15}};
38 SetJSPtLocation(breakpoint[0], POINTER_SIZE, pointerLocations_);
39 SetJSPtLocation(stepOver[0], STEP_SIZE, stepLocations_);
40 TestUtil::SuspendUntilContinue(DebugEvent::LOAD_MODULE);
41 ASSERT_EQ(moduleName, pandaFile_);
42 debugger_->NotifyScriptParsed(0, moduleName.data());
43 auto condFuncRef = FunctionRef::Undefined(vm_);
44 for (auto &iter : pointerLocations_) {
45 auto ret = debugInterface_->SetBreakpoint(iter, condFuncRef);
46 ASSERT_TRUE(ret);
47 }
48 return true;
49 };
50
51 breakpoint = [this](const JSPtLocation &location) {
52 ASSERT_TRUE(location.GetMethodId().IsValid());
53 ASSERT_LOCATION_EQ(location, pointerLocations_.at(breakpointCounter_));
54 ++breakpointCounter_;
55 TestUtil::SuspendUntilContinue(DebugEvent::BREAKPOINT, location);
56 debugger_->SetDebuggerState(DebuggerState::PAUSED);
57 if (stepCompleteCounter_ < STEP_SIZE) {
58 debugger_->StepOver(StepOverParams());
59 } else {
60 debugger_->StepOut();
61 }
62 return true;
63 };
64
65 singleStep = [this](const JSPtLocation &location) {
66 if (debugger_->NotifySingleStep(location)) {
67 ASSERT_TRUE(location.GetMethodId().IsValid());
68 ASSERT_LOCATION_EQ(location, stepLocations_.at(stepCompleteCounter_));
69 stepCompleteCounter_++;
70 TestUtil::SuspendUntilContinue(DebugEvent::STEP_COMPLETE, location);
71 return true;
72 }
73 return false;
74 };
75
76 scenario = [this]() {
77 TestUtil::WaitForLoadModule();
78 TestUtil::Continue();
79 size_t index = 0;
80 while (index < pointerLocations_.size()) {
81 TestUtil::WaitForBreakpoint(pointerLocations_.at(index));
82 TestUtil::Continue();
83 if (index < STEP_SIZE) {
84 TestUtil::WaitForStepComplete(stepLocations_.at(index));
85 TestUtil::Continue();
86 }
87 ++index;
88 }
89 ASSERT_EXITED();
90 return true;
91 };
92 }
93
GetEntryPoint()94 std::pair<std::string, std::string> GetEntryPoint() override
95 {
96 return {pandaFile_, entryPoint_};
97 }
98
99 private:
100 static constexpr size_t LINE_COLUMN = 2;
101 static constexpr size_t POINTER_SIZE = 8;
102 static constexpr size_t STEP_SIZE = 7;
103
104 std::string pandaFile_ = DEBUGGER_ABC_DIR "step.abc";
105 std::string sourceFile_ = DEBUGGER_JS_DIR "step.js";
106 std::string entryPoint_ = "_GLOBAL::func_main_0";
107 JSPtLocation location1_ {nullptr, JSPtLocation::EntityId(0), 0};
108 JSPtLocation location2_ {nullptr, JSPtLocation::EntityId(0), 0};
109 size_t breakpointCounter_ = 0;
110 size_t stepCompleteCounter_ = 0;
111 std::vector<JSPtLocation> pointerLocations_;
112 std::vector<JSPtLocation> stepLocations_;
113
SetJSPtLocation(size_t * arr,size_t number,std::vector<JSPtLocation> & locations)114 void SetJSPtLocation(size_t *arr, size_t number, std::vector<JSPtLocation> &locations)
115 {
116 for (size_t i = 0; i < number; i++) {
117 JSPtLocation location_ = TestUtil::GetLocation(sourceFile_.c_str(), arr[i * LINE_COLUMN],
118 arr[i * LINE_COLUMN + 1], pandaFile_.c_str());
119 locations.push_back(location_);
120 }
121 };
122 };
123
GetJsStepOverTest()124 std::unique_ptr<TestEvents> GetJsStepOverTest()
125 {
126 return std::make_unique<JsStepOverTest>();
127 }
128 } // namespace panda::ecmascript::tooling::test
129
130 #endif // ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_STEP_OVER_TEST_H
131