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(60) 34class TestTaskPool: 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 Index.ets 54 @Concurrent 55 function add(args1, args2) { 56 return args1 + args2 57 } 58 @Concurrent 59 function sub(args1, args2) { 60 return args1 - args2 61 } 62 let taskAdd = new taskpool.Task(add, 200, 100) 63 let taskSub = new taskpool.Task(sub, 200, 100) 64 async function taskpoolTest() { 65 let valueAdd = await taskpool.execute(taskAdd) 66 let valueSub = await taskpool.execute(taskSub) 67 } 68 .OnClick(() => { 69 taskpoolTest() 70 }) 71 """ 72 73 def setup_method(self): 74 logging.info('Start running TestTaskPool: setup') 75 76 self.log_path = rf'{os.path.dirname(__file__)}\..\log' 77 self.hilog_file_name = 'test_task_pool.hilog.txt' 78 self.id_generator = Utils.message_id_generator() 79 80 # receive the hilog before the test start 81 Utils.clear_fault_log() 82 self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path, 83 file_name=self.hilog_file_name, 84 debug_on=True) 85 86 def teardown_method(self): 87 Application.uninstall(self.config['bundle_name']) 88 89 # terminate the hilog receive process after the test done 90 time.sleep(3) 91 self.hilog_process.stdout.close() 92 self.hilog_process.terminate() 93 self.hilog_process.wait() 94 self.write_thread.join() 95 96 Utils.save_fault_log(log_path=self.log_path) 97 logging.info('TestTaskPool done') 98 99 def test(self, test_suite_taskpool_01_debug): 100 logging.info('Start running TestTaskPool: test') 101 self.config = test_suite_taskpool_01_debug 102 websocket = self.config['websocket'] 103 taskpool = self.config['taskpool'] 104 pid = self.config['pid'] 105 self.debugger_impl = debugger_api.DebuggerImpl(self.id_generator, websocket) 106 self.runtime_impl = runtime_api.RuntimeImpl(self.id_generator, websocket) 107 108 taskpool.submit(websocket.main_task(taskpool, self.procedure, pid)) 109 taskpool.await_taskpool() 110 taskpool.task_join() 111 if taskpool.task_exception: 112 raise taskpool.task_exception 113 114 async def procedure(self, websocket): 115 ################################################################################################################ 116 # main thread: connect the debugger server 117 ################################################################################################################ 118 main_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], True) 119 logging.info(f'Connect to the debugger server of instance: {main_thread.instance_id}') 120 ################################################################################################################ 121 # main thread: Runtime.enable 122 ################################################################################################################ 123 await self.runtime_impl.send("Runtime.enable", main_thread) 124 ################################################################################################################ 125 # main thread: Debugger.enable 126 ################################################################################################################ 127 await self.debugger_impl.send("Debugger.enable", main_thread) 128 ################################################################################################################ 129 # main thread: Runtime.runIfWaitingForDebugger 130 ################################################################################################################ 131 await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", main_thread) 132 ################################################################################################################ 133 # main thread: Debugger.scriptParsed 134 ################################################################################################################ 135 response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) 136 assert response['params']['url'] == self.config['file_path']['entry_ability'] 137 assert response['params']['endLine'] == 0 138 ################################################################################################################ 139 # main thread: Debugger.paused 140 ################################################################################################################ 141 response = await self.debugger_impl.recv("Debugger.paused", main_thread) 142 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['entry_ability'] 143 assert response['params']['reason'] == 'Break on start' 144 ################################################################################################################ 145 # main thread: Debugger.resume 146 ################################################################################################################ 147 await self.debugger_impl.send("Debugger.resume", main_thread) 148 ################################################################################################################ 149 # main thread: Debugger.scriptParsed 150 ################################################################################################################ 151 response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread) 152 assert response['params']['url'] == self.config['file_path']['index'] 153 assert response['params']['endLine'] == 0 154 ################################################################################################################ 155 # main thread: Debugger.paused 156 ################################################################################################################ 157 response = await self.debugger_impl.recv("Debugger.paused", main_thread) 158 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 159 assert response['params']['reason'] == 'Break on start' 160 ################################################################################################################ 161 # main thread: Debugger.resume 162 ################################################################################################################ 163 await self.debugger_impl.send("Debugger.resume", main_thread) 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 ################################################################################################################ 182 # main thread: Debugger.removeBreakpointsByUrl 183 ################################################################################################################ 184 params = debugger.RemoveBreakpointsUrl(self.config['file_path']['index']) 185 await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", main_thread, params) 186 ################################################################################################################ 187 # main thread: Debugger.getPossibleAndSetBreakpointByUrl 188 ################################################################################################################ 189 locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=10), 190 debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=17), 191 debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=25)] 192 params = debugger.SetBreakpointsLocations(locations) 193 response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", 194 main_thread, params) 195 assert response['result']['locations'][0]['id'] == 'id:10:0:' + self.config['file_path']['index'] 196 assert response['result']['locations'][1]['id'] == 'id:17:0:' + self.config['file_path']['index'] 197 assert response['result']['locations'][2]['id'] == 'id:25:0:' + self.config['file_path']['index'] 198 ################################################################################################################ 199 # main thread: click on the screen 200 ################################################################################################################ 201 Application.click_on_middle() 202 ################################################################################################################ 203 # worker thread: Debugger.scriptParsed 204 ################################################################################################################ 205 response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread) 206 assert response['params']['url'] == self.config['file_path']['index'] 207 assert response['params']['endLine'] == 0 208 # worker thread: Debugger.paused 209 response = await self.debugger_impl.recv("Debugger.paused", worker_thread) 210 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 211 assert response['params']['reason'] == 'Break on start' 212 ################################################################################################################ 213 # worker thread: Debugger.removeBreakpointsByUrl 214 ################################################################################################################ 215 params = debugger.RemoveBreakpointsUrl(self.config['file_path']['index']) 216 await self.debugger_impl.send("Debugger.removeBreakpointsByUrl", worker_thread, params) 217 ################################################################################################################ 218 # worker thread: Debugger.getPossibleAndSetBreakpointByUrl 219 ################################################################################################################ 220 locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=10), 221 debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=17), 222 debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=25)] 223 params = debugger.SetBreakpointsLocations(locations) 224 response = await self.debugger_impl.send("Debugger.getPossibleAndSetBreakpointsByUrl", 225 worker_thread, params) 226 assert response['result']['locations'][0]['id'] == 'id:10:0:' + self.config['file_path']['index'] 227 assert response['result']['locations'][1]['id'] == 'id:17:0:' + self.config['file_path']['index'] 228 assert response['result']['locations'][2]['id'] == 'id:25:0:' + self.config['file_path']['index'] 229 ################################################################################################################ 230 # worker thread: Debugger.resume 231 ################################################################################################################ 232 await self.debugger_impl.send("Debugger.resume", worker_thread) 233 # worker thread: Debugger.paused 234 response = await self.debugger_impl.recv("Debugger.paused", worker_thread) 235 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 236 assert response['params']['reason'] == 'other' 237 assert response['params']['hitBreakpoints'] == ['id:10:14:' + self.config['file_path']['index']] 238 ################################################################################################################ 239 # worker thread: Runtime.getProperties 240 ################################################################################################################ 241 params = runtime.GetPropertiesParams('0') 242 response = await self.runtime_impl.send("Runtime.getProperties", worker_thread, params) 243 assert response['result']['result'][0]['name'] == 'add' 244 assert response['result']['result'][0]['value']['type'] == 'function' 245 ################################################################################################################ 246 # worker thread: Debugger.stepOut 247 ################################################################################################################ 248 await self.debugger_impl.send("Debugger.stepOut", worker_thread) 249 ################################################################################################################ 250 # main thread: Debugger.paused, hit breakpoint 251 ################################################################################################################ 252 response = await self.debugger_impl.recv("Debugger.paused", main_thread) 253 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 254 assert response['params']['hitBreakpoints'] == ['id:25:4:' + self.config['file_path']['index']] 255 ################################################################################################################ 256 # main thread: Runtime.getProperties 257 ################################################################################################################ 258 params = runtime.GetPropertiesParams('0') 259 response = await self.runtime_impl.send("Runtime.getProperties", main_thread, params) 260 assert response['result']['result'][0]['name'] == 'taskpoolTest' 261 assert response['result']['result'][0]['value']['type'] == 'function' 262 assert response['result']['result'][1]['name'] == 'valueSub' 263 assert response['result']['result'][1]['value']['type'] == 'undefined' 264 assert response['result']['result'][2]['name'] == 'valueAdd' 265 assert response['result']['result'][2]['value']['type'] == 'number' 266 assert response['result']['result'][2]['value']['description'] == '300' 267 ################################################################################################################ 268 # main thread: Debugger.resume 269 ################################################################################################################ 270 await self.debugger_impl.send("Debugger.resume", main_thread) 271 ################################################################################################################ 272 # worker thread: Debugger.paused 273 ################################################################################################################ 274 response = await self.debugger_impl.recv("Debugger.paused", worker_thread) 275 assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index'] 276 assert response['params']['hitBreakpoints'] == ['id:17:14:' + self.config['file_path']['index']] 277 ################################################################################################################ 278 # worker thread: Debugger.resume 279 ################################################################################################################ 280 await self.debugger_impl.send("Debugger.resume", worker_thread) 281 ################################################################################################################ 282 # worker thread: Debugger.disable 283 ################################################################################################################ 284 await self.debugger_impl.send("Debugger.disable", worker_thread) 285 ################################################################################################################ 286 # main thread: Debugger.disable 287 ################################################################################################################ 288 await self.debugger_impl.send("Debugger.disable", main_thread) 289 ################################################################################################################ 290 # close the websocket connections 291 ################################################################################################################ 292 await websocket.send_msg_to_debugger_server(worker_thread.instance_id, worker_thread.send_msg_queue, 'close') 293 await websocket.send_msg_to_debugger_server(main_thread.instance_id, main_thread.send_msg_queue, 'close') 294 await websocket.send_msg_to_connect_server('close') 295 ################################################################################################################