zephyr/scripts/west_commands/tests/test_mdb.py

300 lines
11 KiB
Python

# Copyright (c) 2020 Synopsys
#
# SPDX-License-Identifier: Apache-2.0
import argparse
from os import path, fspath
from unittest.mock import patch
from unittest.mock import call
import pytest
from runners.mdb import MdbNsimBinaryRunner, MdbHwBinaryRunner
from conftest import RC_KERNEL_ELF, RC_BOARD_DIR, RC_BUILD_DIR
TEST_DRIVER_CMD = 'mdb64'
TEST_NSIM_ARGS='test_nsim.args'
TEST_TARGET = 'test-target'
TEST_BOARD_NSIM_ARGS = '@' + path.join(RC_BOARD_DIR, 'support', TEST_NSIM_ARGS)
DOTCONFIG_HOSTLINK = f'''
CONFIG_ARC=y
CONFIG_UART_HOSTLINK=y
'''
DOTCONFIG_NO_HOSTLINK = f'''
CONFIG_ARC=y
'''
# mdb-nsim
TEST_NSIM_FLASH_CASES = [
{
'i': ['--cores=1', '--nsim_args=' + TEST_NSIM_ARGS],
'o': [TEST_DRIVER_CMD, '-nooptions', '-nogoifmain',
'-toggle=include_local_symbols=1',
'-nsim', TEST_BOARD_NSIM_ARGS,
'-run', '-cl', RC_KERNEL_ELF]
}]
TEST_NSIM_DEBUG_CASES = [
{
'i': ['--cores=1', '--nsim_args=' + TEST_NSIM_ARGS],
'o': [TEST_DRIVER_CMD, '-nooptions', '-nogoifmain',
'-toggle=include_local_symbols=1',
'-nsim', TEST_BOARD_NSIM_ARGS,
'-OKN', RC_KERNEL_ELF
]
}]
TEST_NSIM_MULTICORE_CASES = [['--cores=2', '--nsim_args=' + TEST_NSIM_ARGS]]
TEST_NSIM_CORE1 = [TEST_DRIVER_CMD, '-pset=1', '-psetname=core0',
'-nooptions', '-nogoifmain', '-toggle=include_local_symbols=1',
'-nsim', TEST_BOARD_NSIM_ARGS, RC_KERNEL_ELF]
TEST_NSIM_CORE2 = [TEST_DRIVER_CMD, '-pset=2', '-psetname=core1',
'-prop=download=2', '-nooptions', '-nogoifmain',
'-toggle=include_local_symbols=1',
'-nsim', TEST_BOARD_NSIM_ARGS, RC_KERNEL_ELF]
TEST_NSIM_CORES_LAUNCH = [TEST_DRIVER_CMD, '-multifiles=core0,core1',
'-run', '-cl']
# mdb-hw
TEST_HW_FLASH_CASES_NO_HOSTLINK = [
{
'i': ['--jtag=digilent', '--cores=1'],
'o': [TEST_DRIVER_CMD, '-nooptions', '-nogoifmain',
'-toggle=include_local_symbols=1',
'-digilent',
'-run', '-cmd=-nowaitq run', '-cmd=quit', '-cl', RC_KERNEL_ELF]
}, {
'i': ['--jtag=digilent', '--cores=1', '--dig-device=test'],
'o': [TEST_DRIVER_CMD, '-nooptions', '-nogoifmain',
'-toggle=include_local_symbols=1',
'-digilent', '-prop=dig_device=test',
'-run', '-cmd=-nowaitq run', '-cmd=quit', '-cl', RC_KERNEL_ELF]
}]
TEST_HW_FLASH_CASES_HOSTLINK = [
{
'i': ['--jtag=digilent', '--cores=1'],
'o': [TEST_DRIVER_CMD, '-nooptions', '-nogoifmain',
'-toggle=include_local_symbols=1',
'-digilent', '-run', '-cl', RC_KERNEL_ELF]
}, {
'i': ['--jtag=digilent', '--cores=1', '--dig-device=test'],
'o': [TEST_DRIVER_CMD, '-nooptions', '-nogoifmain',
'-toggle=include_local_symbols=1',
'-digilent', '-prop=dig_device=test', '-run', '-cl', RC_KERNEL_ELF]
}]
TEST_HW_FLASH_CASES_ERR = [
{
'i': ['--jtag=test_debug', '--cores=1'],
'e': "unsupported jtag adapter test_debug"
},{
'i': ['--jtag=digilent', '--cores=13'],
'e': "unsupported cores 13"
}]
TEST_HW_DEBUG_CASES = [
{
'i': ['--jtag=digilent', '--cores=1'],
'o': [TEST_DRIVER_CMD, '-nooptions', '-nogoifmain',
'-toggle=include_local_symbols=1',
'-digilent',
'-OKN', RC_KERNEL_ELF]
}, {
'i': ['--jtag=digilent', '--cores=1', '--dig-device=test'],
'o': [TEST_DRIVER_CMD, '-nooptions', '-nogoifmain',
'-toggle=include_local_symbols=1',
'-digilent', '-prop=dig_device=test',
'-OKN', RC_KERNEL_ELF]
}]
TEST_HW_DEBUG_CASES_ERR = [
{
'i': ['--jtag=test_debug', '--cores=1'],
'e': "unsupported jtag adapter test_debug"
}, {
'i': ['--jtag=digilent', '--cores=13'],
'e': "unsupported cores 13"
}]
TEST_HW_MULTICORE_CASES = [['--jtag=digilent', '--cores=2']]
TEST_HW_CORE1 = [TEST_DRIVER_CMD, '-pset=1', '-psetname=core0',
'-nooptions', '-nogoifmain', '-toggle=include_local_symbols=1',
'-digilent', RC_KERNEL_ELF]
TEST_HW_CORE2 = [TEST_DRIVER_CMD, '-pset=2', '-psetname=core1',
'-prop=download=2', '-nooptions', '-nogoifmain',
'-toggle=include_local_symbols=1',
'-digilent', RC_KERNEL_ELF]
TEST_HW_CORES_LAUNCH_NO_HOSTLINK = [TEST_DRIVER_CMD, '-multifiles=core1,core0', '-run',
'-cmd=-nowaitq run', '-cmd=quit', '-cl']
TEST_HW_CORES_LAUNCH_HOSTLINK = [TEST_DRIVER_CMD, '-multifiles=core1,core0', '-run', '-cl']
def adjust_runner_config(runner_config, tmpdir, dotconfig):
# Adjust a RunnerConfig object, 'runner_config', by
# replacing its build directory with 'tmpdir' after writing
# the contents of 'dotconfig' to tmpdir/zephyr/.config.
zephyr = tmpdir / 'zephyr'
zephyr.mkdir()
with open(zephyr / '.config', 'w') as f:
f.write(dotconfig)
print("" + fspath(tmpdir))
return runner_config._replace(build_dir=fspath(tmpdir))
#
# Fixtures
#
def mdb(runner_config, tmpdir, mdb_runner):
'''MdbBinaryRunner from constructor kwargs or command line parameters'''
# This factory takes either a dict of kwargs to pass to the
# constructor, or a list of command-line arguments to parse and
# use with the create() method.
def _factory(args):
# Ensure kernel binaries exist (as empty files, so commands
# which use them must be patched out).
tmpdir.ensure(RC_KERNEL_ELF)
tmpdir.chdir()
if isinstance(args, dict):
return mdb_runner(runner_config, TEST_TARGET, **args)
elif isinstance(args, list):
parser = argparse.ArgumentParser(allow_abbrev=False)
mdb_runner.add_parser(parser)
arg_namespace = parser.parse_args(args)
return mdb_runner.create(runner_config, arg_namespace)
return _factory
@pytest.fixture
def mdb_nsim(runner_config, tmpdir):
return mdb(runner_config, tmpdir, MdbNsimBinaryRunner)
@pytest.fixture
def mdb_hw_no_hl(runner_config, tmpdir):
runner_config = adjust_runner_config(runner_config, tmpdir, DOTCONFIG_NO_HOSTLINK)
return mdb(runner_config, tmpdir, MdbHwBinaryRunner)
@pytest.fixture
def mdb_hw_hl(runner_config, tmpdir):
runner_config = adjust_runner_config(runner_config, tmpdir, DOTCONFIG_HOSTLINK)
return mdb(runner_config, tmpdir, MdbHwBinaryRunner)
#
# Helpers
#
def require_patch(program):
assert program == TEST_DRIVER_CMD
#
# Test cases for runners created by constructor.
#
# mdb-nsim test cases
@pytest.mark.parametrize('test_case', TEST_NSIM_FLASH_CASES)
@patch('runners.mdb.MdbNsimBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_flash_nsim(require, cc, test_case, mdb_nsim):
mdb_nsim(test_case['i']).run('flash')
assert require.called
cc.assert_called_once_with(test_case['o'], cwd=RC_BUILD_DIR)
@pytest.mark.parametrize('test_case', TEST_NSIM_DEBUG_CASES)
@patch('runners.mdb.MdbNsimBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_debug_nsim(require, pii, test_case, mdb_nsim):
mdb_nsim(test_case['i']).run('debug')
assert require.called
pii.assert_called_once_with(test_case['o'], cwd=RC_BUILD_DIR)
@pytest.mark.parametrize('test_case', TEST_NSIM_MULTICORE_CASES)
@patch('runners.mdb.MdbNsimBinaryRunner.check_call')
@patch('runners.mdb.MdbNsimBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_multicores_nsim(require, pii, cc, test_case, mdb_nsim):
mdb_nsim(test_case).run('flash')
assert require.called
cc_calls = [call(TEST_NSIM_CORE1, cwd=RC_BUILD_DIR), call(TEST_NSIM_CORE2, cwd=RC_BUILD_DIR)]
cc.assert_has_calls(cc_calls)
pii.assert_called_once_with(TEST_NSIM_CORES_LAUNCH, cwd=RC_BUILD_DIR)
# mdb-hw test cases
@pytest.mark.parametrize('test_case', TEST_HW_FLASH_CASES_NO_HOSTLINK)
@patch('runners.mdb.MdbHwBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_flash_hw_no_hl(require, cc, test_case, mdb_hw_no_hl, tmpdir):
mdb_hw_no_hl(test_case['i']).run('flash')
assert require.called
cc.assert_called_once_with(test_case['o'], cwd=tmpdir)
@pytest.mark.parametrize('test_case', TEST_HW_FLASH_CASES_HOSTLINK)
@patch('runners.mdb.MdbHwBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_flash_hw_hl(require, cc, test_case, mdb_hw_hl, tmpdir):
mdb_hw_hl(test_case['i']).run('flash')
assert require.called
cc.assert_called_once_with(test_case['o'], cwd=tmpdir)
@pytest.mark.parametrize('test_case', TEST_HW_FLASH_CASES_ERR)
@patch('runners.mdb.MdbHwBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_flash_hw_err(require, cc, test_case, mdb_hw_no_hl):
with pytest.raises(ValueError) as rinfo:
mdb_hw_no_hl(test_case['i']).run('flash')
assert str(rinfo.value) == test_case['e']
@pytest.mark.parametrize('test_case', TEST_HW_DEBUG_CASES)
@patch('runners.mdb.MdbHwBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_debug_hw(require, pii, test_case, mdb_hw_no_hl, tmpdir):
mdb_hw_no_hl(test_case['i']).run('debug')
assert require.called
pii.assert_called_once_with(test_case['o'], cwd=tmpdir)
@pytest.mark.parametrize('test_case', TEST_HW_DEBUG_CASES)
@patch('runners.mdb.MdbHwBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_debug_hw_hl(require, pii, test_case, mdb_hw_hl, tmpdir):
mdb_hw_hl(test_case['i']).run('debug')
assert require.called
pii.assert_called_once_with(test_case['o'], cwd=tmpdir)
@pytest.mark.parametrize('test_case', TEST_HW_DEBUG_CASES_ERR)
@patch('runners.mdb.MdbHwBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_debug_hw_err(require, pii, test_case, mdb_hw_no_hl):
with pytest.raises(ValueError) as rinfo:
mdb_hw_no_hl(test_case['i']).run('debug')
assert str(rinfo.value) == test_case['e']
@pytest.mark.parametrize('test_case', TEST_HW_MULTICORE_CASES)
@patch('runners.mdb.MdbHwBinaryRunner.check_call')
@patch('runners.mdb.MdbHwBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_multicores_hw_no_hl(require, pii, cc, test_case, mdb_hw_no_hl, tmpdir):
mdb_hw_no_hl(test_case).run('flash')
assert require.called
cc_calls = [call(TEST_HW_CORE1, cwd=tmpdir), call(TEST_HW_CORE2, cwd=tmpdir)]
cc.assert_has_calls(cc_calls)
pii.assert_called_once_with(TEST_HW_CORES_LAUNCH_NO_HOSTLINK, cwd=tmpdir)
@pytest.mark.parametrize('test_case', TEST_HW_MULTICORE_CASES)
@patch('runners.mdb.MdbHwBinaryRunner.check_call')
@patch('runners.mdb.MdbHwBinaryRunner.call')
@patch('runners.core.ZephyrBinaryRunner.require', side_effect=require_patch)
def test_multicores_hw_hl(require, pii, cc, test_case, mdb_hw_hl, tmpdir):
mdb_hw_hl(test_case).run('flash')
assert require.called
cc_calls = [call(TEST_HW_CORE1, cwd=tmpdir), call(TEST_HW_CORE2, cwd=tmpdir)]
cc.assert_has_calls(cc_calls)
pii.assert_called_once_with(TEST_HW_CORES_LAUNCH_HOSTLINK, cwd=tmpdir)