Add auto testcase

Issue:     https://gitee.com/openharmony/arkcompiler_toolchain/issues/IAMBK6
Signed-off-by: yanzhiqi1 <yanzhiqi1@huawei.com>
This commit is contained in:
yanzhiqi1 2024-09-06 09:50:42 +08:00
parent 1a28efcd9e
commit 9d74c06f4f
23 changed files with 3081 additions and 260 deletions

View File

@ -9,7 +9,7 @@
- IDE将应用推入设备并拉起应用或attach到已启动应用上
- IDE与应用建立websocket连接
- IDE与应用之间通过websocket发送和接受调试调优相关的业务消息消息格式遵循CDPChrome DevTools Protocol协议
- IDE与应用之间通过websocket发送和接受调试调优相关的业务消息消息格式遵循CDP协议
该自动化框架依据以上流程实现了应用启动、websocket连接、消息交互等步骤的自动化基于此可以进行调试调优用例的执行与开发

View File

@ -1,3 +1,21 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Description: __init__.py of the aw package
"""
from aw.websocket import WebSocket
from aw.application import Application
from aw.utils import Utils
@ -5,7 +23,9 @@ from aw.fport import Fport
from aw.taskpool import TaskPool
from aw.cdp import debugger
from aw.cdp import runtime
from aw.cdp import heap_profiler
from aw.cdp import cpu_profiler
communicate_with_debugger_server = Utils.communicate_with_debugger_server
async_wait_timeout = Utils.async_wait_timeout
async_wait_timeout = Utils.async_wait_timeout

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
@ -17,6 +19,7 @@ Description: Action words of Application launch.
import logging
import subprocess
import re
import time
@ -71,6 +74,41 @@ class Application(object):
cls.uninstall(bundle_name)
cls.install(hap_path)
cls.start(bundle_name, start_mode)
cls.keep_awake()
time.sleep(3)
pid = cls.get_pid(bundle_name)
return int(pid)
@classmethod
def attach(cls, bundle_name):
attach_cmd = (['hdc', 'shell', 'aa', 'attach', '-b', bundle_name])
logging.info('start application: ' + ' '.join(attach_cmd))
attach_result = subprocess.run(attach_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
logging.info(attach_result.stdout)
assert attach_result.stdout.decode('utf-8').strip() == 'attach app debug successfully.'
@classmethod
def click_on_middle(cls):
'''
模拟点击屏幕中间
'''
get_screen_info_cmd = ['hdc', 'shell', 'hidumper', '-s', 'RenderService', '-a', 'screen']
screen_info = subprocess.run(get_screen_info_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
match = re.search(r'physical screen resolution: (\d+)x(\d+)', screen_info.stdout.decode('utf-8'))
assert match is not None
middle_x = int(match.group(1)) // 2
middle_y = int(match.group(2)) // 2
click_cmd = ['hdc', 'shell', 'uinput', '-T', '-c', str(middle_x), str(middle_y)]
click_result = subprocess.run(click_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
click_result_out = click_result.stdout.decode('utf-8').strip()
logging.info(click_result_out)
assert "click coordinate" in click_result_out
@classmethod
def keep_awake(cls):
keep_awake_cmd = ['hdc', 'shell', 'power-shell', 'setmode', '602']
keep_awake_result = subprocess.run(keep_awake_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
keep_awake_result_out = keep_awake_result.stdout.decode('utf-8').strip()
logging.info(keep_awake_result_out)
assert "Set Mode Success!" in keep_awake_result_out

View File

@ -0,0 +1,39 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Description: Python CDP CPU Profiler.
"""
def enable():
return {'method': 'Profiler.enable'}
def disable():
return {'method': 'Profiler.disable'}
def start():
return {'method': 'Profiler.start'}
def stop():
return {'method': 'Profiler.stop'}
def set_sampling_interval(interval: int):
return {'method': 'Profiler.setSamplingInterval',
'params': {'interval': interval}}

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
@ -64,6 +66,16 @@ def step_over():
return command
def step_into():
command = {'method': 'Debugger.stepInto'}
return command
def step_out():
command = {'method': 'Debugger.stepOut'}
return command
def disable():
command = {'method': 'Debugger.disable'}
return command
return command

View File

@ -0,0 +1,50 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Description: Python CDP Heap Profiler.
"""
import typing
def enable():
return {'method': 'HeapProfiler.enable'}
def disable():
return {'method': 'HeapProfiler.disable'}
def start_tracking_heap_objects(track_allocations: typing.Optional[bool] = None):
params = dict()
if track_allocations is not None:
params['trackAllocations'] = track_allocations
return {'method': 'HeapProfiler.startTrackingHeapObjects', 'params': params}
def stop_tracking_heap_objects():
return {'method': 'HeapProfiler.stopTrackingHeapObjects'}
def start_sampling():
return {'method': 'HeapProfiler.startSampling'}
def stop_sampling():
return {'method': 'HeapProfiler.stopSampling'}
def take_heap_snapshot():
return {'method': 'HeapProfiler.takeHeapSnapshot'}

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
@ -45,3 +47,7 @@ def get_properties(object_id: str,
params['nonIndexedPropertiesOnly'] = non_indexed_properties_only
command['params'] = params
return command
def get_heap_usage():
return {'method': 'Runtime.getHeapUsage'}

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
@ -63,7 +65,7 @@ class TaskPool(object):
loop.run_forever()
async def _stop_loop(self, interval=1):
# wait for all tasks in the event loop id done, then we can close the loop
# wait for all tasks in the event loop is done, then we can close the loop
while True:
if self.task_queue.empty():
self.event_loop.stop()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
@ -33,14 +35,6 @@ class Utils(object):
yield message_id
message_id += 1
@classmethod
def get_device_type(cls):
cmd = ['hdc', 'shell', 'param', 'get', 'const.product.devicetype']
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.stdout.decode('utf-8').strip() == 'default':
return 'rk'
return None
@classmethod
def get_custom_protocols(cls):
protocols = ["removeBreakpointsByUrl",

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
@ -149,6 +151,7 @@ class WebSocket(object):
instance_id = response['instanceId']
to_send_msg_queue = self.to_send_msg_queues[instance_id]
await self.send_msg_to_debugger_server(instance_id, to_send_msg_queue, 'close')
num_debugger_server_client -= 1
except ConnectionClosed:
logging.info('Connect server connection closed')

View File

@ -8,6 +8,8 @@ log_date_format = %Y-%m-%d %H:%M:%S
markers =
debug: marks tests as debug
cpu_profiler: marks tests as cpu profiler
heap_profiler: marks tests as heap profiler
testpaths = ./scenario_test

View File

@ -1,7 +1,17 @@
[
{
"application directory": "MyApplicationWorker",
"hap name": "MyApplicationWorker.hap",
"bundle name": "com.example.worker"
"application directory": "MultiWorker01",
"hap name": "MultiWorker01.hap",
"bundle name": "com.example.multiWorker01"
},
{
"application directory": "MultiWorker02",
"hap name": "MultiWorker02.hap",
"bundle name": "com.example.multiWorker02"
},
{
"application directory": "TaskPool01",
"hap name": "TaskPool01.hap",
"bundle name": "com.example.taskPool01"
}
]

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
@ -20,33 +22,124 @@ import os
import pytest
from aw import Application
from aw import Fport
from aw import TaskPool
from aw import WebSocket
from aw import Application, Fport, WebSocket, TaskPool
@pytest.fixture(scope='class')
def test_suite_debug_01():
logging.info('running test_suite_debug_01')
def test_suite_worker_01():
logging.info('running worker_01 in default mode')
config = {
'start_mode': None,
'connect_server_port': 15678,
'debugger_server_port': 15679,
'bundle_name': 'com.example.multiWorker01',
'hap_name': 'MultiWorker01.hap',
'hap_path': rf'{os.path.dirname(__file__)}\..\resource\MultiWorker01.hap',
'file_path': {
'entry_ability': 'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts',
'index': 'entry|entry|1.0.0|src/main/ets/pages/Index.ts',
'worker': 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts'
}
}
launch_hap(config)
return config
bundle_name = 'com.example.worker'
hap_name = 'MyApplicationWorker.hap'
config = {'connect_server_port': 15678,
'debugger_server_port': 15679,
'bundle_name': bundle_name,
'hap_path': rf'{os.path.dirname(__file__)}\..\resource\{hap_name}'}
@pytest.fixture(scope='class')
def test_suite_worker_01_debug():
logging.info('running worker_01 in debug mode')
config = {
'start_mode': '-D',
'connect_server_port': 15678,
'debugger_server_port': 15679,
'bundle_name': 'com.example.multiWorker01',
'hap_name': 'MultiWorker01.hap',
'hap_path': rf'{os.path.dirname(__file__)}\..\resource\MultiWorker01.hap',
'file_path': {
'entry_ability': 'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts',
'index': 'entry|entry|1.0.0|src/main/ets/pages/Index.ts',
'worker': 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts'
}
}
launch_hap(config)
return config
pid = Application.launch_application(config['bundle_name'], config['hap_path'], start_mode='-D')
assert pid != 0, logging.error(f'Pid of {hap_name} is 0!')
@pytest.fixture(scope='class')
def test_suite_worker_02():
logging.info('running worker_02 in default mode')
config = {
'start_mode': None,
'connect_server_port': 15680,
'debugger_server_port': 15681,
'bundle_name': 'com.example.multiWorker02',
'hap_name': 'MultiWorker02.hap',
'hap_path': rf'{os.path.dirname(__file__)}\..\resource\MultiWorker02.hap'
}
launch_hap(config)
return config
@pytest.fixture(scope='class')
def test_suite_worker_02_profile():
logging.info('running worker_02 in profile mode')
config = {
'start_mode': '-p profile jsperf',
'connect_server_port': 15680,
'debugger_server_port': 15681,
'bundle_name': 'com.example.multiWorker02',
'hap_name': 'MultiWorker02.hap',
'hap_path': rf'{os.path.dirname(__file__)}\..\resource\MultiWorker02.hap'
}
launch_hap(config)
return config
@pytest.fixture(scope='class')
def test_suite_taskpool_01():
logging.info('running taskpool_01 in default mode')
config = {
'start_mode': None,
'connect_server_port': 15682,
'debugger_server_port': 15683,
'bundle_name': 'com.example.taskPool01',
'hap_name': 'TaskPool01.hap',
'hap_path': rf'{os.path.dirname(__file__)}\..\resource\TaskPool01.hap',
'file_path': {
'entry_ability': 'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts',
'index': 'entry|entry|1.0.0|src/main/ets/pages/Index.ts',
}
}
launch_hap(config)
return config
@pytest.fixture(scope='class')
def test_suite_taskpool_01_debug():
logging.info('running taskpool_01 in debug mode')
config = {
'start_mode': '-D',
'connect_server_port': 15682,
'debugger_server_port': 15683,
'bundle_name': 'com.example.taskPool01',
'hap_name': 'TaskPool01.hap',
'hap_path': rf'{os.path.dirname(__file__)}\..\resource\TaskPool01.hap',
'file_path': {
'entry_ability': 'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts',
'index': 'entry|entry|1.0.0|src/main/ets/pages/Index.ts',
}
}
launch_hap(config)
return config
def launch_hap(config):
pid = Application.launch_application(config['bundle_name'], config['hap_path'], start_mode=config['start_mode'])
assert pid != 0, logging.error(f'Pid of {config["hap_name"]} is 0!')
config['pid'] = pid
Fport.clear_fport()
Fport.fport_connect_server(config['connect_server_port'], config['pid'], config['bundle_name'])
config['websocket'] = WebSocket(config['connect_server_port'], config['debugger_server_port'])
config['taskpool'] = TaskPool()
return config
config['taskpool'] = TaskPool()

View File

@ -0,0 +1,237 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Description: Scenario test case.
"""
import json
import logging
import os
import time
import pytest
from aw import Utils
from aw import Application
from aw import communicate_with_debugger_server
from aw import runtime, debugger, cpu_profiler
@pytest.mark.cpu_profiler
@pytest.mark.timeout(40)
class TestCpuProfiler01:
"""
测试用例多实例 CPU 调优 Time 录制
测试步骤
1. 连接 connect server 和主线程 debugger server
2. 连接 worker 线程 debugger server
3. 所有线程使能 RuntimeRuntime.enable
4. 所有线程设置采样间隔Profiler.setSamplingInterval
5. 所有线程启动 CPU 调试Profiler.start
6. 所有线程去使能 DebuggerDebugger.disable
7. 等待 10 秒后关闭 CPU 调优获取调优数据Profiler.stop
8. 销毁 worker 线程对应的 debugger server 连接断开
9. 关闭主线程 debugger server connect server 连接
"""
def setup_method(self):
logging.info('Start running TestCpuProfiler01: setup')
self.log_path = rf'{os.path.dirname(__file__)}\..\log'
self.hilog_file_name = 'test_cpu_profiler_01.hilog.txt'
self.id_generator = Utils.message_id_generator()
# receive the hilog before the test start
Utils.clear_fault_log()
self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path,
file_name=self.hilog_file_name,
debug_on=True)
def teardown_method(self):
Application.uninstall(self.config['bundle_name'])
# terminate the hilog receive process after the test done
time.sleep(3)
self.hilog_process.stdout.close()
self.hilog_process.terminate()
self.hilog_process.wait()
self.write_thread.join()
Utils.save_fault_log(log_path=self.log_path)
logging.info('TestCpuProfiler01 done')
def test(self, test_suite_worker_02):
logging.info('Start running TestCpuProfiler01: test')
self.config = test_suite_worker_02
websocket = self.config['websocket']
taskpool = self.config['taskpool']
pid = self.config['pid']
taskpool.submit(websocket.main_task(taskpool, websocket, self.procedure, pid))
taskpool.await_taskpool()
taskpool.task_join()
if taskpool.task_exception:
raise taskpool.task_exception
async def procedure(self, websocket):
################################################################################################################
# main thread: connect the debugger server
################################################################################################################
send_msg = {"type": "connected"}
await websocket.send_msg_to_connect_server(send_msg)
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] == 0, logging.error('instance id of the main thread not equal to 0')
assert response['tid'] == self.config['pid']
main_thread_instance_id = await websocket.get_instance()
main_thread_to_send_queue = websocket.to_send_msg_queues[main_thread_instance_id]
main_thread_received_queue = websocket.received_msg_queues[main_thread_instance_id]
logging.info(f'Connect to the debugger server of instance: {main_thread_instance_id}')
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
workers_num = 2
worker_instances_id = []
worker_thread_to_send_queues = []
worker_thread_received_queues = []
for i in range(workers_num):
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] != 0
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instance_id = await websocket.get_instance()
worker_instances_id.append(worker_instance_id)
worker_thread_to_send_queues.append(websocket.to_send_msg_queues[worker_instance_id])
worker_thread_received_queues.append(websocket.received_msg_queues[worker_instance_id])
logging.info(f'Connect to the debugger server of instance: {worker_instance_id}')
################################################################################################################
# main thread: Runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: Runtime.enable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# main thread: Profiler.setSamplingInterval
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
cpu_profiler.set_sampling_interval(500), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Profiler.setSamplingInterval
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
cpu_profiler.set_sampling_interval(500), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Profiler.start
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
cpu_profiler.start(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Profiler.start
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
cpu_profiler.start(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.disable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.disable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.disable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
debugger.disable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# all thread: sleep 10 seconds
################################################################################################################
time.sleep(10)
################################################################################################################
# main thread: Profiler.stop
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
cpu_profiler.stop(), message_id)
response = json.loads(response)
assert response['id'] == message_id
assert all(i >= 0 for i in response['result']['profile']['timeDeltas'])
################################################################################################################
# worker thread: Profiler.stop
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
cpu_profiler.stop(), message_id)
response = json.loads(response)
assert response['id'] == message_id
assert all(i >= 0 for i in response['result']['profile']['timeDeltas'])
################################################################################################################
# worker thread: destroy instance
################################################################################################################
for i in range(workers_num):
await websocket.send_msg_to_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i], 'close')
################################################################################################################
# close the websocket connections
################################################################################################################
await websocket.send_msg_to_debugger_server(main_thread_instance_id, main_thread_to_send_queue, 'close')
await websocket.send_msg_to_connect_server('close')
################################################################################################################

View File

@ -0,0 +1,203 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Description: Scenario test case.
"""
import json
import logging
import os
import time
import pytest
from aw import Utils
from aw import Application
from aw import communicate_with_debugger_server
from aw import runtime, debugger, cpu_profiler
@pytest.mark.cpu_profiler
@pytest.mark.timeout(40)
class TestCpuProfiler02:
"""
测试用例多实例 CPU 调优 Launch 录制
测试步骤
1. -p 模式启动应用
2. 连接 connect server 和主线程 debugger server
3. 连接 worker 线程 debugger server
4. worker 线程使能 RuntimeRuntime.enable
5. worker 线程设置采样间隔Profiler.setSamplingInterval
6. worker 线程启动 CPU 调试Profiler.start
7. worker 线程去使能 DebuggerDebugger.disable
8. 等待 10 秒后关闭 worker 线程 CPU 调优获取 worker 线程调优数据Profiler.stop
9. 销毁 worker 线程对应的 debugger server 连接断开
10. 关闭主线程 CPU 调优获取主线程调优数据Profiler.stop
11. 关闭主线程 debugger server connect server 连接
"""
def setup_method(self):
logging.info('Start running TestCpuProfiler02: setup')
self.log_path = rf'{os.path.dirname(__file__)}\..\log'
self.hilog_file_name = 'test_cpu_profiler_02.hilog.txt'
self.id_generator = Utils.message_id_generator()
# receive the hilog before the test start
Utils.clear_fault_log()
self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path,
file_name=self.hilog_file_name,
debug_on=True)
def teardown_method(self):
Application.uninstall(self.config['bundle_name'])
# terminate the hilog receive process after the test done
time.sleep(3)
self.hilog_process.stdout.close()
self.hilog_process.terminate()
self.hilog_process.wait()
self.write_thread.join()
Utils.save_fault_log(log_path=self.log_path)
logging.info('TestCpuProfiler02 done')
def test(self, test_suite_worker_02_profile):
logging.info('Start running TestCpuProfiler02: test')
self.config = test_suite_worker_02_profile
websocket = self.config['websocket']
taskpool = self.config['taskpool']
pid = self.config['pid']
taskpool.submit(websocket.main_task(taskpool, websocket, self.procedure, pid))
taskpool.await_taskpool()
taskpool.task_join()
if taskpool.task_exception:
raise taskpool.task_exception
async def procedure(self, websocket):
################################################################################################################
# main thread: connect the debugger server
################################################################################################################
send_msg = {"type": "connected"}
await websocket.send_msg_to_connect_server(send_msg)
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] == 0, logging.error('instance id of the main thread not equal to 0')
assert response['tid'] == self.config['pid']
main_thread_instance_id = await websocket.get_instance()
main_thread_to_send_queue = websocket.to_send_msg_queues[main_thread_instance_id]
main_thread_received_queue = websocket.received_msg_queues[main_thread_instance_id]
logging.info(f'Connect to the debugger server of instance: {main_thread_instance_id}')
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
workers_num = 2
worker_instances_id = []
worker_thread_to_send_queues = []
worker_thread_received_queues = []
for i in range(workers_num):
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] != 0
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instance_id = await websocket.get_instance()
worker_instances_id.append(worker_instance_id)
worker_thread_to_send_queues.append(websocket.to_send_msg_queues[worker_instance_id])
worker_thread_received_queues.append(websocket.received_msg_queues[worker_instance_id])
logging.info(f'Connect to the debugger server of instance: {worker_instance_id}')
################################################################################################################
# worker thread: Runtime.enable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: Profiler.setSamplingInterval
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
cpu_profiler.set_sampling_interval(500), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Profiler.start
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
cpu_profiler.start(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.disable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
debugger.disable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# all thread: sleep 10 seconds
################################################################################################################
time.sleep(10)
################################################################################################################
# worker thread: Profiler.stop
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
cpu_profiler.stop(), message_id)
response = json.loads(response)
assert response['id'] == message_id
assert all(i >= 0 for i in response['result']['profile']['timeDeltas'])
################################################################################################################
# worker thread: destroy instance
################################################################################################################
for i in range(workers_num):
await websocket.send_msg_to_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i], 'close')
################################################################################################################
# main thread: Profiler.stop
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
cpu_profiler.stop(), message_id)
response = json.loads(response)
assert response['id'] == message_id
assert all(i >= 0 for i in response['result']['profile']['timeDeltas'])
################################################################################################################
# close the websocket connections
################################################################################################################
await websocket.send_msg_to_debugger_server(main_thread_instance_id, main_thread_to_send_queue, 'close')
await websocket.send_msg_to_connect_server('close')
################################################################################################################

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
@ -32,21 +34,30 @@ from aw import debugger, runtime
@pytest.mark.timeout(30)
class TestDebug01:
"""
测试用例多实例调试_01
测试用例多实例 debug 调试
测试步骤
1. 连接 connect server
2. 连接主线程 debugger server
3. 主线程文件 Index.ts 设置断点恢复执行并命中断点
4. 连接 worker 线程 debugger server
5. 子线程文件 Worker.ts 设置断点
6. 主线程 step over发送消息给子线程主线程暂停在下一行子线程命中断点
7. 子线程 step over暂停在下一行随后 getProperties
8. 主线程 step over暂停在下一行
9. 主线程 resume命中断点
10. 主线程 step over暂停在下一行
11. 主线程 resume 执行结束
12. 子线程销毁对应的 debugger server 连接断开
13. 关闭主线程 debugger server connect server 连接
1. 连接 connect server 和主线程 debugger server
2. 主线程使能 Runtime Debugger
3. 主线程 Index.ts 文件设置断点Debugger.getPossibleAndSetBreakpointByUrl
4. 主线程 stepOut暂停在下一断点Debugger.stepOut
5. 创建第一个子线程连接子线程 debugger server
6. 主线程 resume暂停在下一断点Debugger.resume
7. 创建另一个子线程连接子线程 debugger server
8. 所有子线程使能 Runtime Debugger
9. 所有子线程 Worker.ts 文件设置断点Debugger.getPossibleAndSetBreakpointByUrl
10. 触发点击事件主线程命中断点
11. 销毁其中一个子线程
12. 主线程 stepInto暂停在下一行Debugger.stepInto
13. 主线程 getProperties返回给定对象的属性Runtime.getProperties
14. 主线程 resume暂停在下一断点Debugger.resume
15. 重新创建一个子线程使能并设置断点
16. 主线程 resume发送消息给子线程主线程暂停在下一断点Debugger.resume
17. 子线程命中断点后 getPropertiesRuntime.getProperties
18. 子线程 stepOut 发消息给主线程Debugger.stepOut
19. 主线程 stepOver发送消息给另一子线程主线程暂停在下一行Debugger.stepOver
20. 子线程命中断点后 resume发消息给主线程Debugger.resume
21. 销毁所有子线程对应的 debugger server 连接断开
22. 关闭主线程 debugger server connect server 连接
"""
def setup_method(self):
@ -75,9 +86,9 @@ class TestDebug01:
Utils.save_fault_log(log_path=self.log_path)
logging.info('TestDebug01 done')
def test(self, test_suite_debug_01):
def test(self, test_suite_worker_01_debug):
logging.info('Start running TestDebug01: test')
self.config = test_suite_debug_01
self.config = test_suite_worker_01_debug
websocket = self.config['websocket']
taskpool = self.config['taskpool']
pid = self.config['pid']
@ -104,7 +115,7 @@ class TestDebug01:
main_thread_received_queue = websocket.received_msg_queues[main_thread_instance_id]
logging.info(f'Connect to the debugger server of instance: {main_thread_instance_id}')
################################################################################################################
# main thread: runtime.enable
# main thread: Runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
@ -112,9 +123,8 @@ class TestDebug01:
main_thread_received_queue,
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# main thread: debugger.enable
# main thread: Debugger.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
@ -124,7 +134,7 @@ class TestDebug01:
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# main thread: runtime.run_if_waiting_for_debugger
# main thread: Runtime.runIfWaitingForDebugger
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
@ -139,7 +149,7 @@ class TestDebug01:
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == 'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts'
assert response['params']['url'] == self.config['file_path']['entry_ability']
assert response['params']['endLine'] == 0
################################################################################################################
# main thread: Debugger.paused
@ -148,8 +158,7 @@ class TestDebug01:
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert (response['params']['callFrames'][0]['url'] ==
'entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts')
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['entry_ability']
assert response['params']['reason'] == 'Break on start'
################################################################################################################
# main thread: Debugger.resume
@ -170,7 +179,7 @@ class TestDebug01:
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == 'entry|entry|1.0.0|src/main/ets/pages/Index.ts'
assert response['params']['url'] == self.config['file_path']['index']
assert response['params']['endLine'] == 0
################################################################################################################
# main thread: Debugger.paused
@ -179,24 +188,26 @@ class TestDebug01:
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == 'entry|entry|1.0.0|src/main/ets/pages/Index.ts'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['reason'] == 'Break on start'
################################################################################################################
# main thread: Debugger.removeBreakpointsByUrl
################################################################################################################
url = 'entry|entry|1.0.0|src/main/ets/pages/Index.ts'
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.remove_breakpoints_by_url(url), message_id)
debugger.remove_breakpoints_by_url(
self.config['file_path']['index']),
message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url='entry|entry|1.0.0|src/main/ets/pages/Index.ts', line_number=22),
debugger.BreakLocationUrl(url='entry|entry|1.0.0|src/main/ets/pages/Index.ts', line_number=26)]
locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=12),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=53),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=57)]
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
@ -204,8 +215,9 @@ class TestDebug01:
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:22:0:entry|entry|1.0.0|src/main/ets/pages/Index.ts'
assert response['result']['locations'][1]['id'] == 'id:26:0:entry|entry|1.0.0|src/main/ets/pages/Index.ts'
assert response['result']['locations'][0]['id'] == 'id:12:0:' + self.config['file_path']['index']
assert response['result']['locations'][1]['id'] == 'id:53:0:' + self.config['file_path']['index']
assert response['result']['locations'][2]['id'] == 'id:57:0:' + self.config['file_path']['index']
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
@ -215,7 +227,8 @@ class TestDebug01:
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.paused, hit breakpoint
@ -224,8 +237,56 @@ class TestDebug01:
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == 'entry|entry|1.0.0|src/main/ets/pages/Index.ts'
assert response['params']['hitBreakpoints'] == ["id:22:4:entry|entry|1.0.0|src/main/ets/pages/Index.ts"]
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['hitBreakpoints'] == ['id:12:4:' + self.config['file_path']['index']]
################################################################################################################
# main thread: Debugger.stepOut
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.step_out(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['hitBreakpoints'] == ['id:12:4:' + self.config['file_path']['index']]
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
workers_num = 2
worker_instances_id = []
worker_thread_to_send_queues = []
worker_thread_received_queues = []
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] != 0
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instance_id = await websocket.get_instance()
worker_instances_id.append(worker_instance_id)
worker_thread_to_send_queues.append(websocket.to_send_msg_queues[worker_instance_id])
worker_thread_received_queues.append(websocket.received_msg_queues[worker_instance_id])
logging.info(f'Connect to the debugger server of instance: {worker_instance_id}')
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
@ -236,11 +297,135 @@ class TestDebug01:
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instance_id = await websocket.get_instance()
worker_thread_to_send_queue = websocket.to_send_msg_queues[worker_instance_id]
worker_thread_received_queue = websocket.received_msg_queues[worker_instance_id]
worker_instances_id.append(worker_instance_id)
worker_thread_to_send_queues.append(websocket.to_send_msg_queues[worker_instance_id])
worker_thread_received_queues.append(websocket.received_msg_queues[worker_instance_id])
logging.info(f'Connect to the debugger server of instance: {worker_instance_id}')
################################################################################################################
# main thread: Runtime.getProperties.
# worker thread: Runtime.enable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: Debugger.enable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
debugger.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# worker thread: Runtime.runIfWaitingForDebugger
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
runtime.run_if_waiting_for_debugger(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
# worker thread: Debugger.scriptParsed
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == self.config['file_path']['worker']
assert response['params']['endLine'] == 0
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
assert response['params']['reason'] == 'Break on start'
################################################################################################################
# worker thread: Debugger.removeBreakpointsByUrl
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
debugger.remove_breakpoints_by_url(
self.config['file_path']['worker']),
message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url=self.config['file_path']['worker'], line_number=11)]
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
debugger.get_possible_and_set_breakpoint_by_url(
locations),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:11:0:' + self.config['file_path']['worker']
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: click on the screen
################################################################################################################
Application.click_on_middle()
################################################################################################################
# main thread: Debugger.paused, hit breakpoint
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['hitBreakpoints'] == ['id:53:16:' + self.config['file_path']['index']]
################################################################################################################
# worker thread: destroy instance
################################################################################################################
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'destroyInstance'
if response['instanceId'] == worker_instances_id[0]:
worker_instances_id[0] = worker_instances_id[1]
worker_thread_to_send_queues[0] = worker_thread_to_send_queues[1]
worker_thread_received_queues[0] = worker_thread_received_queues[1]
################################################################################################################
# main thread: Debugger.stepInto
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.step_into(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response)['method'] == 'Debugger.paused'
################################################################################################################
# main thread: Runtime.getProperties
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
@ -253,138 +438,155 @@ class TestDebug01:
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['result'][0]['name'] == 'newWorker'
assert response['result']['result'][0]['name'] == 'set message'
assert response['result']['result'][0]['value']['type'] == 'function'
assert response['result']['result'][1]['name'] == 'newValue'
assert response['result']['result'][1]['value']['type'] == 'string'
################################################################################################################
# worker thread: runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: debugger.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# worker thread: runtime.run_if_waiting_for_debugger
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
runtime.run_if_waiting_for_debugger(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.scriptParsed
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(worker_instance_id, worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts'
assert response['params']['endLine'] == 0
################################################################################################################
# worker thread: Debugger.paused
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(worker_instance_id, worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts'
assert response['params']['reason'] == 'Break on start'
################################################################################################################
# worker thread: Debugger.removeBreakpointsByUrl
################################################################################################################
url = 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts'
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.remove_breakpoints_by_url(url), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url='entry|entry|1.0.0|src/main/ets/workers/Worker.ts', line_number=17),
debugger.BreakLocationUrl(url='entry|entry|1.0.0|src/main/ets/workers/Worker.ts', line_number=20)]
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.get_possible_and_set_breakpoint_by_url(locations),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:17:0:entry|entry|1.0.0|src/main/ets/workers/Worker.ts'
assert response['result']['locations'][1]['id'] == 'id:20:0:entry|entry|1.0.0|src/main/ets/workers/Worker.ts'
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instance_id, worker_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: step over
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.step_over(), message_id)
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.paused, hit breakpoint
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['hitBreakpoints'] == ['id:57:20:' + self.config['file_path']['index']]
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] != 0
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instances_id[1] = await websocket.get_instance()
worker_thread_to_send_queues[1] = websocket.to_send_msg_queues[worker_instances_id[1]]
worker_thread_received_queues[1] = websocket.received_msg_queues[worker_instances_id[1]]
logging.info(f'Connect to the debugger server of instance: {worker_instances_id[1]}')
################################################################################################################
# worker thread: Runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: Debugger.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# worker thread: Runtime.runIfWaitingForDebugger
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
runtime.run_if_waiting_for_debugger(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == self.config['file_path']['worker']
assert response['params']['endLine'] == 0
################################################################################################################
# worker thread: Debugger.removeBreakpointsByUrl
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.remove_breakpoints_by_url(
self.config['file_path']['worker']),
message_id)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
assert response['params']['reason'] == 'Break on start'
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url=self.config['file_path']['worker'], line_number=11)]
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.get_possible_and_set_breakpoint_by_url(locations),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:11:0:' + self.config['file_path']['worker']
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
# main thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == 'entry|entry|1.0.0|src/main/ets/pages/Index.ts'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == []
assert response['params']['hitBreakpoints'] == ['id:57:20:' + self.config['file_path']['index']]
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instance_id, worker_thread_received_queue)
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[0],
worker_thread_received_queues[0])
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == ["id:17:8:entry|entry|1.0.0|src/main/ets/workers/Worker.ts"]
assert response['params']['hitBreakpoints'] == ['id:11:4:' + self.config['file_path']['worker']]
################################################################################################################
# worker thread: step over
# worker thread: Runtime.getProperties
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.step_over(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instance_id, worker_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instance_id, worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == 'entry|entry|1.0.0|src/main/ets/workers/Worker.ts'
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == []
################################################################################################################
# worker thread: Runtime.getProperties.
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
response = await communicate_with_debugger_server(worker_instances_id[0],
worker_thread_to_send_queues[0],
worker_thread_received_queues[0],
runtime.get_properties(object_id='0',
own_properties=True,
accessor_properties_only=False,
@ -394,97 +596,104 @@ class TestDebug01:
assert response['id'] == message_id
assert response['result']['result'][0]['name'] == ''
assert response['result']['result'][0]['value']['type'] == 'function'
assert response['result']['result'][1]['name'] == 'str'
assert response['result']['result'][1]['value']['type'] == 'string'
assert response['result']['result'][2]['name'] == 'e'
assert response['result']['result'][2]['value']['type'] == 'object'
assert response['result']['result'][1]['name'] == 'e'
assert response['result']['result'][1]['value']['type'] == 'object'
################################################################################################################
# main thread: step over
# worker thread: Debugger.stepOut
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.step_over(), message_id)
response = await communicate_with_debugger_server(worker_instances_id[0],
worker_thread_to_send_queues[0],
worker_thread_received_queues[0],
debugger.step_out(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
# main thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['location']['lineNumber'] == 25
assert response['params']['callFrames'][0]['url'] == 'entry|entry|1.0.0|src/main/ets/pages/Index.ts'
assert response['params']['callFrames'][1]['location']['lineNumber'] == 40
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == []
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
# main thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['location']['lineNumber'] == 26
assert response['params']['callFrames'][0]['url'] == 'entry|entry|1.0.0|src/main/ets/pages/Index.ts'
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == ['id:26:8:entry|entry|1.0.0|src/main/ets/pages/Index.ts']
################################################################################################################
# main thread: step over
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.step_over(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
# main thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['location']['lineNumber'] == 27
assert response['params']['callFrames'][0]['url'] == 'entry|entry|1.0.0|src/main/ets/pages/Index.ts'
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == []
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[0],
worker_thread_received_queues[0])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.disable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
response = await communicate_with_debugger_server(worker_instances_id[0],
worker_thread_to_send_queues[0],
worker_thread_received_queues[0],
debugger.disable(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instance_id, worker_thread_received_queue)
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[0],
worker_thread_received_queues[0])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.stepOver
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.step_over(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
# main thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == []
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == ['id:11:4:' + self.config['file_path']['worker']]
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.disable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.disable(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: destroy instance
################################################################################################################
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'destroyInstance'
assert response['instanceId'] == worker_instance_id
for i in range(workers_num):
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'destroyInstance'
assert response['instanceId'] in worker_instances_id
################################################################################################################
# main thread: Debugger.disable
################################################################################################################
@ -494,11 +703,12 @@ class TestDebug01:
main_thread_received_queue,
debugger.disable(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id, main_thread_received_queue)
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# close the websocket connections
################################################################################################################
await websocket.send_msg_to_debugger_server(main_thread_instance_id, main_thread_to_send_queue, 'close')
await websocket.send_msg_to_connect_server('close')
################################################################################################################
################################################################################################################

View File

@ -0,0 +1,537 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Description: Scenario test case.
"""
import json
import logging
import os
import time
import pytest
from aw import Application
from aw import Utils
from aw import communicate_with_debugger_server
from aw import debugger, runtime
@pytest.mark.debug
@pytest.mark.timeout(30)
class TestDebug02:
"""
测试用例多实例 attach 调试
测试步骤
1. 拉起应用attach 主线程
2. 连接 connect server 和主线程 debugger server
3. 创建两个子线程连接子线程 debugger server
4. 所有线程使能 Runtime Debugger
5. 主线程 Index.ts 文件设置断点Debugger.getPossibleAndSetBreakpointByUrl
6. 触发点击事件主线程命中断点
7. 销毁其中一个子线程
8. 子线程 Worker.ts 文件设置断点Debugger.getPossibleAndSetBreakpointByUrl
9. 主线程 resume暂停在下一断点Debugger.resume
10. 重新创建一个子线程使能并设置断点
11. 主线程 resume发送消息给子线程主线程暂停在下一断点Debugger.resume
12. 子线程命中断点后 stepOut发消息给主线程Debugger.stepOut
13. 主线程 stepOver发送消息给另一子线程主线程暂停在下一行Debugger.stepOver
14. 子线程命中断点后 resume发消息给主线程Debugger.resume
15. 销毁所有子线程对应的 debugger server 连接断开
16. 关闭主线程 debugger server connect server 连接
"""
def setup_method(self):
logging.info('Start running TestDebug02: setup')
self.log_path = rf'{os.path.dirname(__file__)}\..\log'
self.hilog_file_name = 'test_debug_02.hilog.txt'
self.id_generator = Utils.message_id_generator()
# receive the hilog before the test start
Utils.clear_fault_log()
self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path,
file_name=self.hilog_file_name,
debug_on=True)
def teardown_method(self):
Application.uninstall(self.config['bundle_name'])
# terminate the hilog receive process after the test done
time.sleep(3)
self.hilog_process.stdout.close()
self.hilog_process.terminate()
self.hilog_process.wait()
self.write_thread.join()
Utils.save_fault_log(log_path=self.log_path)
logging.info('TestDebug02 done')
def test(self, test_suite_worker_01):
logging.info('Start running TestDebug02: test')
self.config = test_suite_worker_01
websocket = self.config['websocket']
taskpool = self.config['taskpool']
pid = self.config['pid']
Application.attach(self.config['bundle_name'])
taskpool.submit(websocket.main_task(taskpool, websocket, self.procedure, pid))
taskpool.await_taskpool()
taskpool.task_join()
if taskpool.task_exception:
raise taskpool.task_exception
async def procedure(self, websocket):
################################################################################################################
# main thread: connect the debugger server
################################################################################################################
send_msg = {"type": "connected"}
await websocket.send_msg_to_connect_server(send_msg)
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] == 0, logging.error('instance id of the main thread not equal to 0')
assert response['tid'] == self.config['pid']
main_thread_instance_id = await websocket.get_instance()
main_thread_to_send_queue = websocket.to_send_msg_queues[main_thread_instance_id]
main_thread_received_queue = websocket.received_msg_queues[main_thread_instance_id]
logging.info(f'Connect to the debugger server of instance: {main_thread_instance_id}')
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
workers_num = 2
worker_instances_id = []
worker_thread_to_send_queues = []
worker_thread_received_queues = []
for i in range(workers_num):
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] != 0
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instance_id = await websocket.get_instance()
worker_instances_id.append(worker_instance_id)
worker_thread_to_send_queues.append(websocket.to_send_msg_queues[worker_instance_id])
worker_thread_received_queues.append(websocket.received_msg_queues[worker_instance_id])
logging.info(f'Connect to the debugger server of instance: {worker_instance_id}')
################################################################################################################
# worker thread: Runtime.enable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: Debugger.enable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
debugger.enable(), message_id)
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == self.config['file_path']['worker']
assert response['params']['endLine'] == 0
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# worker thread: Runtime.runIfWaitingForDebugger
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
runtime.run_if_waiting_for_debugger(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.enable(), message_id)
assert json.loads(response)['method'] == 'Debugger.scriptParsed'
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response)['method'] == 'Debugger.scriptParsed'
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# main thread: Runtime.runIfWaitingForDebugger
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.run_if_waiting_for_debugger(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.removeBreakpointsByUrl
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.remove_breakpoints_by_url(
self.config['file_path']['index']),
message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=53),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=57)]
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.get_possible_and_set_breakpoint_by_url(locations),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:53:0:' + self.config['file_path']['index']
assert response['result']['locations'][1]['id'] == 'id:57:0:' + self.config['file_path']['index']
################################################################################################################
# main thread: click on the screen
################################################################################################################
Application.click_on_middle()
################################################################################################################
# main thread: Debugger.paused, hit breakpoint
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['hitBreakpoints'] == ['id:53:16:' + self.config['file_path']['index']]
################################################################################################################
# worker thread: destroy instance
################################################################################################################
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'destroyInstance'
if response['instanceId'] == worker_instances_id[0]:
worker_instances_id[0] = worker_instances_id[1]
worker_thread_to_send_queues[0] = worker_thread_to_send_queues[1]
worker_thread_received_queues[0] = worker_thread_received_queues[1]
################################################################################################################
# worker thread: Debugger.removeBreakpointsByUrl
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[0],
worker_thread_to_send_queues[0],
worker_thread_received_queues[0],
debugger.remove_breakpoints_by_url(
self.config['file_path']['worker']),
message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url=self.config['file_path']['worker'], line_number=11)]
response = await communicate_with_debugger_server(worker_instances_id[0],
worker_thread_to_send_queues[0],
worker_thread_received_queues[0],
debugger.get_possible_and_set_breakpoint_by_url(locations),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:11:0:' + self.config['file_path']['worker']
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.paused, hit breakpoint
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['hitBreakpoints'] == ['id:57:20:' + self.config['file_path']['index']]
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] != 0
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instances_id[1] = await websocket.get_instance()
worker_thread_to_send_queues[1] = websocket.to_send_msg_queues[worker_instances_id[1]]
worker_thread_received_queues[1] = websocket.received_msg_queues[worker_instances_id[1]]
logging.info(f'Connect to the debugger server of instance: {worker_instances_id[1]}')
################################################################################################################
# worker thread: Runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: Debugger.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# worker thread: Runtime.runIfWaitingForDebugger
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
runtime.run_if_waiting_for_debugger(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == self.config['file_path']['worker']
assert response['params']['endLine'] == 0
################################################################################################################
# worker thread: Debugger.removeBreakpointsByUrl
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.remove_breakpoints_by_url(
self.config['file_path']['worker']),
message_id)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
assert response['params']['reason'] == 'Break on start'
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url=self.config['file_path']['worker'], line_number=11)]
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.get_possible_and_set_breakpoint_by_url(locations),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:11:0:' + self.config['file_path']['worker']
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
# main thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == ['id:57:20:' + self.config['file_path']['index']]
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[0],
worker_thread_received_queues[0])
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
assert response['params']['reason'] == 'Break on start'
assert response['params']['hitBreakpoints'] == []
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[0],
worker_thread_to_send_queues[0],
worker_thread_received_queues[0],
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[0],
worker_thread_received_queues[0])
assert json.loads(response) == {"id": message_id, "result": {}}
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[0],
worker_thread_received_queues[0])
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == ['id:11:4:' + self.config['file_path']['worker']]
################################################################################################################
# worker thread: Debugger.stepOut
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[0],
worker_thread_to_send_queues[0],
worker_thread_received_queues[0],
debugger.step_out(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[0],
worker_thread_received_queues[0])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.disable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[0],
worker_thread_to_send_queues[0],
worker_thread_received_queues[0],
debugger.disable(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[0],
worker_thread_received_queues[0])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.stepOver
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.step_over(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
# main thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == []
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['worker']
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == ['id:11:4:' + self.config['file_path']['worker']]
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.disable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[1],
worker_thread_to_send_queues[1],
worker_thread_received_queues[1],
debugger.disable(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[1],
worker_thread_received_queues[1])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: destroy instance
################################################################################################################
for i in range(workers_num):
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'destroyInstance'
assert response['instanceId'] in worker_instances_id
################################################################################################################
# main thread: Debugger.disable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.disable(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# close the websocket connections
################################################################################################################
await websocket.send_msg_to_debugger_server(main_thread_instance_id, main_thread_to_send_queue, 'close')
await websocket.send_msg_to_connect_server('close')
################################################################################################################

View File

@ -0,0 +1,431 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Description: Scenario test case.
"""
import json
import logging
import os
import time
import pytest
from aw import Application
from aw import Utils
from aw import communicate_with_debugger_server
from aw import debugger, runtime
@pytest.mark.debug
@pytest.mark.timeout(30)
class TestDebug03:
"""
测试用例 task 实例 debug 调试
测试步骤
1. 连接 connect server 和主线程 debugger server
2. 主线程使能 Runtime Debugger
3. 连接子线程 debugger server用于执行 task 任务
4. 子线程使能 Runtime Debugger
5. 主线程 Index.ts 文件设置断点Debugger.getPossibleAndSetBreakpointByUrl
6. 触发点击事件主线程命中断点
7. 子线程 Index.ts 文件设置断点Debugger.getPossibleAndSetBreakpointByUrl
8. 子线程 resume命中断点Debugger.resume
9. 子线程 getProperties返回给定对象的属性Runtime.getProperties
10. 子线程 stepOut主线程命中断点Debugger.stepOut
11. 主线程 getPropertiesRuntime.getProperties
12. 主线程 resumeDebugger.resume
13. 子线程命中断点后 resumeDebugger.resume
14. 关闭所有线程 debugger server connect server 连接
"""
def setup_method(self):
logging.info('Start running TestDebug03: setup')
self.log_path = rf'{os.path.dirname(__file__)}\..\log'
self.hilog_file_name = 'test_debug_03.hilog.txt'
self.id_generator = Utils.message_id_generator()
# receive the hilog before the test start
Utils.clear_fault_log()
self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path,
file_name=self.hilog_file_name,
debug_on=True)
def teardown_method(self):
Application.uninstall(self.config['bundle_name'])
# terminate the hilog receive process after the test done
time.sleep(3)
self.hilog_process.stdout.close()
self.hilog_process.terminate()
self.hilog_process.wait()
self.write_thread.join()
Utils.save_fault_log(log_path=self.log_path)
logging.info('TestDebug03 done')
def test(self, test_suite_taskpool_01_debug):
logging.info('Start running TestDebug03: test')
self.config = test_suite_taskpool_01_debug
websocket = self.config['websocket']
taskpool = self.config['taskpool']
pid = self.config['pid']
taskpool.submit(websocket.main_task(taskpool, websocket, self.procedure, pid))
taskpool.await_taskpool()
taskpool.task_join()
if taskpool.task_exception:
raise taskpool.task_exception
async def procedure(self, websocket):
################################################################################################################
# main thread: connect the debugger server
################################################################################################################
send_msg = {"type": "connected"}
await websocket.send_msg_to_connect_server(send_msg)
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] == 0, logging.error('instance id of the main thread not equal to 0')
assert response['tid'] == self.config['pid']
main_thread_instance_id = await websocket.get_instance()
main_thread_to_send_queue = websocket.to_send_msg_queues[main_thread_instance_id]
main_thread_received_queue = websocket.received_msg_queues[main_thread_instance_id]
logging.info(f'Connect to the debugger server of instance: {main_thread_instance_id}')
################################################################################################################
# main thread: Runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# main thread: Debugger.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# main thread: Runtime.runIfWaitingForDebugger
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.run_if_waiting_for_debugger(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.scriptParsed
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == self.config['file_path']['entry_ability']
assert response['params']['endLine'] == 0
################################################################################################################
# main thread: Debugger.paused
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['entry_ability']
assert response['params']['reason'] == 'Break on start'
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.scriptParsed
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == self.config['file_path']['index']
assert response['params']['endLine'] == 0
################################################################################################################
# main thread: Debugger.paused
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['reason'] == 'Break on start'
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] != 0
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instance_id = await websocket.get_instance()
worker_thread_to_send_queue = websocket.to_send_msg_queues[worker_instance_id]
worker_thread_received_queue = websocket.received_msg_queues[worker_instance_id]
logging.info(f'Connect to the debugger server of instance: {worker_instance_id}')
################################################################################################################
# worker thread: Runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: Debugger.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# worker thread: Runtime.runIfWaitingForDebugger
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
runtime.run_if_waiting_for_debugger(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.removeBreakpointsByUrl
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.remove_breakpoints_by_url(
self.config['file_path']['index']),
message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=10),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=17),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=25)]
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.get_possible_and_set_breakpoint_by_url(locations),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:10:0:' + self.config['file_path']['index']
assert response['result']['locations'][1]['id'] == 'id:17:0:' + self.config['file_path']['index']
assert response['result']['locations'][2]['id'] == 'id:25:0:' + self.config['file_path']['index']
################################################################################################################
# main thread: click on the screen
################################################################################################################
Application.click_on_middle()
################################################################################################################
# worker thread: Debugger.scriptParsed
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == self.config['file_path']['index']
assert response['params']['endLine'] == 0
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['reason'] == 'Break on start'
################################################################################################################
# worker thread: Debugger.removeBreakpointsByUrl
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.remove_breakpoints_by_url(
self.config['file_path']['index']),
message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=10),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=17),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=25)]
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.get_possible_and_set_breakpoint_by_url(locations),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:10:0:' + self.config['file_path']['index']
assert response['result']['locations'][1]['id'] == 'id:17:0:' + self.config['file_path']['index']
assert response['result']['locations'][2]['id'] == 'id:25:0:' + self.config['file_path']['index']
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == ['id:10:14:' + self.config['file_path']['index']]
################################################################################################################
# worker thread: Runtime.getProperties
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
runtime.get_properties(object_id='0',
own_properties=True,
accessor_properties_only=False,
generate_preview=True),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['result'][0]['name'] == 'add'
assert response['result']['result'][0]['value']['type'] == 'function'
################################################################################################################
# worker thread: Debugger.stepOut
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.step_out(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.paused, hit breakpoint
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['hitBreakpoints'] == ['id:25:4:' + self.config['file_path']['index']]
################################################################################################################
# main thread: Runtime.getProperties
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.get_properties(object_id='0',
own_properties=True,
accessor_properties_only=False,
generate_preview=True),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['result'][0]['name'] == 'taskpoolTest'
assert response['result']['result'][0]['value']['type'] == 'function'
assert response['result']['result'][1]['name'] == 'valueSub'
assert response['result']['result'][1]['value']['type'] == 'undefined'
assert response['result']['result'][2]['name'] == 'valueAdd'
assert response['result']['result'][2]['value']['type'] == 'number'
assert response['result']['result'][2]['value']['description'] == '300'
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.paused
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['hitBreakpoints'] == ['id:17:14:' + self.config['file_path']['index']]
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# close the websocket connections
################################################################################################################
await websocket.send_msg_to_debugger_server(worker_instance_id, worker_thread_to_send_queue, 'close')
await websocket.send_msg_to_debugger_server(main_thread_instance_id, main_thread_to_send_queue, 'close')
await websocket.send_msg_to_connect_server('close')
################################################################################################################

View File

@ -0,0 +1,384 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Description: Scenario test case.
"""
import json
import logging
import os
import time
import pytest
from aw import Application
from aw import Utils
from aw import communicate_with_debugger_server
from aw import debugger, runtime
@pytest.mark.debug
@pytest.mark.timeout(30)
class TestDebug04:
"""
测试用例 task 实例 attach 调试
测试步骤
1. 连接 connect server 和主线程 debugger server
2. 连接子线程 debugger server用于执行 task 任务
3. 所有线程使能 Runtime Debugger
4. 主线程 Index.ts 文件设置断点Debugger.getPossibleAndSetBreakpointByUrl
5. 触发点击事件主线程命中断点
6. 子线程 Index.ts 文件设置断点Debugger.getPossibleAndSetBreakpointByUrl
7. 子线程 resume命中断点Debugger.resume
8. 子线程 getProperties返回给定对象的属性Runtime.getProperties
9. 子线程 stepOut主线程命中断点Debugger.stepOut
10. 主线程 getPropertiesRuntime.getProperties
11. 主线程 resumeDebugger.resume
11. 子线程命中断点后 resumeDebugger.resume
12. 关闭所有线程 debugger server connect server 连接
"""
def setup_method(self):
logging.info('Start running TestDebug04: setup')
self.log_path = rf'{os.path.dirname(__file__)}\..\log'
self.hilog_file_name = 'test_debug_04.hilog.txt'
self.id_generator = Utils.message_id_generator()
# receive the hilog before the test start
Utils.clear_fault_log()
self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path,
file_name=self.hilog_file_name,
debug_on=True)
def teardown_method(self):
Application.uninstall(self.config['bundle_name'])
# terminate the hilog receive process after the test done
time.sleep(3)
self.hilog_process.stdout.close()
self.hilog_process.terminate()
self.hilog_process.wait()
self.write_thread.join()
Utils.save_fault_log(log_path=self.log_path)
logging.info('TestDebug04 done')
def test(self, test_suite_taskpool_01):
logging.info('Start running TestDebug04: test')
self.config = test_suite_taskpool_01
websocket = self.config['websocket']
taskpool = self.config['taskpool']
pid = self.config['pid']
Application.attach(self.config['bundle_name'])
taskpool.submit(websocket.main_task(taskpool, websocket, self.procedure, pid))
taskpool.await_taskpool()
taskpool.task_join()
if taskpool.task_exception:
raise taskpool.task_exception
async def procedure(self, websocket):
################################################################################################################
# main thread: connect the debugger server
################################################################################################################
send_msg = {"type": "connected"}
await websocket.send_msg_to_connect_server(send_msg)
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] == 0, logging.error('instance id of the main thread not equal to 0')
assert response['tid'] == self.config['pid']
main_thread_instance_id = await websocket.get_instance()
main_thread_to_send_queue = websocket.to_send_msg_queues[main_thread_instance_id]
main_thread_received_queue = websocket.received_msg_queues[main_thread_instance_id]
logging.info(f'Connect to the debugger server of instance: {main_thread_instance_id}')
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] != 0
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instance_id = await websocket.get_instance()
worker_thread_to_send_queue = websocket.to_send_msg_queues[worker_instance_id]
worker_thread_received_queue = websocket.received_msg_queues[worker_instance_id]
logging.info(f'Connect to the debugger server of instance: {worker_instance_id}')
################################################################################################################
# main thread: Runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: Runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# main thread: Debugger.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.enable(), message_id)
# main thread: Debugger.scriptParsed
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == self.config['file_path']['index']
assert response['params']['endLine'] == 0
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == self.config['file_path']['entry_ability']
assert response['params']['endLine'] == 0
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# main thread: Runtime.runIfWaitingForDebugger
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.run_if_waiting_for_debugger(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"debuggerId": "0",
"protocols": Utils.get_custom_protocols()}}
################################################################################################################
# worker thread: Runtime.runIfWaitingForDebugger
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
runtime.run_if_waiting_for_debugger(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.removeBreakpointsByUrl
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.remove_breakpoints_by_url(
self.config['file_path']['index']),
message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=10),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=17),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=25)]
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.get_possible_and_set_breakpoint_by_url(locations),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:10:0:' + self.config['file_path']['index']
assert response['result']['locations'][1]['id'] == 'id:17:0:' + self.config['file_path']['index']
assert response['result']['locations'][2]['id'] == 'id:25:0:' + self.config['file_path']['index']
################################################################################################################
# main thread: click on the screen
################################################################################################################
Application.click_on_middle()
################################################################################################################
# worker thread: Debugger.scriptParsed
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.scriptParsed'
assert response['params']['url'] == self.config['file_path']['index']
assert response['params']['endLine'] == 0
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['reason'] == 'Break on start'
################################################################################################################
# worker thread: Debugger.removeBreakpointsByUrl
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.remove_breakpoints_by_url(
self.config['file_path']['index']),
message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.getPossibleAndSetBreakpointByUrl
################################################################################################################
message_id = next(self.id_generator)
locations = [debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=10),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=17),
debugger.BreakLocationUrl(url=self.config['file_path']['index'], line_number=25)]
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.get_possible_and_set_breakpoint_by_url(locations),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['locations'][0]['id'] == 'id:10:0:' + self.config['file_path']['index']
assert response['result']['locations'][1]['id'] == 'id:17:0:' + self.config['file_path']['index']
assert response['result']['locations'][2]['id'] == 'id:25:0:' + self.config['file_path']['index']
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
# worker thread: Debugger.paused
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['reason'] == 'other'
assert response['params']['hitBreakpoints'] == ['id:10:14:' + self.config['file_path']['index']]
################################################################################################################
# worker thread: Runtime.getProperties
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
runtime.get_properties(object_id='0',
own_properties=True,
accessor_properties_only=False,
generate_preview=True),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['result'][0]['name'] == 'add'
assert response['result']['result'][0]['value']['type'] == 'function'
################################################################################################################
# worker thread: Debugger.stepOut
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.step_out(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.paused, hit breakpoint
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['hitBreakpoints'] == ['id:25:4:' + self.config['file_path']['index']]
################################################################################################################
# main thread: Runtime.getProperties
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.get_properties(object_id='0',
own_properties=True,
accessor_properties_only=False,
generate_preview=True),
message_id)
response = json.loads(response)
assert response['id'] == message_id
assert response['result']['result'][0]['name'] == 'taskpoolTest'
assert response['result']['result'][0]['value']['type'] == 'function'
assert response['result']['result'][1]['name'] == 'valueSub'
assert response['result']['result'][1]['value']['type'] == 'undefined'
assert response['result']['result'][2]['name'] == 'valueAdd'
assert response['result']['result'][2]['value']['type'] == 'number'
assert response['result']['result'][2]['value']['description'] == '300'
################################################################################################################
# main thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.paused
################################################################################################################
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
response = json.loads(response)
assert response['method'] == 'Debugger.paused'
assert response['params']['callFrames'][0]['url'] == self.config['file_path']['index']
assert response['params']['hitBreakpoints'] == ['id:17:14:' + self.config['file_path']['index']]
################################################################################################################
# worker thread: Debugger.resume
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instance_id,
worker_thread_to_send_queue,
worker_thread_received_queue,
debugger.resume(), message_id)
assert json.loads(response) == {"method": "Debugger.resumed", "params": {}}
response = await websocket.recv_msg_of_debugger_server(worker_instance_id,
worker_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# close the websocket connections
################################################################################################################
await websocket.send_msg_to_debugger_server(worker_instance_id, worker_thread_to_send_queue, 'close')
await websocket.send_msg_to_debugger_server(main_thread_instance_id, main_thread_to_send_queue, 'close')
await websocket.send_msg_to_connect_server('close')
################################################################################################################

View File

@ -0,0 +1,300 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Description: Scenario test case.
"""
import json
import logging
import os
import time
import pytest
from aw import Application
from aw import Utils
from aw import communicate_with_debugger_server
from aw import debugger, runtime, heap_profiler
@pytest.mark.heap_profiler
@pytest.mark.timeout(40)
class TestHeapProfiler01:
"""
测试用例多实例内存调优 Allocation 录制
测试步骤
1. 拉起应用attach 主线程
2. 连接 connect server 和主线程 debugger server
3. 连接 worker 线程 debugger server
4. 所有线程使能 RuntimeRuntime.enable
5. 所有线程获取内存使用情况Runtime.getHeapUsage
6. 所有线程启动 Allocation 录制HeapProfiler.startTrackingHeapObjects
7. 所有线程获取内存使用情况Runtime.getHeapUsage
8. 等待 10 秒后关闭 Allocation 录制获取数据HeapProfiler.stopTrackingHeapObjects
9. 销毁 worker 线程对应的 debugger server 连接断开
10. 关闭主线程 debugger server connect server 连接
"""
def setup_method(self):
logging.info('Start running TestHeapProfiler01: setup')
self.log_path = rf'{os.path.dirname(__file__)}\..\log'
self.hilog_file_name = 'test_heap_profiler_01.hilog.txt'
self.id_generator = Utils.message_id_generator()
# receive the hilog before the test start
Utils.clear_fault_log()
self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path,
file_name=self.hilog_file_name,
debug_on=True)
def teardown_method(self):
Application.uninstall(self.config['bundle_name'])
# terminate the hilog receive process after the test done
time.sleep(3)
self.hilog_process.stdout.close()
self.hilog_process.terminate()
self.hilog_process.wait()
self.write_thread.join()
Utils.save_fault_log(log_path=self.log_path)
logging.info('TestHeapProfiler01 done')
def test(self, test_suite_worker_02):
logging.info('Start running TestHeapProfiler01: test')
self.config = test_suite_worker_02
websocket = self.config['websocket']
taskpool = self.config['taskpool']
pid = self.config['pid']
Application.attach(self.config['bundle_name'])
taskpool.submit(websocket.main_task(taskpool, websocket, self.procedure, pid))
taskpool.await_taskpool()
taskpool.task_join()
if taskpool.task_exception:
raise taskpool.task_exception
async def procedure(self, websocket):
################################################################################################################
# main thread: connect the debugger server
################################################################################################################
send_msg = {"type": "connected"}
await websocket.send_msg_to_connect_server(send_msg)
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] == 0, logging.error('instance id of the main thread not equal to 0')
assert response['tid'] == self.config['pid']
main_thread_instance_id = await websocket.get_instance()
main_thread_to_send_queue = websocket.to_send_msg_queues[main_thread_instance_id]
main_thread_received_queue = websocket.received_msg_queues[main_thread_instance_id]
logging.info(f'Connect to the debugger server of instance: {main_thread_instance_id}')
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
workers_num = 2
worker_instances_id = []
worker_thread_to_send_queues = []
worker_thread_received_queues = []
for i in range(workers_num):
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] != 0
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instance_id = await websocket.get_instance()
worker_instances_id.append(worker_instance_id)
worker_thread_to_send_queues.append(websocket.to_send_msg_queues[worker_instance_id])
worker_thread_received_queues.append(websocket.received_msg_queues[worker_instance_id])
logging.info(f'Connect to the debugger server of instance: {worker_instance_id}')
################################################################################################################
# main thread: Runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: Runtime.enable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# main thread: Runtime.getHeapUsage
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.get_heap_usage(), message_id)
response = json.loads(response)
assert response['result']['usedSize'] > 0
assert response['result']['totalSize'] > 0
################################################################################################################
# worker thread: Runtime.getHeapUsage
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
runtime.get_heap_usage(), message_id)
response = json.loads(response)
assert response['result']['usedSize'] > 0
assert response['result']['totalSize'] > 0
################################################################################################################
# main thread: HeapProfiler.startTrackingHeapObjects
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
heap_profiler.start_tracking_heap_objects(False),
message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: HeapProfiler.startTrackingHeapObjects
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
heap_profiler.start_tracking_heap_objects(False),
message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: Debugger.disable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.disable(), message_id)
while not json.loads(response).get('id', None):
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.disable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
debugger.disable(), message_id)
while not json.loads(response).get('id', None):
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# all thread: sleep 10 seconds
################################################################################################################
time.sleep(10)
################################################################################################################
# main thread: Runtime.getHeapUsage
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.get_heap_usage(), message_id)
while response.startswith('{"method":"HeapProfiler.lastSeenObjectId"'):
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
response = json.loads(response)
assert response['result']['usedSize'] > 0
assert response['result']['totalSize'] > 0
################################################################################################################
# worker thread: Runtime.getHeapUsage
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
runtime.get_heap_usage(), message_id)
while response.startswith('{"method":"HeapProfiler.lastSeenObjectId"'):
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
response = json.loads(response)
assert response['result']['usedSize'] > 0
assert response['result']['totalSize'] > 0
################################################################################################################
# main thread: HeapProfiler.stopTrackingHeapObjects
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
heap_profiler.stop_tracking_heap_objects(), message_id)
while response.startswith('{"method":"HeapProfiler.lastSeenObjectId"'):
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert r'\"location_fields\":[\"object_index\",\"script_id\",\"line\",\"column\"]' in response
pre_response = response
while response.startswith('{"method":"HeapProfiler.addHeapSnapshotChunk"') or\
response.startswith('{"method":"HeapProfiler.lastSeenObjectId"'):
if response.startswith('{"method":"HeapProfiler.addHeapSnapshotChunk"'):
pre_response = response
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert pre_response.endswith(r'\n]\n}\n"}}')
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: HeapProfiler.stopTrackingHeapObjects
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
heap_profiler.stop_tracking_heap_objects(), message_id)
while response.startswith('{"method":"HeapProfiler.lastSeenObjectId"'):
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
assert r'\"location_fields\":[\"object_index\",\"script_id\",\"line\",\"column\"]' in response
pre_response = response
while response.startswith('{"method":"HeapProfiler.addHeapSnapshotChunk"') or\
response.startswith('{"method":"HeapProfiler.lastSeenObjectId"'):
if response.startswith('{"method":"HeapProfiler.addHeapSnapshotChunk"'):
pre_response = response
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
assert pre_response.endswith(r'\n]\n}\n"}}')
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: destroy instance
################################################################################################################
for i in range(workers_num):
await websocket.send_msg_to_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i], 'close')
################################################################################################################
# close the websocket connections
################################################################################################################
await websocket.send_msg_to_debugger_server(main_thread_instance_id, main_thread_to_send_queue, 'close')
await websocket.send_msg_to_connect_server('close')
################################################################################################################

View File

@ -0,0 +1,246 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (c) 2024 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Description: Scenario test case.
"""
import json
import logging
import os
import time
import pytest
from aw import Application
from aw import Utils
from aw import communicate_with_debugger_server
from aw import debugger, runtime, heap_profiler
@pytest.mark.heap_profiler
@pytest.mark.timeout(40)
class TestHeapProfiler02:
"""
测试用例多实例内存调优 HeapDump 录制
测试步骤
1. 拉起应用attach 主线程
2. 连接 connect server 和主线程 debugger server
3. 连接 worker 线程 debugger server
4. 所有线程使能 RuntimeRuntime.enable
5. 所有线程去使能 DebuggerDebugger.disable
5. 所有线程拍摄内存快照HeapProfiler.takeHeapSnapshot
6. 等待 10 秒后所有线程再次拍摄内存快照HeapProfiler.takeHeapSnapshot
7. 销毁 worker 线程对应的 debugger server 连接断开
8. 关闭主线程 debugger server connect server 连接
"""
def setup_method(self):
logging.info('Start running TestHeapProfiler02: setup')
self.log_path = rf'{os.path.dirname(__file__)}\..\log'
self.hilog_file_name = 'test_heap_profiler_02.hilog.txt'
self.id_generator = Utils.message_id_generator()
# receive the hilog before the test start
Utils.clear_fault_log()
self.hilog_process, self.write_thread = Utils.save_hilog(log_path=self.log_path,
file_name=self.hilog_file_name,
debug_on=True)
def teardown_method(self):
Application.uninstall(self.config['bundle_name'])
# terminate the hilog receive process after the test done
time.sleep(3)
self.hilog_process.stdout.close()
self.hilog_process.terminate()
self.hilog_process.wait()
self.write_thread.join()
Utils.save_fault_log(log_path=self.log_path)
logging.info('TestHeapProfiler02 done')
def test(self, test_suite_worker_02):
logging.info('Start running TestHeapProfiler02: test')
self.config = test_suite_worker_02
websocket = self.config['websocket']
taskpool = self.config['taskpool']
pid = self.config['pid']
Application.attach(self.config['bundle_name'])
taskpool.submit(websocket.main_task(taskpool, websocket, self.procedure, pid))
taskpool.await_taskpool()
taskpool.task_join()
if taskpool.task_exception:
raise taskpool.task_exception
async def procedure(self, websocket):
################################################################################################################
# main thread: connect the debugger server
################################################################################################################
send_msg = {"type": "connected"}
await websocket.send_msg_to_connect_server(send_msg)
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] == 0, logging.error('instance id of the main thread not equal to 0')
assert response['tid'] == self.config['pid']
main_thread_instance_id = await websocket.get_instance()
main_thread_to_send_queue = websocket.to_send_msg_queues[main_thread_instance_id]
main_thread_received_queue = websocket.received_msg_queues[main_thread_instance_id]
logging.info(f'Connect to the debugger server of instance: {main_thread_instance_id}')
################################################################################################################
# worker thread: connect the debugger server
################################################################################################################
workers_num = 2
worker_instances_id = []
worker_thread_to_send_queues = []
worker_thread_received_queues = []
for i in range(workers_num):
response = await websocket.recv_msg_of_connect_server()
response = json.loads(response)
assert response['type'] == 'addInstance'
assert response['instanceId'] != 0
assert response['tid'] != self.config['pid']
assert 'workerThread_' in response['name']
worker_instance_id = await websocket.get_instance()
worker_instances_id.append(worker_instance_id)
worker_thread_to_send_queues.append(websocket.to_send_msg_queues[worker_instance_id])
worker_thread_received_queues.append(websocket.received_msg_queues[worker_instance_id])
logging.info(f'Connect to the debugger server of instance: {worker_instance_id}')
################################################################################################################
# main thread: Runtime.enable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# worker thread: Runtime.enable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
runtime.enable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {"protocols": []}}
################################################################################################################
# main thread: Debugger.disable
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
debugger.disable(), message_id)
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: Debugger.disable
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
debugger.disable(), message_id)
while not json.loads(response).get('id', None):
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# main thread: HeapProfiler.takeHeapSnapshot
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
heap_profiler.take_heap_snapshot(), message_id)
assert r'\"location_fields\":[\"object_index\",\"script_id\",\"line\",\"column\"]' in response
pre_response = response
while response.startswith('{"method":"HeapProfiler.addHeapSnapshotChunk"'):
pre_response = response
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert pre_response.endswith(r'\n]\n}\n"}}')
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: HeapProfiler.takeHeapSnapshot
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
heap_profiler.take_heap_snapshot(), message_id)
assert r'\"location_fields\":[\"object_index\",\"script_id\",\"line\",\"column\"]' in response
pre_response = response
while response.startswith('{"method":"HeapProfiler.addHeapSnapshotChunk"'):
pre_response = response
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
assert pre_response.endswith(r'\n]\n}\n"}}')
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# all thread: sleep 10 seconds
################################################################################################################
time.sleep(10)
################################################################################################################
# main thread: HeapProfiler.takeHeapSnapshot
################################################################################################################
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(main_thread_instance_id,
main_thread_to_send_queue,
main_thread_received_queue,
heap_profiler.take_heap_snapshot(), message_id)
assert r'\"location_fields\":[\"object_index\",\"script_id\",\"line\",\"column\"]' in response
pre_response = response
while response.startswith('{"method":"HeapProfiler.addHeapSnapshotChunk"'):
pre_response = response
response = await websocket.recv_msg_of_debugger_server(main_thread_instance_id,
main_thread_received_queue)
assert pre_response.endswith(r'\n]\n}\n"}}')
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: HeapProfiler.takeHeapSnapshot
################################################################################################################
for i in range(workers_num):
message_id = next(self.id_generator)
response = await communicate_with_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i],
worker_thread_received_queues[i],
heap_profiler.take_heap_snapshot(), message_id)
assert r'\"location_fields\":[\"object_index\",\"script_id\",\"line\",\"column\"]' in response
pre_response = response
while response.startswith('{"method":"HeapProfiler.addHeapSnapshotChunk"'):
pre_response = response
response = await websocket.recv_msg_of_debugger_server(worker_instances_id[i],
worker_thread_received_queues[i])
assert pre_response.endswith(r'\n]\n}\n"}}')
assert json.loads(response) == {"id": message_id, "result": {}}
################################################################################################################
# worker thread: destroy instance
################################################################################################################
for i in range(workers_num):
await websocket.send_msg_to_debugger_server(worker_instances_id[i],
worker_thread_to_send_queues[i], 'close')
################################################################################################################
# close the websocket connections
################################################################################################################
await websocket.send_msg_to_debugger_server(main_thread_instance_id, main_thread_to_send_queue, 'close')
await websocket.send_msg_to_connect_server('close')
################################################################################################################