Files
zephyr/scripts/tests/twister/test_config_parser.py
Pieter De Gendt aad2408b30 scripts: Don't use isort known-first-party
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>
2025-10-16 17:09:14 +03:00

207 lines
6.3 KiB
Python

#!/usr/bin/env python3
# Copyright (c) 2024 Intel Corporation
# Copyright (c) 2024 Arm Limited (or its affiliates). All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
"""
Tests for config_parser.py
"""
import os
from contextlib import nullcontext
from unittest import mock
import pytest
import scl
from twisterlib.config_parser import (
ConfigurationError,
TwisterConfigParser,
extract_fields_from_arg_list,
)
def test_extract_single_field_from_string_argument():
target_fields = {"FIELD1"}
arg_list = "FIELD1=value1 FIELD2=value2 FIELD3=value3"
extracted_fields, other_fields = extract_fields_from_arg_list(
target_fields, arg_list)
assert extracted_fields == {"FIELD1": ["value1"]}
assert other_fields == ["FIELD2=value2", "FIELD3=value3"]
def test_no_fields_to_extract():
target_fields = set()
arg_list = "arg1 arg2 arg3"
extracted_fields, other_fields = extract_fields_from_arg_list(
target_fields, arg_list)
assert extracted_fields == {}
assert other_fields == ["arg1", "arg2", "arg3" ]
def test_missing_fields():
target_fields = {"CONF_FILE", "OVERLAY_CONFIG", "DTC_OVERLAY_FILE"}
arg_list = "arg1 arg2 arg3"
extracted_fields, other_fields = extract_fields_from_arg_list(
target_fields, arg_list)
assert extracted_fields == {"CONF_FILE": [], "OVERLAY_CONFIG": [], "DTC_OVERLAY_FILE": []}
assert other_fields == ["arg1", "arg2", "arg3" ]
def test_load_yaml_with_extra_args_and_retrieve_scenario_data(zephyr_base):
filename = "test_data.yaml"
yaml_data = '''
tests:
scenario1:
tags: ['tag1', 'tag2']
extra_args:
- '--CONF_FILE=file1.conf'
- '--OVERLAY_CONFIG=config1.conf'
filter: 'filter1'
common:
filter: 'filter2'
'''
loaded_schema = scl.yaml_load(
os.path.join(zephyr_base, 'scripts', 'schemas','twister', 'testsuite-schema.yaml')
)
with mock.patch('builtins.open', mock.mock_open(read_data=yaml_data)):
parser = TwisterConfigParser(filename, loaded_schema)
parser.load()
scenario_data = parser.get_scenario('scenario1')
scenario_common = parser.common
assert scenario_data['tags'] == {'tag1', 'tag2'}
assert scenario_data['extra_args'] == ['--CONF_FILE=file1.conf', '--OVERLAY_CONFIG=config1.conf']
assert scenario_common == {'filter': 'filter2'}
def test_default_values(zephyr_base):
filename = "test_data.yaml"
yaml_data = '''
tests:
scenario1:
tags: 'tag1'
extra_args: ''
'''
loaded_schema = scl.yaml_load(
os.path.join(zephyr_base, 'scripts', 'schemas', 'twister','testsuite-schema.yaml')
)
with mock.patch('builtins.open', mock.mock_open(read_data=yaml_data)):
parser = TwisterConfigParser(filename, loaded_schema)
parser.load()
expected_scenario_data = { 'type': 'integration',
'extra_args': [],
'extra_configs': [],
'extra_conf_files': [],
'extra_overlay_confs': [],
'extra_dtc_overlay_files': [],
'required_snippets': [],
'build_only': False,
'build_on_all': False,
'skip': False, 'slow': False,
'timeout': 60,
'min_ram': 8,
'modules': [],
'depends_on': set(),
'min_flash': 32,
'arch_allow': set(),
'arch_exclude': set(),
'extra_sections': [],
'integration_platforms': [],
'ignore_faults': False,
'ignore_qemu_crash': False,
'testcases': [],
'platform_type': [],
'platform_exclude': set(),
'platform_allow': set(),
'platform_key': [],
'toolchain_exclude': set(),
'toolchain_allow': set(),
'filter': '',
'levels': [],
'harness': 'test',
'harness_config': {},
'seed': 0, 'sysbuild': False
}
assert expected_scenario_data.items() <= expected_scenario_data.items()
@pytest.mark.parametrize(
'value, typestr, expected, expected_warning',
[
(' hello ', 'str', 'hello', None),
('3.14', 'float', 3.14, None),
('10', 'int', 10, None),
('True', 'bool', 'True', None), # do-nothing cast
('key: val', 'map', 'key: val', None), # do-nothing cast
('test', 'int', ValueError, None),
('test', 'unknown', ConfigurationError, None),
([ '1', '2', '3' ], 'set', { '1', '2', '2','3' }, None),
],
ids=['str to str', 'str to float', 'str to int', 'str to bool', 'str to map',
'invalid', 'to unknown', "list to set"]
)
def test_cast_value(zephyr_base, value, typestr, expected, expected_warning):
loaded_schema = scl.yaml_load(
os.path.join(zephyr_base, 'scripts', 'schemas', 'twister','testsuite-schema.yaml')
)
parser = TwisterConfigParser("config.yaml", loaded_schema)
with mock.patch('warnings.warn') as warn_mock:
with pytest.raises(expected) if isinstance(expected, type) and issubclass(expected, Exception) else nullcontext():
result = parser._cast_value(value, typestr)
assert result == expected
if expected_warning:
warn_mock.assert_called_once_with(*expected_warning, stacklevel=mock.ANY)
else:
warn_mock.assert_not_called()
def test_load_invalid_test_config_yaml(zephyr_base):
filename = "test_data.yaml"
yaml_data = '''
gibberish data
'''
loaded_schema = scl.yaml_load(
os.path.join(zephyr_base, 'scripts', 'schemas','twister', 'test-config-schema.yaml')
)
with mock.patch('builtins.open', mock.mock_open(read_data=yaml_data)):
parser = TwisterConfigParser(filename, loaded_schema)
with pytest.raises(Exception):
parser.load()
def test_load_yaml_with_no_scenario_data(zephyr_base):
filename = "test_data.yaml"
yaml_data = '''
tests:
common:
extra_args: '--CONF_FILE=file2.conf --OVERLAY_CONFIG=config2.conf'
'''
loaded_schema = scl.yaml_load(
os.path.join(zephyr_base, 'scripts', 'schemas','twister', 'testsuite-schema.yaml')
)
with mock.patch('builtins.open', mock.mock_open(read_data=yaml_data)):
parser = TwisterConfigParser(filename, loaded_schema)
parser.load()
with pytest.raises(KeyError):
scenario_data = parser.get_scenario('scenario1')
assert scenario_data is None