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