-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
twister: pytest: Bluetooth: multi harness boards test against DuT #83641
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Copyright (c) 2025 NXP | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import logging | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def test_os_boot(dut, harness_devices): | ||
dut.readlines_until('Booting Zephyr OS build', timeout=5) | ||
harness_devices[0].readlines_until('Booting Zephyr OS build', timeout=5) | ||
|
||
|
||
def test_bluetooth_boot(dut, harness_devices): | ||
dut.readlines_until('Scanning successfully started', timeout=5) | ||
harness_devices[0].readlines_until('Advertising successfully started', timeout=5) | ||
|
||
|
||
def test_bluetooth_connection(dut, harness_devices): | ||
dut.readlines_until('Connected', timeout=5) | ||
|
||
|
||
def test_match_temp_value_over_ble(dut, harness_devices): | ||
dut.readlines_until(r'Temperature \d{1,2}C', timeout=5) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Copyright (c) 2025 NXP | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import logging | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def test_os_boot(dut, harness_devices): | ||
dut.readlines_until('Booting Zephyr OS build', timeout=5) | ||
harness_devices[0].readlines_until('Booting Zephyr OS build', timeout=5) | ||
|
||
|
||
def test_bluetooth_boot(dut, harness_devices): | ||
dut.readlines_until('Advertising successfully started', timeout=5) | ||
harness_devices[0].readlines_until('Scanning successfully started', timeout=5) | ||
|
||
|
||
def test_bluetooth_connection(dut, harness_devices): | ||
harness_devices[0].readlines_until('Connected', timeout=5) | ||
|
||
|
||
def test_match_temp_value_over_ble(dut, harness_devices): | ||
dut.readlines_until('Indication success', timeout=5) | ||
harness_devices[0].readlines_until(r'Temperature \d{1,2}C', timeout=5) | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,10 +25,13 @@ tests: | |
- mimxrt1020_evk | ||
sample.bluetooth.peripheral_ht.nxp: | ||
# Disabling monolithic since CI environment doesn't use blobs | ||
build_only: true | ||
harness: bluetooth | ||
harness: pytest | ||
platform_allow: | ||
- rd_rw612_bga | ||
- frdm_rw612 | ||
- frdm_mcxw71/mcxw716c | ||
extra_configs: | ||
- CONFIG_NXP_MONOLITHIC_NBU=n | ||
harness_config: | ||
pytest_dut_scope: session | ||
pytest_args: ['--harness_apps=zephyr/samples/bluetooth/central_ht'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seeing from below code, the harness_apps is a list, so need define list like
by the way, why start from zephyr? |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,12 +2,16 @@ | |
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
import os | ||
import sys | ||
import copy | ||
import logging | ||
import time | ||
import subprocess | ||
from pathlib import Path | ||
from typing import Generator, Type | ||
|
||
import pytest | ||
import time | ||
|
||
from twister_harness.device.device_adapter import DeviceAdapter | ||
from twister_harness.device.factory import DeviceFactory | ||
|
@@ -16,6 +20,11 @@ | |
from twister_harness.helpers.mcumgr import MCUmgr | ||
from twister_harness.helpers.utils import find_in_config | ||
|
||
from twister_harness.helpers.domains_helper import ZEPHYR_BASE | ||
sys.path.insert(0, os.path.join(ZEPHYR_BASE, 'scripts')) # import zephyr_module in environment.py | ||
sys.path.insert(0, os.path.join(ZEPHYR_BASE, 'scripts', 'pylib', 'twister')) | ||
from twisterlib.hardwaremap import HardwareMap | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is not good, why fixture mixed with hardware map which supposed to be platform agnostic There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hi hake, thanks for these review and comments, I put the harness devices configuration info in another yaml, and want to import and reuse twister HardwareMap class to load and parse this new yaml, for the harness boards info, do you have any suggestion, where/which file to store/manage those info ? all the boards in the current dut_map.yaml will be recognized as duts and scheduled for tests in parallels. |
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
|
@@ -92,3 +101,70 @@ def is_mcumgr_available() -> None: | |
@pytest.fixture() | ||
def mcumgr(is_mcumgr_available: None, dut: DeviceAdapter) -> Generator[MCUmgr, None, None]: | ||
yield MCUmgr.create_for_serial(dut.device_config.serial) | ||
|
||
|
||
@pytest.fixture(scope='session') | ||
def harness_devices(request, twister_harness_config): | ||
"""Return harness_device list object.""" | ||
|
||
class TwisterOptionsWrapper: | ||
|
||
device_flash_timeout: float = 60.0 # [s] | ||
device_flash_with_test: bool = True | ||
flash_before: bool = False | ||
|
||
harness_device_yml = request.config.getoption('--harness_device_map') | ||
harness_apps = request.config.getoption('--harness_apps') | ||
logger.info(f'harness_device_yml:{harness_device_yml}') | ||
logger.info(f'harness_apps:{harness_apps}') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please update the twister doc to explain the usage of this harness |
||
|
||
harness_app_list = harness_apps.split(' ') | ||
logger.info(f'harness_app:{harness_app_list}') | ||
|
||
# reuse twister HardwareMap class to load harness device config yaml | ||
options = TwisterOptionsWrapper() | ||
harness_device_hwm = HardwareMap(options) | ||
harness_device_hwm.load(harness_device_yml) | ||
logger.info(f'harness_device_hwm[0]:{harness_device_hwm.duts[0]}') | ||
|
||
if not harness_device_hwm.duts or (len(harness_app_list) != len(harness_device_hwm.duts)): | ||
pytest.skip("Skipping all tests due to wrong harness setting.") | ||
|
||
# reuse most dut config for harness_device, only build and flash different app into them | ||
dut_device_config: DeviceConfig = twister_harness_config.devices[0] | ||
logger.info(f'dut_device_config:{dut_device_config}') | ||
|
||
harness_devices = [] | ||
for index, harness_hw in enumerate(harness_device_hwm.duts): | ||
harness_app = harness_app_list[index] | ||
# split harness_app into appname, extra_config | ||
harness_app = harness_app.split('-') | ||
appname, extra_config = harness_app[0], harness_app[1:] | ||
extra_config = ['-' + config for config in extra_config] | ||
# build harness_app image for harness device | ||
build_dir = f'./harness_{harness_hw.platform}_{os.path.basename(appname)}' | ||
cmd = ['west', 'build', appname, '-b', harness_hw.platform, '--build-dir', build_dir] + extra_config | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could be update in CMakefile as dependency. refer to samples/subsys/ipc/openamp/remote There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks hake, will check how to do this with CMakefile system for the dependency board settings |
||
logger.info(' '.join(cmd)) | ||
logger.info(os.getcwd()) | ||
subprocess.call(cmd) | ||
|
||
# update the specific configuration for harness_hw | ||
harness_device_config = copy.deepcopy(dut_device_config) | ||
harness_device_config.id = harness_hw.id | ||
harness_device_config.serial = harness_hw.serial | ||
harness_device_config.build_dir = Path(build_dir) | ||
logger.info(f'harness_device_config:{harness_device_config}') | ||
|
||
# init harness device as DuT | ||
device_class: Type[DeviceAdapter] = DeviceFactory.get_device(harness_device_config.type) | ||
device_object = device_class(harness_device_config) | ||
device_object.initialize_log_files(request.node.name) | ||
harness_devices.append(device_object) | ||
|
||
try: | ||
for device_object in harness_devices: | ||
device_object.launch() | ||
yield harness_devices | ||
finally: # to make sure we close all running processes execution | ||
for device_object in harness_devices: | ||
device_object.close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will the test case be running as part of PR CI, nightly or weekly on the upstream main branch? (if not, these test vectors can get stale when someone change the strings).