Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions doc/develop/test/twister.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,25 @@ using an external J-Link probe. The ``probe_id`` keyword overrides the
runner: jlink
serial: null

Using Single Board For Multiple Variants
++++++++++++++++++++++++++++++++++++++++

The ``platform`` attribute can be a list of names or a string
with names separated by spaces. This allows to run tests for
different platform variants on the same physical board, without
re-configuring the hardware map file for each variant. For example:

.. code-block:: yaml

- connected: true
id: '001234567890'
platform:
- nrf5340dk/nrf5340/cpuapp
- nrf5340dk/nrf5340/cpuapp/ns
product: J-Link
runner: nrfjprog
serial: /dev/ttyACM1

Quarantine
++++++++++

Expand Down
36 changes: 26 additions & 10 deletions scripts/pylib/twister/twisterlib/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import threading
import time

from contextlib import contextmanager
from pathlib import Path
from queue import Queue, Empty
from twisterlib.environment import ZEPHYR_BASE, strip_ansi_sequences
Expand Down Expand Up @@ -457,6 +458,17 @@ def monitor_serial(self, ser, halt_event, harness):

log_out_fp.close()

@staticmethod
@contextmanager
def acquire_dut_locks(duts):
try:
for d in duts:
d.lock.acquire()
yield
finally:
for d in duts:
d.lock.release()

def device_is_available(self, instance):
device = instance.platform.name
fixture = instance.testsuite.harness_config.get("fixture")
Expand All @@ -474,15 +486,16 @@ def device_is_available(self, instance):

# Select an available DUT with less failures
for d in sorted(duts_found, key=lambda _dut: _dut.failures):
d.lock.acquire()
avail = False
if d.available:
d.available = 0
d.counter_increment()
avail = True
logger.debug(f"Retain DUT:{d.platform}, Id:{d.id}, "
f"counter:{d.counter}, failures:{d.failures}")
d.lock.release()
duts_shared_hw = [_d for _d in self.duts if _d.id == d.id] # get all DUTs with the same id
with self.acquire_dut_locks(duts_shared_hw):
avail = False
if d.available:
for _d in duts_shared_hw:
_d.available = 0
d.counter_increment()
avail = True
logger.debug(f"Retain DUT:{d.platform}, Id:{d.id}, "
f"counter:{d.counter}, failures:{d.failures}")
if avail:
return d

Expand All @@ -493,7 +506,10 @@ def make_dut_available(self, dut):
dut.failures_increment()
logger.debug(f"Release DUT:{dut.platform}, Id:{dut.id}, "
f"counter:{dut.counter}, failures:{dut.failures}")
dut.available = 1
duts_shared_hw = [_d for _d in self.duts if _d.id == dut.id] # get all DUTs with the same id
with self.acquire_dut_locks(duts_shared_hw):
for _d in duts_shared_hw:
_d.available = 1

@staticmethod
def run_custom_script(script, timeout):
Expand Down
49 changes: 28 additions & 21 deletions scripts/pylib/twister/twisterlib/hardwaremap.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,36 +262,43 @@ def load(self, map_file):
flash_before = dut.get('flash_before')
if flash_before is None:
flash_before = self.options.flash_before and (not (flash_with_test or serial_pty))
platform = dut.get('platform')
platform = dut.get('platform')
if isinstance(platform, str):
platforms = platform.split()
elif isinstance(platform, list):
platforms = platform
else:
raise ValueError(f"Invalid platform value: {platform}")
id = dut.get('id')
runner = dut.get('runner')
runner_params = dut.get('runner_params')
serial = dut.get('serial')
baud = dut.get('baud', None)
product = dut.get('product')
fixtures = dut.get('fixtures', [])
connected= dut.get('connected') and ((serial or serial_pty) is not None)
connected = dut.get('connected') and ((serial or serial_pty) is not None)
if not connected:
continue
new_dut = DUT(platform=platform,
product=product,
runner=runner,
runner_params=runner_params,
id=id,
serial_pty=serial_pty,
serial=serial,
serial_baud=baud,
connected=connected,
pre_script=pre_script,
flash_before=flash_before,
post_script=post_script,
post_flash_script=post_flash_script,
script_param=script_param,
flash_timeout=flash_timeout,
flash_with_test=flash_with_test)
new_dut.fixtures = fixtures
new_dut.counter = 0
self.duts.append(new_dut)
for plat in platforms:
new_dut = DUT(platform=plat,
product=product,
runner=runner,
runner_params=runner_params,
id=id,
serial_pty=serial_pty,
serial=serial,
serial_baud=baud,
connected=connected,
pre_script=pre_script,
flash_before=flash_before,
post_script=post_script,
post_flash_script=post_flash_script,
script_param=script_param,
flash_timeout=flash_timeout,
flash_with_test=flash_with_test)
new_dut.fixtures = fixtures
new_dut.counter = 0
self.duts.append(new_dut)

def scan(self, persistent=False):
from serial.tools import list_ports
Expand Down
2 changes: 1 addition & 1 deletion scripts/schemas/twister/hwmap-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ sequence:
type: str
required: false
"platform":
type: str
type: any
required: true
"probe_id":
type: str
Expand Down
1 change: 1 addition & 0 deletions scripts/tests/twister/test_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,7 @@ def mock_serial(*args, **kwargs):
dut = DUT()
dut.available = 0
dut.failures = 0
handler.duts = [dut]
Copy link
Member

@golowanow golowanow Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to have some tests added for the changed behavior with several DUTs in the list


hardware_baud = 14400
flash_timeout = 60
Expand Down
Loading