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 import debugger, runtime 29from aw.api import debugger_api, runtime_api 30 31 32@pytest.mark.debug 33@pytest.mark.timeout(30) 34class TestDebug03: 35 """ 36 测试用例:多 task 实例 debug 调试 37 测试步骤: 38 1. 连接 connect server 和主线程 debugger server 39 2. 主线程使能 Runtime 和 Debugger 40 3. 连接子线程 debugger server,用于执行 task 任务 41 4. 子线程使能 Runtime 和 Debugger 42 5. 主线程 Index.ts 文件设置断点(Debugger.getPossibleAndSetBreakpointByUrl) 43 6. 触发点击事件,主线程命中断点 44 7. 子线程 Index.ts 文件设置断点(Debugger.getPossibleAndSetBreakpointByUrl) 45 8. 子线程 resume,命中断点(Debugger.resume) 46 9. 子线程 getProperties,返回给定对象的属性(Runtime.getProperties) 47 10. 子线程 stepOut,主线程命中断点(Debugger.stepOut) 48 11. 主线程 getProperties(Runtime.getProperties) 49 12. 主线程 resume(Debugger.resume) 50 13. 子线程命中断点后 resume(Debugger.resume) 51 14. 关闭所有线程 debugger server 和 connect server 连接 52 """ 53 54 def setup_method(self): 55 logging.info('Start running TestDebug03: setup') 56 57 self.log_path = rf'{os.path.dirname(__file__)}\..\log' 58 self.hilog_file_name = 'test_debug_03.hilog.txt' 59 self.id_generator = Utils.message_id_generator() 60 61 # receive the hilog before the test start 62 Utils.clear_fault_log() 63 self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path, 64 file_name=self.hilog_file_name, 65 debug_on=True) 66 67 def teardown_method(self): 68 Application.uninstall(self.config['bundle_name']) 69 70 # terminate the hilog receive process after the test done 71 time.sleep(3) 72 self.hilog_process.stdout.close() 73 self.hilog_process.terminate() 74 self.hilog_process.wait() 75 self.write_thread.join() 76 77 Utils.save_fault_log(log_path=self.log_path) 78 logging.info('TestDebug03 done') 79 80 def test(self, test_suite_taskpool_01_debug): 81 logging.info('Start running TestDebug03: test') 82 self.config = test_suite_taskpool_01_debug 83 websocket = self.config['websocket'] 84 taskpool = self.config['taskpool'] 85 pid = self.config['pid'] 86 self.debugger_impl = debugger_api.DebuggerImpl(self.id_generator, websocket) 87 self.runtime_impl = runtime_api.RuntimeImpl(self.id_generator, websocket) 88 89 taskpool.submit(websocket.main_task(taskpool, self.procedure, pid)) 90 taskpool.await_taskpool() 91 taskpool.task_join() 92 if taskpool.task_exception: 93 raise taskpool.task_exception 94 95 async def procedure(self, websocket): 96 ################################################################################################################ 97 # main thread: connect the debugger server 98 ################################################################################################################ 99 main_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], True) 100 logging.info(f'Connect to the debugger server of instance: {main_thread.instance_id}') 101 ################################################################################################################ 102 # main thread: Runtime.enable 103 ################################################################################################################ 104 await self.runtime_impl.send("Runtime.enable", main_thread) 105 ################################################################################################################ 106 # main thread: Debugger.enable 107 ################################################################################################################ 108 await self.debugger_impl.send("Debugger.enable", main_thread) 109 ################################################################################################################ 110 # main thread: Runtime.runIfWaitingForDebugger 111 ################################################################################################################ 112 await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", main_thread) 113 ################################################################################################################ 114 # main thread: Debugger.scriptParsed 115 ################################################################################################################ 116 response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) 117 assert response['params']['url'] == self.config['file_path']['entry_ability'] 118 assert response['params']['endLine'] == 0 119 ################################################################################################################ 120 # main thread: Debugger.paused 121 ################################################################################################################ 122 response = await self.debugger_impl.recv("Debugger.paused", main_thread) 123 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['entry_ability'] 124 assert response['params']['reason'] == 'Break on start' 125 ################################################################################################################ 126 # main thread: Debugger.resume 127 ################################################################################################################ 128 await self.debugger_impl.send("Debugger.resume", main_thread) 129 ################################################################################################################ 130 # main thread: Debugger.scriptParsed 131 ################################################################################################################ 132 response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) 133 assert response['params']['url'] == self.config['file_path']['index'] 134 assert response['params']['endLine'] == 0 135 ################################################################################################################ 136 # main thread: Debugger.paused 137 ################################################################################################################ 138 response = await self.debugger_impl.recv("Debugger.paused", main_thread) 139 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 140 assert response['params']['reason'] == 'Break on start' 141 ################################################################################################################ 142 # main thread: Debugger.resume 143 ################################################################################################################ 144 await self.debugger_impl.send("Debugger.resume", main_thread) 145 ################################################################################################################ 146 # worker thread: connect the debugger server 147 ################################################################################################################ 148 worker_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], False) 149 logging.info(f'Connect to the debugger server of instance: {worker_thread.instance_id}') 150 ################################################################################################################ 151 # worker thread: Runtime.enable 152 ################################################################################################################ 153 await self.runtime_impl.send("Runtime.enable", worker_thread) 154 ################################################################################################################ 155 # worker thread: Debugger.enable 156 ################################################################################################################ 157 await self.debugger_impl.send("Debugger.enable", worker_thread) 158 ################################################################################################################ 159 # worker thread: Runtime.runIfWaitingForDebugger 160 ################################################################################################################ 161 await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", worker_thread) 162 ################################################################################################################ 163 # main thread: Debugger.removeBreakpointsByUrl 164 ################################################################################################################ 165 params = debugger.RemoveBreakpointsUrl(self.config['file_path']['index']) 166 await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", main_thread, params) 167 ################################################################################################################ 168 # main thread: Debugger.getPossibleAndSetBreakpointByUrl 169 ################################################################################################################ 170 locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=10), 171 debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=17), 172 debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=25)] 173 params = debugger.SetBreakpointsLocations(locations) 174 response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", 175 main_thread, params) 176 assert response['result']['locations'][0]['id'] == 'id:10:0:' + self.config['file_path']['index'] 177 assert response['result']['locations'][1]['id'] == 'id:17:0:' + self.config['file_path']['index'] 178 assert response['result']['locations'][2]['id'] == 'id:25:0:' + self.config['file_path']['index'] 179 ################################################################################################################ 180 # main thread: click on the screen 181 ################################################################################################################ 182 Application.click_on_middle() 183 ################################################################################################################ 184 # worker thread: Debugger.scriptParsed 185 ################################################################################################################ 186 response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) 187 assert response['params']['url'] == self.config['file_path']['index'] 188 assert response['params']['endLine'] == 0 189 # worker thread: Debugger.paused 190 response = await self.debugger_impl.recv("Debugger.paused", worker_thread) 191 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 192 assert response['params']['reason'] == 'Break on start' 193 ################################################################################################################ 194 # worker thread: Debugger.removeBreakpointsByUrl 195 ################################################################################################################ 196 params = debugger.RemoveBreakpointsUrl(self.config['file_path']['index']) 197 await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", worker_thread, params) 198 ################################################################################################################ 199 # worker thread: Debugger.getPossibleAndSetBreakpointByUrl 200 ################################################################################################################ 201 locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=10), 202 debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=17), 203 debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=25)] 204 params = debugger.SetBreakpointsLocations(locations) 205 response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", 206 worker_thread, params) 207 assert response['result']['locations'][0]['id'] == 'id:10:0:' + self.config['file_path']['index'] 208 assert response['result']['locations'][1]['id'] == 'id:17:0:' + self.config['file_path']['index'] 209 assert response['result']['locations'][2]['id'] == 'id:25:0:' + self.config['file_path']['index'] 210 ################################################################################################################ 211 # worker thread: Debugger.resume 212 ################################################################################################################ 213 await self.debugger_impl.send("Debugger.resume", worker_thread) 214 # worker thread: Debugger.paused 215 response = await self.debugger_impl.recv("Debugger.paused", worker_thread) 216 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 217 assert response['params']['reason'] == 'other' 218 assert response['params']['hitBreakpoints'] == ['id:10:14:' + self.config['file_path']['index']] 219 ################################################################################################################ 220 # worker thread: Runtime.getProperties 221 ################################################################################################################ 222 params = runtime.GetPropertiesParams('0') 223 response = await self.runtime_impl.send("Runtime.getProperties", worker_thread, params) 224 assert response['result']['result'][0]['name'] == 'add' 225 assert response['result']['result'][0]['value']['type'] == 'function' 226 ################################################################################################################ 227 # worker thread: Debugger.stepOut 228 ################################################################################################################ 229 await self.debugger_impl.send("Debugger.stepOut", worker_thread) 230 ################################################################################################################ 231 # main thread: Debugger.paused, hit breakpoint 232 ################################################################################################################ 233 response = await self.debugger_impl.recv("Debugger.paused", main_thread) 234 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 235 assert response['params']['hitBreakpoints'] == ['id:25:4:' + self.config['file_path']['index']] 236 ################################################################################################################ 237 # main thread: Runtime.getProperties 238 ################################################################################################################ 239 params = runtime.GetPropertiesParams('0') 240 response = await self.runtime_impl.send("Runtime.getProperties", main_thread, params) 241 assert response['result']['result'][0]['name'] == 'taskpoolTest' 242 assert response['result']['result'][0]['value']['type'] == 'function' 243 assert response['result']['result'][1]['name'] == 'valueSub' 244 assert response['result']['result'][1]['value']['type'] == 'undefined' 245 assert response['result']['result'][2]['name'] == 'valueAdd' 246 assert response['result']['result'][2]['value']['type'] == 'number' 247 assert response['result']['result'][2]['value']['description'] == '300' 248 ################################################################################################################ 249 # main thread: Debugger.resume 250 ################################################################################################################ 251 await self.debugger_impl.send("Debugger.resume", main_thread) 252 ################################################################################################################ 253 # worker thread: Debugger.paused 254 ################################################################################################################ 255 response = await self.debugger_impl.recv("Debugger.paused", worker_thread) 256 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 257 assert response['params']['hitBreakpoints'] == ['id:17:14:' + self.config['file_path']['index']] 258 ################################################################################################################ 259 # worker thread: Debugger.resume 260 ################################################################################################################ 261 await self.debugger_impl.send("Debugger.resume", worker_thread) 262 ################################################################################################################ 263 # worker thread: Debugger.disable 264 ################################################################################################################ 265 await self.debugger_impl.send("Debugger.disable", worker_thread) 266 ################################################################################################################ 267 # main thread: Debugger.disable 268 ################################################################################################################ 269 await self.debugger_impl.send("Debugger.disable", main_thread) 270 ################################################################################################################ 271 # close the websocket connections 272 ################################################################################################################ 273 await websocket.send_msg_to_debugger_server(worker_thread.instance_id, worker_thread.send_msg_queue, 'close') 274 await websocket.send_msg_to_debugger_server(main_thread.instance_id, main_thread.send_msg_queue, 'close') 275 await websocket.send_msg_to_connect_server('close') 276 ################################################################################################################