zephyr/scripts/west_commands/tests/test_dfu_util.py
Jamie McCrae ec7044437e treewide: Disable automatic argparse argument shortening
Disables allowing the python argparse library from automatically
shortening command line arguments, this prevents issues whereby
a new command is added and code that wrongly uses the shortened
command of an existing argument which is the same as the new
command being added will silently change script behaviour.

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
2023-01-26 20:12:36 +09:00

145 lines
5.3 KiB
Python

# Copyright (c) 2018 Foundries.io
# Copyright (c) 2019 Nordic Semiconductor ASA.
#
# SPDX-License-Identifier: Apache-2.0
import argparse
import os
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]
os_path_isfile = os.path.isfile
def os_path_isfile_patch(filename):
if filename == RC_KERNEL_BIN:
return True
return os_path_isfile(filename)
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)
with patch('os.path.isfile', side_effect=os_path_isfile_patch):
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.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, tc, runner_config, tmpdir):
'''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])
(tmpdir / 'zephyr').mkdir()
with open(os.fspath(tmpdir / 'zephyr' / '.config'), 'w') as f:
f.write('\n')
runner_config = runner_config._replace(build_dir=os.fspath(tmpdir))
parser = argparse.ArgumentParser(allow_abbrev=False)
DfuUtilBinaryRunner.add_parser(parser)
arg_namespace = parser.parse_args(args)
runner = DfuUtilBinaryRunner.create(runner_config, arg_namespace)
with patch('os.path.isfile', side_effect=os_path_isfile_patch):
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])]