• 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.api import debugger_api, runtime_api
29
30
31@pytest.mark.debug
32@pytest.mark.timeout(60)
33class TestWorkerDebuggerPause:
34    """
35    测试用例:多实例 debug 暂停恢复调试
36    测试步骤:
37        1.  连接 connect server 和主线程 debugger server
38        2.  主线程使能 Runtime 和 Debugger
39        3.  主线程 resume(Debugger.resume)
40        4.  触发点击事件,创建子线程,连接子线程 debugger server
41        5.  子线程使能 Runtime 和 Debugger
42        6.  子线程 resume,停在 debugger代码处(Debugger.resume)
43        7.  子线程 resume,所有线程等待2秒(Debugger.resume)
44        8.  暂停子线程(Debugger.pause)
45        9.  再次恢复子线程(Debugger.resume)
46        10. 子线程去使能 debugger(Debugger.disable)
47        11. 暂停主线程(Debugger.pause)
48        12. 再次恢复主线程(Debugger.resume)
49        13. 主线程去使能 debugger(Debugger.disable)
50        14. 关闭所有线程 debugger server 和 connect server 连接
51    关键代码:
52        Index.ets
53            .OnClick(() => {
54                let myWorker = new worker.ThreadWorker("entry/ets/workers/Worker.ets")
55                myWorker.postMessage("hello world")
56                const start = Date.now()
57                while (Date.now() - start < 10000) {}
58            })
59        Worker.ets
60            const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
61            workerPort.onmessage = (e: MessageEvents) => {
62                workerPort.postMessage(e.data)
63                debugger
64                const start = Date.now()
65                while (Date.now() - start < 10000) {}
66            }
67    """
68
69    def setup_method(self):
70        logging.info('Start running TestWorkerDebuggerPause: setup')
71
72        self.log_path = rf'{os.path.dirname(__file__)}\..\log'
73        self.hilog_file_name = 'test_worker_debugger_pause.hilog.txt'
74        self.id_generator = Utils.message_id_generator()
75
76        # receive the hilog before the test start
77        Utils.clear_fault_log()
78        self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path,
79                                                                 file_name=self.hilog_file_name,
80                                                                 debug_on=True)
81
82    def teardown_method(self):
83        Application.uninstall(self.config['bundle_name'])
84
85        # terminate the hilog receive process after the test done
86        time.sleep(3)
87        self.hilog_process.stdout.close()
88        self.hilog_process.terminate()
89        self.hilog_process.wait()
90        self.write_thread.join()
91
92        Utils.save_fault_log(log_path=self.log_path)
93        logging.info('TestWorkerDebuggerPause done')
94
95    def test(self, test_suite_worker_05_debug):
96        logging.info('Start running TestWorkerDebuggerPause: test')
97        self.config = test_suite_worker_05_debug
98        websocket = self.config['websocket']
99        taskpool = self.config['taskpool']
100        pid = self.config['pid']
101        self.debugger_impl = debugger_api.DebuggerImpl(self.id_generator, websocket)
102        self.runtime_impl = runtime_api.RuntimeImpl(self.id_generator, websocket)
103
104        taskpool.submit(websocket.main_task(taskpool, self.procedure, pid))
105        taskpool.await_taskpool()
106        taskpool.task_join()
107        if taskpool.task_exception:
108            raise taskpool.task_exception
109
110    async def procedure(self, websocket):
111        ################################################################################################################
112        # main thread: connect the debugger server
113        ################################################################################################################
114        main_thread = await self.debugger_impl.connect_to_debugger_server(self.config['pid'], True)
115        logging.info(f'Connect to the debugger server of instance: {main_thread.instance_id}')
116        ################################################################################################################
117        # main thread: Runtime.enable
118        ################################################################################################################
119        await self.runtime_impl.send("Runtime.enable", main_thread)
120        ################################################################################################################
121        # main thread: Debugger.enable
122        ################################################################################################################
123        await self.debugger_impl.send("Debugger.enable", main_thread)
124        ################################################################################################################
125        # main thread: Runtime.runIfWaitingForDebugger
126        ################################################################################################################
127        await self.runtime_impl.send("Runtime.runIfWaitingForDebugger", main_thread)
128        ################################################################################################################
129        # main thread: Debugger.scriptParsed
130        ################################################################################################################
131        response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread)
132        assert response['params']['url'] == self.config['file_path']['entry_ability']
133        assert response['params']['endLine'] == 0
134        ################################################################################################################
135        # main thread: Debugger.paused
136        ################################################################################################################
137        response = await self.debugger_impl.recv("Debugger.paused", main_thread)
138        assert response['params']['callFrames'][0]['url'] == self.config['file_path']['entry_ability']
139        assert response['params']['reason'] == 'Break on start'
140        ################################################################################################################
141        # main thread: Debugger.resume
142        ################################################################################################################
143        await self.debugger_impl.send("Debugger.resume", main_thread)
144        ################################################################################################################
145        # main thread: Debugger.scriptParsed
146        ################################################################################################################
147        response = await self.debugger_impl.recv("Debugger.scriptParsed", main_thread)
148        assert response['params']['url'] == self.config['file_path']['index']
149        assert response['params']['endLine'] == 0
150        ################################################################################################################
151        # main thread: Debugger.paused
152        ################################################################################################################
153        response = await self.debugger_impl.recv("Debugger.paused", main_thread)
154        assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
155        assert response['params']['reason'] == 'Break on start'
156        ################################################################################################################
157        # main thread: Debugger.resume
158        ################################################################################################################
159        await self.debugger_impl.send("Debugger.resume", main_thread)
160        ################################################################################################################
161        # main thread: click on the screen
162        ################################################################################################################
163        Application.click_on_middle()
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        # worker thread: Debugger.scriptParsed
182        response = await self.debugger_impl.recv("Debugger.scriptParsed", worker_thread)
183        assert response['params']['url'] == self.config['file_path']['worker']
184        assert response['params']['endLine'] == 0
185        # worker thread: Debugger.paused
186        response = await self.debugger_impl.recv("Debugger.paused", worker_thread)
187        assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
188        assert response['params']['reason'] == 'Break on start'
189        ################################################################################################################
190        # worker thread: Debugger.resume
191        ################################################################################################################
192        await self.debugger_impl.send("Debugger.resume", worker_thread)
193        # worker thread: Debugger.paused
194        response = await self.debugger_impl.recv("Debugger.paused", worker_thread)
195        assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
196        assert response['params']['reason'] == 'other'
197        assert response['params']['hitBreakpoints'] == ['id:0:0:']
198        ################################################################################################################
199        # worker thread: Debugger.resume
200        ################################################################################################################
201        await self.debugger_impl.send("Debugger.resume", worker_thread)
202        ################################################################################################################
203        # all thread: sleep 2 seconds
204        ################################################################################################################
205        time.sleep(2)
206        ################################################################################################################
207        # worker thread: Debugger.pause
208        ################################################################################################################
209        await self.debugger_impl.send("Debugger.pause", worker_thread)
210        # worker thread: Debugger.paused
211        response = await self.debugger_impl.recv("Debugger.paused", worker_thread)
212        assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
213        assert response['params']['reason'] == 'other'
214        assert response['params']['hitBreakpoints'] == []
215        ################################################################################################################
216        # worker thread: Debugger.resume
217        ################################################################################################################
218        await self.debugger_impl.send("Debugger.resume", worker_thread)
219        ################################################################################################################
220        # worker thread: Debugger.disable
221        ################################################################################################################
222        await self.debugger_impl.send("Debugger.disable", worker_thread)
223        ################################################################################################################
224        # main thread: Debugger.pause
225        ################################################################################################################
226        await self.debugger_impl.send("Debugger.pause", main_thread)
227        # main thread: Debugger.paused
228        response = await self.debugger_impl.recv("Debugger.paused", main_thread)
229        assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
230        assert response['params']['reason'] == 'other'
231        assert response['params']['hitBreakpoints'] == []
232        ################################################################################################################
233        # main thread: Debugger.resume
234        ################################################################################################################
235        await self.debugger_impl.send("Debugger.resume", main_thread)
236        ################################################################################################################
237        # main thread: Debugger.disable
238        ################################################################################################################
239        await self.debugger_impl.send("Debugger.disable", main_thread)
240        ################################################################################################################
241        # close the websocket connections
242        ################################################################################################################
243        await websocket.send_msg_to_debugger_server(worker_thread.instance_id, worker_thread.send_msg_queue, 'close')
244        await websocket.send_msg_to_debugger_server(main_thread.instance_id, main_thread.send_msg_queue, 'close')
245        await websocket.send_msg_to_connect_server('close')
246        ################################################################################################################