Skip to content

Commit bdd26cb

Browse files
[uss_qualifier] Improve check-matching (#1380)
1 parent d53099e commit bdd26cb

File tree

8 files changed

+68
-32
lines changed

8 files changed

+68
-32
lines changed

monitoring/monitorlib/inspection.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import inspect
33
import pkgutil
44

5+
_modules_imported = set()
6+
57

68
def import_submodules(module) -> None:
79
"""Ensure that all descendant modules of a module are loaded.
@@ -10,10 +12,13 @@ def import_submodules(module) -> None:
1012
1113
:param module: Parent module from which to start explicitly importing modules.
1214
"""
15+
if module in _modules_imported:
16+
return
1317
for loader, module_name, is_pkg in pkgutil.walk_packages(
1418
module.__path__, module.__name__ + "."
1519
):
1620
importlib.import_module(module_name)
21+
_modules_imported.add(module)
1722

1823

1924
def get_module_object_by_name(parent_module, object_name: str):

monitoring/uss_qualifier/configurations/configuration.py

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -168,24 +168,13 @@ class FullyQualifiedCheck(ImplicitDict):
168168
"""Scenario in which the check occurs."""
169169

170170
test_case_name: str
171-
"""Test case in which the check occurs."""
171+
"""Test case in which the check occurs, omitting the ' test case' suffix. Must be an exact match to documentation; sensitive to case and spacing."""
172172

173173
test_step_name: str
174-
"""Test step in which the check occurs."""
174+
"""Test step in which the check occurs, omitting the ' test step' suffix. Must be an exact match to documentation; sensitive to case and spacing."""
175175

176176
check_name: str
177-
"""Name of the check."""
178-
179-
def contained_in(self, collection: Iterable[FullyQualifiedCheck]) -> bool:
180-
for other in collection:
181-
if (
182-
self.scenario_type == other.scenario_type
183-
and self.test_case_name == other.test_case_name
184-
and self.test_step_name == other.test_step_name
185-
and self.check_name == other.check_name
186-
):
187-
return True
188-
return False
177+
"""Name of the check, omitting the ' check' suffix. Must be an exact match to documentation; sensitive to case and spacing."""
189178

190179

191180
class TestedRequirementsConfiguration(ImplicitDict):

monitoring/uss_qualifier/configurations/dev/f3548_self_contained.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ v1:
417417

418418
# It is acceptable for the checks listed below to fail (in terms of determining the status of tested requirements in this artifact)
419419
acceptable_findings:
420-
- scenario_type: scenarios.astm.utm.dss.DSSInteroperability
420+
- scenario_type: scenarios.astm.utm.dss.dss_interoperability.DSSInteroperability
421421
test_case_name: "Prerequisites"
422422
test_step_name: "Test environment requirements"
423423
check_name: "DSS instance is publicly addressable"

monitoring/uss_qualifier/reports/tested_requirements/breakdown.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@
3737
from monitoring.uss_qualifier.requirements.definitions import RequirementID
3838
from monitoring.uss_qualifier.scenarios.definitions import TestScenarioTypeName
3939
from monitoring.uss_qualifier.scenarios.documentation.parsing import get_documentation
40-
from monitoring.uss_qualifier.scenarios.scenario import get_scenario_type_by_name
40+
from monitoring.uss_qualifier.scenarios.scenario import (
41+
are_scenario_types_equal,
42+
fully_qualified_check_in_collection,
43+
get_scenario_type_by_name,
44+
)
4145
from monitoring.uss_qualifier.suites.definitions import (
4246
ActionType,
4347
TestSuiteActionDeclaration,
@@ -188,7 +192,7 @@ def _populate_breakdown_with_scenario_report(
188192
matches = [
189193
s
190194
for s in tested_requirement.scenarios
191-
if s.type == scenario_type_name
195+
if are_scenario_types_equal(s.type, scenario_type_name)
192196
]
193197
if matches:
194198
tested_scenario = matches[0]
@@ -237,8 +241,8 @@ def _populate_breakdown_with_scenario_report(
237241
name=check.name,
238242
url="",
239243
has_todo=False,
240-
is_finding_acceptable=current_check.contained_in(
241-
acceptable_findings
244+
is_finding_acceptable=fully_qualified_check_in_collection(
245+
current_check, acceptable_findings
242246
),
243247
) # TODO: Consider populating has_todo with documentation instead
244248
if isinstance(check, FailedCheck):
@@ -340,7 +344,7 @@ def _populate_breakdown_with_scenario(
340344
matches = [
341345
s
342346
for s in tested_requirement.scenarios
343-
if s.type == scenario_type_name
347+
if are_scenario_types_equal(s.type, scenario_type_name)
344348
]
345349
if matches:
346350
tested_scenario = matches[0]
@@ -383,8 +387,8 @@ def _populate_breakdown_with_scenario(
383387
name=check.name,
384388
url=check.url,
385389
has_todo=check.has_todo,
386-
is_finding_acceptable=current_check.contained_in(
387-
acceptable_findings
390+
is_finding_acceptable=fully_qualified_check_in_collection(
391+
current_check, acceptable_findings
388392
),
389393
)
390394
tested_step.checks.append(tested_check)

monitoring/uss_qualifier/scenarios/definitions.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
from monitoring.uss_qualifier.resources.definitions import ResourceID
44

55
TestScenarioTypeName = str
6-
"""This plain string represents a type of test scenario, expressed as a Python class name qualified relative to the `uss_qualifier` module"""
6+
"""This plain string represents a type of test scenario, expressed as a Python class name qualified relative to the
7+
`uss_qualifier` module.
8+
9+
Note that equality between different TestScenarioTypeNames (whether they refer to the same type of test scenario) should
10+
be determined via are_scenario_types_equal as multiple TestScenarioTypeNames may resolve to the same test scenario type.
11+
"""
712

813

914
class TestScenarioDeclaration(ImplicitDict):

monitoring/uss_qualifier/scenarios/scenario.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import time as pytime
33
import traceback
44
from abc import ABC, abstractmethod
5-
from collections.abc import Callable
5+
from collections.abc import Callable, Iterable
66
from datetime import UTC, datetime, timedelta
77
from enum import Enum
88
from typing import TypeVar
@@ -19,6 +19,7 @@
1919
from monitoring.monitorlib.temporal import TestTimeContext
2020
from monitoring.uss_qualifier import scenarios as scenarios_module
2121
from monitoring.uss_qualifier.common_data_definitions import Severity
22+
from monitoring.uss_qualifier.configurations.configuration import FullyQualifiedCheck
2223
from monitoring.uss_qualifier.reports.report import (
2324
ErrorReport,
2425
FailedCheck,
@@ -222,6 +223,29 @@ def get_scenario_type_by_name(scenario_type_name: TestScenarioTypeName) -> type:
222223
return scenario_type
223224

224225

226+
def are_scenario_types_equal(
227+
scenario_type_name_1: TestScenarioTypeName,
228+
scenario_type_name_2: TestScenarioTypeName,
229+
) -> bool:
230+
scenario_type_1 = get_scenario_type_by_name(scenario_type_name_1)
231+
scenario_type_2 = get_scenario_type_by_name(scenario_type_name_2)
232+
return scenario_type_1 == scenario_type_2
233+
234+
235+
def fully_qualified_check_in_collection(
236+
check: FullyQualifiedCheck, collection: Iterable[FullyQualifiedCheck]
237+
) -> bool:
238+
for other in collection:
239+
if (
240+
are_scenario_types_equal(check.scenario_type, other.scenario_type)
241+
and check.test_case_name == other.test_case_name
242+
and check.test_step_name == other.test_step_name
243+
and check.check_name == other.check_name
244+
):
245+
return True
246+
return False
247+
248+
225249
class GenericTestScenario(ABC):
226250
"""Generic Test Scenario allowing mutualization of test scenario implementation.
227251

monitoring/uss_qualifier/suites/suite.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
ScenarioCannotContinueError,
5252
TestRunCannotContinueError,
5353
TestScenario,
54+
are_scenario_types_equal,
55+
fully_qualified_check_in_collection,
5456
get_scenario_type_by_name,
5557
)
5658
from monitoring.uss_qualifier.suites.definitions import (
@@ -482,7 +484,9 @@ def stop_fast(
482484
test_step_name=test_step_name,
483485
check_name=check_name,
484486
)
485-
if current_check.contained_in(self.acceptable_findings):
487+
if fully_qualified_check_in_collection(
488+
current_check, self.acceptable_findings
489+
):
486490
return False
487491
return True
488492
return False
@@ -569,10 +573,15 @@ def _is_selected_by(
569573
"types" in f.is_test_scenario
570574
and f.is_test_scenario.types is not None
571575
):
572-
if (
573-
action.test_scenario.declaration.scenario_type
574-
not in f.is_test_scenario.types
575-
):
576+
matches_scenario_type = False
577+
for scenario_type in f.is_test_scenario.types:
578+
if are_scenario_types_equal(
579+
scenario_type,
580+
action.test_scenario.declaration.scenario_type,
581+
):
582+
matches_scenario_type = True
583+
break
584+
if not matches_scenario_type:
576585
return False
577586
result = True
578587
else:

schemas/monitoring/uss_qualifier/configurations/configuration/FullyQualifiedCheck.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@
88
"type": "string"
99
},
1010
"check_name": {
11-
"description": "Name of the check.",
11+
"description": "Name of the check, omitting the ' check' suffix. Must be an exact match to documentation; sensitive to case and spacing.",
1212
"type": "string"
1313
},
1414
"scenario_type": {
1515
"description": "Scenario in which the check occurs.",
1616
"type": "string"
1717
},
1818
"test_case_name": {
19-
"description": "Test case in which the check occurs.",
19+
"description": "Test case in which the check occurs, omitting the ' test case' suffix. Must be an exact match to documentation; sensitive to case and spacing.",
2020
"type": "string"
2121
},
2222
"test_step_name": {
23-
"description": "Test step in which the check occurs.",
23+
"description": "Test step in which the check occurs, omitting the ' test step' suffix. Must be an exact match to documentation; sensitive to case and spacing.",
2424
"type": "string"
2525
}
2626
},

0 commit comments

Comments
 (0)