diff --git a/.basedpyright/baseline.json b/.basedpyright/baseline.json index 861fa1b68c..c8b99f63c4 100644 --- a/.basedpyright/baseline.json +++ b/.basedpyright/baseline.json @@ -4894,772 +4894,6 @@ } } ], - "./monitoring/uss_qualifier/reports/globally_expanded/generate.py": [ - { - "code": "reportArgumentType", - "range": { - "startColumn": 42, - "endColumn": 74, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 66, - "endColumn": 74, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 41, - "endColumn": 54, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 110, - "endColumn": 116, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 52, - "endColumn": 60, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 37, - "endColumn": 45, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 46, - "endColumn": 54, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 29, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 27, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 23, - "endColumn": 31, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 27, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 71, - "endColumn": 79, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 42, - "endColumn": 50, - "lineCount": 1 - } - }, - { - "code": "reportOperatorIssue", - "range": { - "startColumn": 27, - "endColumn": 60, - "lineCount": 1 - } - }, - { - "code": "reportOperatorIssue", - "range": { - "startColumn": 23, - "endColumn": 58, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 48, - "endColumn": 56, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 35, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 28, - "endColumn": 36, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 24, - "endColumn": 32, - "lineCount": 1 - } - }, - { - "code": "reportOperatorIssue", - "range": { - "startColumn": 20, - "endColumn": 35, - "lineCount": 2 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 43, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 34, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 61, - "endColumn": 66, - "lineCount": 1 - } - }, - { - "code": "reportOperatorIssue", - "range": { - "startColumn": 20, - "endColumn": 35, - "lineCount": 2 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 67, - "endColumn": 80, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 35, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 57, - "endColumn": 69, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 93, - "endColumn": 102, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 35, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 57, - "endColumn": 69, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 93, - "endColumn": 102, - "lineCount": 1 - } - }, - { - "code": "reportOperatorIssue", - "range": { - "startColumn": 19, - "endColumn": 58, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 48, - "endColumn": 56, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 29, - "endColumn": 37, - "lineCount": 1 - } - }, - { - "code": "reportCallIssue", - "range": { - "startColumn": 16, - "endColumn": 28, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 16, - "endColumn": 28, - "lineCount": 1 - } - }, - { - "code": "reportCallIssue", - "range": { - "startColumn": 16, - "endColumn": 28, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 16, - "endColumn": 28, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 32, - "endColumn": 48, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 32, - "endColumn": 48, - "lineCount": 1 - } - }, - { - "code": "reportCallIssue", - "range": { - "startColumn": 32, - "endColumn": 53, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 44, - "endColumn": 52, - "lineCount": 1 - } - }, - { - "code": "reportOperatorIssue", - "range": { - "startColumn": 35, - "endColumn": 36, - "lineCount": 3 - } - } - ], - "./monitoring/uss_qualifier/reports/report.py": [ - { - "code": "reportArgumentType", - "range": { - "startColumn": 35, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 65, - "endColumn": 85, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 27, - "endColumn": 47, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 40, - "endColumn": 47, - "lineCount": 1 - } - } - ], - "./monitoring/uss_qualifier/reports/sequence_view/events.py": [ - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 36, - "endColumn": 43, - "lineCount": 1 - } - }, - { - "code": "reportReturnType", - "range": { - "startColumn": 8, - "endColumn": 24, - "lineCount": 1 - } - } - ], - "./monitoring/uss_qualifier/reports/sequence_view/generate.py": [ - { - "code": "reportOperatorIssue", - "range": { - "startColumn": 12, - "endColumn": 57, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 46, - "endColumn": 56, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 72, - "endColumn": 82, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 43, - "endColumn": 59, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 51, - "endColumn": 67, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 74, - "endColumn": 87, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 48, - "endColumn": 62, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 38, - "endColumn": 42, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 45, - "endColumn": 65, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 79, - "endColumn": 86, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 35, - "endColumn": 39, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 36, - "endColumn": 50, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 81, - "endColumn": 88, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 34, - "endColumn": 55, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 50, - "endColumn": 58, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 51, - "endColumn": 55, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 34, - "endColumn": 46, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 46, - "endColumn": 58, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 43, - "endColumn": 57, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 39, - "endColumn": 53, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 51, - "endColumn": 65, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 46, - "endColumn": 59, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 45, - "endColumn": 77, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 69, - "endColumn": 77, - "lineCount": 1 - } - } - ], - "./monitoring/uss_qualifier/reports/sequence_view/kml.py": [ - { - "code": "reportReturnType", - "range": { - "startColumn": 9, - "endColumn": 26, - "lineCount": 1 - } - }, - { - "code": "reportInvalidTypeForm", - "range": { - "startColumn": 14, - "endColumn": 17, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 30, - "endColumn": 74, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 28, - "endColumn": 52, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 28, - "endColumn": 53, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 66, - "endColumn": 74, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 1, - "endColumn": 74, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 1, - "endColumn": 69, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 1, - "endColumn": 71, - "lineCount": 1 - } - } - ], - "./monitoring/uss_qualifier/reports/sequence_view/summary_types.py": [ - { - "code": "reportOptionalIterable", - "range": { - "startColumn": 17, - "endColumn": 34, - "lineCount": 1 - } - } - ], - "./monitoring/uss_qualifier/reports/tested_requirements/breakdown.py": [ - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 43, - "endColumn": 50, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 49, - "endColumn": 56, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 44, - "endColumn": 57, - "lineCount": 1 - } - }, - { - "code": "reportOperatorIssue", - "range": { - "startColumn": 11, - "endColumn": 44, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 67, - "endColumn": 77, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 60, - "endColumn": 70, - "lineCount": 1 - } - }, - { - "code": "reportOperatorIssue", - "range": { - "startColumn": 12, - "endColumn": 51, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 34, - "endColumn": 50, - "lineCount": 1 - } - }, - { - "code": "reportOptionalMemberAccess", - "range": { - "startColumn": 39, - "endColumn": 55, - "lineCount": 1 - } - }, - { - "code": "reportArgumentType", - "range": { - "startColumn": 12, - "endColumn": 35, - "lineCount": 1 - } - }, - { - "code": "reportAttributeAccessIssue", - "range": { - "startColumn": 43, - "endColumn": 52, - "lineCount": 1 - } - } - ], "./monitoring/uss_qualifier/requirements/documentation.py": [ { "code": "reportAttributeAccessIssue", diff --git a/monitoring/uss_qualifier/reports/globally_expanded/generate.py b/monitoring/uss_qualifier/reports/globally_expanded/generate.py index 79b2036245..9cf20dd9fc 100644 --- a/monitoring/uss_qualifier/reports/globally_expanded/generate.py +++ b/monitoring/uss_qualifier/reports/globally_expanded/generate.py @@ -21,8 +21,6 @@ from monitoring.uss_qualifier.reports.sequence_view.summary_types import ( ActionNode, ActionNodeType, - EpochType, - EventType, Indexer, TestedCase, TestedScenario, @@ -110,6 +108,7 @@ def generate_globally_expanded_report( """ + assert report.configuration.v1 and report.configuration.v1.test_run resource_pool = make_resources_config(report.configuration.v1.test_run) def indented_ul(value) -> list[str]: @@ -184,6 +183,7 @@ def describe_pool_resource(k: str, v: dict) -> str: def _generate_sections(node: ActionNode) -> Iterator[_Section]: if node.node_type == ActionNodeType.Scenario: + assert node.scenario yield _generate_scenario_section(node.scenario) elif node.node_type == ActionNodeType.SkippedAction: yield _generate_skipped_scenario_section(node) @@ -195,7 +195,7 @@ def _generate_sections(node: ActionNode) -> Iterator[_Section]: def _generate_skipped_scenario_section(node: ActionNode) -> _Section: return _Section( title=f"[skipped] {node.name}", - body=f"This instance of this test scenario was skipped in this test run because: {node.skipped_action.reason}", + body=f"This instance of this test scenario was skipped in this test run because: {node.skipped_action.reason if node.skipped_action else '?'}", ) @@ -237,15 +237,15 @@ def _indent_headings(elements: Sequence[marko.element.Element], levels: int) -> for element in elements: if isinstance(element, marko.block.Heading): element.level = min(element.level + levels, 6) - if hasattr(element, "children") and element.children: - _indent_headings(element.children, levels) + if hasattr(element, "children") and element.children: # pyright: ignore[reportAttributeAccessIssue] + _indent_headings(element.children, levels) # pyright: ignore[reportAttributeAccessIssue] def _inflate_fragments(parent: marko.element.Element, origin_filename: str) -> None: - if hasattr(parent, "children") and parent.children: + if hasattr(parent, "children") and parent.children: # pyright: ignore[reportAttributeAccessIssue] c = 0 - while c < len(parent.children): - child = parent.children[c] + while c < len(parent.children): # pyright: ignore[reportAttributeAccessIssue] + child = parent.children[c] # pyright: ignore[reportAttributeAccessIssue] if ( isinstance(child, marko.block.Heading) and hasattr(child, "children") @@ -260,12 +260,12 @@ def _inflate_fragments(parent: marko.element.Element, origin_filename: str) -> N doc = _get_test_step_fragment(absolute_path, child.level) _update_links(doc, absolute_path) _strip_link(child) - parent.children = ( - parent.children[0 : c + 1] + doc.children + parent.children[c + 1 :] + parent.children = ( # pyright: ignore[reportAttributeAccessIssue] + parent.children[0 : c + 1] + doc.children + parent.children[c + 1 :] # pyright: ignore[reportAttributeAccessIssue] ) c += len(doc.children) elif isinstance(child, marko.element.Element): - _inflate_fragments(parent.children[c], origin_filename) + _inflate_fragments(parent.children[c], origin_filename) # pyright: ignore[reportAttributeAccessIssue] c += 1 else: c += 1 @@ -286,14 +286,14 @@ def add_resource_origin(): note = marko.parse( """∅ _This resource was not applicable to this test run and was therefore not provided._\n\n""" ) - doc.children = doc.children[0:c] + note.children + doc.children[c:] + doc.children = doc.children[0:c] + note.children + doc.children[c:] # pyright: ignore[reportAttributeAccessIssue,reportOperatorIssue] c += len(note.children) return # Insert resource origin information origin = marko.parse( f"\n\n✅ Provided by {scenario.resource_origins[current_resource]}.\n" ) - doc.children = doc.children[0:c] + origin.children + doc.children[c:] + doc.children = doc.children[0:c] + origin.children + doc.children[c:] # pyright: ignore[reportOperatorIssue] c += len(origin.children) while c < len(doc.children): @@ -327,11 +327,11 @@ def add_resource_origin(): def _strip_link(element: marko.element.Element) -> None: - if hasattr(element, "children") and element.children: - for c in range(len(element.children)): - child = element.children[c] + if hasattr(element, "children") and element.children: # pyright: ignore[reportAttributeAccessIssue] + for c in range(len(element.children)): # pyright: ignore[reportAttributeAccessIssue] + child = element.children[c] # pyright: ignore[reportAttributeAccessIssue] if isinstance(child, marko.block.inline.Link): - element.children[c] = child.children[0] + element.children[c] = child.children[0] # pyright: ignore[reportAttributeAccessIssue] elif isinstance(child, marko.element.Element): _strip_link(child) @@ -372,7 +372,7 @@ def add_context_to_case(): """∅ _This test case was not applicable to this test run and is therefore not statused._\n\n""" ) doc.children = ( - doc.children[0 : test_case_i0 + 1] + doc.children[0 : test_case_i0 + 1] # pyright: ignore[reportAttributeAccessIssue,reportOperatorIssue] + note.children + doc.children[test_case_i0 + 1 :] ) @@ -394,7 +394,7 @@ def add_context_to_case(): test_case_i0 = c test_case_level = child.level for epoch in scenario.epochs: - if epoch.type != EpochType.Case: + if epoch.case is None: continue if case_name == epoch.case.name: test_case = epoch.case @@ -407,7 +407,7 @@ def add_context_to_case(): test_case_level = child.level cleanup = True for epoch in scenario.epochs: - if epoch.type != EpochType.Case: + if epoch.case is None: continue if len(epoch.case.steps) == 1 and epoch.case.steps[0].name == "Cleanup": test_case = epoch.case @@ -444,7 +444,7 @@ def add_context_to_step(): ) dc = len(note.children) doc.children = ( - doc.children[0 : test_step_i0 + 1] + doc.children[0 : test_step_i0 + 1] # pyright: ignore[reportOperatorIssue] + note.children + doc.children[test_step_i0 + 1 :] ) @@ -494,6 +494,7 @@ def _add_context_to_step( def add_context_to_check(): nonlocal c, i1, added, test_check_name, test_check_i0, test_check_level if test_check_name is not None: + assert test_check_i0 is not None dc = _add_context_to_check(doc, step, test_check_name, test_check_i0, c) c += dc i1 += dc @@ -533,14 +534,14 @@ def _add_context_to_check( check_text = [""] for event in step.events: if ( - event.type == EventType.PassedCheck + event.passed_check is not None and event.passed_check.name == test_check_name ): check_text.append( f"✅ {', '.join(event.passed_check.participants)} ({event.passed_check.timestamp})" ) elif ( - event.type == EventType.FailedCheck + event.failed_check is not None and event.failed_check.name == test_check_name ): check_text.append( @@ -552,7 +553,7 @@ def _add_context_to_check( additions = marko.parse( """∅ _This check was not applicable to this test run and is therefore not statused._\n\n""" ) - doc.children = doc.children[0:i1] + additions.children + doc.children[i1:] + doc.children = doc.children[0:i1] + additions.children + doc.children[i1:] # pyright: ignore[reportOperatorIssue] return len(additions.children) @@ -571,8 +572,8 @@ def _update_links(element: marko.element.Element, origin_filename: str) -> None: url = url.replace("/github.com/", "/raw.githubusercontent.com/") url = url.replace("/blob/", "/") element.dest = url - if hasattr(element, "children") and element.children: - for child in element.children: + if hasattr(element, "children") and element.children: # pyright: ignore[reportAttributeAccessIssue] + for child in element.children: # pyright: ignore[reportAttributeAccessIssue] if isinstance(child, marko.element.Element): _update_links(child, origin_filename) @@ -580,7 +581,7 @@ def _update_links(element: marko.element.Element, origin_filename: str) -> None: def _add_section_numbers(elements: Sequence[marko.element.Element]) -> None: heading_level = 2 levels = [0] - headings = [None] + headings: list[str | None] = [None] prev_heading = None for i, element in enumerate(elements): if isinstance(element, marko.block.Heading): @@ -599,7 +600,7 @@ def _add_section_numbers(elements: Sequence[marko.element.Element]) -> None: heading_level += 1 else: headings.append(text_of(element)) - heading_trace = " -> ".join(headings) + heading_trace = " -> ".join([str(heading) for heading in headings]) raise ValueError( f"Encountered a level {element.level} heading ({text_of(element)}) at element {i} following a level {heading_level} heading ({prev_heading}); expected heading levels to increase by 1 level at a time. Trace: {heading_trace}" ) @@ -612,4 +613,4 @@ def _add_section_numbers(elements: Sequence[marko.element.Element]) -> None: else: element.children = [ marko.block.inline.RawText(section_number) - ] + element.children + ] + element.children # pyright: ignore[reportOperatorIssue] diff --git a/monitoring/uss_qualifier/reports/report.py b/monitoring/uss_qualifier/reports/report.py index e377221515..796f1c6026 100644 --- a/monitoring/uss_qualifier/reports/report.py +++ b/monitoring/uss_qualifier/reports/report.py @@ -357,12 +357,13 @@ def queries(self) -> list[fetch.Query]: for case in self.cases: for step in case.steps: if step.has_field_with_value("queries"): + assert step.queries queries.extend(step.queries) - if self.has_field_with_value("cleanup") and self.cleanup.has_field_with_value( + if self.has_field_with_value("cleanup") and self.cleanup.has_field_with_value( # pyright: ignore[reportOptionalMemberAccess] "queries" ): - queries.extend(self.cleanup.queries) + queries.extend(self.cleanup.queries) # pyright: ignore[reportOptionalMemberAccess,reportArgumentType] return queries diff --git a/monitoring/uss_qualifier/reports/sequence_view/events.py b/monitoring/uss_qualifier/reports/sequence_view/events.py index 7519e96d78..4c1c3140f8 100644 --- a/monitoring/uss_qualifier/reports/sequence_view/events.py +++ b/monitoring/uss_qualifier/reports/sequence_view/events.py @@ -15,7 +15,6 @@ from monitoring.uss_qualifier.reports.sequence_view.summary_types import ( Epoch, Event, - EventType, Indexer, NoteEvent, TestedCase, @@ -67,7 +66,7 @@ def _step_events( scenario_participants: dict[ParticipantID, TestedParticipant], all_events: list[Event], after: datetime | None, -) -> tuple[TestedStep, datetime]: +) -> tuple[TestedStep, datetime | None]: events = [] # Create events for this step's passed checks @@ -116,7 +115,7 @@ def _step_events( found = False for e in all_events: if ( - e.type == EventType.Query + e.query is not None and e.query.request.initiated_at == query_timestamp ): query_events.append(e) diff --git a/monitoring/uss_qualifier/reports/sequence_view/generate.py b/monitoring/uss_qualifier/reports/sequence_view/generate.py index 720ae82e63..75d32f65c4 100644 --- a/monitoring/uss_qualifier/reports/sequence_view/generate.py +++ b/monitoring/uss_qualifier/reports/sequence_view/generate.py @@ -31,8 +31,6 @@ from monitoring.uss_qualifier.reports.sequence_view.summary_types import ( ActionNode, ActionNodeType, - EpochType, - EventType, Indexer, OverviewRow, SkippedAction, @@ -51,6 +49,7 @@ def _skipped_action_of(report: SkippedActionReport) -> ActionNode: if report.declaration.get_action_type() == ActionType.TestSuite: + assert report.declaration.test_suite if ( "suite_type" in report.declaration.test_suite and report.declaration.test_suite.suite_type @@ -76,6 +75,7 @@ def _skipped_action_of(report: SkippedActionReport) -> ActionNode: ) name = "All actions in test suite" elif report.declaration.get_action_type() == ActionType.TestScenario: + assert report.declaration.test_scenario docs = get_documentation_by_name(report.declaration.test_scenario.scenario_type) return ActionNode( name=docs.name, @@ -84,6 +84,7 @@ def _skipped_action_of(report: SkippedActionReport) -> ActionNode: skipped_action=SkippedAction(reason=report.reason), ) elif report.declaration.get_action_type() == ActionType.ActionGenerator: + assert report.declaration.action_generator generator_type = action_generator_type_from_name( report.declaration.action_generator.generator_type ) @@ -123,6 +124,7 @@ def compute_action_node(report: TestSuiteActionReport, indexer: Indexer) -> Acti is_action_generator, ) = report.get_applicable_report() if is_test_scenario: + assert report.test_scenario return ActionNode( name=report.test_scenario.name, node_type=ActionNodeType.Scenario, @@ -130,6 +132,7 @@ def compute_action_node(report: TestSuiteActionReport, indexer: Indexer) -> Acti scenario=compute_tested_scenario(report.test_scenario, indexer), ) elif is_test_suite: + assert report.test_suite children = [compute_action_node(a, indexer) for a in report.test_suite.actions] return ActionNode( name=report.test_suite.name, @@ -137,6 +140,7 @@ def compute_action_node(report: TestSuiteActionReport, indexer: Indexer) -> Acti children=children, ) elif is_action_generator: + assert report.action_generator generator_type = action_generator_type_from_name( report.action_generator.generator_type ) @@ -148,6 +152,7 @@ def compute_action_node(report: TestSuiteActionReport, indexer: Indexer) -> Acti ], ) else: + assert report.skipped_action return _skipped_action_of(report.skipped_action) @@ -177,9 +182,13 @@ def _align_overview_rows(rows: list[OverviewRow]) -> None: row.filled = True to_fill -= 1 elif len(row.suite_cells) < max_suite_cols: - if row.suite_cells[-1].first_row and all( - c.node_type == ActionNodeType.Scenario - for c in row.suite_cells[-1].node.children + if ( + row.suite_cells[-1].first_row + and row.suite_cells[-1].node is not None + and all( + c.node_type == ActionNodeType.Scenario + for c in row.suite_cells[-1].node.children + ) ): row.suite_cells[-1].colspan += max_suite_cols - len(row.suite_cells) row.filled = True @@ -212,6 +221,7 @@ def _align_overview_rows(rows: list[OverviewRow]) -> None: def _enumerate_all_participants(node: ActionNode) -> list[ParticipantID]: if node.node_type == ActionNodeType.Scenario: + assert node.scenario return list(node.scenario.participants) else: result = set() @@ -225,6 +235,7 @@ def _generate_scenario_pages( node: ActionNode, config: SequenceViewConfiguration, output_path: str ) -> None: if node.node_type == ActionNodeType.Scenario: + assert node.scenario all_participants = list(node.scenario.participants) all_participants.sort() if UNATTRIBUTED_PARTICIPANT in all_participants: @@ -241,8 +252,6 @@ def _generate_scenario_pages( test_scenario=node.scenario, all_participants=all_participants, kml_file=kml_file if config.render_kml else None, - EpochType=EpochType, - EventType=EventType, UNATTRIBUTED_PARTICIPANT=UNATTRIBUTED_PARTICIPANT, len=len, str=str, @@ -308,6 +317,7 @@ def generate_sequence_view( ) -> None: node = compute_action_node(report.report, Indexer()) + assert report.configuration.v1 and report.configuration.v1.test_run resources_config = make_resources_config(report.configuration.v1.test_run) os.makedirs(output_path, exist_ok=True) diff --git a/monitoring/uss_qualifier/reports/sequence_view/kml.py b/monitoring/uss_qualifier/reports/sequence_view/kml.py index 511c6aa79f..33b1774625 100644 --- a/monitoring/uss_qualifier/reports/sequence_view/kml.py +++ b/monitoring/uss_qualifier/reports/sequence_view/kml.py @@ -36,7 +36,7 @@ class QueryKMLRenderer(Protocol): def __call__( self, query: Query, req: ImplicitDict, resp: ImplicitDict - ) -> list[kml.Element]: + ) -> list[kml.Element]: # pyright: ignore[reportInvalidTypeForm, reportReturnType] """Function that renders the provided query information into KML elements. Args: @@ -47,6 +47,8 @@ def __call__( Returns: List of KML elements to include the folder for the query. """ + __name__: str + @dataclass class QueryKMLRenderInfo: @@ -99,7 +101,11 @@ def make_scenario_kml(scenario: TestedScenario) -> str: step_folder = kml.Folder(kml.name(step.name)) case_folder.append(step_folder) for event in step.events: - if not event.query or "query_type" not in event.query: + if ( + not event.query + or "query_type" not in event.query + or not event.query.query_type + ): continue # Only visualize queries of known types if event.query.query_type not in _query_kml_renderers: continue # Only visualize queries with renderers @@ -116,11 +122,14 @@ def make_scenario_kml(scenario: TestedScenario) -> str: ) step_folder.append(query_folder) - kwargs = {} + kwargs: dict[str, ImplicitDict | Query] = {} if render_info.include_query: kwargs["query"] = event.query if render_info.request_type: try: + if not event.query.request.json: + raise ValueError("No JSON in request") + kwargs["req"] = ImplicitDict.parse( event.query.request.json, render_info.request_type, @@ -139,6 +148,9 @@ def make_scenario_kml(scenario: TestedScenario) -> str: and render_info.response_type ): try: + if not event.query.response.json: + raise ValueError("No JSON in response") + kwargs["resp"] = ImplicitDict.parse( event.query.response.json, render_info.response_type, @@ -153,7 +165,7 @@ def make_scenario_kml(scenario: TestedScenario) -> str: ) continue try: - query_folder.extend(render_info.renderer(**kwargs)) + query_folder.extend(render_info.renderer(**kwargs)) # pyright: ignore[reportArgumentType] except (TypeError, KeyError, ValueError) as e: msg = f"Error rendering {render_info.renderer.__name__}" query_folder.append( @@ -174,7 +186,7 @@ def make_scenario_kml(scenario: TestedScenario) -> str: return etree.tostring(format_xml_with_cdata(doc), pretty_print=True).decode("utf-8") -@query_kml_renderer(QueryType.F3548v21DSSQueryOperationalIntentReferences) +@query_kml_renderer(QueryType.F3548v21DSSQueryOperationalIntentReferences) # pyright: ignore[reportArgumentType] def render_query_op_intent_references( req: QueryOperationalIntentReferenceParameters, resp: QueryOperationalIntentReferenceResponse, @@ -182,12 +194,12 @@ def render_query_op_intent_references( return [op_intent_refs_query(req, resp)] -@query_kml_renderer(QueryType.F3548v21USSGetOperationalIntentDetails) +@query_kml_renderer(QueryType.F3548v21USSGetOperationalIntentDetails) # pyright: ignore[reportArgumentType] def render_get_op_intent_details(resp: GetOperationalIntentDetailsResponse): return [full_op_intent(resp.operational_intent)] -@query_kml_renderer(QueryType.InterUSSFlightPlanningV1UpsertFlightPlan) +@query_kml_renderer(QueryType.InterUSSFlightPlanningV1UpsertFlightPlan) # pyright: ignore[reportArgumentType] def render_flight_planning_upsert_flight_plan( req: UpsertFlightPlanRequest, resp: UpsertFlightPlanResponse ): diff --git a/monitoring/uss_qualifier/reports/sequence_view/summary_types.py b/monitoring/uss_qualifier/reports/sequence_view/summary_types.py index 861da638c0..2b0c351e53 100644 --- a/monitoring/uss_qualifier/reports/sequence_view/summary_types.py +++ b/monitoring/uss_qualifier/reports/sequence_view/summary_types.py @@ -23,13 +23,6 @@ class NoteEvent(ImplicitDict): timestamp: datetime -class EventType(str, Enum): - PassedCheck = "PassedCheck" - FailedCheck = "FailedCheck" - Query = "Query" - Note = "Note" - - class Event(ImplicitDict): event_index: int = 0 passed_check: Optional[PassedCheck] = None @@ -38,19 +31,6 @@ class Event(ImplicitDict): query: Optional[Query] = None note: Optional[NoteEvent] = None - @property - def type(self) -> EventType: - if self.passed_check: - return EventType.PassedCheck - elif self.failed_check: - return EventType.FailedCheck - elif self.query: - return EventType.Query - elif self.note: - return EventType.Note - else: - raise ValueError("Invalid Event type") - @property def timestamp(self) -> datetime: if self.passed_check: @@ -66,7 +46,7 @@ def timestamp(self) -> datetime: def get_query_links(self) -> str: links = [] - for e in self.query_events: + for e in self.query_events or []: if isinstance(e, str): links.append(e) else: @@ -94,24 +74,10 @@ def rows(self) -> int: return sum(s.rows for s in self.steps) -class EpochType(str, Enum): - Case = "Case" - Events = "Events" - - class Epoch(ImplicitDict): case: Optional[TestedCase] = None events: Optional[list[Event]] = None - @property - def type(self) -> EpochType: - if self.case: - return EpochType.Case - elif self.events: - return EpochType.Events - else: - raise ValueError("Invalid Epoch did not specify case or events") - @property def rows(self) -> int: if self.case: diff --git a/monitoring/uss_qualifier/reports/templates/sequence_view/scenario.html b/monitoring/uss_qualifier/reports/templates/sequence_view/scenario.html index 79a0d2cd3a..3dba385eca 100644 --- a/monitoring/uss_qualifier/reports/templates/sequence_view/scenario.html +++ b/monitoring/uss_qualifier/reports/templates/sequence_view/scenario.html @@ -52,7 +52,7 @@

{% set first_row = namespace(epoch=True, step=True) %} {% for epoch in test_scenario.epochs %} {% set first_row.epoch = True %} - {% if epoch.type == EpochType.Case %} + {% if epoch.case %} {% for test_step in epoch.case.steps %} {% set first_row.step = True %} {% for event in test_step.events %} @@ -76,7 +76,7 @@

{% endif %} {{ event.event_index }} - {% if event.type == EventType.PassedCheck %} + {% if event.passed_check %} ✅ {{ event.passed_check.name }} @@ -88,7 +88,7 @@

{% endif %} {% endfor %} - {% elif event.type == EventType.FailedCheck %} + {% elif event.failed_check %} {{ severity_symbol(event.failed_check.severity) }} {% if event.failed_check.documentation_url %} @@ -117,7 +117,7 @@

{% endif %} {% endfor %} - {% elif event.type == EventType.Query %} + {% elif event.query %} 🌐 {% set query_dict = {event.query.request.method + " " + event.query.request.url_hostname + " " + str(event.query.response.status_code): event.query} %} @@ -132,20 +132,20 @@

{% endif %} {% endfor %} - {% elif event.type == EventType.Note %} + {% elif event.note %} 📓 {{ event.note.key }}: {{ event.note.message }} {% else %} - ???Render error: unknown EventType '{{ event.type }}' + ???Render error: unknown event type {% endif %} {% set first_row.epoch = False %} {% set first_row.step = False %} {% endfor %} {% endfor %} - {% elif epoch.type == EpochType.Events %} + {% elif epoch.events %} {% for event in epoch.events %} {% if first_row.epoch %} diff --git a/monitoring/uss_qualifier/reports/tested_requirements/breakdown.py b/monitoring/uss_qualifier/reports/tested_requirements/breakdown.py index e3c3c05573..1be493d377 100644 --- a/monitoring/uss_qualifier/reports/tested_requirements/breakdown.py +++ b/monitoring/uss_qualifier/reports/tested_requirements/breakdown.py @@ -129,11 +129,13 @@ def _populate_breakdown_with_action_report( req_set, ) elif test_suite: + assert action.test_suite for subaction in action.test_suite.actions: _populate_breakdown_with_action_report( breakdown, subaction, acceptable_findings, participant_ids, req_set ) elif action_generator: + assert action.action_generator for subaction in action.action_generator.actions: _populate_breakdown_with_action_report( breakdown, subaction, acceptable_findings, participant_ids, req_set @@ -267,10 +269,12 @@ def _populate_breakdown_with_action_declaration( ) -> None: action_type = action.get_action_type() if action_type == ActionType.TestScenario: + assert action.test_scenario _populate_breakdown_with_scenario( breakdown, action.test_scenario.scenario_type, acceptable_findings, req_set ) elif action_type == ActionType.TestSuite: + assert action.test_suite if "suite_type" in action.test_suite and action.test_suite.suite_type: suite_def: TestSuiteDefinition = ImplicitDict.parse( load_dict_with_references(action.test_suite.suite_type), @@ -291,6 +295,7 @@ def _populate_breakdown_with_action_declaration( else: raise ValueError("Test suite action missing suite type or definition") elif action_type == ActionType.ActionGenerator: + assert action.action_generator potential_actions = list_potential_actions_for_action_generator_definition( action.action_generator ) @@ -392,5 +397,5 @@ def _populate_breakdown_with_scenario( ), ) tested_step.checks.append(tested_check) - if not tested_check.url: + if not tested_check.url and check.url: tested_check.url = check.url