Partially revert 1bcc065224
This change impacts all other scripts that import those modules, while
those weren't updated.
It will be hard to maintain this list, whilst keeping the entire tree
compliant.
Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
684 lines
24 KiB
Python
684 lines
24 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright (c) 2020 Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
# pylint: disable=line-too-long
|
|
"""
|
|
Tests for testinstance class
|
|
"""
|
|
|
|
import os
|
|
from contextlib import nullcontext
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
from expr_parser import reserved
|
|
from twisterlib.error import BuildError
|
|
from twisterlib.handlers import QEMUHandler
|
|
from twisterlib.platform import Simulator
|
|
from twisterlib.runner import TwisterRunner
|
|
from twisterlib.statuses import TwisterStatus
|
|
from twisterlib.testinstance import TestInstance
|
|
|
|
TESTDATA_PART_1 = [
|
|
(False, False, "console", None, "qemu", False, [], (False, True)),
|
|
(False, False, "console", "native", "qemu", False, [], (False, True)),
|
|
(True, False, "console", "native", "nsim", False, [], (True, False)),
|
|
(True, True, "console", "native", "renode", False, [], (True, False)),
|
|
(False, False, "sensor", "native", "", False, [], (True, False)),
|
|
(False, False, "sensor", None, "", False, [], (True, False)),
|
|
(False, True, "sensor", "native", "", True, [], (True, False)),
|
|
]
|
|
@pytest.mark.parametrize(
|
|
"build_only, slow, harness, platform_type, platform_sim, device_testing,fixture, expected",
|
|
TESTDATA_PART_1
|
|
)
|
|
def test_check_build_or_run(
|
|
class_testplan,
|
|
all_testsuites_dict,
|
|
platforms_list,
|
|
build_only,
|
|
slow,
|
|
harness,
|
|
platform_type,
|
|
platform_sim,
|
|
device_testing,
|
|
fixture,
|
|
expected
|
|
):
|
|
"""" Test to check the conditions for build_only and run scenarios
|
|
Scenario 1: Test when different parameters are passed, build_only and run are set correctly
|
|
Scenario 2: Test if build_only is enabled when the OS is Windows"""
|
|
|
|
class_testplan.testsuites = all_testsuites_dict
|
|
testsuite = class_testplan.testsuites.get('scripts/tests/twister/test_data/testsuites/tests/'
|
|
'test_a/test_a.check_1')
|
|
print(testsuite)
|
|
|
|
class_testplan.platforms = platforms_list
|
|
platform = class_testplan.get_platform("demo_board_2")
|
|
platform.type = platform_type
|
|
platform.simulators = [Simulator({"name": platform_sim})] if platform_sim else []
|
|
testsuite.harness = harness
|
|
testsuite.build_only = build_only
|
|
testsuite.slow = slow
|
|
|
|
testinstance = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir)
|
|
env = mock.Mock(
|
|
options=mock.Mock(
|
|
device_testing=False,
|
|
enable_slow=slow,
|
|
fixtures=fixture,
|
|
filter="",
|
|
sim_name=platform_sim
|
|
)
|
|
)
|
|
run = testinstance.check_runnable(env.options)
|
|
_, r = expected
|
|
assert run == r
|
|
|
|
with mock.patch('os.name', 'nt'):
|
|
# path to QEMU binary is not in QEMU_BIN_PATH environment variable
|
|
run = testinstance.check_runnable(env.options)
|
|
assert not run
|
|
|
|
# mock path to QEMU binary in QEMU_BIN_PATH environment variable
|
|
with mock.patch('os.environ', {'QEMU_BIN_PATH': ''}):
|
|
run = testinstance.check_runnable(env.options)
|
|
_, r = expected
|
|
assert run == r
|
|
|
|
|
|
TESTDATA_PART_2 = [
|
|
(True, True, True, ["demo_board_2/unit_testing"], "native",
|
|
None, '\nCONFIG_COVERAGE=y\nCONFIG_ASAN=y\nCONFIG_UBSAN=y'),
|
|
(True, False, True, ["demo_board_2/unit_testing"], "native",
|
|
None, '\nCONFIG_COVERAGE=y\nCONFIG_ASAN=y'),
|
|
(False, False, True, ["demo_board_2/unit_testing"], 'native',
|
|
None, '\nCONFIG_COVERAGE=y'),
|
|
(True, False, True, ["demo_board_2/unit_testing"], 'mcu',
|
|
None, '\nCONFIG_COVERAGE=y'),
|
|
(False, False, False, ["demo_board_2/unit_testing"], 'native', None, ''),
|
|
(False, False, True, ['demo_board_1'], 'native', None, ''),
|
|
(True, False, False, ["demo_board_2"], 'native', None, '\nCONFIG_ASAN=y'),
|
|
(False, True, False, ["demo_board_2"], 'native', None, '\nCONFIG_UBSAN=y'),
|
|
(False, False, False, ["demo_board_2"], 'native',
|
|
["CONFIG_LOG=y"], 'CONFIG_LOG=y'),
|
|
(False, False, False, ["demo_board_2"], 'native',
|
|
["arch:x86:CONFIG_LOG=y"], 'CONFIG_LOG=y'),
|
|
(False, False, False, ["demo_board_2"], 'native',
|
|
["arch:arm:CONFIG_LOG=y"], ''),
|
|
(False, False, False, ["demo_board_2"], 'native',
|
|
["platform:demo_board_2/unit_testing:CONFIG_LOG=y"], 'CONFIG_LOG=y'),
|
|
(False, False, False, ["demo_board_2"], 'native',
|
|
["platform:demo_board_1:CONFIG_LOG=y"], ''),
|
|
]
|
|
|
|
@pytest.mark.parametrize(
|
|
'enable_asan, enable_ubsan, enable_coverage, coverage_platform, platform_type,'
|
|
' extra_configs, expected_content',
|
|
TESTDATA_PART_2
|
|
)
|
|
def test_create_overlay(
|
|
class_testplan,
|
|
all_testsuites_dict,
|
|
platforms_list,
|
|
enable_asan,
|
|
enable_ubsan,
|
|
enable_coverage,
|
|
coverage_platform,
|
|
platform_type,
|
|
extra_configs,
|
|
expected_content
|
|
):
|
|
"""Test correct content is written to testcase_extra.conf based on if conditions."""
|
|
class_testplan.testsuites = all_testsuites_dict
|
|
testcase = class_testplan.testsuites.get('scripts/tests/twister/test_data/testsuites/samples/'
|
|
'test_app/sample_test.app')
|
|
|
|
if extra_configs:
|
|
testcase.extra_configs = extra_configs
|
|
|
|
class_testplan.platforms = platforms_list
|
|
platform = class_testplan.get_platform("demo_board_2")
|
|
|
|
testinstance = TestInstance(testcase, platform, 'zephyr', class_testplan.env.outdir)
|
|
platform.type = platform_type
|
|
assert testinstance.create_overlay(platform, enable_asan, enable_ubsan, enable_coverage, coverage_platform) == expected_content
|
|
|
|
def test_calculate_sizes(class_testplan, all_testsuites_dict, platforms_list):
|
|
""" Test Calculate sizes method for zephyr elf"""
|
|
class_testplan.testsuites = all_testsuites_dict
|
|
testcase = class_testplan.testsuites.get('scripts/tests/twister/test_data/testsuites/samples/'
|
|
'test_app/sample_test.app')
|
|
class_testplan.platforms = platforms_list
|
|
platform = class_testplan.get_platform("demo_board_2")
|
|
testinstance = TestInstance(testcase, platform, 'zephyr', class_testplan.env.outdir)
|
|
|
|
with pytest.raises(BuildError):
|
|
assert testinstance.calculate_sizes() == "Missing/multiple output ELF binary"
|
|
|
|
TESTDATA_PART_3 = [
|
|
(
|
|
'CONFIG_ARCH_HAS_THREAD_LOCAL_STORAGE and' \
|
|
' CONFIG_TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE and' \
|
|
' not (CONFIG_TOOLCHAIN_ARCMWDT_SUPPORTS_THREAD_LOCAL_STORAGE and CONFIG_USERSPACE)',
|
|
['kconfig']
|
|
),
|
|
(
|
|
'(dt_compat_enabled("st,stm32-flash-controller") or' \
|
|
' dt_compat_enabled("st,stm32h7-flash-controller")) and' \
|
|
' dt_label_with_parent_compat_enabled("storage_partition", "fixed-partitions")',
|
|
['dts']
|
|
),
|
|
(
|
|
'((CONFIG_FLASH_HAS_DRIVER_ENABLED and not CONFIG_TRUSTED_EXECUTION_NONSECURE) and' \
|
|
' dt_label_with_parent_compat_enabled("storage_partition", "fixed-partitions")) or' \
|
|
' (CONFIG_FLASH_HAS_DRIVER_ENABLED and CONFIG_TRUSTED_EXECUTION_NONSECURE and' \
|
|
' dt_label_with_parent_compat_enabled("slot1_ns_partition", "fixed-partitions"))',
|
|
['dts', 'kconfig']
|
|
),
|
|
(
|
|
'((CONFIG_CPU_AARCH32_CORTEX_R or CONFIG_CPU_CORTEX_M) and' \
|
|
' CONFIG_CPU_HAS_FPU and TOOLCHAIN_HAS_NEWLIB == 1) or CONFIG_ARCH_POSIX',
|
|
['full']
|
|
)
|
|
]
|
|
|
|
@pytest.mark.parametrize("filter_expr, expected_stages", TESTDATA_PART_3)
|
|
def test_which_filter_stages(filter_expr, expected_stages):
|
|
logic_keys = reserved.keys()
|
|
stages = TwisterRunner.get_cmake_filter_stages(filter_expr, logic_keys)
|
|
assert sorted(stages) == sorted(expected_stages)
|
|
|
|
|
|
@pytest.fixture(name='testinstance')
|
|
def sample_testinstance(all_testsuites_dict, class_testplan, platforms_list, request):
|
|
testsuite_path = 'scripts/tests/twister/test_data/testsuites'
|
|
if request.param['testsuite_kind'] == 'sample':
|
|
testsuite_path += '/samples/test_app/sample_test.app'
|
|
elif request.param['testsuite_kind'] == 'tests':
|
|
testsuite_path += '/tests/test_a/test_a.check_1'
|
|
|
|
class_testplan.testsuites = all_testsuites_dict
|
|
testsuite = class_testplan.testsuites.get(testsuite_path)
|
|
class_testplan.platforms = platforms_list
|
|
platform = class_testplan.get_platform(request.param.get('board_name', 'demo_board_2'))
|
|
|
|
testinstance = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir)
|
|
return testinstance
|
|
|
|
|
|
TESTDATA_1 = [
|
|
(False),
|
|
(True),
|
|
]
|
|
|
|
@pytest.mark.parametrize('detailed_test_id', TESTDATA_1)
|
|
def test_testinstance_init(all_testsuites_dict, class_testplan, platforms_list, detailed_test_id):
|
|
testsuite_path = 'scripts/tests/twister/test_data/testsuites/samples/test_app/sample_test.app'
|
|
class_testplan.testsuites = all_testsuites_dict
|
|
testsuite = class_testplan.testsuites.get(testsuite_path)
|
|
testsuite.detailed_test_id = detailed_test_id
|
|
class_testplan.platforms = platforms_list
|
|
platform = class_testplan.get_platform("demo_board_2/unit_testing")
|
|
|
|
testinstance = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir)
|
|
|
|
if detailed_test_id:
|
|
assert testinstance.build_dir == os.path.join(class_testplan.env.outdir, platform.normalized_name, 'zephyr', testsuite_path)
|
|
else:
|
|
assert testinstance.build_dir == os.path.join(class_testplan.env.outdir, platform.normalized_name, 'zephyr', testsuite.source_dir_rel, testsuite.name)
|
|
|
|
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'sample'}], indirect=True)
|
|
def test_testinstance_record(testinstance):
|
|
testinstance.testcases = [mock.Mock()]
|
|
recording = [ {'field_1': 'recording_1_1', 'field_2': 'recording_1_2'},
|
|
{'field_1': 'recording_2_1', 'field_2': 'recording_2_2'}
|
|
]
|
|
with mock.patch(
|
|
'builtins.open',
|
|
mock.mock_open(read_data='')
|
|
) as mock_file, \
|
|
mock.patch(
|
|
'csv.DictWriter.writerow',
|
|
mock.Mock()
|
|
) as mock_writeheader, \
|
|
mock.patch(
|
|
'csv.DictWriter.writerows',
|
|
mock.Mock()
|
|
) as mock_writerows:
|
|
testinstance.record(recording)
|
|
|
|
print(mock_file.mock_calls)
|
|
|
|
mock_file.assert_called_with(
|
|
os.path.join(testinstance.build_dir, 'recording.csv'),
|
|
'w'
|
|
)
|
|
|
|
mock_writeheader.assert_has_calls([mock.call({ k:k for k in recording[0]})])
|
|
mock_writerows.assert_has_calls([mock.call(recording)])
|
|
|
|
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'sample'}], indirect=True)
|
|
def test_testinstance_add_filter(testinstance):
|
|
reason = 'dummy reason'
|
|
filter_type = 'dummy type'
|
|
|
|
testinstance.add_filter(reason, filter_type)
|
|
|
|
assert {'type': filter_type, 'reason': reason} in testinstance.filters
|
|
assert testinstance.status == TwisterStatus.FILTER
|
|
assert testinstance.reason == reason
|
|
assert testinstance.filter_type == filter_type
|
|
|
|
|
|
def test_testinstance_init_cases(all_testsuites_dict, class_testplan, platforms_list):
|
|
testsuite_path = 'scripts/tests/twister/test_data/testsuites/tests/test_a/test_a.check_1'
|
|
class_testplan.testsuites = all_testsuites_dict
|
|
testsuite = class_testplan.testsuites.get(testsuite_path)
|
|
class_testplan.platforms = platforms_list
|
|
platform = class_testplan.get_platform("demo_board_2")
|
|
|
|
testinstance = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir)
|
|
|
|
testinstance.init_cases()
|
|
|
|
assert all(
|
|
[
|
|
any(
|
|
[
|
|
tcc.name == tc.name and tcc.freeform == tc.freeform \
|
|
for tcc in testinstance.testsuite.testcases
|
|
]
|
|
) for tc in testsuite.testcases
|
|
]
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'sample'}], indirect=True)
|
|
def test_testinstance_get_run_id(testinstance):
|
|
res = testinstance._get_run_id()
|
|
|
|
assert isinstance(res, str)
|
|
|
|
|
|
TESTDATA_2 = [
|
|
('another reason', 'another reason'),
|
|
(None, 'dummy reason'),
|
|
]
|
|
|
|
@pytest.mark.parametrize('reason, expected_reason', TESTDATA_2)
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'tests'}], indirect=True)
|
|
def test_testinstance_add_missing_case_status(testinstance, reason, expected_reason):
|
|
testinstance.reason = 'dummy reason'
|
|
|
|
status = TwisterStatus.PASS
|
|
|
|
assert len(testinstance.testcases) > 1, 'Selected testsuite does not have enough testcases.'
|
|
|
|
testinstance.testcases[0].status = TwisterStatus.STARTED
|
|
testinstance.testcases[-1].status = TwisterStatus.NONE
|
|
|
|
testinstance.add_missing_case_status(status, reason)
|
|
|
|
assert testinstance.testcases[0].status == TwisterStatus.FAIL
|
|
assert testinstance.testcases[-1].status == TwisterStatus.PASS
|
|
assert testinstance.testcases[-1].reason == expected_reason
|
|
|
|
|
|
def test_testinstance_dunders(all_testsuites_dict, class_testplan, platforms_list):
|
|
testsuite_path = 'scripts/tests/twister/test_data/testsuites/samples/test_app/sample_test.app'
|
|
class_testplan.testsuites = all_testsuites_dict
|
|
testsuite = class_testplan.testsuites.get(testsuite_path)
|
|
class_testplan.platforms = platforms_list
|
|
platform = class_testplan.get_platform("demo_board_2")
|
|
|
|
testinstance = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir)
|
|
testinstance_copy = TestInstance(testsuite, platform, 'zephyr', class_testplan.env.outdir)
|
|
|
|
d = testinstance.__getstate__()
|
|
|
|
d['name'] = 'dummy name'
|
|
testinstance_copy.__setstate__(d)
|
|
|
|
d['name'] = 'another name'
|
|
testinstance.__setstate__(d)
|
|
|
|
assert testinstance < testinstance_copy
|
|
|
|
testinstance_copy.__setstate__(d)
|
|
|
|
assert not testinstance < testinstance_copy
|
|
assert not testinstance_copy < testinstance
|
|
|
|
assert testinstance.__repr__() == f'<TestSuite {testsuite_path} on demo_board_2/unit_testing>'
|
|
|
|
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'tests'}], indirect=True)
|
|
def test_testinstance_set_case_status_by_name(testinstance):
|
|
name = 'test_a.check_1.2a'
|
|
status = TwisterStatus.PASS
|
|
reason = 'dummy reason'
|
|
|
|
tc = testinstance.set_case_status_by_name(name, status, reason)
|
|
|
|
assert tc.name == name
|
|
assert tc.status == status
|
|
assert tc.reason == reason
|
|
|
|
tc = testinstance.set_case_status_by_name(name, status, None)
|
|
|
|
assert tc.reason == reason
|
|
|
|
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'tests'}], indirect=True)
|
|
def test_testinstance_add_testcase(testinstance):
|
|
name = 'test_a.check_1.3a'
|
|
freeform = True
|
|
|
|
tc = testinstance.add_testcase(name, freeform)
|
|
|
|
assert tc in testinstance.testcases
|
|
|
|
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'tests'}], indirect=True)
|
|
def test_testinstance_get_case_by_name(testinstance):
|
|
name = 'test_a.check_1.2a'
|
|
|
|
tc = testinstance.get_case_by_name(name)
|
|
|
|
assert tc.name == name
|
|
|
|
name = 'test_a.check_1.3a'
|
|
|
|
tc = testinstance.get_case_by_name(name)
|
|
|
|
assert tc is None
|
|
|
|
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'tests'}], indirect=True)
|
|
def test_testinstance_get_case_or_create(caplog, testinstance):
|
|
name = 'test_a.check_1.2a'
|
|
|
|
tc = testinstance.get_case_or_create(name)
|
|
|
|
assert tc.name == name
|
|
|
|
name = 'test_a.check_1.3a'
|
|
|
|
tc = testinstance.get_case_or_create(name)
|
|
|
|
assert tc.name == name
|
|
assert 'Could not find a matching testcase for test_a.check_1.3a' in caplog.text
|
|
|
|
|
|
TESTDATA_3 = [
|
|
(None, 'nonexistent harness', False),
|
|
('nonexistent fixture', 'console', False),
|
|
(None, 'console', True),
|
|
('dummy fixture', 'console', True),
|
|
]
|
|
|
|
@pytest.mark.parametrize(
|
|
'fixture, harness, expected_can_run',
|
|
TESTDATA_3,
|
|
ids=['improper harness', 'fixture not in list', 'no fixture specified', 'fixture in list']
|
|
)
|
|
def test_testinstance_testsuite_runnable(
|
|
all_testsuites_dict,
|
|
class_testplan,
|
|
fixture,
|
|
harness,
|
|
expected_can_run
|
|
):
|
|
testsuite_path = 'scripts/tests/twister/test_data/testsuites/samples/test_app/sample_test.app'
|
|
class_testplan.testsuites = all_testsuites_dict
|
|
testsuite = class_testplan.testsuites.get(testsuite_path)
|
|
|
|
testsuite.harness = harness
|
|
testsuite.harness_config['fixture'] = fixture
|
|
|
|
fixtures = ['dummy fixture']
|
|
|
|
can_run = TestInstance.testsuite_runnable(testsuite, fixtures)\
|
|
|
|
assert can_run == expected_can_run
|
|
|
|
|
|
TESTDATA_4 = [
|
|
(True, mock.ANY, mock.ANY, mock.ANY, None, [], False),
|
|
(False, True, mock.ANY, mock.ANY, 'device', [], True),
|
|
(False, False, 'qemu', mock.ANY, 'qemu', ['QEMU_PIPE=1'], True),
|
|
(False, False, 'armfvp', mock.ANY, 'armfvp', [], True),
|
|
(False, False, None, 'unit', 'unit', ['COVERAGE=1'], True),
|
|
(False, False, None, 'dummy type', '', [], False),
|
|
]
|
|
|
|
@pytest.mark.parametrize(
|
|
'preexisting_handler, device_testing, platform_sim, testsuite_type,' \
|
|
' expected_handler_type, expected_handler_args, expected_handler_ready',
|
|
TESTDATA_4,
|
|
ids=['preexisting handler', 'device testing', 'qemu simulation',
|
|
'non-qemu simulation with exec', 'unit teting', 'no handler']
|
|
)
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'tests'}], indirect=True)
|
|
def test_testinstance_setup_handler(
|
|
testinstance,
|
|
preexisting_handler,
|
|
device_testing,
|
|
platform_sim,
|
|
testsuite_type,
|
|
expected_handler_type,
|
|
expected_handler_args,
|
|
expected_handler_ready
|
|
):
|
|
testinstance.handler = mock.Mock() if preexisting_handler else None
|
|
testinstance.platform.simulators = [Simulator({"name": platform_sim, "exec": 'dummy exec'})] if platform_sim else []
|
|
testinstance.testsuite.type = testsuite_type
|
|
env = mock.Mock(
|
|
options=mock.Mock(
|
|
device_testing=device_testing,
|
|
enable_coverage=True,
|
|
sim_name=platform_sim,
|
|
)
|
|
)
|
|
|
|
with mock.patch.object(QEMUHandler, 'get_fifo', return_value=1), \
|
|
mock.patch('shutil.which', return_value=True):
|
|
testinstance.setup_handler(env)
|
|
|
|
if expected_handler_type:
|
|
assert testinstance.handler.type_str == expected_handler_type
|
|
assert testinstance.handler.ready == expected_handler_ready
|
|
assert all([arg in testinstance.handler.args for arg in expected_handler_args])
|
|
|
|
|
|
TESTDATA_5 = [
|
|
('nt', 'renode', mock.ANY, mock.ANY,
|
|
mock.ANY, mock.ANY, mock.ANY,
|
|
mock.ANY, mock.ANY, mock.ANY, mock.ANY, False),
|
|
('linux', mock.ANY, mock.ANY, mock.ANY,
|
|
True, mock.ANY, mock.ANY,
|
|
mock.ANY, mock.ANY, mock.ANY, mock.ANY, False),
|
|
('linux', mock.ANY, mock.ANY, mock.ANY,
|
|
False, True, mock.ANY,
|
|
False, mock.ANY, mock.ANY, mock.ANY, False),
|
|
('linux', 'qemu', mock.ANY, mock.ANY,
|
|
False, mock.ANY, 'pytest',
|
|
mock.ANY, 'not runnable', mock.ANY, None, True),
|
|
('linux', 'renode', 'renode', True,
|
|
False, mock.ANY, 'console',
|
|
mock.ANY, 'not runnable', [], None, True),
|
|
('linux', 'renode', 'renode', False,
|
|
False, mock.ANY, 'not pytest',
|
|
mock.ANY, 'not runnable', mock.ANY, None, False),
|
|
('linux', 'qemu', mock.ANY, mock.ANY,
|
|
False, mock.ANY, 'console',
|
|
mock.ANY, 'not runnable', ['?'], mock.Mock(duts=[mock.Mock(platform='demo_board_2', fixtures=[])]), True),
|
|
]
|
|
|
|
@pytest.mark.parametrize(
|
|
'os_name, platform_sim, platform_sim_exec, exec_exists,' \
|
|
' testsuite_build_only, testsuite_slow, testsuite_harness,' \
|
|
' enable_slow, filter, fixtures, hardware_map, expected',
|
|
TESTDATA_5,
|
|
ids=['windows', 'build only', 'skip slow', 'pytest harness', 'sim', 'no sim', 'hardware map']
|
|
)
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'tests'}], indirect=True)
|
|
def test_testinstance_check_runnable(
|
|
testinstance,
|
|
os_name,
|
|
platform_sim,
|
|
platform_sim_exec,
|
|
exec_exists,
|
|
testsuite_build_only,
|
|
testsuite_slow,
|
|
testsuite_harness,
|
|
enable_slow,
|
|
filter,
|
|
fixtures,
|
|
hardware_map,
|
|
expected
|
|
):
|
|
testinstance.platform.simulators = [Simulator({"name": platform_sim, "exec": platform_sim_exec})]
|
|
testinstance.testsuite.build_only = testsuite_build_only
|
|
testinstance.testsuite.slow = testsuite_slow
|
|
testinstance.testsuite.harness = testsuite_harness
|
|
|
|
env = mock.Mock(
|
|
options=mock.Mock(
|
|
device_testing=False,
|
|
enable_slow=enable_slow,
|
|
fixtures=fixtures,
|
|
filter=filter,
|
|
sim_name=platform_sim
|
|
)
|
|
)
|
|
with mock.patch('os.name', os_name), \
|
|
mock.patch('shutil.which', return_value=exec_exists):
|
|
res = testinstance.check_runnable(env.options, hardware_map)
|
|
|
|
assert res == expected
|
|
|
|
|
|
TESTDATA_6 = [
|
|
(True, 'build.log'),
|
|
(False, ''),
|
|
]
|
|
|
|
@pytest.mark.parametrize('from_buildlog, expected_buildlog_filepath', TESTDATA_6)
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'tests'}], indirect=True)
|
|
def test_testinstance_calculate_sizes(testinstance, from_buildlog, expected_buildlog_filepath):
|
|
expected_elf_filepath = 'dummy.elf'
|
|
expected_extra_sections = []
|
|
expected_warning = True
|
|
testinstance.get_elf_file = mock.Mock(return_value='dummy.elf')
|
|
testinstance.get_buildlog_file = mock.Mock(return_value='build.log')
|
|
|
|
sc_mock = mock.Mock()
|
|
mock_sc = mock.Mock(return_value=sc_mock)
|
|
|
|
with mock.patch('twisterlib.testinstance.SizeCalculator', mock_sc):
|
|
res = testinstance.calculate_sizes(from_buildlog, expected_warning)
|
|
|
|
assert res == sc_mock
|
|
mock_sc.assert_called_once_with(
|
|
elf_filename=expected_elf_filepath,
|
|
extra_sections=expected_extra_sections,
|
|
buildlog_filepath=expected_buildlog_filepath,
|
|
generate_warning=expected_warning
|
|
)
|
|
|
|
|
|
TESTDATA_7 = [
|
|
(True, None),
|
|
(False, BuildError),
|
|
]
|
|
|
|
@pytest.mark.parametrize('sysbuild, expected_error', TESTDATA_7)
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'tests'}], indirect=True)
|
|
def test_testinstance_get_elf_file(caplog, tmp_path, testinstance, sysbuild, expected_error):
|
|
sysbuild_dir = tmp_path / 'sysbuild'
|
|
sysbuild_dir.mkdir()
|
|
zephyr_dir = sysbuild_dir / 'zephyr'
|
|
zephyr_dir.mkdir()
|
|
sysbuild_elf = zephyr_dir / 'dummy.elf'
|
|
sysbuild_elf.write_bytes(b'0')
|
|
sysbuild_elf2 = zephyr_dir / 'dummy2.elf'
|
|
sysbuild_elf2.write_bytes(b'0')
|
|
|
|
testinstance.sysbuild = sysbuild
|
|
testinstance.domains = mock.Mock(
|
|
get_default_domain=mock.Mock(
|
|
return_value=mock.Mock(
|
|
build_dir=sysbuild_dir
|
|
)
|
|
)
|
|
)
|
|
|
|
with pytest.raises(expected_error) if expected_error else nullcontext():
|
|
testinstance.get_elf_file()
|
|
|
|
if expected_error is None:
|
|
assert 'multiple ELF files detected: ' in caplog.text
|
|
|
|
|
|
TESTDATA_8 = [
|
|
(True, None),
|
|
(False, BuildError),
|
|
]
|
|
|
|
@pytest.mark.parametrize('create_build_log, expected_error', TESTDATA_8)
|
|
@pytest.mark.parametrize('testinstance', [{'testsuite_kind': 'tests'}], indirect=True)
|
|
def test_testinstance_get_buildlog_file(tmp_path, testinstance, create_build_log, expected_error):
|
|
if create_build_log:
|
|
build_dir = tmp_path / 'build'
|
|
build_dir.mkdir()
|
|
build_log = build_dir / 'build.log'
|
|
build_log.write_text('')
|
|
testinstance.build_dir = build_dir
|
|
|
|
with pytest.raises(expected_error) if expected_error else nullcontext():
|
|
res = testinstance.get_buildlog_file()
|
|
|
|
if expected_error is None:
|
|
assert res == str(build_log)
|
|
|
|
|
|
TESTDATA_9 = [
|
|
(
|
|
{'ztest_suite_repeat': 5, 'ztest_test_repeat': 10, 'ztest_test_shuffle': True},
|
|
'\nCONFIG_ZTEST_REPEAT=y\nCONFIG_ZTEST_SUITE_REPEAT_COUNT=5\nCONFIG_ZTEST_TEST_REPEAT_COUNT=10\nCONFIG_ZTEST_SHUFFLE=y'
|
|
),
|
|
(
|
|
{'ztest_suite_repeat': 3},
|
|
'\nCONFIG_ZTEST_REPEAT=y\nCONFIG_ZTEST_SUITE_REPEAT_COUNT=3'
|
|
),
|
|
(
|
|
{'ztest_test_repeat': 7},
|
|
'\nCONFIG_ZTEST_REPEAT=y\nCONFIG_ZTEST_TEST_REPEAT_COUNT=7'
|
|
),
|
|
(
|
|
{'ztest_test_shuffle': True},
|
|
'\nCONFIG_ZTEST_REPEAT=y\nCONFIG_ZTEST_SHUFFLE=y'
|
|
),
|
|
(
|
|
{},
|
|
''
|
|
),
|
|
]
|
|
|
|
@pytest.mark.parametrize('harness_config, expected_content', TESTDATA_9)
|
|
def test_create_overlay_with_harness_config(class_testplan, all_testsuites_dict, platforms_list, harness_config, expected_content):
|
|
testsuite_path = 'scripts/tests/twister/test_data/testsuites/samples/test_app/sample_test.app'
|
|
class_testplan.testsuites = all_testsuites_dict
|
|
testsuite = class_testplan.testsuites.get(testsuite_path)
|
|
testsuite.harness_config = harness_config
|
|
class_testplan.platforms = platforms_list
|
|
platform = class_testplan.get_platform("demo_board_2")
|
|
testinstance = TestInstance(testsuite, platform,'zephyr', class_testplan.env.outdir)
|
|
assert testinstance.create_overlay(platform) == expected_content
|