Skip to content

Commit 437b905

Browse files
committed
[nrf fromtree] twister: Allow sharing hardware platform between variants
Extended hardware map to share a single board between variants. To run tests for different variants on the same board without re-configuring the hardware map file for each variant, one can use a `platform` atribute as a list of names. Signed-off-by: Grzegorz Chwierut <[email protected]> (cherry picked from commit e0bd7e7)
1 parent b257192 commit 437b905

File tree

5 files changed

+75
-32
lines changed

5 files changed

+75
-32
lines changed

doc/develop/test/twister.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,25 @@ using an external J-Link probe. The ``probe_id`` keyword overrides the
12551255
runner: jlink
12561256
serial: null
12571257
1258+
Using Single Board For Multiple Variants
1259+
++++++++++++++++++++++++++++++++++++++++
1260+
1261+
The ``platform`` attribute can be a list of names or a string
1262+
with names separated by spaces. This allows to run tests for
1263+
different platform variants on the same physical board, without
1264+
re-configuring the hardware map file for each variant. For example:
1265+
1266+
.. code-block:: yaml
1267+
1268+
- connected: true
1269+
id: '001234567890'
1270+
platform:
1271+
- nrf5340dk/nrf5340/cpuapp
1272+
- nrf5340dk/nrf5340/cpuapp/ns
1273+
product: J-Link
1274+
runner: nrfjprog
1275+
serial: /dev/ttyACM1
1276+
12581277
Quarantine
12591278
++++++++++
12601279

scripts/pylib/twister/twisterlib/handlers.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import threading
2222
import time
2323

24+
from contextlib import contextmanager
2425
from pathlib import Path
2526
from queue import Queue, Empty
2627
from twisterlib.environment import ZEPHYR_BASE, strip_ansi_sequences
@@ -458,6 +459,17 @@ def monitor_serial(self, ser, halt_event, harness):
458459

459460
log_out_fp.close()
460461

462+
@staticmethod
463+
@contextmanager
464+
def acquire_dut_locks(duts):
465+
try:
466+
for d in duts:
467+
d.lock.acquire()
468+
yield
469+
finally:
470+
for d in duts:
471+
d.lock.release()
472+
461473
def device_is_available(self, instance):
462474
device = instance.platform.name
463475
fixture = instance.testsuite.harness_config.get("fixture")
@@ -475,15 +487,16 @@ def device_is_available(self, instance):
475487

476488
# Select an available DUT with less failures
477489
for d in sorted(duts_found, key=lambda _dut: _dut.failures):
478-
d.lock.acquire()
479-
avail = False
480-
if d.available:
481-
d.available = 0
482-
d.counter_increment()
483-
avail = True
484-
logger.debug(f"Retain DUT:{d.platform}, Id:{d.id}, "
485-
f"counter:{d.counter}, failures:{d.failures}")
486-
d.lock.release()
490+
duts_shared_hw = [_d for _d in self.duts if _d.id == d.id] # get all DUTs with the same id
491+
with self.acquire_dut_locks(duts_shared_hw):
492+
avail = False
493+
if d.available:
494+
for _d in duts_shared_hw:
495+
_d.available = 0
496+
d.counter_increment()
497+
avail = True
498+
logger.debug(f"Retain DUT:{d.platform}, Id:{d.id}, "
499+
f"counter:{d.counter}, failures:{d.failures}")
487500
if avail:
488501
return d
489502

@@ -494,7 +507,10 @@ def make_dut_available(self, dut):
494507
dut.failures_increment()
495508
logger.debug(f"Release DUT:{dut.platform}, Id:{dut.id}, "
496509
f"counter:{dut.counter}, failures:{dut.failures}")
497-
dut.available = 1
510+
duts_shared_hw = [_d for _d in self.duts if _d.id == dut.id] # get all DUTs with the same id
511+
with self.acquire_dut_locks(duts_shared_hw):
512+
for _d in duts_shared_hw:
513+
_d.available = 1
498514

499515
@staticmethod
500516
def run_custom_script(script, timeout):

scripts/pylib/twister/twisterlib/hardwaremap.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,13 @@ def load(self, map_file):
259259
flash_before = dut.get('flash_before')
260260
if flash_before is None:
261261
flash_before = self.options.flash_before and (not (flash_with_test or serial_pty))
262-
platform = dut.get('platform')
262+
platform = dut.get('platform')
263+
if isinstance(platform, str):
264+
platforms = platform.split()
265+
elif isinstance(platform, list):
266+
platforms = platform
267+
else:
268+
raise ValueError(f"Invalid platform value: {platform}")
263269
id = dut.get('id')
264270
runner = dut.get('runner')
265271
runner_params = dut.get('runner_params')
@@ -268,28 +274,29 @@ def load(self, map_file):
268274
baud = dut.get('baud', None)
269275
product = dut.get('product')
270276
fixtures = dut.get('fixtures', [])
271-
connected= dut.get('connected') and ((serial or serial_pty) is not None)
277+
connected = dut.get('connected') and ((serial or serial_pty) is not None)
272278
if not connected:
273279
continue
274-
new_dut = DUT(platform=platform,
275-
product=product,
276-
runner=runner,
277-
runner_params=runner_params,
278-
id=id,
279-
serial_pty=serial_pty,
280-
serial=serial,
281-
serial_baud=baud,
282-
connected=connected,
283-
pre_script=pre_script,
284-
flash_before=flash_before,
285-
post_script=post_script,
286-
post_flash_script=post_flash_script,
287-
script_param=script_param,
288-
flash_timeout=flash_timeout,
289-
flash_with_test=flash_with_test)
290-
new_dut.fixtures = fixtures
291-
new_dut.counter = 0
292-
self.duts.append(new_dut)
280+
for plat in platforms:
281+
new_dut = DUT(platform=plat,
282+
product=product,
283+
runner=runner,
284+
runner_params=runner_params,
285+
id=id,
286+
serial_pty=serial_pty,
287+
serial=serial,
288+
serial_baud=baud,
289+
connected=connected,
290+
pre_script=pre_script,
291+
flash_before=flash_before,
292+
post_script=post_script,
293+
post_flash_script=post_flash_script,
294+
script_param=script_param,
295+
flash_timeout=flash_timeout,
296+
flash_with_test=flash_with_test)
297+
new_dut.fixtures = fixtures
298+
new_dut.counter = 0
299+
self.duts.append(new_dut)
293300

294301
def scan(self, persistent=False):
295302
from serial.tools import list_ports

scripts/schemas/twister/hwmap-schema.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ sequence:
1616
type: str
1717
required: false
1818
"platform":
19-
type: str
19+
type: any
2020
required: true
2121
"probe_id":
2222
type: str

scripts/tests/twister/test_handlers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,7 @@ def mock_serial(*args, **kwargs):
12731273
dut = DUT()
12741274
dut.available = 0
12751275
dut.failures = 0
1276+
handler.duts = [dut]
12761277

12771278
hardware_baud = 14400
12781279
flash_timeout = 60

0 commit comments

Comments
 (0)