1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2021-2024 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import os 18import unittest 19from typing import Dict, Any, Optional 20 21from runner.options.yaml_document import YamlDocument 22 23 24class MultipleConfigTest(unittest.TestCase): 25 current_folder = os.path.dirname(__file__) 26 27 def compare_dicts(self, dict1: Dict[str, Any], dict2: Dict[str, Any]) -> None: 28 self.assertEqual(len(dict1), len(dict2), f"Dict1: {dict1.keys()}, dict2: {dict2.keys()}") 29 for key in dict1: 30 self.assertTrue(key in dict2) 31 value1 = dict1[key] 32 value2 = dict2[key] 33 self.assertEqual(type(value1), type(value2), 34 f"Key '{key}': type of value1 = {type(value1)}, " 35 f"type of value2 = {type(value2)}. Expected to be equal") 36 37 if value1 and value2 and isinstance(value1, dict): 38 self.compare_dicts(value1, value2) 39 elif isinstance(value1, list): 40 self.assertListEqual(sorted(value1), sorted(value2)) 41 else: 42 self.assertEqual(value1, value2, 43 f"Key '{key}': value1 = {value1}, value2 = {value2}. Expected to be equal") 44 45 def test_load_one_config(self) -> None: 46 yaml = YamlDocument() 47 yaml.load_configs( 48 [os.path.join(self.current_folder, "config-1.yaml")] 49 ) 50 actual: Optional[Dict[str, Any]] = yaml.document() 51 expected: Dict[str, Any] = { 52 'test-suites': ['ets_func_tests'], 53 'general': { 54 'build': '~/build', 55 'verbose': 'NONE', 56 'show-progress': True 57 }, 58 'es2panda': { 59 'timeout': 60, 60 'opt-level': 4 61 }, 62 'ark': { 63 'timeout': 180, 64 'heap-verifier': 'fail_on_verification', 65 'ark_args': [ 66 'world', 67 "-a=5"] 68 } 69 } 70 self.assertIsNotNone(actual) 71 if actual: 72 self.compare_dicts(actual, expected) 73 self.assertListEqual(yaml.warnings(), []) 74 75 def test_load_independent_configs(self) -> None: 76 yaml = YamlDocument() 77 yaml.load_configs( 78 [ 79 os.path.join(self.current_folder, "config-1.yaml"), 80 os.path.join(self.current_folder, "config-2.yaml") 81 ] 82 ) 83 actual: Optional[Dict[str, Any]] = yaml.document() 84 expected: Dict[str, Any] = { 85 'test-suites': ['ets_func_tests'], 86 'general': { 87 'build': '~/build', 88 'verbose': 'NONE', 89 'show-progress': True, 90 }, 91 'es2panda': { 92 'timeout': 60, 93 'opt-level': 4, 94 }, 95 'ark': { 96 'timeout': 180, 97 'heap-verifier': 'fail_on_verification', 98 'ark_args': [ 99 'world', 100 "-a=5"], 101 }, 102 'verifier': { 103 'enable': True, 104 'timeout': 30 105 } 106 } 107 self.assertIsNotNone(actual) 108 if actual: 109 self.compare_dicts(actual, expected) 110 self.assertListEqual(yaml.warnings(), []) 111 112 def test_load_configs_repeated_values(self) -> None: 113 yaml = YamlDocument() 114 yaml.load_configs( 115 [ 116 os.path.join(self.current_folder, "config-1.yaml"), 117 os.path.join(self.current_folder, "config-3.yaml") 118 ] 119 ) 120 actual: Optional[Dict[str, Any]] = yaml.document() 121 expected: Dict[str, Any] = { 122 'test-suites': ['ets_func_tests'], 123 'general': { 124 'build': '~/build', 125 'verbose': 'NONE', 126 'show-progress': True, 127 }, 128 'es2panda': { 129 'timeout': 30, 130 'opt-level': 2, 131 }, 132 'ark': { 133 'timeout': 180, 134 'heap-verifier': 'fail_on_verification', 135 'ark_args': [ 136 'world', 137 "-a=5"], 138 }, 139 } 140 self.assertIsNotNone(actual) 141 if actual: 142 self.compare_dicts(actual, expected) 143 for warning in yaml.warnings(): 144 self.assertTrue(warning.find("config-3.yaml' replaces value") > 0) 145 self.assertEqual(len(yaml.warnings()), 2) 146 147 def test_load_configs_repeated_values_inverse(self) -> None: 148 yaml = YamlDocument() 149 yaml.load_configs( 150 [ 151 os.path.join(self.current_folder, "config-3.yaml"), 152 os.path.join(self.current_folder, "config-1.yaml"), 153 ] 154 ) 155 actual: Optional[Dict[str, Any]] = yaml.document() 156 expected: Dict[str, Any] = { 157 'test-suites': ['ets_func_tests'], 158 'general': { 159 'build': '~/build', 160 'verbose': 'NONE', 161 'show-progress': True, 162 }, 163 'es2panda': { 164 'timeout': 60, 165 'opt-level': 4, 166 }, 167 'ark': { 168 'timeout': 180, 169 'heap-verifier': 'fail_on_verification', 170 'ark_args': [ 171 'world', 172 "-a=5"], 173 }, 174 } 175 self.assertIsNotNone(actual) 176 if actual: 177 self.compare_dicts(actual, expected) 178 for warning in yaml.warnings(): 179 self.assertTrue(warning.find("config-1.yaml' replaces value") > 0) 180 self.assertEqual(len(yaml.warnings()), 2) 181 182 def test_load_configs_different_types(self) -> None: 183 yaml = YamlDocument() 184 yaml.load_configs( 185 [ 186 os.path.join(self.current_folder, "config-1.yaml"), 187 os.path.join(self.current_folder, "config-4.yaml") 188 ] 189 ) 190 actual: Optional[Dict[str, Any]] = yaml.document() 191 expected: Dict[str, Any] = { 192 'test-suites': ['ets_func_tests'], 193 'general': { 194 'build': '~/build', 195 'verbose': 'NONE', 196 'show-progress': True, 197 }, 198 'es2panda': { 199 'timeout': 60, 200 'opt-level': 4, 201 }, 202 'ark': { 203 'timeout': 180, 204 'heap-verifier': 'fail_on_verification', 205 'ark_args': [ 206 'world', 207 "-a=5"], 208 }, 209 } 210 self.assertIsNotNone(actual) 211 if actual: 212 self.compare_dicts(actual, expected) 213 for warning in yaml.warnings(): 214 self.assertTrue(warning.find("config-4.yaml") > 0 and warning.find("provides different type") > 0, 215 f"Actual warning: {warning}. Expected: provides different type") 216 self.assertEqual(len(yaml.warnings()), 2) 217 218 def test_load_configs_merging_lists(self) -> None: 219 yaml = YamlDocument() 220 yaml.load_configs( 221 [ 222 os.path.join(self.current_folder, "config-1.yaml"), 223 os.path.join(self.current_folder, "config-5.yaml") 224 ] 225 ) 226 actual: Optional[Dict[str, Any]] = yaml.document() 227 expected: Dict[str, Any] = { 228 'test-suites': ['ets_func_tests'], 229 'general': { 230 'build': '~/build', 231 'verbose': 'NONE', 232 'show-progress': True, 233 }, 234 'es2panda': { 235 'timeout': 60, 236 'opt-level': 4, 237 }, 238 'ark': { 239 'timeout': 180, 240 'heap-verifier': 'fail_on_verification', 241 'ark_args': [ 242 "-a=5", 243 'world', 244 'hello', 245 ], 246 }, 247 } 248 self.assertIsNotNone(actual) 249 if actual: 250 self.compare_dicts(actual, expected) 251 for warning in yaml.warnings(): 252 self.assertTrue(warning.find("config-5.yaml") > 0 and warning.find("merges value") > 0, 253 f"Actual warning: {warning}. Expected: merges value") 254 self.assertEqual(len(yaml.warnings()), 1) 255 256 def test_load_configs_many(self) -> None: 257 yaml = YamlDocument() 258 yaml.load_configs( 259 [ 260 os.path.join(self.current_folder, "config-1.yaml"), 261 os.path.join(self.current_folder, "config-2.yaml"), 262 os.path.join(self.current_folder, "config-3.yaml"), 263 os.path.join(self.current_folder, "config-4.yaml"), 264 os.path.join(self.current_folder, "config-5.yaml") 265 ] 266 ) 267 actual: Optional[Dict[str, Any]] = yaml.document() 268 expected: Dict[str, Any] = { 269 'test-suites': ['ets_func_tests'], 270 'general': { 271 'build': '~/build', 272 'verbose': 'NONE', 273 'show-progress': True, 274 }, 275 'es2panda': { 276 'timeout': 30, 277 'opt-level': 2, 278 }, 279 'ark': { 280 'timeout': 180, 281 'heap-verifier': 'fail_on_verification', 282 'ark_args': [ 283 "-a=5", 284 'world', 285 'hello', 286 ], 287 }, 288 'verifier': { 289 'enable': True, 290 'timeout': 30 291 } 292 } 293 self.assertIsNotNone(actual) 294 if actual: 295 self.compare_dicts(actual, expected) 296 self.assertEqual(len(yaml.warnings()), 5) 297 298 def test_non_exiting_config(self) -> None: 299 with self.assertRaises(FileNotFoundError): 300 yaml = YamlDocument() 301 yaml.load_configs( 302 [ 303 os.path.join(self.current_folder, "config-non-exist.yaml"), 304 ] 305 ) 306 self.assertIsNone(yaml.document()) 307