Skip to content

Commit 456c153

Browse files
committed
scripts: twister: Fix --flash-before with serial-pty script
Honor the --flash-before option when using a serial-pty script with --device-serial-pty <script> and start the script only after flashing the device. Signed-off-by: Tim Pambor <[email protected]>
1 parent 7819196 commit 456c153

File tree

2 files changed

+45
-48
lines changed

2 files changed

+45
-48
lines changed

scripts/pylib/twister/twisterlib/handlers.py

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -682,28 +682,21 @@ def get_hardware(self):
682682
logger.error(self.instance.reason)
683683
return hardware
684684

685-
def _get_serial_device(self, serial_pty, hardware_serial):
685+
def _start_serial_pty(self, serial_pty, serial_pty_master):
686686
ser_pty_process = None
687-
if serial_pty:
688-
master, slave = pty.openpty()
689-
try:
690-
ser_pty_process = subprocess.Popen(
691-
re.split('[, ]', serial_pty),
692-
stdout=master,
693-
stdin=master,
694-
stderr=master
695-
)
696-
except subprocess.CalledProcessError as error:
697-
logger.error(
698-
f"Failed to run subprocess {serial_pty}, error {error.output}"
699-
)
700-
return
701-
702-
serial_device = os.ttyname(slave)
703-
else:
704-
serial_device = hardware_serial
687+
try:
688+
ser_pty_process = subprocess.Popen(
689+
re.split('[, ]', serial_pty),
690+
stdout=serial_pty_master,
691+
stdin=serial_pty_master,
692+
stderr=serial_pty_master
693+
)
694+
except subprocess.CalledProcessError as error:
695+
logger.error(
696+
f"Failed to run subprocess {serial_pty}, error {error.output}"
697+
)
705698

706-
return serial_device, ser_pty_process
699+
return ser_pty_process
707700

708701
def handle(self, harness):
709702
runner = None
@@ -716,7 +709,11 @@ def handle(self, harness):
716709
runner = hardware.runner or self.options.west_runner
717710
serial_pty = hardware.serial_pty
718711

719-
serial_device, ser_pty_process = self._get_serial_device(serial_pty, hardware.serial)
712+
if not serial_pty:
713+
serial_device = hardware.serial
714+
else:
715+
ser_pty_master, slave = pty.openpty()
716+
serial_device = os.ttyname(slave)
720717

721718
logger.debug(f"Using serial device {serial_device} @ {hardware.baud} baud")
722719

@@ -738,7 +735,10 @@ def handle(self, harness):
738735
flash_timeout += self.get_test_timeout()
739736

740737
serial_port = None
738+
ser_pty_process = None
741739
if hardware.flash_before is False:
740+
if serial_pty:
741+
ser_pty_process = self._start_serial_pty(serial_pty, ser_pty_master)
742742
serial_port = serial_device
743743

744744
try:
@@ -804,6 +804,8 @@ def handle(self, harness):
804804
# Connect to device after flashing it
805805
if hardware.flash_before:
806806
try:
807+
if serial_pty:
808+
ser_pty_process = self._start_serial_pty(serial_pty, ser_pty_master)
807809
logger.debug(f"Attach serial device {serial_device} @ {hardware.baud} baud")
808810
ser.port = serial_device
809811
ser.open()

scripts/tests/twister/test_handlers.py

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,21 +1308,19 @@ def mock_serial(*args, **kwargs):
13081308

13091309

13101310
TESTDATA_16 = [
1311-
('dummy1 dummy2', None, 'slave name'),
1312-
('dummy1,dummy2', CalledProcessError, None),
1313-
(None, None, 'dummy hardware serial'),
1311+
('dummy1 dummy2', None),
1312+
('dummy1,dummy2', CalledProcessError),
13141313
]
13151314

13161315
@pytest.mark.parametrize(
1317-
'serial_pty, popen_exception, expected_device',
1316+
'serial_pty, popen_exception',
13181317
TESTDATA_16,
1319-
ids=['pty', 'pty process error', 'no pty']
1318+
ids=['pty', 'pty process error']
13201319
)
1321-
def test_devicehandler_get_serial_device(
1320+
def test_devicehandler_start_serial_pty(
13221321
mocked_instance,
13231322
serial_pty,
1324-
popen_exception,
1325-
expected_device
1323+
popen_exception
13261324
):
13271325
def mock_popen(command, *args, **kwargs):
13281326
assert command == ['dummy1', 'dummy2']
@@ -1331,21 +1329,16 @@ def mock_popen(command, *args, **kwargs):
13311329
return mock.Mock()
13321330

13331331
handler = DeviceHandler(mocked_instance, 'build', mock.Mock())
1334-
hardware_serial = 'dummy hardware serial'
13351332

13361333
popen_mock = mock.Mock(side_effect=mock_popen)
1337-
openpty_mock = mock.Mock(return_value=('master', 'slave'))
1338-
ttyname_mock = mock.Mock(side_effect=lambda x: x + ' name')
13391334

1340-
with mock.patch('subprocess.Popen', popen_mock), \
1341-
mock.patch('pty.openpty', openpty_mock), \
1342-
mock.patch('os.ttyname', ttyname_mock):
1343-
result = handler._get_serial_device(serial_pty, hardware_serial)
1335+
with mock.patch('subprocess.Popen', popen_mock):
1336+
result = handler._start_serial_pty(serial_pty, 'master')
13441337

13451338
if popen_exception:
13461339
assert result is None
13471340
else:
1348-
assert result[0] == expected_device
1341+
assert result is not None
13491342

13501343
TESTDATA_17 = [
13511344
(False, False, False, False, None, False, False,
@@ -1387,16 +1380,13 @@ def test_devicehandler_handle(
13871380
expected_reason,
13881381
expected_logs
13891382
):
1390-
def mock_get_serial(serial_pty, hardware_serial):
1391-
if serial_pty:
1392-
serial_pty_process = mock.Mock(
1393-
name='dummy serial PTY process',
1394-
communicate=mock.Mock(
1395-
return_value=('', '')
1396-
)
1383+
def mock_start_serial_pty(serial_pty, serial_pty_master):
1384+
return mock.Mock(
1385+
name='dummy serial PTY process',
1386+
communicate=mock.Mock(
1387+
return_value=('', '')
13971388
)
1398-
return 'dummy serial PTY device', serial_pty_process
1399-
return 'dummy serial device', None
1389+
)
14001390

14011391
def mock_create_serial(*args, **kwargs):
14021392
if raise_create_serial:
@@ -1450,7 +1440,7 @@ def mock_popen(command, *args, **kwargs):
14501440
west_flash=None,
14511441
west_runner=None
14521442
)
1453-
handler._get_serial_device = mock.Mock(side_effect=mock_get_serial)
1443+
handler._start_serial_pty = mock.Mock(side_effect=mock_start_serial_pty)
14541444
handler._create_command = mock.Mock(return_value=['dummy', 'command'])
14551445
handler.run_custom_script = mock.Mock()
14561446
handler._create_serial_connection = mock.Mock(
@@ -1466,10 +1456,15 @@ def mock_popen(command, *args, **kwargs):
14661456

14671457
harness = mock.Mock()
14681458

1459+
openpty_mock = mock.Mock(return_value=('master', 'slave'))
1460+
ttyname_mock = mock.Mock(side_effect=lambda x: x + ' name')
1461+
14691462
with mock.patch('builtins.open', mock.mock_open(read_data='')), \
14701463
mock.patch('subprocess.Popen', side_effect=mock_popen), \
14711464
mock.patch('threading.Event', mock.Mock()), \
1472-
mock.patch('threading.Thread', side_effect=mock_thread):
1465+
mock.patch('threading.Thread', side_effect=mock_thread), \
1466+
mock.patch('pty.openpty', openpty_mock), \
1467+
mock.patch('os.ttyname', ttyname_mock):
14731468
handler.handle(harness)
14741469

14751470
handler.get_hardware.assert_called_once()

0 commit comments

Comments
 (0)