scripts: runners: check for required programs
Add self.require() checks before running commands. Increase test coverage, including for this feature, while we are here. Signed-off-by: Marti Bolivar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
c07267a26a
commit
c24e044c6e
18 changed files with 309 additions and 20 deletions
|
@ -64,6 +64,7 @@ class EmStarterKitBinaryRunner(ZephyrBinaryRunner):
|
||||||
gdb_port=args.gdb_port)
|
gdb_port=args.gdb_port)
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
|
self.require(self.openocd_cmd[0])
|
||||||
kwargs['openocd-cfg'] = path.join(self.cfg.board_dir, 'support',
|
kwargs['openocd-cfg'] = path.join(self.cfg.board_dir, 'support',
|
||||||
'openocd.cfg')
|
'openocd.cfg')
|
||||||
|
|
||||||
|
@ -73,8 +74,8 @@ class EmStarterKitBinaryRunner(ZephyrBinaryRunner):
|
||||||
self.debugserver(**kwargs)
|
self.debugserver(**kwargs)
|
||||||
|
|
||||||
def flash_debug(self, command, **kwargs):
|
def flash_debug(self, command, **kwargs):
|
||||||
|
self.require(self.gdb_cmd[0])
|
||||||
config = kwargs['openocd-cfg']
|
config = kwargs['openocd-cfg']
|
||||||
|
|
||||||
server_cmd = (self.openocd_cmd +
|
server_cmd = (self.openocd_cmd +
|
||||||
['-f', config] +
|
['-f', config] +
|
||||||
['-c', 'tcl_port {}'.format(self.tcl_port),
|
['-c', 'tcl_port {}'.format(self.tcl_port),
|
||||||
|
|
|
@ -35,8 +35,6 @@ class BlackMagicProbeRunner(ZephyrBinaryRunner):
|
||||||
help='GDB serial port')
|
help='GDB serial port')
|
||||||
|
|
||||||
def bmp_flash(self, command, **kwargs):
|
def bmp_flash(self, command, **kwargs):
|
||||||
if self.gdb is None:
|
|
||||||
raise ValueError('Cannot flash; gdb is missing')
|
|
||||||
if self.elf_file is None:
|
if self.elf_file is None:
|
||||||
raise ValueError('Cannot debug; elf file is missing')
|
raise ValueError('Cannot debug; elf file is missing')
|
||||||
command = (self.gdb +
|
command = (self.gdb +
|
||||||
|
@ -51,8 +49,6 @@ class BlackMagicProbeRunner(ZephyrBinaryRunner):
|
||||||
self.check_call(command)
|
self.check_call(command)
|
||||||
|
|
||||||
def bmp_attach(self, command, **kwargs):
|
def bmp_attach(self, command, **kwargs):
|
||||||
if self.gdb is None:
|
|
||||||
raise ValueError('Cannot attach; gdb is missing')
|
|
||||||
if self.elf_file is None:
|
if self.elf_file is None:
|
||||||
command = (self.gdb +
|
command = (self.gdb +
|
||||||
['-ex', "set confirm off",
|
['-ex', "set confirm off",
|
||||||
|
@ -71,8 +67,6 @@ class BlackMagicProbeRunner(ZephyrBinaryRunner):
|
||||||
self.check_call(command)
|
self.check_call(command)
|
||||||
|
|
||||||
def bmp_debug(self, command, **kwargs):
|
def bmp_debug(self, command, **kwargs):
|
||||||
if self.gdb is None:
|
|
||||||
raise ValueError('Cannot debug; gdb is missing')
|
|
||||||
if self.elf_file is None:
|
if self.elf_file is None:
|
||||||
raise ValueError('Cannot debug; elf file is missing')
|
raise ValueError('Cannot debug; elf file is missing')
|
||||||
command = (self.gdb +
|
command = (self.gdb +
|
||||||
|
@ -85,6 +79,9 @@ class BlackMagicProbeRunner(ZephyrBinaryRunner):
|
||||||
self.check_call(command)
|
self.check_call(command)
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
|
if self.gdb is None:
|
||||||
|
raise ValueError('Cannot execute; gdb not specified')
|
||||||
|
self.require(self.gdb[0])
|
||||||
|
|
||||||
if command == 'flash':
|
if command == 'flash':
|
||||||
self.bmp_flash(command, **kwargs)
|
self.bmp_flash(command, **kwargs)
|
||||||
|
|
|
@ -50,6 +50,8 @@ class BossacBinaryRunner(ZephyrBinaryRunner):
|
||||||
msg = 'CAUTION: No flash tool for your host system found!'
|
msg = 'CAUTION: No flash tool for your host system found!'
|
||||||
raise NotImplementedError(msg)
|
raise NotImplementedError(msg)
|
||||||
|
|
||||||
|
self.require('stty')
|
||||||
|
self.require(self.bossac)
|
||||||
cmd_stty = ['stty', '-F', self.port, 'raw', 'ispeed', '1200',
|
cmd_stty = ['stty', '-F', self.port, 'raw', 'ispeed', '1200',
|
||||||
'ospeed', '1200', 'cs8', '-cstopb', 'ignpar', 'eol', '255',
|
'ospeed', '1200', 'cs8', '-cstopb', 'ignpar', 'eol', '255',
|
||||||
'eof', '255']
|
'eof', '255']
|
||||||
|
|
|
@ -90,6 +90,7 @@ class DfuUtilBinaryRunner(ZephyrBinaryRunner):
|
||||||
return self.list_pattern in output
|
return self.list_pattern in output
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
|
self.require(self.cmd[0])
|
||||||
reset = False
|
reset = False
|
||||||
if not self.find_device():
|
if not self.find_device():
|
||||||
reset = True
|
reset = True
|
||||||
|
|
|
@ -78,6 +78,7 @@ class Esp32BinaryRunner(ZephyrBinaryRunner):
|
||||||
partition_table_bin=args.esp_flash_partition_table)
|
partition_table_bin=args.esp_flash_partition_table)
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
|
self.require(self.espidf)
|
||||||
bin_name = path.splitext(self.elf)[0] + path.extsep + 'bin'
|
bin_name = path.splitext(self.elf)[0] + path.extsep + 'bin'
|
||||||
cmd_convert = [self.espidf, '--chip', 'esp32', 'elf2image', self.elf]
|
cmd_convert = [self.espidf, '--chip', 'esp32', 'elf2image', self.elf]
|
||||||
cmd_flash = [self.espidf, '--chip', 'esp32', '--port', self.device,
|
cmd_flash = [self.espidf, '--chip', 'esp32', '--port', self.device,
|
||||||
|
|
|
@ -36,6 +36,8 @@ class HiFive1BinaryRunner(ZephyrBinaryRunner):
|
||||||
return HiFive1BinaryRunner(cfg)
|
return HiFive1BinaryRunner(cfg)
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
|
self.require(self.cfg.openocd)
|
||||||
|
self.require(self.cfg.gdb)
|
||||||
openocd_cmd = ([self.cfg.openocd, '-f', self.openocd_config])
|
openocd_cmd = ([self.cfg.openocd, '-f', self.openocd_config])
|
||||||
gdb_cmd = ([self.cfg.gdb, self.cfg.elf_file, '--batch',
|
gdb_cmd = ([self.cfg.gdb, self.cfg.elf_file, '--batch',
|
||||||
'-ex', 'set remotetimeout 240',
|
'-ex', 'set remotetimeout 240',
|
||||||
|
|
|
@ -61,6 +61,7 @@ class IntelS1000BinaryRunner(ZephyrBinaryRunner):
|
||||||
gdb_port=args.gdb_port)
|
gdb_port=args.gdb_port)
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
|
self.require(self.xt_ocd_dir)
|
||||||
kwargs['ocd-topology'] = path.join(self.board_dir, 'support',
|
kwargs['ocd-topology'] = path.join(self.board_dir, 'support',
|
||||||
self.ocd_topology)
|
self.ocd_topology)
|
||||||
kwargs['ocd-jtag-instr'] = path.join(self.board_dir, 'support',
|
kwargs['ocd-jtag-instr'] = path.join(self.board_dir, 'support',
|
||||||
|
@ -76,6 +77,9 @@ class IntelS1000BinaryRunner(ZephyrBinaryRunner):
|
||||||
self.do_debug(**kwargs)
|
self.do_debug(**kwargs)
|
||||||
|
|
||||||
def flash(self, **kwargs):
|
def flash(self, **kwargs):
|
||||||
|
if self.gdb_cmd is None:
|
||||||
|
raise ValueError('Cannot debug; no gdb specified')
|
||||||
|
self.require(self.gdb_cmd)
|
||||||
topology_file = kwargs['ocd-topology']
|
topology_file = kwargs['ocd-topology']
|
||||||
jtag_instr_file = kwargs['ocd-jtag-instr']
|
jtag_instr_file = kwargs['ocd-jtag-instr']
|
||||||
gdb_flash_file = kwargs['gdb-flash-file']
|
gdb_flash_file = kwargs['gdb-flash-file']
|
||||||
|
@ -113,6 +117,7 @@ class IntelS1000BinaryRunner(ZephyrBinaryRunner):
|
||||||
raise ValueError('Cannot debug; elf is missing')
|
raise ValueError('Cannot debug; elf is missing')
|
||||||
if self.gdb_cmd is None:
|
if self.gdb_cmd is None:
|
||||||
raise ValueError('Cannot debug; no gdb specified')
|
raise ValueError('Cannot debug; no gdb specified')
|
||||||
|
self.require(self.gdb_cmd)
|
||||||
|
|
||||||
topology_file = kwargs['ocd-topology']
|
topology_file = kwargs['ocd-topology']
|
||||||
jtag_instr_file = kwargs['ocd-jtag-instr']
|
jtag_instr_file = kwargs['ocd-jtag-instr']
|
||||||
|
|
|
@ -61,7 +61,7 @@ class Nios2BinaryRunner(ZephyrBinaryRunner):
|
||||||
cmd = [self.quartus_py,
|
cmd = [self.quartus_py,
|
||||||
'--sof', self.cpu_sof,
|
'--sof', self.cpu_sof,
|
||||||
'--kernel', self.hex_name]
|
'--kernel', self.hex_name]
|
||||||
|
self.require(cmd[0])
|
||||||
self.check_call(cmd)
|
self.check_call(cmd)
|
||||||
|
|
||||||
def print_gdbserver_message(self, gdb_port):
|
def print_gdbserver_message(self, gdb_port):
|
||||||
|
@ -80,6 +80,7 @@ class Nios2BinaryRunner(ZephyrBinaryRunner):
|
||||||
server_cmd = (['nios2-gdb-server',
|
server_cmd = (['nios2-gdb-server',
|
||||||
'--tcpport', str(gdb_port),
|
'--tcpport', str(gdb_port),
|
||||||
'--stop', '--reset-target'])
|
'--stop', '--reset-target'])
|
||||||
|
self.require(server_cmd[0])
|
||||||
|
|
||||||
if command == 'debugserver':
|
if command == 'debugserver':
|
||||||
self.print_gdbserver_message(gdb_port)
|
self.print_gdbserver_message(gdb_port)
|
||||||
|
@ -94,6 +95,7 @@ class Nios2BinaryRunner(ZephyrBinaryRunner):
|
||||||
self.tui_arg +
|
self.tui_arg +
|
||||||
[self.elf_name,
|
[self.elf_name,
|
||||||
'-ex', 'target remote :{}'.format(gdb_port)])
|
'-ex', 'target remote :{}'.format(gdb_port)])
|
||||||
|
self.require(gdb_cmd[0])
|
||||||
|
|
||||||
self.print_gdbserver_message(gdb_port)
|
self.print_gdbserver_message(gdb_port)
|
||||||
self.run_server_and_client(server_cmd, gdb_cmd)
|
self.run_server_and_client(server_cmd, gdb_cmd)
|
||||||
|
|
|
@ -87,6 +87,8 @@ class NrfJprogBinaryRunner(ZephyrBinaryRunner):
|
||||||
return snrs[value - 1]
|
return snrs[value - 1]
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
|
self.require('nrfjprog')
|
||||||
|
|
||||||
commands = []
|
commands = []
|
||||||
if self.snr is None:
|
if self.snr is None:
|
||||||
board_snr = self.get_board_snr_from_user()
|
board_snr = self.get_board_snr_from_user()
|
||||||
|
|
|
@ -55,6 +55,7 @@ class NsimBinaryRunner(ZephyrBinaryRunner):
|
||||||
props=args.props)
|
props=args.props)
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
|
self.require(self.nsim_cmd[0])
|
||||||
kwargs['nsim-cfg'] = path.join(self.cfg.board_dir, 'support',
|
kwargs['nsim-cfg'] = path.join(self.cfg.board_dir, 'support',
|
||||||
self.props)
|
self.props)
|
||||||
|
|
||||||
|
@ -77,10 +78,10 @@ class NsimBinaryRunner(ZephyrBinaryRunner):
|
||||||
server_cmd = (self.nsim_cmd + ['-gdb',
|
server_cmd = (self.nsim_cmd + ['-gdb',
|
||||||
'-port={}'.format(self.gdb_port),
|
'-port={}'.format(self.gdb_port),
|
||||||
'-propsfile', config])
|
'-propsfile', config])
|
||||||
|
|
||||||
gdb_cmd = (self.gdb_cmd +
|
gdb_cmd = (self.gdb_cmd +
|
||||||
['-ex', 'target remote :{}'.format(self.gdb_port),
|
['-ex', 'target remote :{}'.format(self.gdb_port),
|
||||||
'-ex', 'load', self.cfg.elf_file])
|
'-ex', 'load', self.cfg.elf_file])
|
||||||
|
self.require(gdb_cmd[0])
|
||||||
|
|
||||||
self.run_server_and_client(server_cmd, gdb_cmd)
|
self.run_server_and_client(server_cmd, gdb_cmd)
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner):
|
||||||
gdb_port=args.gdb_port)
|
gdb_port=args.gdb_port)
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
|
self.require(self.openocd_cmd[0])
|
||||||
if command == 'flash':
|
if command == 'flash':
|
||||||
self.do_flash(**kwargs)
|
self.do_flash(**kwargs)
|
||||||
elif command == 'debug':
|
elif command == 'debug':
|
||||||
|
@ -135,11 +136,10 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner):
|
||||||
'-c', 'init',
|
'-c', 'init',
|
||||||
'-c', 'targets',
|
'-c', 'targets',
|
||||||
'-c', 'halt'])
|
'-c', 'halt'])
|
||||||
|
|
||||||
gdb_cmd = (self.gdb_cmd + self.tui_arg +
|
gdb_cmd = (self.gdb_cmd + self.tui_arg +
|
||||||
['-ex', 'target remote :{}'.format(self.gdb_port),
|
['-ex', 'target remote :{}'.format(self.gdb_port),
|
||||||
self.elf_name])
|
self.elf_name])
|
||||||
|
self.require(gdb_cmd[0])
|
||||||
self.run_server_and_client(server_cmd, gdb_cmd)
|
self.run_server_and_client(server_cmd, gdb_cmd)
|
||||||
|
|
||||||
def do_debugserver(self, **kwargs):
|
def do_debugserver(self, **kwargs):
|
||||||
|
|
|
@ -108,6 +108,7 @@ class PyOcdBinaryRunner(ZephyrBinaryRunner):
|
||||||
return ['-p', str(self.gdb_port)]
|
return ['-p', str(self.gdb_port)]
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
|
self.require(self.pyocd)
|
||||||
if command == 'flash':
|
if command == 'flash':
|
||||||
self.flash(**kwargs)
|
self.flash(**kwargs)
|
||||||
else:
|
else:
|
||||||
|
@ -166,5 +167,6 @@ class PyOcdBinaryRunner(ZephyrBinaryRunner):
|
||||||
'-ex', 'monitor reset',
|
'-ex', 'monitor reset',
|
||||||
'-ex', 'load']
|
'-ex', 'load']
|
||||||
|
|
||||||
|
self.require(client_cmd[0])
|
||||||
self.print_gdbserver_message()
|
self.print_gdbserver_message()
|
||||||
self.run_server_and_client(server_cmd, client_cmd)
|
self.run_server_and_client(server_cmd, client_cmd)
|
||||||
|
|
|
@ -36,5 +36,5 @@ class XtensaBinaryRunner(ZephyrBinaryRunner):
|
||||||
|
|
||||||
def do_run(self, command, **kwargs):
|
def do_run(self, command, **kwargs):
|
||||||
gdb_cmd = [self.cfg.gdb, self.cfg.elf_file]
|
gdb_cmd = [self.cfg.gdb, self.cfg.elf_file]
|
||||||
|
self.require(gdb_cmd[0])
|
||||||
self.check_call(gdb_cmd)
|
self.check_call(gdb_cmd)
|
||||||
|
|
70
scripts/west_commands/tests/test_blackmagicprobe.py
Normal file
70
scripts/west_commands/tests/test_blackmagicprobe.py
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
# Copyright (c) 2018 Foundries.io
|
||||||
|
# Copyright (c) 2019 Nordic Semiconductor ASA.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
from unittest.mock import patch, call
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from runners.blackmagicprobe import BlackMagicProbeRunner
|
||||||
|
from conftest import RC_KERNEL_ELF, RC_GDB
|
||||||
|
|
||||||
|
TEST_GDB_SERIAL = 'test-gdb-serial'
|
||||||
|
|
||||||
|
# Expected subprocesses to be run for each command. Using the
|
||||||
|
# runner_config fixture (and always specifying gdb-serial) means we
|
||||||
|
# don't get 100% coverage, but it's a starting out point.
|
||||||
|
EXPECTED_COMMANDS = {
|
||||||
|
'attach':
|
||||||
|
([RC_GDB,
|
||||||
|
'-ex', "set confirm off",
|
||||||
|
'-ex', "target extended-remote {}".format(TEST_GDB_SERIAL),
|
||||||
|
'-ex', "monitor swdp_scan",
|
||||||
|
'-ex', "attach 1",
|
||||||
|
'-ex', "file {}".format(RC_KERNEL_ELF)],),
|
||||||
|
'debug':
|
||||||
|
([RC_GDB,
|
||||||
|
'-ex', "set confirm off",
|
||||||
|
'-ex', "target extended-remote {}".format(TEST_GDB_SERIAL),
|
||||||
|
'-ex', "monitor swdp_scan",
|
||||||
|
'-ex', "attach 1",
|
||||||
|
'-ex', "file {}".format(RC_KERNEL_ELF),
|
||||||
|
'-ex', "load {}".format(RC_KERNEL_ELF)],),
|
||||||
|
'flash':
|
||||||
|
([RC_GDB,
|
||||||
|
'-ex', "set confirm off",
|
||||||
|
'-ex', "target extended-remote {}".format(TEST_GDB_SERIAL),
|
||||||
|
'-ex', "monitor swdp_scan",
|
||||||
|
'-ex', "attach 1",
|
||||||
|
'-ex', "load {}".format(RC_KERNEL_ELF),
|
||||||
|
'-ex', "kill",
|
||||||
|
'-ex', "quit",
|
||||||
|
'-silent'],),
|
||||||
|
}
|
||||||
|
|
||||||
|
def require_patch(program):
|
||||||
|
assert program == RC_GDB
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('command', EXPECTED_COMMANDS)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.check_call')
|
||||||
|
def test_blackmagicprobe_init(cc, req, command, runner_config):
|
||||||
|
'''Test commands using a runner created by constructor.'''
|
||||||
|
runner = BlackMagicProbeRunner(runner_config, TEST_GDB_SERIAL)
|
||||||
|
runner.run(command)
|
||||||
|
assert cc.call_args_list == [call(x) for x in EXPECTED_COMMANDS[command]]
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('command', EXPECTED_COMMANDS)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.check_call')
|
||||||
|
def test_blackmagicprobe_create(cc, req, command, runner_config):
|
||||||
|
'''Test commands using a runner created from command line parameters.'''
|
||||||
|
args = ['--gdb-serial', TEST_GDB_SERIAL]
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
BlackMagicProbeRunner.add_parser(parser)
|
||||||
|
arg_namespace = parser.parse_args(args)
|
||||||
|
runner = BlackMagicProbeRunner.create(runner_config, arg_namespace)
|
||||||
|
runner.run(command)
|
||||||
|
assert cc.call_args_list == [call(x) for x in EXPECTED_COMMANDS[command]]
|
44
scripts/west_commands/tests/test_bossac.py
Normal file
44
scripts/west_commands/tests/test_bossac.py
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Copyright (c) 2018 Foundries.io
|
||||||
|
# Copyright (c) 2019 Nordic Semiconductor ASA.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
from unittest.mock import patch, call
|
||||||
|
|
||||||
|
from runners.bossac import BossacBinaryRunner
|
||||||
|
from conftest import RC_KERNEL_BIN
|
||||||
|
|
||||||
|
TEST_BOSSAC_PORT = 'test-bossac-serial'
|
||||||
|
TEST_OFFSET = 1234
|
||||||
|
EXPECTED_COMMANDS = [
|
||||||
|
['stty', '-F', TEST_BOSSAC_PORT, 'raw', 'ispeed', '1200', 'ospeed', '1200',
|
||||||
|
'cs8', '-cstopb', 'ignpar', 'eol', '255', 'eof', '255'],
|
||||||
|
['bossac', '-p', TEST_BOSSAC_PORT, '-R', '-e', '-w', '-v',
|
||||||
|
'-o', str(TEST_OFFSET), '-b', RC_KERNEL_BIN],
|
||||||
|
]
|
||||||
|
|
||||||
|
def require_patch(program):
|
||||||
|
assert program in ['bossac', 'stty']
|
||||||
|
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.check_call')
|
||||||
|
def test_bossac_init(cc, req, runner_config):
|
||||||
|
'''Test commands using a runner created by constructor.'''
|
||||||
|
runner = BossacBinaryRunner(runner_config, port=TEST_BOSSAC_PORT,
|
||||||
|
offset=TEST_OFFSET)
|
||||||
|
runner.run('flash')
|
||||||
|
assert cc.call_args_list == [call(x) for x in EXPECTED_COMMANDS]
|
||||||
|
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.check_call')
|
||||||
|
def test_bossac_create(cc, req, runner_config):
|
||||||
|
'''Test commands using a runner created from command line parameters.'''
|
||||||
|
args = ['--bossac-port', str(TEST_BOSSAC_PORT),
|
||||||
|
'--offset', str(TEST_OFFSET)]
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
BossacBinaryRunner.add_parser(parser)
|
||||||
|
arg_namespace = parser.parse_args(args)
|
||||||
|
runner = BossacBinaryRunner.create(runner_config, arg_namespace)
|
||||||
|
runner.run('flash')
|
||||||
|
assert cc.call_args_list == [call(x) for x in EXPECTED_COMMANDS]
|
131
scripts/west_commands/tests/test_dfu_util.py
Normal file
131
scripts/west_commands/tests/test_dfu_util.py
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
# Copyright (c) 2018 Foundries.io
|
||||||
|
# Copyright (c) 2019 Nordic Semiconductor ASA.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
from unittest.mock import patch, call
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from runners.dfu import DfuUtilBinaryRunner, DfuSeConfig
|
||||||
|
from conftest import RC_KERNEL_BIN
|
||||||
|
|
||||||
|
DFU_UTIL = 'dfu-util'
|
||||||
|
TEST_EXE = 'test-dfu-util'
|
||||||
|
TEST_PID = '0000:9999'
|
||||||
|
TEST_PID_RES = '-d,{}'.format(TEST_PID)
|
||||||
|
TEST_ALT_INT = '1'
|
||||||
|
TEST_ALT_STR = 'alt-name'
|
||||||
|
TEST_BIN_NAME = 'test-img.bin'
|
||||||
|
TEST_DFUSE_ADDR = 2
|
||||||
|
TEST_DFUSE_OPTS = 'test-dfuse-opt'
|
||||||
|
TEST_DCFG_OPT = DfuSeConfig(address=TEST_DFUSE_ADDR, options='test-dfuse-opt')
|
||||||
|
TEST_DCFG_OPT_RES = '{}:{}'.format(hex(TEST_DFUSE_ADDR), TEST_DFUSE_OPTS)
|
||||||
|
TEST_DCFG_NOPT = DfuSeConfig(address=TEST_DFUSE_ADDR, options='')
|
||||||
|
TEST_DCFG_NOPT_RES = '{}:'.format(hex(TEST_DFUSE_ADDR))
|
||||||
|
# A map from a test case to the expected dfu-util call.
|
||||||
|
# Test cases are (alt, exe, img, dfuse) tuples.
|
||||||
|
EXPECTED_COMMAND = {
|
||||||
|
(DFU_UTIL, TEST_ALT_INT, None, RC_KERNEL_BIN):
|
||||||
|
[DFU_UTIL, TEST_PID_RES, '-a', TEST_ALT_INT, '-D', RC_KERNEL_BIN],
|
||||||
|
|
||||||
|
(DFU_UTIL, TEST_ALT_STR, None, RC_KERNEL_BIN):
|
||||||
|
[DFU_UTIL, TEST_PID_RES, '-a', TEST_ALT_STR, '-D', RC_KERNEL_BIN],
|
||||||
|
|
||||||
|
(TEST_EXE, TEST_ALT_INT, None, RC_KERNEL_BIN):
|
||||||
|
[TEST_EXE, TEST_PID_RES, '-a', TEST_ALT_INT, '-D', RC_KERNEL_BIN],
|
||||||
|
|
||||||
|
(DFU_UTIL, TEST_ALT_INT, None, TEST_BIN_NAME):
|
||||||
|
[DFU_UTIL, TEST_PID_RES, '-a', TEST_ALT_INT, '-D', TEST_BIN_NAME],
|
||||||
|
|
||||||
|
(DFU_UTIL, TEST_ALT_INT, TEST_DCFG_OPT, RC_KERNEL_BIN):
|
||||||
|
[DFU_UTIL, TEST_PID_RES, '-s', TEST_DCFG_OPT_RES, '-a', TEST_ALT_INT,
|
||||||
|
'-D', RC_KERNEL_BIN],
|
||||||
|
|
||||||
|
(DFU_UTIL, TEST_ALT_INT, TEST_DCFG_NOPT, RC_KERNEL_BIN):
|
||||||
|
[DFU_UTIL, TEST_PID_RES, '-s', TEST_DCFG_NOPT_RES, '-a', TEST_ALT_INT,
|
||||||
|
'-D', RC_KERNEL_BIN],
|
||||||
|
}
|
||||||
|
|
||||||
|
def find_device_patch():
|
||||||
|
return True
|
||||||
|
|
||||||
|
def require_patch(program):
|
||||||
|
assert program in [DFU_UTIL, TEST_EXE]
|
||||||
|
|
||||||
|
def id_fn(tc):
|
||||||
|
return 'exe={},alt={},dfuse_config={},img={}'.format(*tc)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('tc', [
|
||||||
|
# (exe, alt, dfuse_config, img)
|
||||||
|
(DFU_UTIL, TEST_ALT_INT, None, RC_KERNEL_BIN),
|
||||||
|
(DFU_UTIL, TEST_ALT_STR, None, RC_KERNEL_BIN),
|
||||||
|
(TEST_EXE, TEST_ALT_INT, None, RC_KERNEL_BIN),
|
||||||
|
(DFU_UTIL, TEST_ALT_INT, None, TEST_BIN_NAME),
|
||||||
|
(DFU_UTIL, TEST_ALT_INT, TEST_DCFG_OPT, RC_KERNEL_BIN),
|
||||||
|
(DFU_UTIL, TEST_ALT_INT, TEST_DCFG_NOPT, RC_KERNEL_BIN),
|
||||||
|
], ids=id_fn)
|
||||||
|
@patch('runners.dfu.DfuUtilBinaryRunner.find_device',
|
||||||
|
side_effect=find_device_patch)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.check_call')
|
||||||
|
def test_dfu_util_init(cc, req, find_device, tc, runner_config):
|
||||||
|
'''Test commands using a runner created by constructor.'''
|
||||||
|
exe, alt, dfuse_config, img = tc
|
||||||
|
runner = DfuUtilBinaryRunner(runner_config, TEST_PID, alt, img, exe=exe,
|
||||||
|
dfuse_config=dfuse_config)
|
||||||
|
runner.run('flash')
|
||||||
|
assert find_device.called
|
||||||
|
assert req.called_with(exe)
|
||||||
|
assert cc.call_args_list == [call(EXPECTED_COMMAND[tc])]
|
||||||
|
|
||||||
|
def get_flash_address_patch(args, bcfg):
|
||||||
|
return TEST_DFUSE_ADDR
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('tc', [
|
||||||
|
# arg spec: (exe, alt, dfuse, modifiers, img)
|
||||||
|
(None, TEST_ALT_INT, False, None, None),
|
||||||
|
(None, TEST_ALT_STR, False, None, None),
|
||||||
|
(TEST_EXE, TEST_ALT_INT, False, None, None),
|
||||||
|
(None, TEST_ALT_INT, False, None, TEST_BIN_NAME),
|
||||||
|
(None, TEST_ALT_INT, True, TEST_DFUSE_OPTS, None),
|
||||||
|
(None, TEST_ALT_INT, True, None, None),
|
||||||
|
|
||||||
|
], ids=id_fn)
|
||||||
|
@patch('runners.core.BuildConfiguration._init',)
|
||||||
|
@patch('runners.dfu.DfuUtilBinaryRunner.find_device',
|
||||||
|
side_effect=find_device_patch)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.get_flash_address',
|
||||||
|
side_effect=get_flash_address_patch)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
@patch('runners.core.ZephyrBinaryRunner.check_call')
|
||||||
|
def test_dfu_util_create(cc, req, gfa, find_device, bcfg, tc, runner_config):
|
||||||
|
'''Test commands using a runner created from command line parameters.'''
|
||||||
|
exe, alt, dfuse, modifiers, img = tc
|
||||||
|
args = ['--pid', TEST_PID, '--alt', alt]
|
||||||
|
if img:
|
||||||
|
args.extend(['--img', img])
|
||||||
|
if dfuse:
|
||||||
|
args.append('--dfuse')
|
||||||
|
if modifiers:
|
||||||
|
args.extend(['--dfuse-modifiers', modifiers])
|
||||||
|
else:
|
||||||
|
args.extend(['--dfuse-modifiers', ''])
|
||||||
|
if exe:
|
||||||
|
args.extend(['--dfu-util', exe])
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
DfuUtilBinaryRunner.add_parser(parser)
|
||||||
|
arg_namespace = parser.parse_args(args)
|
||||||
|
runner = DfuUtilBinaryRunner.create(runner_config, arg_namespace)
|
||||||
|
runner.run('flash')
|
||||||
|
|
||||||
|
if dfuse:
|
||||||
|
cfg = DfuSeConfig(address=TEST_DFUSE_ADDR, options=modifiers or '')
|
||||||
|
else:
|
||||||
|
cfg = None
|
||||||
|
map_tc = (exe or DFU_UTIL, alt, cfg, img or RC_KERNEL_BIN)
|
||||||
|
assert find_device.called
|
||||||
|
assert req.called_with(exe)
|
||||||
|
assert cc.call_args_list == [call(EXPECTED_COMMAND[map_tc])]
|
|
@ -186,6 +186,10 @@ def get_board_snr_patch():
|
||||||
return TEST_DEF_SNR
|
return TEST_DEF_SNR
|
||||||
|
|
||||||
|
|
||||||
|
def require_patch(program):
|
||||||
|
assert program == 'nrfjprog'
|
||||||
|
|
||||||
|
|
||||||
def id_fn(test_case):
|
def id_fn(test_case):
|
||||||
ret = ''
|
ret = ''
|
||||||
for x in test_case:
|
for x in test_case:
|
||||||
|
@ -197,16 +201,18 @@ 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.nrfjprog.NrfJprogBinaryRunner.get_board_snr_from_user',
|
@patch('runners.nrfjprog.NrfJprogBinaryRunner.get_board_snr_from_user',
|
||||||
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, test_case, runner_config):
|
def test_nrfjprog_init(cc, get_snr, req, test_case, runner_config):
|
||||||
family, softreset, snr, erase = test_case
|
family, softreset, snr, erase = test_case
|
||||||
|
|
||||||
runner = NrfJprogBinaryRunner(runner_config, family, softreset, snr,
|
runner = NrfJprogBinaryRunner(runner_config, family, softreset, snr,
|
||||||
erase=erase)
|
erase=erase)
|
||||||
runner.run('flash')
|
runner.run('flash')
|
||||||
|
|
||||||
|
assert req.called
|
||||||
assert cc.call_args_list == [call(x) for x in
|
assert cc.call_args_list == [call(x) for x in
|
||||||
expected_commands(*test_case)]
|
expected_commands(*test_case)]
|
||||||
if snr is None:
|
if snr is None:
|
||||||
|
@ -216,10 +222,11 @@ def test_nrfjprog_init(cc, get_snr, 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.nrfjprog.NrfJprogBinaryRunner.get_board_snr_from_user',
|
@patch('runners.nrfjprog.NrfJprogBinaryRunner.get_board_snr_from_user',
|
||||||
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, test_case, runner_config):
|
def test_nrfjprog_create(cc, get_snr, req, test_case, runner_config):
|
||||||
family, softreset, snr, erase = test_case
|
family, softreset, snr, erase = test_case
|
||||||
|
|
||||||
args = ['--nrf-family', family]
|
args = ['--nrf-family', family]
|
||||||
|
@ -236,6 +243,7 @@ def test_nrfjprog_create(cc, get_snr, test_case, runner_config):
|
||||||
runner = NrfJprogBinaryRunner.create(runner_config, arg_namespace)
|
runner = NrfJprogBinaryRunner.create(runner_config, arg_namespace)
|
||||||
runner.run('flash')
|
runner.run('flash')
|
||||||
|
|
||||||
|
assert req.called
|
||||||
assert cc.call_args_list == [call(x) for x in
|
assert cc.call_args_list == [call(x) for x in
|
||||||
expected_commands(*test_case)]
|
expected_commands(*test_case)]
|
||||||
if snr is None:
|
if snr is None:
|
||||||
|
|
|
@ -136,6 +136,14 @@ def pyocd(runner_config, tmpdir):
|
||||||
return _factory
|
return _factory
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Helpers
|
||||||
|
#
|
||||||
|
|
||||||
|
def require_patch(program):
|
||||||
|
assert program in ['pyocd', TEST_PYOCD, RC_GDB]
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test cases for runners created by constructor.
|
# Test cases for runners created by constructor.
|
||||||
#
|
#
|
||||||
|
@ -145,8 +153,10 @@ def pyocd(runner_config, tmpdir):
|
||||||
(TEST_DEF_KWARGS, FLASH_DEF_EXPECTED_CALL)
|
(TEST_DEF_KWARGS, FLASH_DEF_EXPECTED_CALL)
|
||||||
])
|
])
|
||||||
@patch('runners.pyocd.PyOcdBinaryRunner.check_call')
|
@patch('runners.pyocd.PyOcdBinaryRunner.check_call')
|
||||||
def test_flash(cc, pyocd_args, expected, pyocd):
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
def test_flash(require, cc, pyocd_args, expected, pyocd):
|
||||||
pyocd(pyocd_args).run('flash')
|
pyocd(pyocd_args).run('flash')
|
||||||
|
assert require.called
|
||||||
cc.assert_called_once_with(expected)
|
cc.assert_called_once_with(expected)
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,8 +165,10 @@ def test_flash(cc, pyocd_args, expected, pyocd):
|
||||||
(TEST_DEF_KWARGS, (DEBUG_DEF_EXPECTED_SERVER, DEBUG_DEF_EXPECTED_CLIENT))
|
(TEST_DEF_KWARGS, (DEBUG_DEF_EXPECTED_SERVER, DEBUG_DEF_EXPECTED_CLIENT))
|
||||||
])
|
])
|
||||||
@patch('runners.pyocd.PyOcdBinaryRunner.run_server_and_client')
|
@patch('runners.pyocd.PyOcdBinaryRunner.run_server_and_client')
|
||||||
def test_debug(rsc, pyocd_args, expectedv, pyocd):
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
def test_debug(require, rsc, pyocd_args, expectedv, pyocd):
|
||||||
pyocd(pyocd_args).run('debug')
|
pyocd(pyocd_args).run('debug')
|
||||||
|
assert require.called
|
||||||
rsc.assert_called_once_with(*expectedv)
|
rsc.assert_called_once_with(*expectedv)
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,8 +177,10 @@ def test_debug(rsc, pyocd_args, expectedv, pyocd):
|
||||||
(TEST_DEF_KWARGS, DEBUGSERVER_DEF_EXPECTED_CALL)
|
(TEST_DEF_KWARGS, DEBUGSERVER_DEF_EXPECTED_CALL)
|
||||||
])
|
])
|
||||||
@patch('runners.pyocd.PyOcdBinaryRunner.check_call')
|
@patch('runners.pyocd.PyOcdBinaryRunner.check_call')
|
||||||
def test_debugserver(cc, pyocd_args, expected, pyocd):
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
def test_debugserver(require, cc, pyocd_args, expected, pyocd):
|
||||||
pyocd(pyocd_args).run('debugserver')
|
pyocd(pyocd_args).run('debugserver')
|
||||||
|
assert require.called
|
||||||
cc.assert_called_once_with(expected)
|
cc.assert_called_once_with(expected)
|
||||||
|
|
||||||
|
|
||||||
|
@ -183,10 +197,12 @@ def test_debugserver(cc, pyocd_args, expected, pyocd):
|
||||||
])
|
])
|
||||||
@patch('runners.pyocd.BuildConfiguration')
|
@patch('runners.pyocd.BuildConfiguration')
|
||||||
@patch('runners.pyocd.PyOcdBinaryRunner.check_call')
|
@patch('runners.pyocd.PyOcdBinaryRunner.check_call')
|
||||||
def test_flash_args(cc, bc, pyocd_args, flash_addr, expected, pyocd):
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
def test_flash_args(require, cc, bc, pyocd_args, flash_addr, expected, pyocd):
|
||||||
with patch.object(PyOcdBinaryRunner, 'get_flash_address',
|
with patch.object(PyOcdBinaryRunner, 'get_flash_address',
|
||||||
return_value=flash_addr):
|
return_value=flash_addr):
|
||||||
pyocd(pyocd_args).run('flash')
|
pyocd(pyocd_args).run('flash')
|
||||||
|
assert require.called
|
||||||
bc.assert_called_once_with(RC_BUILD_DIR)
|
bc.assert_called_once_with(RC_BUILD_DIR)
|
||||||
cc.assert_called_once_with(expected)
|
cc.assert_called_once_with(expected)
|
||||||
|
|
||||||
|
@ -197,8 +213,10 @@ def test_flash_args(cc, bc, pyocd_args, flash_addr, expected, pyocd):
|
||||||
])
|
])
|
||||||
@patch('runners.pyocd.BuildConfiguration')
|
@patch('runners.pyocd.BuildConfiguration')
|
||||||
@patch('runners.pyocd.PyOcdBinaryRunner.run_server_and_client')
|
@patch('runners.pyocd.PyOcdBinaryRunner.run_server_and_client')
|
||||||
def test_debug_args(rsc, bc, pyocd_args, expectedv, pyocd):
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
def test_debug_args(require, rsc, bc, pyocd_args, expectedv, pyocd):
|
||||||
pyocd(pyocd_args).run('debug')
|
pyocd(pyocd_args).run('debug')
|
||||||
|
assert require.called
|
||||||
bc.assert_called_once_with(RC_BUILD_DIR)
|
bc.assert_called_once_with(RC_BUILD_DIR)
|
||||||
rsc.assert_called_once_with(*expectedv)
|
rsc.assert_called_once_with(*expectedv)
|
||||||
|
|
||||||
|
@ -209,7 +227,9 @@ def test_debug_args(rsc, bc, pyocd_args, expectedv, pyocd):
|
||||||
])
|
])
|
||||||
@patch('runners.pyocd.BuildConfiguration')
|
@patch('runners.pyocd.BuildConfiguration')
|
||||||
@patch('runners.pyocd.PyOcdBinaryRunner.check_call')
|
@patch('runners.pyocd.PyOcdBinaryRunner.check_call')
|
||||||
def test_debugserver_args(cc, bc, pyocd_args, expected, pyocd):
|
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
|
||||||
|
def test_debugserver_args(require, cc, bc, pyocd_args, expected, pyocd):
|
||||||
pyocd(pyocd_args).run('debugserver')
|
pyocd(pyocd_args).run('debugserver')
|
||||||
|
assert require.called
|
||||||
bc.assert_called_once_with(RC_BUILD_DIR)
|
bc.assert_called_once_with(RC_BUILD_DIR)
|
||||||
cc.assert_called_once_with(expected)
|
cc.assert_called_once_with(expected)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue