scripts: runners: nrfjprog: restrict when we guess snr

Right now, the nrfjprog runner will prompt the user for which board to
use if there are multiple possibilities and the --snr command line was
not given to specify one ahead of time.

Tweak this so it only happens if standard input is connected to a
terminal. This should avoid stalling the process on board farms when
this runner is used in automation.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
Martí Bolívar 2020-01-09 14:45:14 -08:00 committed by Anas Nashif
commit e4768ad7e7
2 changed files with 19 additions and 14 deletions

View file

@ -60,26 +60,34 @@ class NrfJprogBinaryRunner(ZephyrBinaryRunner):
def ensure_snr(self): def ensure_snr(self):
if not self.snr: if not self.snr:
self.snr = self.get_board_snr_from_user() self.snr = self.get_board_snr()
def get_board_snr(self):
# Use nrfjprog --ids to discover connected boards.
#
# If there's exactly one board connected, it's safe to assume
# the user wants that one. Otherwise, bail unless there are
# multiple boards and we are connected to a terminal, in which
# case use print() and input() to ask what the user wants.
def get_board_snr_from_user(self):
snrs = self.check_output(['nrfjprog', '--ids']) snrs = self.check_output(['nrfjprog', '--ids'])
snrs = snrs.decode(sys.getdefaultencoding()).strip().splitlines() snrs = snrs.decode(sys.getdefaultencoding()).strip().splitlines()
if not snrs: if not snrs:
raise RuntimeError('"nrfjprog --ids" did not find a board; ' raise RuntimeError('"nrfjprog --ids" did not find a board; '
'is the board connected?') 'is the board connected?')
elif len(snrs) == 1:
if len(snrs) == 1:
board_snr = snrs[0] board_snr = snrs[0]
if board_snr == '0': if board_snr == '0':
raise RuntimeError('"nrfjprog --ids" returned 0; ' raise RuntimeError('"nrfjprog --ids" returned 0; '
'is a debugger already connected?') 'is a debugger already connected?')
return board_snr return board_snr
elif not sys.stdin.isatty():
raise RuntimeError(
f'refusing to guess which of {len(snrs)} '
'connected boards to use. (Interactive prompts '
'disabled since standard input is not a terminal.) '
'Please specify a serial number on the command line.')
# Use of print() here is advised. We don't want to lose
# this information in a separate log -- this is
# interactive and requires a terminal.
print('There are multiple boards connected.') print('There are multiple boards connected.')
for i, snr in enumerate(snrs, 1): for i, snr in enumerate(snrs, 1):
print('{}. {}'.format(i, snr)) print('{}. {}'.format(i, snr))
@ -103,10 +111,7 @@ class NrfJprogBinaryRunner(ZephyrBinaryRunner):
self.ensure_snr() self.ensure_snr()
commands = [] commands = []
if self.snr is None: board_snr = self.snr.lstrip("0")
raise ValueError("self.snr must not be None")
else:
board_snr = self.snr.lstrip("0")
if not os.path.isfile(self.hex_): if not os.path.isfile(self.hex_):
raise ValueError('Cannot flash; hex file ({}) does not exist. '. raise ValueError('Cannot flash; hex file ({}) does not exist. '.

View file

@ -241,7 +241,7 @@ def id_fn(test_case):
@pytest.mark.parametrize('test_case', TEST_CASES, ids=id_fn) @pytest.mark.parametrize('test_case', TEST_CASES, ids=id_fn)
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch) @patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
@patch('runners.nrfjprog.NrfJprogBinaryRunner.get_board_snr_from_user', @patch('runners.nrfjprog.NrfJprogBinaryRunner.get_board_snr',
side_effect=get_board_snr_patch) side_effect=get_board_snr_patch)
@patch('runners.nrfjprog.NrfJprogBinaryRunner.check_call') @patch('runners.nrfjprog.NrfJprogBinaryRunner.check_call')
def test_nrfjprog_init(cc, get_snr, req, test_case, runner_config): def test_nrfjprog_init(cc, get_snr, req, test_case, runner_config):
@ -262,7 +262,7 @@ def test_nrfjprog_init(cc, get_snr, req, test_case, runner_config):
@pytest.mark.parametrize('test_case', TEST_CASES, ids=id_fn) @pytest.mark.parametrize('test_case', TEST_CASES, ids=id_fn)
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch) @patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
@patch('runners.nrfjprog.NrfJprogBinaryRunner.get_board_snr_from_user', @patch('runners.nrfjprog.NrfJprogBinaryRunner.get_board_snr',
side_effect=get_board_snr_patch) side_effect=get_board_snr_patch)
@patch('runners.nrfjprog.NrfJprogBinaryRunner.check_call') @patch('runners.nrfjprog.NrfJprogBinaryRunner.check_call')
def test_nrfjprog_create(cc, get_snr, req, test_case, runner_config): def test_nrfjprog_create(cc, get_snr, req, test_case, runner_config):