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