1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3""" 4Copyright (c) 2024 Huawei Device Co., Ltd. 5Licensed under the Apache License, Version 2.0 (the "License"); 6you may not use this file except in compliance with the License. 7You may obtain a copy of the License at 8 9 http://www.apache.org/licenses/LICENSE-2.0 10 11Unless required by applicable law or agreed to in writing, software 12distributed under the License is distributed on an "AS IS" BASIS, 13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14See the License for the specific language governing permissions and 15limitations under the License. 16 17Description: Scenario test case. 18""" 19 20import logging 21import os 22import time 23 24import pytest 25 26from aw import Application 27from aw import Utils 28from aw.api import debugger_api, runtime_api 29 30 31@pytest.mark.debug 32@pytest.mark.timeout(60) 33class TestWorkerDebuggerPause: 34 """ 35 测试用例:多实例 debug 暂停恢复调试 36 测试步骤: 37 1. 连接 connect server 和主线程 debugger server 38 2. 主线程使能 Runtime 和 Debugger 39 3. 主线程 resume(Debugger.resume) 40 4. 触发点击事件,创建子线程,连接子线程 debugger server 41 5. 子线程使能 Runtime 和 Debugger 42 6. 子线程 resume,停在 debugger代码处(Debugger.resume) 43 7. 子线程 resume,所有线程等待2秒(Debugger.resume) 44 8. 暂停子线程(Debugger.pause) 45 9. 再次恢复子线程(Debugger.resume) 46 10. 子线程去使能 debugger(Debugger.disable) 47 11. 暂停主线程(Debugger.pause) 48 12. 再次恢复主线程(Debugger.resume) 49 13. 主线程去使能 debugger(Debugger.disable) 50 14. 关闭所有线程 debugger server 和 connect server 连接 51 关键代码: 52 Index.ets 53 .OnClick(() => { 54 let myWorker = new worker.ThreadWorker("entry/ets/workers/Worker.ets") 55 myWorker.postMessage("hello world") 56 const start = Date.now() 57 while (Date.now() - start < 10000) {} 58 }) 59 Worker.ets 60 const workerPort: ThreadWorkerGlobalScope = worker.workerPort; 61 workerPort.onmessage = (e: MessageEvents) => { 62 workerPort.postMessage(e.data) 63 debugger 64 const start = Date.now() 65 while (Date.now() - start < 10000) {} 66 } 67 """ 68 69 def setup_method(self): 70 logging.info('Start running TestWorkerDebuggerPause: setup') 71 72 self.log_path = rf'{os.path.dirname(__file__)}\..\log' 73 self.hilog_file_name = 'test_worker_debugger_pause.hilog.txt' 74 self.id_generator = Utils.message_id_generator() 75 76 # receive the hilog before the test start 77 Utils.clear_fault_log() 78 self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path, 79 file_name=self.hilog_file_name, 80 debug_on=True) 81 82 def teardown_method(self): 83 Application.uninstall(self.config['bundle_name']) 84 85 # terminate the hilog receive process after the test done 86 time.sleep(3) 87 self.hilog_process.stdout.close() 88 self.hilog_process.terminate() 89 self.hilog_process.wait() 90 self.write_thread.join() 91 92 Utils.save_fault_log(log_path=self.log_path) 93 logging.info('TestWorkerDebuggerPause done') 94 95 def test(self, test_suite_worker_05_debug): 96 logging.info('Start running TestWorkerDebuggerPause: test') 97 self.config = test_suite_worker_05_debug 98 websocket = self.config['websocket'] 99 taskpool = self.config['taskpool'] 100 pid = self.config['pid'] 101 self.debugger_impl = debugger_api.DebuggerImpl(self.id_generator, websocket) 102 self.runtime_impl = runtime_api.RuntimeImpl(self.id_generator, websocket) 103 104 taskpool.submit(websocket.main_task(taskpool, self.procedure, pid)) 105 taskpool.await_taskpool() 106 taskpool.task_join() 107 if taskpool.task_exception: 108 raise taskpool.task_exception 109 110 async def procedure(self, websocket): 111 ################################################################################################################ 112 # main thread: connect the debugger server 113 ################################################################################################################ 114 main_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], True) 115 logging.info(f'Connect to the debugger server of instance: {main_thread.instance_id}') 116 ################################################################################################################ 117 # main thread: Runtime.enable 118 ################################################################################################################ 119 await self.runtime_impl.send("Runtime.enable", main_thread) 120 ################################################################################################################ 121 # main thread: Debugger.enable 122 ################################################################################################################ 123 await self.debugger_impl.send("Debugger.enable", main_thread) 124 ################################################################################################################ 125 # main thread: Runtime.runIfWaitingForDebugger 126 ################################################################################################################ 127 await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", main_thread) 128 ################################################################################################################ 129 # main thread: Debugger.scriptParsed 130 ################################################################################################################ 131 response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) 132 assert response['params']['url'] == self.config['file_path']['entry_ability'] 133 assert response['params']['endLine'] == 0 134 ################################################################################################################ 135 # main thread: Debugger.paused 136 ################################################################################################################ 137 response = await self.debugger_impl.recv("Debugger.paused", main_thread) 138 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['entry_ability'] 139 assert response['params']['reason'] == 'Break on start' 140 ################################################################################################################ 141 # main thread: Debugger.resume 142 ################################################################################################################ 143 await self.debugger_impl.send("Debugger.resume", main_thread) 144 ################################################################################################################ 145 # main thread: Debugger.scriptParsed 146 ################################################################################################################ 147 response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) 148 assert response['params']['url'] == self.config['file_path']['index'] 149 assert response['params']['endLine'] == 0 150 ################################################################################################################ 151 # main thread: Debugger.paused 152 ################################################################################################################ 153 response = await self.debugger_impl.recv("Debugger.paused", main_thread) 154 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 155 assert response['params']['reason'] == 'Break on start' 156 ################################################################################################################ 157 # main thread: Debugger.resume 158 ################################################################################################################ 159 await self.debugger_impl.send("Debugger.resume", main_thread) 160 ################################################################################################################ 161 # main thread: click on the screen 162 ################################################################################################################ 163 Application.click_on_middle() 164 ################################################################################################################ 165 # worker thread: connect the debugger server 166 ################################################################################################################ 167 worker_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], False) 168 logging.info(f'Connect to the debugger server of instance: {worker_thread.instance_id}') 169 ################################################################################################################ 170 # worker thread: Runtime.enable 171 ################################################################################################################ 172 await self.runtime_impl.send("Runtime.enable", worker_thread) 173 ################################################################################################################ 174 # worker thread: Debugger.enable 175 ################################################################################################################ 176 await self.debugger_impl.send("Debugger.enable", worker_thread) 177 ################################################################################################################ 178 # worker thread: Runtime.runIfWaitingForDebugger 179 ################################################################################################################ 180 await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", worker_thread) 181 # worker thread: Debugger.scriptParsed 182 response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) 183 assert response['params']['url'] == self.config['file_path']['worker'] 184 assert response['params']['endLine'] == 0 185 # worker thread: Debugger.paused 186 response = await self.debugger_impl.recv("Debugger.paused", worker_thread) 187 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker'] 188 assert response['params']['reason'] == 'Break on start' 189 ################################################################################################################ 190 # worker thread: Debugger.resume 191 ################################################################################################################ 192 await self.debugger_impl.send("Debugger.resume", worker_thread) 193 # worker thread: Debugger.paused 194 response = await self.debugger_impl.recv("Debugger.paused", worker_thread) 195 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker'] 196 assert response['params']['reason'] == 'other' 197 assert response['params']['hitBreakpoints'] == ['id:0:0:'] 198 ################################################################################################################ 199 # worker thread: Debugger.resume 200 ################################################################################################################ 201 await self.debugger_impl.send("Debugger.resume", worker_thread) 202 ################################################################################################################ 203 # all thread: sleep 2 seconds 204 ################################################################################################################ 205 time.sleep(2) 206 ################################################################################################################ 207 # worker thread: Debugger.pause 208 ################################################################################################################ 209 await self.debugger_impl.send("Debugger.pause", worker_thread) 210 # worker thread: Debugger.paused 211 response = await self.debugger_impl.recv("Debugger.paused", worker_thread) 212 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker'] 213 assert response['params']['reason'] == 'other' 214 assert response['params']['hitBreakpoints'] == [] 215 ################################################################################################################ 216 # worker thread: Debugger.resume 217 ################################################################################################################ 218 await self.debugger_impl.send("Debugger.resume", worker_thread) 219 ################################################################################################################ 220 # worker thread: Debugger.disable 221 ################################################################################################################ 222 await self.debugger_impl.send("Debugger.disable", worker_thread) 223 ################################################################################################################ 224 # main thread: Debugger.pause 225 ################################################################################################################ 226 await self.debugger_impl.send("Debugger.pause", main_thread) 227 # main thread: Debugger.paused 228 response = await self.debugger_impl.recv("Debugger.paused", main_thread) 229 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 230 assert response['params']['reason'] == 'other' 231 assert response['params']['hitBreakpoints'] == [] 232 ################################################################################################################ 233 # main thread: Debugger.resume 234 ################################################################################################################ 235 await self.debugger_impl.send("Debugger.resume", main_thread) 236 ################################################################################################################ 237 # main thread: Debugger.disable 238 ################################################################################################################ 239 await self.debugger_impl.send("Debugger.disable", main_thread) 240 ################################################################################################################ 241 # close the websocket connections 242 ################################################################################################################ 243 await websocket.send_msg_to_debugger_server(worker_thread.instance_id, worker_thread.send_msg_queue, 'close') 244 await websocket.send_msg_to_debugger_server(main_thread.instance_id, main_thread.send_msg_queue, 'close') 245 await websocket.send_msg_to_connect_server('close') 246 ################################################################################################################