1#!/usr/bin/env python3 2# Copyright (c) 2024 Intel Corporation 3# Copyright (c) 2024 Arm Limited (or its affiliates). All rights reserved. 4# 5# SPDX-License-Identifier: Apache-2.0 6""" 7Tests for config_parser.py 8""" 9 10import os 11import pytest 12import mock 13import scl 14 15from twisterlib.config_parser import TwisterConfigParser, extract_fields_from_arg_list, ConfigurationError 16from contextlib import nullcontext 17 18def test_extract_single_field_from_string_argument(): 19 target_fields = {"FIELD1"} 20 arg_list = "FIELD1=value1 FIELD2=value2 FIELD3=value3" 21 extracted_fields, other_fields = extract_fields_from_arg_list( 22 target_fields, arg_list) 23 24 assert extracted_fields == {"FIELD1": ["value1"]} 25 assert other_fields == ["FIELD2=value2", "FIELD3=value3"] 26 27 28def test_no_fields_to_extract(): 29 target_fields = set() 30 arg_list = "arg1 arg2 arg3" 31 32 extracted_fields, other_fields = extract_fields_from_arg_list( 33 target_fields, arg_list) 34 35 assert extracted_fields == {} 36 assert other_fields == ["arg1", "arg2", "arg3" ] 37 38 39def test_missing_fields(): 40 target_fields = {"CONF_FILE", "OVERLAY_CONFIG", "DTC_OVERLAY_FILE"} 41 arg_list = "arg1 arg2 arg3" 42 extracted_fields, other_fields = extract_fields_from_arg_list( 43 target_fields, arg_list) 44 45 assert extracted_fields == {"CONF_FILE": [], "OVERLAY_CONFIG": [], "DTC_OVERLAY_FILE": []} 46 assert other_fields == ["arg1", "arg2", "arg3" ] 47 48def test_load_yaml_with_extra_args_and_retrieve_scenario_data(zephyr_base): 49 filename = "test_data.yaml" 50 51 yaml_data = ''' 52 tests: 53 scenario1: 54 tags: ['tag1', 'tag2'] 55 extra_args: 56 - '--CONF_FILE=file1.conf' 57 - '--OVERLAY_CONFIG=config1.conf' 58 filter: 'filter1' 59 common: 60 filter: 'filter2' 61 ''' 62 63 loaded_schema = scl.yaml_load( 64 os.path.join(zephyr_base, 'scripts', 'schemas','twister', 'testsuite-schema.yaml') 65 ) 66 67 with mock.patch('builtins.open', mock.mock_open(read_data=yaml_data)): 68 parser = TwisterConfigParser(filename, loaded_schema) 69 parser.load() 70 71 scenario_data = parser.get_scenario('scenario1') 72 scenario_common = parser.common 73 74 assert scenario_data['tags'] == {'tag1', 'tag2'} 75 assert scenario_data['extra_args'] == ['--CONF_FILE=file1.conf', '--OVERLAY_CONFIG=config1.conf'] 76 assert scenario_common == {'filter': 'filter2'} 77 78 79def test_default_values(zephyr_base): 80 filename = "test_data.yaml" 81 82 yaml_data = ''' 83 tests: 84 scenario1: 85 tags: 'tag1' 86 extra_args: '' 87 ''' 88 89 loaded_schema = scl.yaml_load( 90 os.path.join(zephyr_base, 'scripts', 'schemas', 'twister','testsuite-schema.yaml') 91 ) 92 93 with mock.patch('builtins.open', mock.mock_open(read_data=yaml_data)): 94 parser = TwisterConfigParser(filename, loaded_schema) 95 parser.load() 96 97 expected_scenario_data = { 'type': 'integration', 98 'extra_args': [], 99 'extra_configs': [], 100 'extra_conf_files': [], 101 'extra_overlay_confs': [], 102 'extra_dtc_overlay_files': [], 103 'required_snippets': [], 104 'build_only': False, 105 'build_on_all': False, 106 'skip': False, 'slow': False, 107 'timeout': 60, 108 'min_ram': 8, 109 'modules': [], 110 'depends_on': set(), 111 'min_flash': 32, 112 'arch_allow': set(), 113 'arch_exclude': set(), 114 'extra_sections': [], 115 'integration_platforms': [], 116 'ignore_faults': False, 117 'ignore_qemu_crash': False, 118 'testcases': [], 119 'platform_type': [], 120 'platform_exclude': set(), 121 'platform_allow': set(), 122 'platform_key': [], 123 'toolchain_exclude': set(), 124 'toolchain_allow': set(), 125 'filter': '', 126 'levels': [], 127 'harness': 'test', 128 'harness_config': {}, 129 'seed': 0, 'sysbuild': False 130 } 131 132 assert expected_scenario_data.items() <= expected_scenario_data.items() 133 134@pytest.mark.parametrize( 135 'value, typestr, expected, expected_warning', 136 [ 137 (' hello ', 'str', 'hello', None), 138 ('3.14', 'float', 3.14, None), 139 ('10', 'int', 10, None), 140 ('True', 'bool', 'True', None), # do-nothing cast 141 ('key: val', 'map', 'key: val', None), # do-nothing cast 142 ('test', 'int', ValueError, None), 143 ('test', 'unknown', ConfigurationError, None), 144 ([ '1', '2', '3' ], 'set', { '1', '2', '2','3' }, None), 145 ], 146 ids=['str to str', 'str to float', 'str to int', 'str to bool', 'str to map', 147 'invalid', 'to unknown', "list to set"] 148) 149 150def test_cast_value(zephyr_base, value, typestr, expected, expected_warning): 151 loaded_schema = scl.yaml_load( 152 os.path.join(zephyr_base, 'scripts', 'schemas', 'twister','testsuite-schema.yaml') 153 ) 154 155 parser = TwisterConfigParser("config.yaml", loaded_schema) 156 with mock.patch('warnings.warn') as warn_mock: 157 with pytest.raises(expected) if isinstance(expected, type) and issubclass(expected, Exception) else nullcontext(): 158 result = parser._cast_value(value, typestr) 159 assert result == expected 160 if expected_warning: 161 warn_mock.assert_called_once_with(*expected_warning, stacklevel=mock.ANY) 162 else: 163 warn_mock.assert_not_called() 164 165def test_load_invalid_test_config_yaml(zephyr_base): 166 filename = "test_data.yaml" 167 168 yaml_data = ''' 169 gibberish data 170 ''' 171 172 loaded_schema = scl.yaml_load( 173 os.path.join(zephyr_base, 'scripts', 'schemas','twister', 'test-config-schema.yaml') 174 ) 175 176 with mock.patch('builtins.open', mock.mock_open(read_data=yaml_data)): 177 parser = TwisterConfigParser(filename, loaded_schema) 178 with pytest.raises(Exception): 179 parser.load() 180 181 182def test_load_yaml_with_no_scenario_data(zephyr_base): 183 filename = "test_data.yaml" 184 185 yaml_data = ''' 186 tests: 187 common: 188 extra_args: '--CONF_FILE=file2.conf --OVERLAY_CONFIG=config2.conf' 189 ''' 190 191 loaded_schema = scl.yaml_load( 192 os.path.join(zephyr_base, 'scripts', 'schemas','twister', 'testsuite-schema.yaml') 193 ) 194 195 with mock.patch('builtins.open', mock.mock_open(read_data=yaml_data)): 196 parser = TwisterConfigParser(filename, loaded_schema) 197 parser.load() 198 199 with pytest.raises(KeyError): 200 scenario_data = parser.get_scenario('scenario1') 201 assert scenario_data is None 202