From 3cf02a158ed71be7e37ecc3158a8bc20cda3cab2 Mon Sep 17 00:00:00 2001 From: panmingxuan Date: Fri, 6 Jun 2025 11:14:08 +0800 Subject: [PATCH] =?UTF-8?q?testcases/toolchain=E6=B5=8B=E8=AF=95=E7=94=A8?= =?UTF-8?q?=E4=BE=8B=E5=90=8C=E6=AD=A55?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sync testcases/toolchain from YZ to BZ Issue: https://gitee.com/openharmony/arkcompiler_toolchain/issues/ICAVG3 Signed-off-by: panmingxuan --- .../debug/TestWorkerEvaluateOnCallFrame.json | 15 + .../debug/TestWorkerEvaluateOnCallFrame.py | 443 ++++++++++++++++++ .../TestWorkerExceptionBreakpoints01.json | 16 + .../debug/TestWorkerExceptionBreakpoints01.py | 309 ++++++++++++ .../TestWorkerExceptionBreakpoints02.json | 15 + .../debug/TestWorkerExceptionBreakpoints02.py | 320 +++++++++++++ .../debug/TestWorkerGetProperties.json | 15 + .../debug/TestWorkerGetProperties.py | 329 +++++++++++++ .../debug/TestWorkerLaunchAccelerate.json | 15 + .../debug/TestWorkerLaunchAccelerate.py | 327 +++++++++++++ 10 files changed, 1804 insertions(+) create mode 100644 test/autotest/testcases/toolchain/debug/TestWorkerEvaluateOnCallFrame.json create mode 100644 test/autotest/testcases/toolchain/debug/TestWorkerEvaluateOnCallFrame.py create mode 100644 test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints01.json create mode 100644 test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints01.py create mode 100644 test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints02.json create mode 100644 test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints02.py create mode 100644 test/autotest/testcases/toolchain/debug/TestWorkerGetProperties.json create mode 100644 test/autotest/testcases/toolchain/debug/TestWorkerGetProperties.py create mode 100644 test/autotest/testcases/toolchain/debug/TestWorkerLaunchAccelerate.json create mode 100644 test/autotest/testcases/toolchain/debug/TestWorkerLaunchAccelerate.py diff --git a/test/autotest/testcases/toolchain/debug/TestWorkerEvaluateOnCallFrame.json b/test/autotest/testcases/toolchain/debug/TestWorkerEvaluateOnCallFrame.json new file mode 100644 index 00000000..b0b4e878 --- /dev/null +++ b/test/autotest/testcases/toolchain/debug/TestWorkerEvaluateOnCallFrame.json @@ -0,0 +1,15 @@ +{ + "description": "Config for TestWorkerEvaluateOnCallFrame", + "environment": [ + { + "type": "device", + "label": "phone" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "toolchain/debug/TestWorkerEvaluateOnCallFrame.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/testcases/toolchain/debug/TestWorkerEvaluateOnCallFrame.py b/test/autotest/testcases/toolchain/debug/TestWorkerEvaluateOnCallFrame.py new file mode 100644 index 00000000..c2204244 --- /dev/null +++ b/test/autotest/testcases/toolchain/debug/TestWorkerEvaluateOnCallFrame.py @@ -0,0 +1,443 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright (c) 2025 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +#================================================================== +#文 件 名: TestWorkerEvaluateOnCallFrame.py +#文件说明: 多实例 debug 调试 evaluateOnCallFrame +#================================================================== +测试步骤: + 1. 连接 connect server 和主线程 debugger server + 2. 主线程使能 Runtime 和 Debugger + 3. 主线程 Index.ts 文件设置断点(Debugger.getPossibleAndSetBreakpointByUrl) + 4. 主线程 resume,暂停在下一断点(Debugger.resume) + 5. 创建子线程,连接子线程 debugger server + 6. 子线程使能 Runtime 和 Debugger + 7. 子线程 Worker.ets 文件设置断点(Debugger.getPossibleAndSetBreakpointByUrl) + 8. 主线程 resume,发送消息给子线程,子线程暂停在断点(Debugger.resume) + 9. 子线程对 local/closure/module/global 作用域变量进行查看、修改等操作(Debugger.evaluateOnCallFrame) + 10. 触发点击事件,销毁子线程,对应的 debugger server 连接断开 + 11. 关闭主线程 debugger server 和 connect server 连接 +#================================================================== +关键代码: + Index.ets + let myWorker = new worker.ThreadWorker("entry/ets/workers/Worker.ets") + myWorker.postMessage("hello world") + .OnClick(() => { + myWorker.terminate() + }) + Worker.ets + const workerPort: ThreadWorkerGlobalScope = worker.workerPort; + let closureBoolean = false + ...... // 定义不同的闭包变量 + globalThis.globalBool = new Boolean(closureBoolean) + ...... // 定义不同的全局变量 + workerPort.onmessage = (e: MessageEvents) => { + let localNull = null + ...... // 定义不同的局部变量 + workerPort.postMessage(e.data) + } +#!!================================================================ +""" +import sys +from pathlib import Path + +root_path = Path(__file__).parent.parent.parent.parent +resource_path = root_path / 'resource' +sys.path.append(str(root_path / 'aw')) # add aw path to sys.path + +from devicetest.core.test_case import TestCase, Step +from hypium import UiDriver +from all_utils import CommonUtils, UiUtils +from cdp import debugger +from implement_api import debugger_api, runtime_api + + +class TestWorkerEvaluateOnCallFrame(TestCase): + def __init__(self, controllers): + self.TAG = self.__class__.__name__ + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + self.ui_utils = UiUtils(self.driver) + self.common_utils = CommonUtils(self.driver) + self.id_generator = CommonUtils.message_id_generator() + self.config = { + 'start_mode': '-D', + 'connect_server_port': 15638, + 'debugger_server_port': 15639, + 'bundle_name': 'com.example.multiWorker04', + 'hap_name': 'MultiWorker04.hap', + 'hap_path': str(resource_path / 'hap' / 'MultiWorker04.hap'), + 'file_path': { + 'entry_ability': 'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts', + 'index': 'entry|entry|1.0.0|src/main/ets/pages/Index.ts', + 'worker': 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts' + } + } + + def setup(self): + Step('1.下载应用') + self.driver.install_app(self.config['hap_path'], "-r") + Step('2.启动应用') + self.driver.start_app(package_name=self.config['bundle_name'], params=self.config['start_mode']) + self.config['pid'] = self.common_utils.get_pid(self.config['bundle_name']) + assert self.config['pid'] != 0, f'Failed to get pid of {self.config["bundle_name"]}' + Step('3.设置屏幕常亮') + self.ui_utils.keep_awake() + Step('4.端口映射,连接server') + self.common_utils.connect_server(self.config) + self.debugger_impl = debugger_api.DebuggerImpl(self.id_generator, self.config['websocket']) + self.runtime_impl = runtime_api.RuntimeImpl(self.id_generator, self.config['websocket']) + + def process(self): + Step('5.执行测试用例') + websocket = self.config['websocket'] + taskpool = self.config['taskpool'] + taskpool.submit(websocket.main_task(taskpool, self.test, self.config['pid'])) + taskpool.await_taskpool() + taskpool.task_join() + if taskpool.task_exception: + raise taskpool.task_exception + + def teardown(self): + Step('6.关闭应用') + self.driver.stop_app(self.config['bundle_name']) + Step('7.卸载应用') + self.driver.uninstall_app(self.config['bundle_name']) + + async def test(self, websocket): + ################################################################################################################ + # main thread: connect the debugger server + ################################################################################################################ + main_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], True) + ################################################################################################################ + # main thread: Runtime.enable + ################################################################################################################ + await self.runtime_impl.send("Runtime.enable", main_thread) + ################################################################################################################ + # main thread: Debugger.enable + ################################################################################################################ + await self.debugger_impl.send("Debugger.enable", main_thread) + ################################################################################################################ + # main thread: Runtime.runIfWaitingForDebugger + ################################################################################################################ + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", main_thread) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['entry_ability']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + ################################################################################################################ + # main thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], + self.config['file_path']['entry_ability']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + ################################################################################################################ + # main thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # main thread: Debugger.removeBreakpointsByUrl + ################################################################################################################ + params = debugger.RemoveBreakpointsUrl(self.config['file_path']['index']) + await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", main_thread, params) + ################################################################################################################ + # main thread: Debugger.getPossibleAndSetBreakpointByUrl + ################################################################################################################ + locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=12)] + params = debugger.SetBreakpointsLocations(locations) + response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", main_thread, params) + self.common_utils.assert_equal(response['result']['locations'][0]['id'], + 'id:12:0:' + self.config['file_path']['index']) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + ################################################################################################################ + # main thread: Debugger.paused, hit breakpoint + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:12:0:' + self.config['file_path']['index']]) + ################################################################################################################ + # worker thread: connect the debugger server + ################################################################################################################ + worker_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], False) + ################################################################################################################ + # worker thread: Runtime.enable + ################################################################################################################ + await self.runtime_impl.send("Runtime.enable", worker_thread) + ################################################################################################################ + # worker thread: Debugger.enable + ################################################################################################################ + await self.debugger_impl.send("Debugger.enable", worker_thread) + ################################################################################################################ + # worker thread: Runtime.runIfWaitingForDebugger + ################################################################################################################ + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", worker_thread) + # worker thread: Debugger.scriptParsed + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + # worker thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # worker thread: Debugger.removeBreakpointsByUrl + ################################################################################################################ + params = debugger.RemoveBreakpointsUrl(self.config['file_path']['worker']) + await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", worker_thread, params) + ################################################################################################################ + # worker thread: Debugger.getPossibleAndSetBreakpointByUrl + ################################################################################################################ + locations = [debugger.BreakLocationUrl(url=self.config['file_path']['worker'], line_number=116)] + params = debugger.SetBreakpointsLocations(locations) + response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", worker_thread, params) + self.common_utils.assert_equal(response['result']['locations'][0]['id'], + 'id:116:0:' + self.config['file_path']['worker']) + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + # worker thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'other') + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:116:4:' + self.config['file_path']['worker']]) + ################################################################################################################ + # worker thread: Debugger.evaluateOnCallFrame + ################################################################################################################ + LOCALPERSON_AGE = ( + 'UEFOREEAAAAAAAAADAACAGABAAAAAAAAAAAAAAIAAAA8AAAAAQAAAFwBAAAAAAAARAAAAAEAAABEAAAApAAAANcAAACAAAAAYAEAAAIAAA' + 'BsAAAAAwAAAHQAAAD/////////////////////pAAAANcAAACAAAAAhQAAAJcAAAAHYWdlACFkZWJ1Z2dlckdldFZhbHVlABdsb2NhbFBl' + 'cnNvbgAzTF9FU1Nsb3ROdW1iZXJBbm5vdGF0aW9uOwAAAAAAgUAAAAIAABdmdW5jX21haW5fMAATTF9HTE9CQUw7AAAAAAABAAECAAABAP' + '//ygAAAIgCASEBAAACAAVSAQAABhQBAAAAFVNsb3ROdW1iZXIAAAABAAgBAAAGAAAANwkDKABEkEShRLJtYQVgBUIAAQBhBj4CAGEHAmEI' + 'YAYrAgcIYQRgBEIEAABkC2sBDwD/////DwACACEATQEAAA==') + params = debugger.EvaluateOnCallFrameParams(LOCALPERSON_AGE) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "number", "unserializableValue": "20", "description": "20"}) + SET_LOCALPERSON_AGE_22 = ( + 'UEFOREEAAAAAAAAADAACAGQBAAAAAAAAAAAAAAIAAAA8AAAAAQAAAGABAAAAAAAARAAAAAEAAABEAAAApAAAANcAAACAAAAAZAEAAAIAAA' + 'BsAAAAAwAAAHQAAAD/////////////////////pAAAANcAAACAAAAAhQAAAJcAAAAHYWdlACFkZWJ1Z2dlckdldFZhbHVlABdsb2NhbFBl' + 'cnNvbgAzTF9FU1Nsb3ROdW1iZXJBbm5vdGF0aW9uOwAAAAAAgUAAAAIAABdmdW5jX21haW5fMAATTF9HTE9CQUw7AAAAAAABAAECAAABAP' + '//ygAAAIgCASEBAAACAAVWAQAABhQBAAAAFVNsb3ROdW1iZXIAAAABAAgBAAAGAAAANwkDLABEkEShRLJtYQVgBUIAAQBhBj4CAGEHAmEI' + 'YAYrAgcIYQRiFgAAAEMEAAAEZAtrAQ8A/////w8AAgAlAFEBAAA=') + params = debugger.EvaluateOnCallFrameParams(SET_LOCALPERSON_AGE_22) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "number", "unserializableValue": "22", "description": "22"}) + LOCALPERSON_AGE_PLUS_10 = ( + 'UEFOREEAAAAAAAAADAACAGwBAAAAAAAAAAAAAAIAAAA8AAAAAQAAAGgBAAAAAAAARAAAAAEAAABEAAAApAAAANcAAACAAAAAbAEAAAIAAA' + 'BsAAAAAwAAAHQAAAD/////////////////////pAAAANcAAACAAAAAhQAAAJcAAAAHYWdlACFkZWJ1Z2dlckdldFZhbHVlABdsb2NhbFBl' + 'cnNvbgAzTF9FU1Nsb3ROdW1iZXJBbm5vdGF0aW9uOwAAAAAAgUAAAAIAABdmdW5jX21haW5fMAATTF9HTE9CQUw7AAAAAAABAAECAAABAP' + '//ygAAAIgCASEBAAACAAVcAQAABhQBAAAAFVNsb3ROdW1iZXIAAAABAAgBAAAHAAAANwoDMgBEoESxRMJtYQZgBkIAAQBhBz4CAGEIAmEJ' + 'YAcrAggJYQVgBUIEAABhBGIKAAAACgYEZAtrAQ8A/////w8AAgArAAAAVwEAAA==') + params = debugger.EvaluateOnCallFrameParams(LOCALPERSON_AGE_PLUS_10) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "number", "unserializableValue": "32", "description": "32"}) + ################################################################################################################ + # worker thread: Debugger.evaluateOnCallFrame + ################################################################################################################ + SET_LOCALPERSON_NAME_TIM_AGE_30 = ( + 'UEFOREEAAAAAAAAADAACAKgBAAAAAAAAAAAAAAIAAAA8AAAAAQAAAKQBAAAAAAAARAAAAAEAAABEAAAAxgAAAPkAAACIAAAAqAEAAAIAAA' + 'BsAAAABQAAAHQAAAD/////////////////////xgAAAPkAAACIAAAAkAAAAJUAAACnAAAAuQAAAA1QZXJzb24AB1RpbQAhZGVidWdnZXJH' + 'ZXRWYWx1ZQAhZGVidWdnZXJTZXRWYWx1ZQAXbG9jYWxQZXJzb24AM0xfRVNTbG90TnVtYmVyQW5ub3RhdGlvbjsAAAAAAIFAAAACAAAXZn' + 'VuY19tYWluXzAAE0xfR0xPQkFMOwAAAAAAAQABAgAAAQD//+wAAACIAgFDAQAAAgAFmAEAAAY2AQAAABVTbG90TnVtYmVyAAAAAQAqAQAA' + 'CgAAADcJA0wARJBEoUSybWEFYAVCAAIAYQY+AABhBwJhCGAGKwIHCGEEPgEAYQViHgAAAGEGCAQDBGEEbWEFYAVCBgMAYQY+BABhB0RIYA' + 'YrCAcIZAtrAQ8A/////w8AAgBFAAAAkwEAAA==' + ) + params = debugger.EvaluateOnCallFrameParams(SET_LOCALPERSON_NAME_TIM_AGE_30) + await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + LOCALPERSON_NAME = ( + 'UEFOREEAAAAAAAAADAACAGQBAAAAAAAAAAAAAAIAAAA8AAAAAQAAAGABAAAAAAAARAAAAAEAAABEAAAApQAAANgAAACAAAAAZAEAAAIAAA' + 'BsAAAAAwAAAHQAAAD/////////////////////pQAAANgAAACAAAAAkgAAAJ8AAAAhZGVidWdnZXJHZXRWYWx1ZQAXbG9jYWxQZXJzb24A' + 'CW5hbWUAM0xfRVNTbG90TnVtYmVyQW5ub3RhdGlvbjsAAAAAAIFAAAACAAAXZnVuY19tYWluXzAAE0xfR0xPQkFMOwAAAAAAAQABAgAAAQ' + 'D//8sAAACIAgEiAQAAAgAFUwEAAAYVAQAAABVTbG90TnVtYmVyAAAAAQAJAQAABgAAADcJAygARJBEoUSybWEFYAVCAAAAYQY+AQBhBwJh' + 'CGAGKwIHCGEEYARCBAIAZAtrAQ8A/////w8AAgAhAAAAAE4BAAA=') + params = debugger.EvaluateOnCallFrameParams(LOCALPERSON_NAME) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "string", "unserializableValue": "Tim", "description": "Tim"}) + params = debugger.EvaluateOnCallFrameParams(LOCALPERSON_AGE) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "number", "unserializableValue": "30", "description": "30"}) + ################################################################################################################ + # worker thread: Debugger.evaluateOnCallFrame + ################################################################################################################ + params = debugger.EvaluateOnCallFrameParams('closureString') + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "string", "unserializableValue": "closure", "description": "closure"}) + params = debugger.EvaluateOnCallFrameParams('closureString = "modified"') + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "string", "unserializableValue": "modified", "description": "modified"}) + params = debugger.EvaluateOnCallFrameParams('closureString') + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "string", "unserializableValue": "modified", "description": "modified"}) + ################################################################################################################ + # worker thread: Debugger.evaluateOnCallFrame + ################################################################################################################ + CLOSUREMAP_GET_1 = ( + 'UEFOREEAAAAAAAAADAACAHABAAAAAAAAAAAAAAIAAAA8AAAAAQAAAGwBAAAAAAAARAAAAAEAAABEAAAAowAAANYAAACAAAAAcAEAAAIAAA' + 'BsAAAAAwAAAHQAAAD/////////////////////owAAANYAAACAAAAAjAAAAJ4AAAAVY2xvc3VyZU1hcAAhZGVidWdnZXJHZXRWYWx1ZQAH' + 'Z2V0ADNMX0VTU2xvdE51bWJlckFubm90YXRpb247AAAAAACBQAAAAgAAF2Z1bmNfbWFpbl8wABNMX0dMT0JBTDsAAAAAAAEAAQIAAAEA//' + '/JAAAAiAIBIAEAAAIABWABAAAGEwEAAAAVU2xvdE51bWJlcgAAAAEABwEAAAgAAAA3CgM3AESgRLFEwm1hBmAGQgABAGEHPgAAYQgCYQlg' + 'BysCCAlhBWAFQgQCAGEEYgEAAABhBmAELgYFBmQLawEPAP////8PAAIAMAAAAFsBAAA=') + params = debugger.EvaluateOnCallFrameParams(CLOSUREMAP_GET_1) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], {"type": "undefined"}) + CLOSUREMAP_SET_1_2 = ( + 'UEFOREEAAAAAAAAADAACAHgBAAAAAAAAAAAAAAIAAAA8AAAAAQAAAHQBAAAAAAAARAAAAAEAAABEAAAAowAAANYAAACAAAAAeAEAAAIAAA' + 'BsAAAAAwAAAHQAAAD/////////////////////owAAANYAAACAAAAAjAAAAJ4AAAAVY2xvc3VyZU1hcAAhZGVidWdnZXJHZXRWYWx1ZQAH' + 'c2V0ADNMX0VTU2xvdE51bWJlckFubm90YXRpb247AAAAAACBQAAAAgAAF2Z1bmNfbWFpbl8wABNMX0dMT0JBTDsAAAAAAAEAAQIAAAEA//' + '/JAAAAiAIBIAEAAAIABWgBAAAGEwEAAAAVU2xvdE51bWJlcgAAAAEABwEAAAgAAAA3CgM/AESgRLFEwm1hBmAGQgABAGEHPgAAYQgCYQlg' + 'BysCCAlhBWAFQgQCAGEEYgEAAABhBmICAAAAYQdgBC8GBQYHZAtrAQ8A/////w8AAgA4AAAAYwEAAA==') + params = debugger.EvaluateOnCallFrameParams(CLOSUREMAP_SET_1_2) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + assert response['result']['result']['description'].startswith('Map(1) {1 => 2}'), \ + f'The description of the evaluation "closureMap.set(1, 2)" is incorrect.' + params = debugger.EvaluateOnCallFrameParams(CLOSUREMAP_GET_1) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "number", "unserializableValue": "2", "description": "2"}) + ################################################################################################################ + # worker thread: Debugger.evaluateOnCallFrame + ################################################################################################################ + params = debugger.EvaluateOnCallFrameParams('globalArray') + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + assert response['result']['result']['description'].startswith('Array(3)'), \ + f'The description of the parameter globalArray is incorrect.' + GLOBALARRAY_PUSH_999 = ( + 'UEFOREEAAAAAAAAADAACAHABAAAAAAAAAAAAAAIAAAA8AAAAAQAAAGwBAAAAAAAARAAAAAEAAABEAAAApQAAANgAAACAAAAAcAEAAAIAAA' + 'BsAAAAAwAAAHQAAAD/////////////////////pQAAANgAAACAAAAAkgAAAJ8AAAAhZGVidWdnZXJHZXRWYWx1ZQAXZ2xvYmFsQXJyYXkA' + 'CXB1c2gAM0xfRVNTbG90TnVtYmVyQW5ub3RhdGlvbjsAAAAAAIFAAAACAAAXZnVuY19tYWluXzAAE0xfR0xPQkFMOwAAAAAAAQABAgAAAQ' + 'D//8sAAACIAgEiAQAAAgAFYgEAAAYVAQAAABVTbG90TnVtYmVyAAAAAQAJAQAACAAAADcKAzcARKBEsUTCbWEGYAZCAAAAYQc+AQBhCAJh' + 'CWAHKwIICWEFYAVCBAIAYQRi5wMAAGEGYAQuBgUGZAtrAQ8A/////w8AAgAwAF0BAAA=') + params = debugger.EvaluateOnCallFrameParams(GLOBALARRAY_PUSH_999) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "number", "unserializableValue": "4", "description": "4"}) + GLOBALARRAY_INDEX_3 = ( + 'UEFOREEAAAAAAAAADAACAGABAAAAAAAAAAAAAAIAAAA8AAAAAQAAAFwBAAAAAAAARAAAAAEAAABEAAAAmwAAAM4AAAB8AAAAYAEAAAIAAA' + 'BsAAAAAgAAAHQAAAD/////////////////////mwAAAM4AAAB8AAAAjgAAACFkZWJ1Z2dlckdldFZhbHVlABdnbG9iYWxBcnJheQAzTF9F' + 'U1Nsb3ROdW1iZXJBbm5vdGF0aW9uOwAAAAAAgUAAAAIAABdmdW5jX21haW5fMAATTF9HTE9CQUw7AAAAAAABAAECAAABAP//wQAAAIgCAR' + 'gBAAACAAVPAQAABgsBAAAAFVNsb3ROdW1iZXIAAAABAP8AAAAGAAAANwkDLgBEkEShRLJtYQVgBUIAAABhBj4BAGEHAmEIYAYrAgcIYQRi' + 'AwAAAGEFYAU3BARkC2sBDwD/////DwACACcAAAAASgEAAA==') + params = debugger.EvaluateOnCallFrameParams(GLOBALARRAY_INDEX_3) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "number", "unserializableValue": "999", "description": "999"}) + ################################################################################################################ + # worker thread: Debugger.evaluateOnCallFrame + ################################################################################################################ + params = debugger.EvaluateOnCallFrameParams('globalBool') + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result']['type'], 'object') + params = debugger.EvaluateOnCallFrameParams('globalBool = true') + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "boolean", "unserializableValue": "true", "description": "true"}) + params = debugger.EvaluateOnCallFrameParams('globalBool') + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "boolean", "unserializableValue": "true", "description": "true"}) + ################################################################################################################ + # worker thread: Debugger.evaluateOnCallFrame + ################################################################################################################ + WORKER_WORKERPORT = ( + 'UEFOREEAAAAAAAAADAACAGQBAAAAAAAAAAAAAAIAAAA8AAAAAQAAAGABAAAAAAAARAAAAAEAAABEAAAApgAAANkAAACAAAAAZAEAAAIAAA' + 'BsAAAAAwAAAHQAAAD/////////////////////pgAAANkAAACAAAAAkgAAAJoAAAAhZGVidWdnZXJHZXRWYWx1ZQANd29ya2VyABV3b3Jr' + 'ZXJQb3J0ADNMX0VTU2xvdE51bWJlckFubm90YXRpb247AAAAAACBQAAAAgAAF2Z1bmNfbWFpbl8wABNMX0dMT0JBTDsAAAAAAAEAAQIAAA' + 'EA///MAAAAiAIBIwEAAAIABVQBAAAGFgEAAAAVU2xvdE51bWJlcgAAAAEACgEAAAYAAAA3CQMoAESQRKFEsm1hBWAFQgAAAGEGPgEAYQcC' + 'YQhgBisCBwhhBGAEQgQCAGQLawEPAP////8PAAIAIQAAAE8BAAA=') + params = debugger.EvaluateOnCallFrameParams(WORKER_WORKERPORT) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result']['type'], 'object') + SET_WORKER_WORKERPORT_UNDEFINED = ( + 'UEFOREEAAAAAAAAADAACAGQBAAAAAAAAAAAAAAIAAAA8AAAAAQAAAGABAAAAAAAARAAAAAEAAABEAAAApgAAANkAAACAAAAAZAEAAAIAAA' + 'BsAAAAAwAAAHQAAAD/////////////////////pgAAANkAAACAAAAAkgAAAJoAAAAhZGVidWdnZXJHZXRWYWx1ZQANd29ya2VyABV3b3Jr' + 'ZXJQb3J0ADNMX0VTU2xvdE51bWJlckFubm90YXRpb247AAAAAACBQAAAAgAAF2Z1bmNfbWFpbl8wABNMX0dMT0JBTDsAAAAAAAEAAQIAAA' + 'EA///MAAAAiAIBIwEAAAIABVQBAAAGFgEAAAAVU2xvdE51bWJlcgAAAAEACgEAAAYAAAA3CQMoAESQRKFEsm1hBWAFQgAAAGEGPgEAYQcC' + 'YQhgBisCBwhhBABDBAIABGQLawEPAP////8PAAIAIQAAAE8BAAA=') + params = debugger.EvaluateOnCallFrameParams(SET_WORKER_WORKERPORT_UNDEFINED) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result']['type'], 'undefined') + params = debugger.EvaluateOnCallFrameParams(WORKER_WORKERPORT) + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result']['type'], 'undefined') + ################################################################################################################ + # worker thread: Debugger.evaluateOnCallFrame + ################################################################################################################ + params = debugger.EvaluateOnCallFrameParams("Deque") + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result']['type'], 'function') + params = debugger.EvaluateOnCallFrameParams("Deque = 0") + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "number", "unserializableValue": "0", "description": "0"}) + params = debugger.EvaluateOnCallFrameParams("Deque") + response = await self.debugger_impl.send("Debugger.evaluateOnCallFrame", worker_thread, params) + self.common_utils.assert_equal(response['result']['result'], + {"type": "number", "unserializableValue": "0", "description": "0"}) + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread) + ################################################################################################################ + # main thread: click on the screen + ################################################################################################################ + self.ui_utils.click_on_middle() + ################################################################################################################ + # worker thread: destroy instance + ################################################################################################################ + response = await self.debugger_impl.destroy_instance() + self.common_utils.assert_equal(response['instanceId'], worker_thread.instance_id) + ################################################################################################################ + # main thread: Debugger.disable + ################################################################################################################ + await self.debugger_impl.send("Debugger.disable", main_thread) + ################################################################################################################ + # close the websocket connections + ################################################################################################################ + await websocket.send_msg_to_debugger_server(main_thread.instance_id, main_thread.send_msg_queue, 'close') + await websocket.send_msg_to_connect_server('close') + ################################################################################################################ \ No newline at end of file diff --git a/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints01.json b/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints01.json new file mode 100644 index 00000000..2f851899 --- /dev/null +++ b/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints01.json @@ -0,0 +1,16 @@ + +{ + "description": "Config for TestWorkerExceptionBreakpoints01", + "environment": [ + { + "type": "device", + "label": "phone" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "toolchain/debug/TestWorkerExceptionBreakpoints01.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints01.py b/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints01.py new file mode 100644 index 00000000..20ea22a1 --- /dev/null +++ b/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints01.py @@ -0,0 +1,309 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright (c) 2025 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +#================================================================== +#文 件 名: TestWorkerExceptionBreakpoints01.py +#文件说明: 多实例 debug 调试异常断点 ALL 和 NONE 模式 +#================================================================== +测试步骤: + 1. 连接 connect server 和主线程 debugger server + 2. 主线程使能 Runtime 和 Debugger + 3. 主线程 Index.ts 文件设置断点(Debugger.getPossibleAndSetBreakpointByUrl) + 4. 主线程 resume,停在断点处(Debugger.resume) + 5. 创建子线程1,连接 debugger server + 6. 主线程 resume,停在断点处(Debugger.resume) + 7. 创建子线程2,连接 debugger server + 8. 所有子线程使能 Runtime 和 Debugger + 9. 子线程1设置异常断点类型为 ALL(Debugger.setPauseOnExceptions) + 10. 主线程 resume,停在断点处,子线程1停在第一个异常处(Debugger.resume) + 11. 子线程1 resume,停在第二个异常断点处(Debugger.resume) + 12. 子线程1 resume,抛出异常 + 13. 子线程2设置异常断点类型为 NONE(Debugger.setPauseOnExceptions) + 14. 主线程 resume,子线程2抛出异常 + 15. 关闭所有线程 debugger server 和 connect server 连接 +#================================================================== +关键代码: + Index.ets + let workerIndex = 0 + function newWorker() {} // 创建一个子线程, workerIndex++ + function terminateWorker() {} // 销毁一个子线程, workerIndex-- + for (let i = 0; i < 2; i++) { + newWorker() + } + for (let i = 0; i < workerIndex; i++) { + workers[i].postMessage("hello world") + } + Worker.ets + const workerPort: ThreadWorkerGlobalScope = worker.workerPort; + workerPort.onmessage = (e: MessageEvents) => { + workerPort.postMessage(e.data) + try { + throw new Error('[worker] caught error') + } catch (e) { + console.info('[worker] caught error') + } + throw new Error('[worker] uncaught error') + } +#!!================================================================ +""" +import sys +from pathlib import Path + +root_path = Path(__file__).parent.parent.parent.parent +resource_path = root_path / 'resource' +sys.path.append(str(root_path / 'aw')) # add aw path to sys.path + +from devicetest.core.test_case import TestCase, Step +from hypium import UiDriver +from all_utils import CommonUtils, UiUtils +from cdp import debugger +from implement_api import debugger_api, runtime_api + + +class TestWorkerExceptionBreakpoints01(TestCase): + def __init__(self, controllers): + self.TAG = self.__class__.__name__ + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + self.ui_utils = UiUtils(self.driver) + self.common_utils = CommonUtils(self.driver) + self.id_generator = CommonUtils.message_id_generator() + self.config = { + 'start_mode': '-D', + 'connect_server_port': 15640, + 'debugger_server_port': 15641, + 'bundle_name': 'com.example.multiWorker03', + 'hap_name': 'MultiWorker03.hap', + 'hap_path': str(resource_path / 'hap' / 'MultiWorker03.hap'), + 'file_path': { + 'entry_ability': 'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts', + 'index': 'entry|entry|1.0.0|src/main/ets/pages/Index.ts', + 'worker': 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts' + } + } + + def setup(self): + Step('1.下载应用') + self.driver.install_app(self.config['hap_path'], "-r") + Step('2.启动应用') + self.driver.start_app(package_name=self.config['bundle_name'], params=self.config['start_mode']) + self.config['pid'] = self.common_utils.get_pid(self.config['bundle_name']) + assert self.config['pid'] != 0, f'Failed to get pid of {self.config["bundle_name"]}' + Step('3.设置屏幕常亮') + self.ui_utils.keep_awake() + Step('4.端口映射,连接server') + self.common_utils.connect_server(self.config) + self.debugger_impl = debugger_api.DebuggerImpl(self.id_generator, self.config['websocket']) + self.runtime_impl = runtime_api.RuntimeImpl(self.id_generator, self.config['websocket']) + + def process(self): + Step('5.执行测试用例') + websocket = self.config['websocket'] + taskpool = self.config['taskpool'] + taskpool.submit(websocket.main_task(taskpool, self.test, self.config['pid'])) + taskpool.await_taskpool() + taskpool.task_join() + if taskpool.task_exception: + raise taskpool.task_exception + + def teardown(self): + Step('6.关闭应用') + self.driver.stop_app(self.config['bundle_name']) + Step('7.卸载应用') + self.driver.uninstall_app(self.config['bundle_name']) + + async def test(self, websocket): + ################################################################################################################ + # main thread: connect the debugger server + ################################################################################################################ + main_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], True) + ################################################################################################################ + # main thread: Runtime.enable + ################################################################################################################ + await self.runtime_impl.send("Runtime.enable", main_thread) + ################################################################################################################ + # main thread: Debugger.enable + ################################################################################################################ + await self.debugger_impl.send("Debugger.enable", main_thread) + ################################################################################################################ + # main thread: Runtime.runIfWaitingForDebugger + ################################################################################################################ + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", main_thread) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['entry_ability']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + ################################################################################################################ + # main thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], + self.config['file_path']['entry_ability']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + ################################################################################################################ + # main thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # main thread: Debugger.removeBreakpointsByUrl + ################################################################################################################ + params = debugger.RemoveBreakpointsUrl(self.config['file_path']['index']) + await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", main_thread, params) + ################################################################################################################ + # main thread: Debugger.getPossibleAndSetBreakpointByUrl + ################################################################################################################ + locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=16), + debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=84)] + params = debugger.SetBreakpointsLocations(locations) + response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", main_thread, params) + self.common_utils.assert_equal(response['result']['locations'][0]['id'], + 'id:16:0:' + self.config['file_path']['index']) + self.common_utils.assert_equal(response['result']['locations'][1]['id'], + 'id:84:0:' + self.config['file_path']['index']) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + ################################################################################################################ + # main thread: Debugger.paused, hit breakpoint + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:84:1:' + self.config['file_path']['index']]) + ################################################################################################################ + # worker thread: connect the debugger server + ################################################################################################################ + worker_thread_1 = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], False) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + # main thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:84:1:' + self.config['file_path']['index']]) + ################################################################################################################ + # worker thread: connect the debugger server + ################################################################################################################ + worker_thread_2 = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], False) + ################################################################################################################ + # worker thread: Runtime.enable + ################################################################################################################ + await self.runtime_impl.send("Runtime.enable", worker_thread_1) + await self.runtime_impl.send("Runtime.enable", worker_thread_2) + ################################################################################################################ + # worker thread: Debugger.enable + ################################################################################################################ + await self.debugger_impl.send("Debugger.enable", worker_thread_1) + await self.debugger_impl.send("Debugger.enable", worker_thread_2) + ################################################################################################################ + # worker thread: Runtime.runIfWaitingForDebugger + ################################################################################################################ + # worker thread 1: Runtime.runIfWaitingForDebugger + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", worker_thread_1) + # worker thread 1: Debugger.scriptParsed + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread_1) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + # worker thread 1: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread_1) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + # worker thread 2: Runtime.runIfWaitingForDebugger + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", worker_thread_2) + # worker thread 2: Debugger.scriptParsed + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread_2) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + # worker thread 2: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread_2) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread_1) + await self.debugger_impl.send("Debugger.resume", worker_thread_2) + ################################################################################################################ + # worker thread: Debugger.setPauseOnExceptions + ################################################################################################################ + params = debugger.PauseOnExceptionsState.ALL + await self.debugger_impl.send("Debugger.setPauseOnExceptions", worker_thread_1, params) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + # main thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['reason'], 'other') + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:16:4:' + self.config['file_path']['index']]) + # worker thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread_1) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'exception') + assert 'caught error' in response['params']['data']['description'], \ + f"'caught error' is not in description: '{response['params']['data']['description']}'" + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread_1) + # worker thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread_1) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'exception') + assert 'uncaught error' in response['params']['data']['description'], \ + f"'uncaught error' is not in description: '{response['params']['data']['description']}'" + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread_1) + ################################################################################################################ + # worker thread: Debugger.setPauseOnExceptions + ################################################################################################################ + params = debugger.PauseOnExceptionsState.NONE + await self.debugger_impl.send("Debugger.setPauseOnExceptions", worker_thread_2, params) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + ################################################################################################################ + # close the websocket connections + ################################################################################################################ + await websocket.send_msg_to_debugger_server(worker_thread_2.instance_id, worker_thread_2.send_msg_queue, + 'close') + await websocket.send_msg_to_debugger_server(worker_thread_1.instance_id, worker_thread_1.send_msg_queue, + 'close') + await websocket.send_msg_to_debugger_server(main_thread.instance_id, main_thread.send_msg_queue, 'close') + await websocket.send_msg_to_connect_server('close') + ################################################################################################################ \ No newline at end of file diff --git a/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints02.json b/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints02.json new file mode 100644 index 00000000..5fac6a4a --- /dev/null +++ b/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints02.json @@ -0,0 +1,15 @@ +{ + "description": "Config for TestWorkerExceptionBreakpoints02", + "environment": [ + { + "type": "device", + "label": "phone" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "toolchain/debug/TestWorkerExceptionBreakpoints02.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints02.py b/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints02.py new file mode 100644 index 00000000..7bbc0709 --- /dev/null +++ b/test/autotest/testcases/toolchain/debug/TestWorkerExceptionBreakpoints02.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright (c) 2025 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +#================================================================== +#文 件 名: TestWorkerExceptionBreakpoints02.py +#文件说明: 多实例 debug 调试异常断点 CAUGHT 和 UNCAUGHT 模式 +#================================================================== +测试步骤: + 1. 连接 connect server 和主线程 debugger server + 2. 主线程使能 Runtime 和 Debugger + 3. 主线程 Index.ts 文件设置断点(Debugger.getPossibleAndSetBreakpointByUrl) + 4. 主线程 resume,停在断点处(Debugger.resume) + 5. 创建子线程1,连接 debugger server + 6. 主线程 resume,停在断点处(Debugger.resume) + 7. 创建子线程2,连接 debugger server + 8. 所有子线程使能 Runtime 和 Debugger + 9. 子线程1设置异常断点类型为 CAUGHT(Debugger.setPauseOnExceptions) + 10. 主线程 resume,停在断点处,子线程1停在第一个异常处(Debugger.resume) + 11. 子线程1 resume,停在第二个异常断点处(Debugger.resume) + 12. 子线程1 resume,抛出异常 + 13. 子线程2设置异常断点类型为 UNCAUGHT(Debugger.setPauseOnExceptions) + 14. 主线程 resume,子线程2停在第二个异常处(Debugger.resume) + 15. 子线程2 resume,抛出异常 + 16. 关闭所有线程 debugger server 和 connect server 连接 +#================================================================== +关键代码: + Index.ets + let workerIndex = 0 + function newWorker() {} // 创建一个子线程, workerIndex++ + function terminateWorker() {} // 销毁一个子线程, workerIndex-- + for (let i = 0; i < 2; i++) { + newWorker() + } + for (let i = 0; i < workerIndex; i++) { + workers[i].postMessage("hello world") + } + Worker.ets + const workerPort: ThreadWorkerGlobalScope = worker.workerPort; + workerPort.onmessage = (e: MessageEvents) => { + workerPort.postMessage(e.data) + try { + throw new Error('[worker] caught error') + } catch (e) { + console.info('[worker] caught error') + } + throw new Error('[worker] uncaught error') + } +#!!================================================================ +""" +import sys +from pathlib import Path + +root_path = Path(__file__).parent.parent.parent.parent +resource_path = root_path / 'resource' +sys.path.append(str(root_path / 'aw')) # add aw path to sys.path + +from devicetest.core.test_case import TestCase, Step +from hypium import UiDriver +from all_utils import CommonUtils, UiUtils +from cdp import debugger +from implement_api import debugger_api, runtime_api + + +class TestWorkerExceptionBreakpoints02(TestCase): + def __init__(self, controllers): + self.TAG = self.__class__.__name__ + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + self.ui_utils = UiUtils(self.driver) + self.common_utils = CommonUtils(self.driver) + self.id_generator = CommonUtils.message_id_generator() + self.config = { + 'start_mode': '-D', + 'connect_server_port': 15642, + 'debugger_server_port': 15643, + 'bundle_name': 'com.example.multiWorker03', + 'hap_name': 'MultiWorker03.hap', + 'hap_path': str(resource_path / 'hap' / 'MultiWorker03.hap'), + 'file_path': { + 'entry_ability': 'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts', + 'index': 'entry|entry|1.0.0|src/main/ets/pages/Index.ts', + 'worker': 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts' + } + } + + def setup(self): + Step('1.下载应用') + self.driver.install_app(self.config['hap_path'], "-r") + Step('2.启动应用') + self.driver.start_app(package_name=self.config['bundle_name'], params=self.config['start_mode']) + self.config['pid'] = self.common_utils.get_pid(self.config['bundle_name']) + assert self.config['pid'] != 0, f'Failed to get pid of {self.config["bundle_name"]}' + Step('3.设置屏幕常亮') + self.ui_utils.keep_awake() + Step('4.端口映射,连接server') + self.common_utils.connect_server(self.config) + self.debugger_impl = debugger_api.DebuggerImpl(self.id_generator, self.config['websocket']) + self.runtime_impl = runtime_api.RuntimeImpl(self.id_generator, self.config['websocket']) + + def process(self): + Step('5.执行测试用例') + websocket = self.config['websocket'] + taskpool = self.config['taskpool'] + taskpool.submit(websocket.main_task(taskpool, self.test, self.config['pid'])) + taskpool.await_taskpool() + taskpool.task_join() + if taskpool.task_exception: + raise taskpool.task_exception + + def teardown(self): + Step('6.关闭应用') + self.driver.stop_app(self.config['bundle_name']) + Step('7.卸载应用') + self.driver.uninstall_app(self.config['bundle_name']) + + async def test(self, websocket): + ################################################################################################################ + # main thread: connect the debugger server + ################################################################################################################ + main_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], True) + ################################################################################################################ + # main thread: Runtime.enable + ################################################################################################################ + await self.runtime_impl.send("Runtime.enable", main_thread) + ################################################################################################################ + # main thread: Debugger.enable + ################################################################################################################ + await self.debugger_impl.send("Debugger.enable", main_thread) + ################################################################################################################ + # main thread: Runtime.runIfWaitingForDebugger + ################################################################################################################ + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", main_thread) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['entry_ability']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + ################################################################################################################ + # main thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], + self.config['file_path']['entry_ability']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + ################################################################################################################ + # main thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # main thread: Debugger.removeBreakpointsByUrl + ################################################################################################################ + params = debugger.RemoveBreakpointsUrl(self.config['file_path']['index']) + await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", main_thread, params) + ################################################################################################################ + # main thread: Debugger.getPossibleAndSetBreakpointByUrl + ################################################################################################################ + locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=16), + debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=84)] + params = debugger.SetBreakpointsLocations(locations) + response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", main_thread, params) + self.common_utils.assert_equal(response['result']['locations'][0]['id'], + 'id:16:0:' + self.config['file_path']['index']) + self.common_utils.assert_equal(response['result']['locations'][1]['id'], + 'id:84:0:' + self.config['file_path']['index']) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + ################################################################################################################ + # main thread: Debugger.paused, hit breakpoint + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:84:1:' + self.config['file_path']['index']]) + ################################################################################################################ + # worker thread: connect the debugger server + ################################################################################################################ + worker_thread_1 = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], False) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + # main thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:84:1:' + self.config['file_path']['index']]) + ################################################################################################################ + # worker thread: connect the debugger server + ################################################################################################################ + worker_thread_2 = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], False) + ################################################################################################################ + # worker thread: Runtime.enable + ################################################################################################################ + await self.runtime_impl.send("Runtime.enable", worker_thread_1) + await self.runtime_impl.send("Runtime.enable", worker_thread_2) + ################################################################################################################ + # worker thread: Debugger.enable + ################################################################################################################ + await self.debugger_impl.send("Debugger.enable", worker_thread_1) + await self.debugger_impl.send("Debugger.enable", worker_thread_2) + ################################################################################################################ + # worker thread: Runtime.runIfWaitingForDebugger + ################################################################################################################ + # worker thread 1: Runtime.runIfWaitingForDebugger + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", worker_thread_1) + # worker thread 1: Debugger.scriptParsed + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread_1) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + # worker thread 1: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread_1) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + # worker thread 2: Runtime.runIfWaitingForDebugger + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", worker_thread_2) + # worker thread 2: Debugger.scriptParsed + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread_2) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + # worker thread 2: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread_2) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread_1) + await self.debugger_impl.send("Debugger.resume", worker_thread_2) + ################################################################################################################ + # worker thread: Debugger.setPauseOnExceptions + ################################################################################################################ + params = debugger.PauseOnExceptionsState.CAUGHT + await self.debugger_impl.send("Debugger.setPauseOnExceptions", worker_thread_1, params) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + # main thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['reason'], 'other') + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:16:4:' + self.config['file_path']['index']]) + # worker thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread_1) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'exception') + assert 'caught error' in response['params']['data']['description'], \ + f"'caught error' is not in description: '{response['params']['data']['description']}'" + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread_1) + # worker thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread_1) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'exception') + assert 'uncaught error' in response['params']['data']['description'], \ + f"'uncaught error' is not in description: '{response['params']['data']['description']}'" + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread_1) + ################################################################################################################ + # worker thread: Debugger.setPauseOnExceptions + ################################################################################################################ + params = debugger.PauseOnExceptionsState.UNCAUGHT + await self.debugger_impl.send("Debugger.setPauseOnExceptions", worker_thread_2, params) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + # worker thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread_2) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'exception') + assert 'uncaught error' in response['params']['data']['description'], \ + f"'uncaught error' is not in description: '{response['params']['data']['description']}'" + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread_2) + ################################################################################################################ + # close the websocket connections + ################################################################################################################ + await websocket.send_msg_to_debugger_server(worker_thread_2.instance_id, worker_thread_2.send_msg_queue, + 'close') + await websocket.send_msg_to_debugger_server(worker_thread_1.instance_id, worker_thread_1.send_msg_queue, + 'close') + await websocket.send_msg_to_debugger_server(main_thread.instance_id, main_thread.send_msg_queue, 'close') + await websocket.send_msg_to_connect_server('close') + ################################################################################################################ \ No newline at end of file diff --git a/test/autotest/testcases/toolchain/debug/TestWorkerGetProperties.json b/test/autotest/testcases/toolchain/debug/TestWorkerGetProperties.json new file mode 100644 index 00000000..9008636d --- /dev/null +++ b/test/autotest/testcases/toolchain/debug/TestWorkerGetProperties.json @@ -0,0 +1,15 @@ +{ + "description": "Config for TestWorkerGetProperties", + "environment": [ + { + "type": "device", + "label": "phone" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "toolchain/debug/TestWorkerGetProperties.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/testcases/toolchain/debug/TestWorkerGetProperties.py b/test/autotest/testcases/toolchain/debug/TestWorkerGetProperties.py new file mode 100644 index 00000000..b1a1f44b --- /dev/null +++ b/test/autotest/testcases/toolchain/debug/TestWorkerGetProperties.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright (c) 2025 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +#================================================================== +#文 件 名: TestWorkerGetProperties.py +#文件说明: 多实例 debug 调试 getProperties +#================================================================== +测试步骤: + 1. 连接 connect server 和主线程 debugger server + 2. 主线程使能 Runtime 和 Debugger + 3. 主线程 Index.ts 文件设置断点(Debugger.getPossibleAndSetBreakpointByUrl) + 4. 主线程 resume,暂停在下一断点(Debugger.resume) + 5. 创建子线程,连接子线程 debugger server + 6. 子线程使能 Runtime 和 Debugger + 7. 子线程 Worker.ets 文件设置断点(Debugger.getPossibleAndSetBreakpointByUrl) + 8. 主线程 resume,发送消息给子线程,子线程暂停在断点(Debugger.resume) + 9. 子线程 getProperties 获取 local/closure/module/global作用域变量信息(Debugger.getProperties) + 10. 销毁子线程,对应的 debugger server 连接断开 + 11. 关闭主线程 debugger server 和 connect server 连接 +#================================================================== +关键代码: + Index.ets + let myWorker = new worker.ThreadWorker("entry/ets/workers/Worker.ets") + myWorker.postMessage("hello world") + .OnClick(() => { + myWorker.terminate() + }) + Worker.ets + const workerPort: ThreadWorkerGlobalScope = worker.workerPort; + let closureBoolean = false + ...... // 定义不同的闭包变量 + globalThis.globalBool = new Boolean(closureBoolean) + ...... // 定义不同的全局变量 + workerPort.onmessage = (e: MessageEvents) => { + let localNull = null + ...... // 定义不同的局部变量 + workerPort.postMessage(e.data) + } +#!!================================================================ +""" +import sys +from pathlib import Path + +root_path = Path(__file__).parent.parent.parent.parent +resource_path = root_path / 'resource' +sys.path.append(str(root_path / 'aw')) # add aw path to sys.path + +from devicetest.core.test_case import TestCase, Step +from hypium import UiDriver +from all_utils import CommonUtils, UiUtils +from cdp import debugger, runtime +from implement_api import debugger_api, runtime_api + + +class TestWorkerGetProperties(TestCase): + def __init__(self, controllers): + self.TAG = self.__class__.__name__ + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + self.ui_utils = UiUtils(self.driver) + self.common_utils = CommonUtils(self.driver) + self.id_generator = CommonUtils.message_id_generator() + self.config = { + 'start_mode': '-D', + 'connect_server_port': 15644, + 'debugger_server_port': 15645, + 'bundle_name': 'com.example.multiWorker04', + 'hap_name': 'MultiWorker04.hap', + 'hap_path': str(resource_path / 'hap' / 'MultiWorker04.hap'), + 'file_path': { + 'entry_ability': 'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts', + 'index': 'entry|entry|1.0.0|src/main/ets/pages/Index.ts', + 'worker': 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts' + } + } + + def setup(self): + Step('1.下载应用') + self.driver.install_app(self.config['hap_path'], "-r") + Step('2.启动应用') + self.driver.start_app(package_name=self.config['bundle_name'], params=self.config['start_mode']) + self.config['pid'] = self.common_utils.get_pid(self.config['bundle_name']) + assert self.config['pid'] != 0, f'Failed to get pid of {self.config["bundle_name"]}' + Step('3.设置屏幕常亮') + self.ui_utils.keep_awake() + Step('4.端口映射,连接server') + self.common_utils.connect_server(self.config) + self.debugger_impl = debugger_api.DebuggerImpl(self.id_generator, self.config['websocket']) + self.runtime_impl = runtime_api.RuntimeImpl(self.id_generator, self.config['websocket']) + + def process(self): + Step('5.执行测试用例') + websocket = self.config['websocket'] + taskpool = self.config['taskpool'] + taskpool.submit(websocket.main_task(taskpool, self.test, self.config['pid'])) + taskpool.await_taskpool() + taskpool.task_join() + if taskpool.task_exception: + raise taskpool.task_exception + + def teardown(self): + Step('6.关闭应用') + self.driver.stop_app(self.config['bundle_name']) + Step('7.卸载应用') + self.driver.uninstall_app(self.config['bundle_name']) + + async def test(self, websocket): + ################################################################################################################ + # main thread: connect the debugger server + ################################################################################################################ + main_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], True) + ################################################################################################################ + # main thread: Runtime.enable + ################################################################################################################ + await self.runtime_impl.send("Runtime.enable", main_thread) + ################################################################################################################ + # main thread: Debugger.enable + ################################################################################################################ + await self.debugger_impl.send("Debugger.enable", main_thread) + ################################################################################################################ + # main thread: Runtime.runIfWaitingForDebugger + ################################################################################################################ + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", main_thread) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['entry_ability']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + ################################################################################################################ + # main thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], + self.config['file_path']['entry_ability']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + ################################################################################################################ + # main thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # main thread: Debugger.removeBreakpointsByUrl + ################################################################################################################ + params = debugger.RemoveBreakpointsUrl(self.config['file_path']['index']) + await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", main_thread, params) + ################################################################################################################ + # main thread: Debugger.getPossibleAndSetBreakpointByUrl + ################################################################################################################ + locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=12)] + params = debugger.SetBreakpointsLocations(locations) + response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", main_thread, params) + self.common_utils.assert_equal(response['result']['locations'][0]['id'], + 'id:12:0:' + self.config['file_path']['index']) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + ################################################################################################################ + # main thread: Debugger.paused, hit breakpoint + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", main_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['index']) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:12:0:' + self.config['file_path']['index']]) + ################################################################################################################ + # worker thread: connect the debugger server + ################################################################################################################ + worker_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], False) + ################################################################################################################ + # worker thread: Runtime.enable + ################################################################################################################ + await self.runtime_impl.send("Runtime.enable", worker_thread) + ################################################################################################################ + # worker thread: Debugger.enable + ################################################################################################################ + await self.debugger_impl.send("Debugger.enable", worker_thread) + ################################################################################################################ + # worker thread: Runtime.runIfWaitingForDebugger + ################################################################################################################ + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", worker_thread) + # worker thread: Debugger.scriptParsed + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['endLine'], 0) + # worker thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'Break on start') + ################################################################################################################ + # worker thread: Debugger.removeBreakpointsByUrl + ################################################################################################################ + params = debugger.RemoveBreakpointsUrl(self.config['file_path']['worker']) + await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", worker_thread, params) + ################################################################################################################ + # worker thread: Debugger.getPossibleAndSetBreakpointByUrl + ################################################################################################################ + locations = [debugger.BreakLocationUrl(url=self.config['file_path']['worker'], line_number=116)] + params = debugger.SetBreakpointsLocations(locations) + response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", worker_thread, params) + self.common_utils.assert_equal(response['result']['locations'][0]['id'], + 'id:116:0:' + self.config['file_path']['worker']) + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread) + ################################################################################################################ + # main thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", main_thread) + # worker thread: Debugger.paused + response = await self.debugger_impl.recv("Debugger.paused", worker_thread) + self.common_utils.assert_equal(response['params']['callFrames'][0]['url'], self.config['file_path']['worker']) + self.common_utils.assert_equal(response['params']['reason'], 'other') + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:116:4:' + self.config['file_path']['worker']]) + ################################################################################################################ + # worker thread: Runtime.getProperties + ################################################################################################################ + params = runtime.GetPropertiesParams('0') + response = await self.runtime_impl.send("Runtime.getProperties", worker_thread, params) + variables = CommonUtils.get_variables_from_properties(response['result']['result'], 'local') + expected_variables = {'localArrayList': 'ArrayList', 'localBigInt64Array': 'BigInt64Array', + 'localBigUint64Array': 'BigUint64Array', 'localDataView': 'DataView(20)', + 'localDeque': 'Deque', 'localFloat32Array': 'Float32Array', + 'localFloat64Array': 'Float64Array', 'localHashMap': 'HashMap', 'localHashSet': 'HashSet', + 'localInt16Array': 'Int16Array(0)', 'localInt32Array': 'Int32Array(0)', + 'localInt8Array': 'Int8Array(0)', 'localLightWeightMap': 'LightWeightMap', + 'localLightWeightSet': 'LightWeightSet', 'localLinkedList': 'LinkedList', + 'localList': 'List', 'localMapIter': 'function entries( { [native code] }', + 'localNull': 'null', 'localPerson': 'Person', 'localPlainArray': 'PlainArray', + 'localPromise': 'Promise', 'localProxy': 'Proxy', 'localQueue': 'Queue', + 'localSendableClass': 'SendableClass[Sendable]', + 'localSharedArrayBuffer': 'SharedArrayBuffer(32)', 'localStack': 'Stack', + 'localTreeMap': 'TreeMap', 'localTreeSet': 'TreeSet', 'localUint16Array': 'Uint16Array', + 'localUint32Array': 'Uint32Array', 'localUint8Array': 'Uint8Array(3)', + 'localUint8ClampedArray': 'Uint8ClampedArray', 'localUndefined': 'undefined', + 'localWeakMap': 'WeakMap(0)', 'localWeakRef': 'WeakRef {}', 'localWeakSet': 'WeakSet(0)'} + self.common_utils.assert_equal(variables, expected_variables) + ################################################################################################################ + # worker thread: Runtime.getProperties + ################################################################################################################ + params = runtime.GetPropertiesParams('1') + response = await self.runtime_impl.send("Runtime.getProperties", worker_thread, params) + variables = CommonUtils.get_variables_from_properties(response['result']['result'], 'closure') + expected_variables = {'closureArray': 'Array(3)', 'closureArrayBuffer': 'Arraybuffer(20)', + 'closureMap': 'Map(0)', 'closureNum': '20', 'closureRegExp': '/^ab+c/g', + 'closureSet': "Set(1) {'closure'}", 'closureString': 'closure'} + self.common_utils.assert_equal(variables, expected_variables) + ################################################################################################################ + # worker thread: Runtime.getProperties + ################################################################################################################ + params = runtime.GetPropertiesParams('2') + response = await self.runtime_impl.send("Runtime.getProperties", worker_thread, params) + variables = CommonUtils.get_variables_from_properties(response['result']['result'], '') + expected_variables = {'ArrayList': 'function ArrayList( { [native code] }', + 'Deque': 'function Deque( { [native code] }', + 'HashMap': 'function HashMap( { [native code] }', + 'HashSet': 'function HashSet( { [native code] }', + 'LightWeightMap': 'function LightWeightMap( { [native code] }', + 'LightWeightSet': 'function LightWeightSet( { [native code] }', + 'LinkedList': 'function LinkedList( { [native code] }', + 'List': 'function List( { [native code] }', + 'PlainArray': 'function PlainArray( { [native code] }', + 'Queue': 'function Queue( { [native code] }', + 'Stack': 'function Stack( { [native code] }', + 'TreeMap': 'function TreeMap( { [native code] }', + 'TreeSet': 'function TreeSet( { [native code] }', 'worker': 'Object'} + self.common_utils.assert_equal(variables, expected_variables) + ################################################################################################################ + # worker thread: Runtime.getProperties + ################################################################################################################ + params = runtime.GetPropertiesParams('3') + response = await self.runtime_impl.send("Runtime.getProperties", worker_thread, params) + variables = CommonUtils.get_variables_from_properties(response['result']['result'], 'global') + expected_variables = {'globalArray': 'Array(3)', 'globalBigInt': '9007199254740991n', + 'globalBool': 'Boolean{[[PrimitiveValue]]: false}', + 'globalDate': 'Wed Aug 28 2024 02:41:00 GMT+0800', + 'globalNum': 'Number{[[PrimitiveValue]]: 20}', + 'globalObject': 'String{[[PrimitiveValue]]: globalObject}', + 'globalStr': 'String{[[PrimitiveValue]]: globalStr}', 'globalThis': 'Object'} + self.common_utils.assert_equal(variables, expected_variables) + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread) + ################################################################################################################ + # main thread: click on the screen + ################################################################################################################ + self.ui_utils.click_on_middle() + ################################################################################################################ + # worker thread: destroy instance + ################################################################################################################ + response = await self.debugger_impl.destroy_instance() + self.common_utils.assert_equal(response['instanceId'], worker_thread.instance_id) + ################################################################################################################ + # main thread: Debugger.disable + ################################################################################################################ + await self.debugger_impl.send("Debugger.disable", main_thread) + ################################################################################################################ + # close the websocket connections + ################################################################################################################ + await websocket.send_msg_to_debugger_server(main_thread.instance_id, main_thread.send_msg_queue, 'close') + await websocket.send_msg_to_connect_server('close') + ################################################################################################################ \ No newline at end of file diff --git a/test/autotest/testcases/toolchain/debug/TestWorkerLaunchAccelerate.json b/test/autotest/testcases/toolchain/debug/TestWorkerLaunchAccelerate.json new file mode 100644 index 00000000..c7f13277 --- /dev/null +++ b/test/autotest/testcases/toolchain/debug/TestWorkerLaunchAccelerate.json @@ -0,0 +1,15 @@ +{ + "description": "Config for TestWorkerLaunchAccelerate", + "environment": [ + { + "type": "device", + "label": "phone" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "toolchain/debug/TestWorkerLaunchAccelerate.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/testcases/toolchain/debug/TestWorkerLaunchAccelerate.py b/test/autotest/testcases/toolchain/debug/TestWorkerLaunchAccelerate.py new file mode 100644 index 00000000..916e3425 --- /dev/null +++ b/test/autotest/testcases/toolchain/debug/TestWorkerLaunchAccelerate.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Copyright (c) 2025 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +#================================================================== +#文 件 名: TestWorkerLaunchAccelerate.py +#文件说明: worker线程冷启性能优化测试 +#================================================================== +测试步骤: + 1. 连接 connect server 和主线程 debugger server + 2. 主线程使能 Runtime 和 Debugger,开始运行 + 3. 触发点击事件,连接子线程 debugger server + 4. 子线程使能 Runtime 和 Debugger + 5. 子线程设置所有断点(Debugger.saveAllPossibleBreakpoints) + 6. 子线程 scriptParsed 加载文件(Debugger.scriptPaused) + 7. 子线程多次 resume, 程序停在设置的断点处(Debugger.resume) + 8. 子线程在 params.ets 文件中设置断点(Debugger.getPossibleAndSetBreakpointsByUrl) + 9. 子线程 resume,命中断点(Debugger.resume) + 10. 子线程 resume(Debugger.resume) + 11. 关闭所有线程 debugger server 和 connect server 连接 +#!!================================================================ +""" +import sys +from pathlib import Path + +root_path = Path(__file__).parent.parent.parent.parent +resource_path = root_path / 'resource' +sys.path.append(str(root_path / 'aw')) # add aw path to sys.path + +from devicetest.core.test_case import TestCase, Step +from hypium import UiDriver +from all_utils import CommonUtils, UiUtils +from cdp import debugger +from implement_api import debugger_api, runtime_api + + +class TestWorkerLaunchAccelerate(TestCase): + def __init__(self, controllers): + self.TAG = self.__class__.__name__ + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + self.ui_utils = UiUtils(self.driver) + self.common_utils = CommonUtils(self.driver) + self.id_generator = CommonUtils.message_id_generator() + self.config = { + 'start_mode': '-D', + 'connect_server_port': 15646, + 'debugger_server_port': 15647, + 'bundle_name': 'com.example.multiWorker09', + 'hap_name': 'MultiWorker09.hap', + 'hap_path': str(resource_path / 'hap' / 'MultiWorker09.hap'), + 'file_path': { + 'entry_ability': 'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts', + 'params': 'entry|entry|1.0.0|src/main/ets/resources/Params.ts', + 'index': 'entry|entry|1.0.0|src/main/ets/pages/Index.ts', + 'sendable': 'entry|entry|1.0.0|src/main/ets/resources/Sendable.ts', + 'person': 'entry|entry|1.0.0|src/main/ets/resources/Person.ts', + 'drop_frame': 'entry|entry|1.0.0|src/main/ets/resources/DropFrame.ts', + 'step': 'entry|entry|1.0.0|src/main/ets/resources/Step.ts', + 'calculate': 'entry|entry|1.0.0|src/main/ets/resources/Calculate.ts', + 'sleep': 'entry|entry|1.0.0|src/main/ets/resources/Sleep.ts', + 'worker': 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts' + } + } + + def setup(self): + Step('1.下载应用') + self.driver.install_app(self.config['hap_path'], "-r") + Step('2.启动应用') + self.driver.start_app(package_name=self.config['bundle_name'], params=self.config['start_mode']) + self.config['pid'] = self.common_utils.get_pid(self.config['bundle_name']) + assert self.config['pid'] != 0, f'Failed to get pid of {self.config["bundle_name"]}' + Step('3.设置屏幕常亮') + self.ui_utils.keep_awake() + Step('4.端口映射,连接server') + self.common_utils.connect_server(self.config) + self.debugger_impl = debugger_api.DebuggerImpl(self.id_generator, self.config['websocket']) + self.runtime_impl = runtime_api.RuntimeImpl(self.id_generator, self.config['websocket']) + + def process(self): + Step('5.执行测试用例') + websocket = self.config['websocket'] + taskpool = self.config['taskpool'] + taskpool.submit(websocket.main_task(taskpool, self.test, self.config['pid'])) + taskpool.await_taskpool() + taskpool.task_join() + if taskpool.task_exception: + raise taskpool.task_exception + + def teardown(self): + Step('6.关闭应用') + self.driver.stop_app(self.config['bundle_name']) + Step('7.卸载应用') + self.driver.uninstall_app(self.config['bundle_name']) + + async def test(self, websocket): + ################################################################################################################ + # main thread: connect the debugger server + ################################################################################################################- + main_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], True) + ################################################################################################################ + # main thread: Runtime.enable + ################################################################################################################ + await self.runtime_impl.send("Runtime.enable", main_thread) + ################################################################################################################ + # main thread: Debugger.enable + ################################################################################################################ + await self.debugger_impl.send("Debugger.enable", main_thread, debugger.EnableAccelerateLaunchParams()) + ################################################################################################################ + # main thread: Debugger.saveAllPossibleBreakpoints + ################################################################################################################ + params = debugger.SaveAllPossibleBreakpointsParams({}) + await self.debugger_impl.send("Debugger.saveAllPossibleBreakpoints", main_thread, params) + ################################################################################################################ + # main thread: Runtime.runIfWaitingForDebugger + ################################################################################################################ + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", main_thread) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['entry_ability']) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['sendable']) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['person']) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['params']) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['drop_frame']) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['calculate']) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['step']) + ################################################################################################################ + # main thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['index']) + ################################################################################################################ + # main thread: click on the screen + ################################################################################################################ + self.ui_utils.click_on_middle() + ################################################################################################################ + # worker thread: connect the debugger server + ################################################################################################################- + worker_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], False) + ################################################################################################################ + # worker thread: Runtime.enable + ################################################################################################################ + await self.runtime_impl.send("Runtime.enable", worker_thread) + ################################################################################################################ + # worker thread: Debugger.enable + ################################################################################################################ + await self.debugger_impl.send("Debugger.enable", worker_thread, debugger.EnableAccelerateLaunchParams()) + ################################################################################################################ + # worker thread: Debugger.saveAllPossibleBreakpoints + ################################################################################################################ + locations = { + self.config['file_path']['step']: [3], + self.config['file_path']['worker']: [15, 17, 1000], + self.config['file_path']['params']: [77, 79, 83] + } + params = debugger.SaveAllPossibleBreakpointsParams(locations) + await self.debugger_impl.send("Debugger.saveAllPossibleBreakpoints", worker_thread, params) + ################################################################################################################ + # worker thread: Runtime.runIfWaitingForDebugger + ################################################################################################################ + await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", worker_thread) + ################################################################################################################ + # worker thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['sendable']) + ################################################################################################################ + # worker thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['person']) + ################################################################################################################ + # worker thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['params']) + ################################################################################################################ + # worker thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['drop_frame']) + ################################################################################################################ + # worker thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['calculate']) + ################################################################################################################ + # worker thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['step']) + ################################################################################################################ + # worker thread: Debugger.scriptParsed + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) + self.common_utils.assert_equal(response['params']['url'], self.config['file_path']['worker']) + ################################################################################################################ + # worker thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", worker_thread) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:15:4:' + self.config['file_path']['worker']]) + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread) + ################################################################################################################ + # worker thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", worker_thread) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:3:19:' + self.config['file_path']['step']]) + ################################################################################################################ + # worker thread: Debugger.removeBreakpointsByUrl + ################################################################################################################ + params = debugger.RemoveBreakpointsUrl(self.config['file_path']['step']) + await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", worker_thread, params) + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread) + ################################################################################################################ + # worker thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", worker_thread) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:17:4:' + self.config['file_path']['worker']]) + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread) + ################################################################################################################ + # worker thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", worker_thread) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:77:4:' + self.config['file_path']['params']]) + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread) + ################################################################################################################ + # worker thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", worker_thread) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:79:4:' + self.config['file_path']['params']]) + ################################################################################################################ + # worker thread: Debugger.removeBreakpointsByUrl + ################################################################################################################ + params = debugger.RemoveBreakpointsUrl(self.config['file_path']['params']) + await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", worker_thread, params) + ################################################################################################################ + # worker thread: Debugger.getPossibleAndSetBreakpointByUrl + ################################################################################################################ + locations = [debugger.BreakLocationUrl(url=self.config['file_path']['params'], line_number=84)] + params = debugger.SetBreakpointsLocations(locations) + response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", worker_thread, params) + result_locations = response['result']['locations'] + self.common_utils.assert_equal(result_locations[0]['id'], 'id:84:0:' + self.config['file_path']['params']) + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread) + ################################################################################################################ + # worker thread: Debugger.paused + ################################################################################################################ + response = await self.debugger_impl.recv("Debugger.paused", worker_thread) + self.common_utils.assert_equal(response['params']['hitBreakpoints'], + ['id:84:4:' + self.config['file_path']['params']]) + ################################################################################################################ + # worker thread: Debugger.resume + ################################################################################################################ + await self.debugger_impl.send("Debugger.resume", worker_thread) + ################################################################################################################ + # worker thread: Debugger.disable + ################################################################################################################ + await self.debugger_impl.send("Debugger.disable", worker_thread) + ################################################################################################################ + # main thread: Debugger.disable + ################################################################################################################ + await self.debugger_impl.send("Debugger.disable", main_thread) + ################################################################################################################ + # close the websocket connections + ################################################################################################################ + await websocket.send_msg_to_debugger_server(worker_thread.instance_id, worker_thread.send_msg_queue, 'close') + await websocket.send_msg_to_debugger_server(main_thread.instance_id, main_thread.send_msg_queue, 'close') + await websocket.send_msg_to_connect_server('close') + ################################################################################################################ \ No newline at end of file -- Gitee