diff --git a/inspector/inspector.cpp b/inspector/inspector.cpp index 0988b350f99e659e0f5bc006508ef031cd5aabf5..979436f0137dda7100b9828c5f093ebe80f2296a 100644 --- a/inspector/inspector.cpp +++ b/inspector/inspector.cpp @@ -50,6 +50,9 @@ using OnMessage = void(*)(void*, std::string&&); using ProcessMessage = void(*)(void*); using GetDispatchStatus = int32_t(*)(void*); using GetCallFrames = char*(*)(void*); +using SaveAllBreakpoints = char*(*)(void*, const char*); +using RemoveBreakpoint = char*(*)(void*, const char*); +using SetBreakpoint = char*(*)(void*, const char*); OnMessage g_onMessage = nullptr; InitializeDebugger g_initializeDebugger = nullptr; @@ -58,6 +61,9 @@ WaitForDebugger g_waitForDebugger = nullptr; ProcessMessage g_processMessage = nullptr; GetDispatchStatus g_getDispatchStatus = nullptr; GetCallFrames g_getCallFrames = nullptr; +SaveAllBreakpoints g_saveAllBreakpoints = nullptr; +RemoveBreakpoint g_removeBreakpoint = nullptr; +SetBreakpoint g_setBreakpoint = nullptr; std::atomic g_hasArkFuncsInited = false; std::unordered_map g_inspectors; @@ -222,6 +228,24 @@ bool InitializeArkFunctionsOthers() ResetServiceLocked(g_vm, true); return false; } + g_saveAllBreakpoints = reinterpret_cast( + GetArkDynFunction("SaveAllBreakpoints")); + if (g_saveAllBreakpoints == nullptr) { + ResetServiceLocked(g_vm, true); + return false; + } + g_removeBreakpoint = reinterpret_cast( + GetArkDynFunction("RemoveBreakpoint")); + if (g_removeBreakpoint == nullptr) { + ResetServiceLocked(g_vm, true); + return false; + } + g_setBreakpoint = reinterpret_cast( + GetArkDynFunction("SetBreakpoint")); + if (g_setBreakpoint == nullptr) { + ResetServiceLocked(g_vm, true); + return false; + } return true; } #else @@ -235,6 +259,9 @@ bool InitializeArkFunctionsIOS() g_getDispatchStatus = reinterpret_cast(&tooling::GetDispatchStatus); g_processMessage = reinterpret_cast(&tooling::ProcessMessage); g_getCallFrames = reinterpret_cast(&tooling::GetCallFrames); + g_saveAllBreakpoints = reinterpret_cast(&tooling::SaveAllBreakpoints); + g_removeBreakpoint = reinterpret_cast(&tooling::RemoveBreakpoint); + g_setBreakpoint = reinterpret_cast(&tooling::SetBreakpoint); return true; } #endif @@ -479,4 +506,49 @@ const char* GetJsBacktrace() return ""; #endif } + +const char* SaveAllJsBreakpoints(const char* message) +{ + (void)message; // Mark the parameter as unused to avoid warnings. +#if defined(OHOS_PLATFORM) + void* vm = GetEcmaVM(Inspector::GetThreadOrTaskId()); + if (g_saveAllBreakpoints == nullptr) { + LOGE("SaveAllBreakpoints symbol resolve failed"); + return ""; + } + return g_saveAllBreakpoints(vm, message); +#else + return ""; +#endif +} + +const char* RemoveJsBreakpoint(const char* message) +{ + (void)message; // Mark the parameter as unused to avoid warnings. +#if defined(OHOS_PLATFORM) + void* vm = GetEcmaVM(Inspector::GetThreadOrTaskId()); + if (g_removeBreakpoint == nullptr) { + LOGE("RemoveBreakpoint symbol resolve failed"); + return ""; + } + return g_removeBreakpoint(vm, message); +#else + return ""; +#endif +} + +const char* SetJsBreakpoint(const char* message) +{ + (void)message; // Mark the parameter as unused to avoid warnings. +#if defined(OHOS_PLATFORM) + void* vm = GetEcmaVM(Inspector::GetThreadOrTaskId()); + if (g_setBreakpoint == nullptr) { + LOGE("SetBreakpoint symbol resolve failed"); + return ""; + } + return g_setBreakpoint(vm, message); +#else + return ""; +#endif +} } // namespace OHOS::ArkCompiler::Toolchain diff --git a/inspector/inspector.h b/inspector/inspector.h index 9b4db96888c92a6cf19c468d0d31209ce8abaf4f..5402b6a31d8715c974bcf1cfdb416e93b3e41a0a 100644 --- a/inspector/inspector.h +++ b/inspector/inspector.h @@ -50,6 +50,12 @@ void StoreDebuggerInfo(int tid, void* vm, const DebuggerPostTask& debuggerPostTa // The returned pointer must be released using free() after it is no longer needed. // Failure to release the memory will result in memory leaks. const char* GetJsBacktrace(); + +const char* SaveAllJsBreakpoints(const char* message); + +const char* RemoveJsBreakpoint(const char* message); + +const char* SetJsBreakpoint(const char* message); #if __cplusplus } #endif diff --git a/tooling/agent/debugger_impl.cpp b/tooling/agent/debugger_impl.cpp index a8a80762594c5622dffbc2fd9774a2674f3eadfa..83cb5f1df70d7e23d458960df46d90d25bde3b55 100755 --- a/tooling/agent/debugger_impl.cpp +++ b/tooling/agent/debugger_impl.cpp @@ -774,6 +774,18 @@ void DebuggerImpl::DispatcherImpl::RemoveBreakpointsByUrl(const DispatchRequest SendResponse(request, response); } +std::string DebuggerImpl::DispatcherImpl::RemoveBreakpointsByUrl( + const int32_t callId, std::unique_ptr params) +{ + if (params == nullptr) { + LOG_DEBUGGER(WARN) << "DebuggerImpl::DispatcherImpl::RemoveBreakpointsByUrl: params is nullptr"; + return ReturnsValueToString(callId, DispatchResponsetToJson(DispatchResponse::Fail("wrong params"))); + } + + DispatchResponse response = debugger_->RemoveBreakpointsByUrl(*params); + return ReturnsValueToString(callId, DispatchResponsetToJson(response)); +} + void DebuggerImpl::DispatcherImpl::Resume(const DispatchRequest &request) { std::unique_ptr params = ResumeParams::Create(request.GetParams()); @@ -833,6 +845,24 @@ void DebuggerImpl::DispatcherImpl::GetPossibleAndSetBreakpointByUrl(const Dispat SendResponse(request, response, result); } +std::string DebuggerImpl::DispatcherImpl::GetPossibleAndSetBreakpointByUrl( + const int32_t callId, std::unique_ptr params) +{ + if (params == nullptr) { + LOG_DEBUGGER(WARN) << "DebuggerImpl::DispatcherImpl::GetPossibleAndSetBreakpointByUrl: params is nullptr"; + return ReturnsValueToString(callId, DispatchResponsetToJson(DispatchResponse::Fail("wrong params"))); + } + std::vector> outLocation; + DispatchResponse response = debugger_->GetPossibleAndSetBreakpointByUrl(*params, outLocation); + if (outLocation.empty() || !response.IsOk()) { + LOG_DEBUGGER(WARN) << "outLocation is empty or response code is not ok"; + return ReturnsValueToString(callId, DispatchResponsetToJson(response)); + } + + GetPossibleAndSetBreakpointByUrlReturns result(std::move(outLocation)); + return ReturnsValueToString(callId, result.ToJson()); +} + void DebuggerImpl::DispatcherImpl::SaveAllPossibleBreakpoints(const DispatchRequest &request) { std::unique_ptr params = @@ -845,6 +875,17 @@ void DebuggerImpl::DispatcherImpl::SaveAllPossibleBreakpoints(const DispatchRequ SendResponse(request, response); } +std::string DebuggerImpl::DispatcherImpl::SaveAllPossibleBreakpoints( + const int32_t callId, std::unique_ptr params) +{ + if (params == nullptr) { + LOG_DEBUGGER(WARN) << "DebuggerImpl::DispatcherImpl::SaveAllPossibleBreakpoints: params is nullptr"; + return ReturnsValueToString(callId, DispatchResponsetToJson(DispatchResponse::Fail("wrong params"))); + } + DispatchResponse response = debugger_->SaveAllPossibleBreakpoints(*params); + return ReturnsValueToString(callId, DispatchResponsetToJson(response)); +} + void DebuggerImpl::DispatcherImpl::SetSymbolicBreakpoints(const DispatchRequest &request) { std::unique_ptr params = diff --git a/tooling/agent/debugger_impl.h b/tooling/agent/debugger_impl.h index 9ee191c589e4e95c31d0b123fbe9ad0bb810da34..c67c9fd53bcc69f80f1a26edb9514dcae1ac939a 100644 --- a/tooling/agent/debugger_impl.h +++ b/tooling/agent/debugger_impl.h @@ -187,6 +187,12 @@ public: void SaveAllPossibleBreakpoints(const DispatchRequest &request); void SetSymbolicBreakpoints(const DispatchRequest &request); void RemoveSymbolicBreakpoints(const DispatchRequest &request); + std::string SaveAllPossibleBreakpoints(const int32_t callId, + std::unique_ptr params); + std::string RemoveBreakpointsByUrl(const int32_t callId, + std::unique_ptr params); + std::string GetPossibleAndSetBreakpointByUrl(const int32_t callId, + std::unique_ptr params); enum class Method { CONTINUE_TO_LOCATION, diff --git a/tooling/debugger_service.cpp b/tooling/debugger_service.cpp index 86afa0a48d5e9c5155f7a2a3d30e26b16b5d7faa..01ae1535f3bb13b0bbee3a494b3e367a79e06754 100644 --- a/tooling/debugger_service.cpp +++ b/tooling/debugger_service.cpp @@ -115,4 +115,61 @@ const char* GetCallFrames(const ::panda::ecmascript::EcmaVM *vm) } return ""; } + +const char* SaveAllBreakpoints(const ::panda::ecmascript::EcmaVM *vm, const char* message) +{ + if (vm == nullptr || vm->GetJsDebuggerManager() == nullptr) { + LOG_DEBUGGER(ERROR) << "VM has already been destroyed"; + return ""; + } + ProtocolHandler *handler = vm->GetJsDebuggerManager()->GetDebuggerHandler(); + if (LIKELY(handler != nullptr)) { + auto dispatcher = handler->GetDispatcher(); + if (LIKELY(dispatcher != nullptr)) { + auto info = dispatcher->SaveAllBreakpoints(message); + const char* buffer = strdup(info.c_str()); + return buffer; + } + return ""; + } + return ""; +} + +const char* RemoveBreakpoint(const ::panda::ecmascript::EcmaVM *vm, const char* message) +{ + if (vm == nullptr || vm->GetJsDebuggerManager() == nullptr) { + LOG_DEBUGGER(ERROR) << "VM has already been destroyed"; + return ""; + } + ProtocolHandler *handler = vm->GetJsDebuggerManager()->GetDebuggerHandler(); + if (LIKELY(handler != nullptr)) { + auto dispatcher = handler->GetDispatcher(); + if (LIKELY(dispatcher != nullptr)) { + auto info = dispatcher->RemoveBreakpoint(message); + const char* buffer = strdup(info.c_str()); + return buffer; + } + return ""; + } + return ""; +} + +const char* SetBreakpoint(const ::panda::ecmascript::EcmaVM *vm, const char* message) +{ + if (vm == nullptr || vm->GetJsDebuggerManager() == nullptr) { + LOG_DEBUGGER(ERROR) << "VM has already been destroyed"; + return ""; + } + ProtocolHandler *handler = vm->GetJsDebuggerManager()->GetDebuggerHandler(); + if (LIKELY(handler != nullptr)) { + auto dispatcher = handler->GetDispatcher(); + if (LIKELY(dispatcher != nullptr)) { + auto info = dispatcher->SetBreakpoint(message); + const char* buffer = strdup(info.c_str()); + return buffer; + } + return ""; + } + return ""; +} } // namespace panda::ecmascript::tooling \ No newline at end of file diff --git a/tooling/debugger_service.h b/tooling/debugger_service.h index 95bd86d9bb27eca00dafaac1b4f8d407b13071c6..7834a40add5e8e5b41658824e1e383dd1c5ca963 100644 --- a/tooling/debugger_service.h +++ b/tooling/debugger_service.h @@ -47,6 +47,12 @@ TOOLCHAIN_EXPORT int32_t GetDispatchStatus(const ::panda::ecmascript::EcmaVM *vm TOOLCHAIN_EXPORT const char* GetCallFrames(const ::panda::ecmascript::EcmaVM *vm); +TOOLCHAIN_EXPORT const char* SaveAllBreakpoints(const ::panda::ecmascript::EcmaVM *vm, const char* message); + +TOOLCHAIN_EXPORT const char* RemoveBreakpoint(const ::panda::ecmascript::EcmaVM *vm, const char* message); + +TOOLCHAIN_EXPORT const char* SetBreakpoint(const ::panda::ecmascript::EcmaVM *vm, const char* message); + #ifdef __cplusplus #if __cplusplus } diff --git a/tooling/dispatcher.cpp b/tooling/dispatcher.cpp index afbdbc0783b6b5fc295fbea7a959c103bf49861f..791d6b0e14c2304f49555ea872e3275bb18b1fc9 100644 --- a/tooling/dispatcher.cpp +++ b/tooling/dispatcher.cpp @@ -130,6 +130,32 @@ void DispatcherBase::SendResponse(const DispatchRequest &request, const Dispatch } } +std::string DispatcherBase::ReturnsValueToString(const int32_t callId, const std::unique_ptr resultObj) +{ + std::unique_ptr ptJson = PtJson::CreateObject(); + ptJson->Add("id", callId); + ptJson->Add("result", resultObj); + std::string str = ptJson->Stringify(); + if (str.empty()) { + LOG_DEBUGGER(ERROR) << "Dispatcher::ReturnsValueToString: json stringify error"; + return ""; + } + ptJson->ReleaseRoot(); + return str; +} + +std::unique_ptr DispatcherBase::DispatchResponsetToJson(const DispatchResponse &response) const +{ + std::unique_ptr result = PtJson::CreateObject(); + + if (!response.IsOk()) { + result->Add("code", static_cast(response.GetError())); + result->Add("message", response.GetMessage().c_str()); + } + + return result; +} + Dispatcher::Dispatcher(const EcmaVM *vm, ProtocolChannel *channel) { // profiler @@ -214,4 +240,67 @@ std::string Dispatcher::GetJsFrames() const } return ""; } + +std::string Dispatcher::SaveAllBreakpoints(const char* message) const +{ + DispatchRequest request(message); + if (request.GetMethod() == "saveAllPossibleBreakpoints") { + auto dispatcher = dispatchers_.find("Debugger"); + if (dispatcher != dispatchers_.end()) { + return SaveAllBreakpoints(request, dispatcher->second.get()); + } + return ""; + } + return ""; +} + +std::string Dispatcher::SaveAllBreakpoints(const DispatchRequest &request, DispatcherBase *dispatcher) const +{ + auto debuggerImpl = reinterpret_cast(dispatcher); + std::unique_ptr params = + SaveAllPossibleBreakpointsParams::Create(request.GetParams()); + return debuggerImpl->SaveAllPossibleBreakpoints(request.GetCallId(), std::move(params)); +} + +std::string Dispatcher::RemoveBreakpoint(const char* message) const +{ + DispatchRequest request(message); + if (request.GetMethod() == "removeBreakpointsByUrl") { + auto dispatcher = dispatchers_.find("Debugger"); + if (dispatcher != dispatchers_.end()) { + return RemoveBreakpoint(request, dispatcher->second.get()); + } + return ""; + } + return ""; +} + +std::string Dispatcher::RemoveBreakpoint(const DispatchRequest &request, DispatcherBase *dispatcher) const +{ + auto debuggerImpl = reinterpret_cast(dispatcher); + std::unique_ptr params = + RemoveBreakpointsByUrlParams::Create(request.GetParams()); + return debuggerImpl->RemoveBreakpointsByUrl(request.GetCallId(), std::move(params)); +} + +std::string Dispatcher::SetBreakpoint(const char* message) const +{ + DispatchRequest request(message); + if (request.GetMethod() == "getPossibleAndSetBreakpointByUrl") { + auto dispatcher = dispatchers_.find("Debugger"); + if (dispatcher != dispatchers_.end()) { + return SetBreakpoint(request, dispatcher->second.get()); + } + return ""; + } + return ""; +} + +std::string Dispatcher::SetBreakpoint(const DispatchRequest &request, DispatcherBase *dispatcher) const +{ + auto debuggerImpl = reinterpret_cast(dispatcher); + std::unique_ptr params = + GetPossibleAndSetBreakpointParams::Create(request.GetParams()); + return debuggerImpl->GetPossibleAndSetBreakpointByUrl(request.GetCallId(), std::move(params)); +} } // namespace panda::ecmascript::tooling diff --git a/tooling/dispatcher.h b/tooling/dispatcher.h index 7066f86e16b998467fd05492d6b18cb3182716a6..8bbad751847c3bf4067cecf419b8e6cd1a6570f0 100644 --- a/tooling/dispatcher.h +++ b/tooling/dispatcher.h @@ -136,6 +136,8 @@ public: protected: void SendResponse(const DispatchRequest &request, const DispatchResponse &response, const PtBaseReturns &result = PtBaseReturns()); + std::string ReturnsValueToString(const int32_t callId, const std::unique_ptr resultObj); + std::unique_ptr DispatchResponsetToJson(const DispatchResponse &response) const; private: ProtocolChannel *channel_ {nullptr}; @@ -150,8 +152,14 @@ public: ~Dispatcher() = default; void Dispatch(const DispatchRequest &request); std::string GetJsFrames() const; + std::string SaveAllBreakpoints(const char* message) const; + std::string RemoveBreakpoint(const char* message) const; + std::string SetBreakpoint(const char* message) const; private: + std::string SaveAllBreakpoints(const DispatchRequest &request, DispatcherBase *dispatcher) const; + std::string RemoveBreakpoint(const DispatchRequest &request, DispatcherBase *dispatcher) const; + std::string SetBreakpoint(const DispatchRequest &request, DispatcherBase *dispatcher) const; std::unordered_map> dispatchers_ {}; NO_COPY_SEMANTIC(Dispatcher); diff --git a/tooling/test/debugger_impl_test.cpp b/tooling/test/debugger_impl_test.cpp index 7e5987636d05980c8d931cb906616ef542bc7169..e14c509c9902b95f0c88f918fca7051f8097d6af 100644 --- a/tooling/test/debugger_impl_test.cpp +++ b/tooling/test/debugger_impl_test.cpp @@ -648,6 +648,61 @@ HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_RemoveBreakpointsByUrl__002) } } +HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_RemoveBreakpointsByUrl__003) +{ + ProtocolChannel *protocolChannel = new ProtocolHandler(nullptr, ecmaVm); + auto runtimeImpl = std::make_unique(ecmaVm, protocolChannel); + auto debuggerImpl = std::make_unique(ecmaVm, protocolChannel, runtimeImpl.get()); + auto dispatcherImpl = std::make_unique(protocolChannel, std::move(debuggerImpl)); + int32_t callId = 0; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.removeBreakpointsByUrl", + "params": { + "url": "entry|entry|1.0.0|src/main/ets/pages/Index.ts" + } + })"; + std::unique_ptr params = + RemoveBreakpointsByUrlParams::Create(DispatchRequest(msg).GetParams()); + std::string result = dispatcherImpl->RemoveBreakpointsByUrl(callId, std::move(params)); + EXPECT_STREQ(result.c_str(), R"({"id":0,"result":{}})"); + if (protocolChannel) { + delete protocolChannel; + protocolChannel = nullptr; + } +} + +HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_SaveAllPossibleBreakpoints__001) +{ + ProtocolChannel *protocolChannel = new ProtocolHandler(nullptr, ecmaVm); + auto runtimeImpl = std::make_unique(ecmaVm, protocolChannel); + auto debuggerImpl = std::make_unique(ecmaVm, protocolChannel, runtimeImpl.get()); + auto dispatcherImpl = std::make_unique(protocolChannel, std::move(debuggerImpl)); + int32_t callId = 0; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.saveAllPossibleBreakpoints", + "params": { + "locations": { + "entry|entry|1.0.0|src/main/ets/pages/Index.ts": [{ + "lineNumber": 59, + "columnNumber": 16 + }] + } + } + })"; + std::unique_ptr params = + SaveAllPossibleBreakpointsParams::Create(DispatchRequest(msg).GetParams()); + std::string result = dispatcherImpl->SaveAllPossibleBreakpoints(callId, std::move(params)); + EXPECT_STREQ(result.c_str(), R"({"id":0,"result":{}})"); + if (protocolChannel) { + delete protocolChannel; + protocolChannel = nullptr; + } +} + HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_SetSymbolBreakpoints_001) { std::string outStrForCallbackCheck = ""; @@ -1333,6 +1388,46 @@ HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_GetPossibleAndSetBreakpoint__0 } } +HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_GetPossibleAndSetBreakpointByUrl__001) +{ + ProtocolChannel *protocolChannel = new ProtocolHandler(nullptr, ecmaVm); + auto runtimeImpl = std::make_unique(ecmaVm, protocolChannel); + auto debuggerImpl = std::make_unique(ecmaVm, protocolChannel, runtimeImpl.get()); + auto dispatcherImpl = std::make_unique(protocolChannel, std::move(debuggerImpl)); + int32_t callId = 0; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.getPossibleAndSetBreakpointByUrl", + "params": { + "locations": [{ + "url": "entry|entry|1.0.0|src/main/ets/pages/Index.ts", + "lineNumber": 59, + "columnNumber": 16 + }] + } + })"; + std::unique_ptr params = + GetPossibleAndSetBreakpointParams::Create(DispatchRequest(msg).GetParams()); + std::string result = dispatcherImpl->GetPossibleAndSetBreakpointByUrl(callId, std::move(params)); + EXPECT_STREQ(result.c_str(), + R"({ + "id": 0, + "result": { + "locations": [{ + "lineNumber": 59, + "columnNumber": 0, + "id": "id:59:0:entry|entry|1.0.0|src/main/ets/pages/Index.ts", + "scriptId": 1 + }] + } + })"); + if (protocolChannel) { + delete protocolChannel; + protocolChannel = nullptr; + } +} + HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_DropFrame__001) { std::string outStrForCallbackCheck = ""; diff --git a/tooling/test/debugger_service_test.cpp b/tooling/test/debugger_service_test.cpp index 68b8796fbb9073291f62c68f24a46d541a5f3429..d28bca1e6254e9efd6f466c90723d51bb3d1ef25 100644 --- a/tooling/test/debugger_service_test.cpp +++ b/tooling/test/debugger_service_test.cpp @@ -135,4 +135,54 @@ HWTEST_F_L0(DebuggerServiceTest, GetDispatchStatusTest) int32_t GetDispatchStatusTest = GetDispatchStatus(vm); ASSERT_TRUE(GetDispatchStatusTest == 0); } + +HWTEST_F_L0(DebuggerServiceTest, SaveAllBreakpointsTest) +{ + const char *message = "{\"id\":0,\"method\":\"Debugger.saveAllPossibleBreakpoints\"," + "\"params\":{\"locations\":{\"entry|entry|1.0.0|src/main/ets/pages/Index.ts\":" + "[{\"lineNumber\":59,\"columnNumber\":16}]}}}"; + const char *str0 = SaveAllBreakpoints(nullptr, message); + ASSERT_TRUE(str0 != nullptr && *str0 == '\0'); + + const char *str1 = SaveAllBreakpoints(ecmaVm, message); + ASSERT_TRUE(str1 != nullptr && *str1 == '\0'); + + InitializeDebugger(ecmaVm, nullptr); + const char *str2 = SaveAllBreakpoints(ecmaVm, message); + ASSERT_TRUE(str2 != nullptr && *str2 != '\0'); + UninitializeDebugger(ecmaVm); +} + +HWTEST_F_L0(DebuggerServiceTest, RemoveBreakpointTest) +{ + const char *message = "{\"id\":0,\"method\":\"Debugger.removeBreakpointsByUrl\"," + "\"params\":{\"url\":\"entry|entry|1.0.0|src/main/ets/pages/Index.ts\"}}"; + const char *str0 = RemoveBreakpoint(nullptr, message); + ASSERT_TRUE(str0 != nullptr && *str0 == '\0'); + + const char *str1 = RemoveBreakpoint(ecmaVm, message); + ASSERT_TRUE(str1 != nullptr && *str1 == '\0'); + + InitializeDebugger(ecmaVm, nullptr); + const char *str2 = RemoveBreakpoint(ecmaVm, message); + ASSERT_TRUE(str2 != nullptr && *str2 != '\0'); + UninitializeDebugger(ecmaVm); +} + +HWTEST_F_L0(DebuggerServiceTest, SetBreakpointTest) +{ + const char *message = "{\"id\":0,\"method\":\"Debugger.getPossibleAndSetBreakpointByUrl\"," + "\"params\":{\"locations\":[{\"url\":\"entry|entry|1.0.0|src/main/ets/pages/Index.ts\"," + "\"lineNumber\":59,\"columnNumber\":16}]}}"; + const char *str0 = SetBreakpoint(nullptr, message); + ASSERT_TRUE(str0 != nullptr && *str0 == '\0'); + + const char *str1 = SetBreakpoint(ecmaVm, message); + ASSERT_TRUE(str1 != nullptr && *str1 == '\0'); + + InitializeDebugger(ecmaVm, nullptr); + const char *str2 = SetBreakpoint(ecmaVm, message); + ASSERT_TRUE(str2 != nullptr && *str2 != '\0'); + UninitializeDebugger(ecmaVm); +} } // namespace panda::test \ No newline at end of file diff --git a/tooling/test/dispatcher_test.cpp b/tooling/test/dispatcher_test.cpp index 9624b450dd39b68b2cb421cd1c4a7511ae1bb964..6b962c6ae664eeafeb33ce7dbdc51b6b987c0794 100644 --- a/tooling/test/dispatcher_test.cpp +++ b/tooling/test/dispatcher_test.cpp @@ -148,4 +148,90 @@ HWTEST_F_L0(DispatcherTest, DispatcherDispatchTest) dispatcher->Dispatch(dispatchRequest2); ASSERT_TRUE(result == ""); } + +HWTEST_F_L0(DispatcherTest, SaveAllBreakpointsTest) +{ + ProtocolChannel *channel = new ProtocolHandler(nullptr, ecmaVm); + auto dispatcher = std::make_unique(ecmaVm, channel); + + std::string result = ""; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.saveAllPossibleBreakpoints", + "params": { + "locations": { + "entry|entry|1.0.0|src/main/ets/pages/Index.ts": [{ + "lineNumber": 59, + "columnNumber": 16 + }] + } + } + })"; + result = dispatcher->SaveAllBreakpoints(msg.c_str()); + EXPECT_STREQ(result.c_str(), R"({"id":0,"result":{}})"); + if (channel) { + delete channel; + channel = nullptr; + } +} + +HWTEST_F_L0(DispatcherTest, RemoveBreakpointTest) +{ + ProtocolChannel *channel = new ProtocolHandler(nullptr, ecmaVm); + auto dispatcher = std::make_unique(ecmaVm, channel); + + std::string result = ""; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.removeBreakpointsByUrl", + "params": { + "url": "entry|entry|1.0.0|src/main/ets/pages/Index.ts" + } + })"; + result = dispatcher->RemoveBreakpoint(msg.c_str()); + EXPECT_STREQ(result.c_str(), R"({"id":0,"result":{}})"); + if (channel) { + delete channel; + channel = nullptr; + } +} + +HWTEST_F_L0(DispatcherTest, SetBreakpointTest) +{ + ProtocolChannel *channel = new ProtocolHandler(nullptr, ecmaVm); + auto dispatcher = std::make_unique(ecmaVm, channel); + + std::string result = ""; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.getPossibleAndSetBreakpointByUrl", + "params": { + "locations": [{ + "url": "entry|entry|1.0.0|src/main/ets/pages/Index.ts", + "lineNumber": 59, + "columnNumber": 16 + }] + } + })"; + result = dispatcher->SetBreakpoint(msg.c_str()); + EXPECT_STREQ(result.c_str(), + R"({ + "id": 0, + "result": { + "locations": [{ + "lineNumber": 59, + "columnNumber": 0, + "id": "id:59:0:entry|entry|1.0.0|src/main/ets/pages/Index.ts", + "scriptId": 1 + }] + } + })"); + if (channel) { + delete channel; + channel = nullptr; + } +} } // namespace panda::test \ No newline at end of file