-
-
Notifications
You must be signed in to change notification settings - Fork 165
Expand file tree
/
Copy pathTestSuite.py
More file actions
145 lines (120 loc) · 6.2 KB
/
Copy pathTestSuite.py
File metadata and controls
145 lines (120 loc) · 6.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
from dataclasses import dataclass, field
from typing import Optional, List, Dict
from metadata_parser.metdata import Tutorials, Tutorial, Case, CaseCombination, ReferenceResult
import yaml
@dataclass
class TestSuite:
name: str
cases_of_tutorial: Dict[Tutorial, List[CaseCombination]]
reference_results: Dict[Tutorial, List[ReferenceResult]]
max_times: Dict[Tutorial, list] = field(default_factory=dict)
max_time_windows: Dict[Tutorial, list] = field(default_factory=dict)
timeouts: Dict[Tutorial, List] = field(default_factory=dict)
def __repr__(self) -> str:
return_string = f"Test suite: {self.name} contains:"
for tutorial, cases in self.cases_of_tutorial.items():
return_string += f"""
{tutorial.name}
cases: {cases}
reference_results: {self.reference_results[tutorial]}"""
return return_string
class TestSuites(list):
"""
Represents the collection of testsuites read in from the tests.yaml
"""
def __init__(self, testsuites: List[TestSuite]):
self.testsuites = testsuites
@staticmethod
def _iter_tutorial_cases(tutorials_section):
"""Yield tutorial case dicts, flattening YAML list aliases (e.g. shard lists)."""
for item in tutorials_section:
if isinstance(item, list):
yield from TestSuites._iter_tutorial_cases(item)
else:
yield item
@classmethod
def from_yaml(cls, path, parsed_tutorials: Tutorials):
"""
Creates a TestSuites instance from a YAML file.
Args:
path: The path to the YAML file.
Returns:
An instance of TestSuites.
"""
testsuites = []
with open(path, 'r') as f:
data = yaml.safe_load(f)
test_suites_raw = data['test_suites']
for test_suite_name in test_suites_raw:
case_combinations_of_tutorial = {}
reference_results_of_tutorial = {}
max_times_of_tutorial = {}
max_time_windows_of_tutorial = {}
timeouts_of_tutorial = {}
# iterate over tutorials:
for tutorial_case in cls._iter_tutorial_cases(
test_suites_raw[test_suite_name]['tutorials']):
tutorial = parsed_tutorials.get_by_path(tutorial_case['path'])
if not tutorial:
raise Exception(f"No tutorial with path {tutorial_case['path']} found.")
# initialize the datastructure for the new Testsuite
if tutorial not in case_combinations_of_tutorial:
case_combinations_of_tutorial[tutorial] = []
reference_results_of_tutorial[tutorial] = []
max_times_of_tutorial[tutorial] = []
max_time_windows_of_tutorial[tutorial] = []
timeouts_of_tutorial[tutorial] = []
all_case_combinations = tutorial.case_combinations
case_combination_requested = CaseCombination.from_string_list(
tutorial_case['case_combination'], tutorial)
if case_combination_requested in all_case_combinations:
case_combinations_of_tutorial[tutorial].append(case_combination_requested)
reference_results_of_tutorial[tutorial].append(ReferenceResult(
tutorial_case['reference_result'], case_combination_requested))
max_time_raw = tutorial_case.get('max_time', None)
if max_time_raw is not None and (not isinstance(
max_time_raw, (int, float)) or max_time_raw <= 0):
raise ValueError(f"max_time must be a positive number, got {max_time_raw!r}")
max_times_of_tutorial[tutorial].append(max_time_raw)
mtw_raw = tutorial_case.get('max_time_windows', None)
if mtw_raw is not None and (not isinstance(mtw_raw, int) or mtw_raw <= 0):
raise ValueError(f"max_time_windows must be a positive integer, got {mtw_raw!r}")
max_time_windows_of_tutorial[tutorial].append(mtw_raw)
timeout_value = tutorial_case.get('timeout', None)
if timeout_value is not None and not isinstance(timeout_value, int):
raise TypeError(
f"Expected 'timeout' to be an integer or None, but got {type(timeout_value).__name__} "
f"(value: {timeout_value}) in tutorial '{tutorial}'."
)
timeouts_of_tutorial[tutorial].append(timeout_value)
else:
raise Exception(
f"Could not find the case combination {tutorial_case['case_combination']} in the current metadata of tutorial {tutorial.name}, or it does not define all necessary participants.")
testsuites.append(TestSuite(test_suite_name, case_combinations_of_tutorial,
reference_results_of_tutorial, max_times_of_tutorial, max_time_windows_of_tutorial, timeouts_of_tutorial))
return cls(testsuites)
def __iter__(self):
return iter(self.testsuites)
def __getitem__(self, index):
return self.testsuites[index]
def __setitem__(self, index, value):
self.testsuites[index] = value
def __len__(self):
return len(self.testsuites)
def get_by_name(self, name_to_search) -> Optional[TestSuite]:
"""
Retrieves a testsuite by its name.
Args:
name_to_search: The name of the testsuite to search for.
Returns:
The component with the specified name, or None if not found.
"""
for testsuite in self.testsuites:
if testsuite.name == name_to_search:
return testsuite
return None
def __repr__(self) -> str:
return_str = ""
for tests_suite in self.testsuites:
return_str += f"{tests_suite}\n\n"
return return_str