1 /* 2 * Copyright (c) 2021 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_TEST_HOOKS_H 17 #define ECMASCRIPT_TOOLING_TEST_UTILS_TEST_HOOKS_H 18 19 #include "ecmascript/tooling/agent/debugger_impl.h" 20 #include "ecmascript/tooling/backend/js_pt_hooks.h" 21 #include "ecmascript/tooling/test/utils/test_util.h" 22 23 namespace panda::ecmascript::tooling::test { 24 class TestHooks : public PtHooks { 25 public: TestHooks(const std::string & testName,const EcmaVM * vm)26 TestHooks(const std::string &testName, const EcmaVM *vm) : vm_(vm) 27 { 28 runtime_ = std::make_unique<RuntimeImpl>(vm, nullptr); 29 debugger_ = std::make_unique<DebuggerImpl>(vm, nullptr, runtime_.get()); 30 testName_ = testName; 31 test_ = TestUtil::GetTest(testName); 32 test_->vm_ = vm; 33 test_->debugger_ = debugger_.get(); 34 test_->debugInterface_ = debugger_->jsDebugger_; 35 debugInterface_ = debugger_->jsDebugger_; 36 TestUtil::Reset(); 37 debugInterface_->RegisterHooks(this); 38 } 39 Run()40 void Run() 41 { 42 if (test_->scenario) { 43 test_->scenario(); 44 } 45 } 46 Breakpoint(const JSPtLocation & location)47 void Breakpoint(const JSPtLocation &location) override 48 { 49 if (test_->breakpoint) { 50 test_->breakpoint(location); 51 } 52 } 53 LoadModule(std::string_view panda_file_name)54 void LoadModule(std::string_view panda_file_name) override 55 { 56 if (test_->loadModule) { 57 test_->loadModule(panda_file_name); 58 } 59 } 60 Exception(const JSPtLocation & location)61 void Exception(const JSPtLocation &location) override 62 { 63 if (test_->exception) { 64 Local<JSValueRef> exception = DebuggerApi::GetAndClearException(vm_); 65 66 test_->exception(location); 67 68 if (!exception->IsHole()) { 69 DebuggerApi::SetException(vm_, exception); 70 } 71 } 72 } 73 SingleStep(const JSPtLocation & location)74 bool SingleStep(const JSPtLocation &location) override 75 { 76 if (test_->singleStep) { 77 return test_->singleStep(location); 78 } 79 return false; 80 } 81 VmDeath()82 void VmDeath() override 83 { 84 if (test_->vmDeath) { 85 test_->vmDeath(); 86 } 87 TestUtil::Event(DebugEvent::VM_DEATH); 88 } 89 VmStart()90 void VmStart() override 91 { 92 if (test_->vmStart) { 93 test_->vmStart(); 94 } 95 TestUtil::Event(DebugEvent::VM_START); 96 } 97 PendingJobEntry()98 void PendingJobEntry() override {} 99 TerminateTest()100 void TerminateTest() 101 { 102 debugInterface_->UnregisterHooks(); 103 if (TestUtil::IsTestFinished()) { 104 return; 105 } 106 LOG(FATAL, DEBUGGER) << "Test " << testName_ << " failed"; 107 } 108 109 ~TestHooks() = default; 110 111 private: 112 const EcmaVM *vm_ {nullptr}; 113 std::unique_ptr<RuntimeImpl> runtime_ {nullptr}; 114 std::unique_ptr<DebuggerImpl> debugger_ {nullptr}; 115 JSDebugger *debugInterface_; 116 std::string testName_; 117 TestEvents *test_; 118 }; 119 } // namespace panda::ecmascript::tooling::test 120 121 #endif // ECMASCRIPT_TOOLING_TEST_UTILS_TEST_HOOKS_H 122