• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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        ################################################################################################################