From 345ecedee50d7392465a8ed2e8ca067afa2550bf Mon Sep 17 00:00:00 2001 From: Martin Hoyer Date: Wed, 25 Sep 2024 18:10:12 +0200 Subject: [PATCH] trying to make check fail affect test result --- tmt/result.py | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/tmt/result.py b/tmt/result.py index 277300bc8b..6668bdf7ce 100644 --- a/tmt/result.py +++ b/tmt/result.py @@ -200,7 +200,7 @@ class Result(BaseResult): context: tmt.utils.FmfContext = field( default_factory=tmt.utils.FmfContext, serialize=lambda context: context.to_spec(), - unserialize=lambda serialized: tmt.utils.FmfContext(serialized) + unserialize=tmt.utils.FmfContext ) ids: ResultIds = field( default_factory=cast(Callable[[], ResultIds], dict) @@ -208,7 +208,7 @@ class Result(BaseResult): guest: ResultGuestData = field( default_factory=ResultGuestData, serialize=lambda value: value.to_serialized(), - unserialize=lambda serialized: ResultGuestData.from_serialized(serialized) + unserialize=ResultGuestData.from_serialized ) subresult: list[SubResult] = field( @@ -230,6 +230,27 @@ class Result(BaseResult): unserialize=lambda value: None if value is None else Path(value) ) + original_result: Optional[ResultOutcome] = field( + default=None, + + serialize=lambda result: result.value if result else None, + # TODO unserialize add a function and cast? + unserialize=lambda value: ResultOutcome( + value) if value else None # pyright: ignore[reportArgumentType] + ) + respect_checks: bool = True + + def __post_init__(self) -> None: + self._update_result() + + def _update_result(self) -> None: + if self.respect_checks and any(check.result == ResultOutcome.FAIL for check in self.check): + self.result = ResultOutcome.FAIL + if self.note: + self.note += ', check failed' + else: + self.note = 'check failed' + @classmethod def from_test_invocation( cls, @@ -238,7 +259,8 @@ def from_test_invocation( result: ResultOutcome, note: Optional[str] = None, ids: Optional[ResultIds] = None, - log: Optional[list[Path]] = None) -> 'Result': + log: Optional[list[Path]] = None, + respect_checks: bool = True) -> 'Result': """ Create a result from a test invocation. @@ -255,6 +277,7 @@ def from_test_invocation( :param ids: additional test IDs. They will be added to IDs extracted from the test. :param log: optional list of test logs. + :param respect_checks: whether to respect or ignore check results. """ # Saving identifiable information for each test case so we can match them @@ -286,7 +309,9 @@ def from_test_invocation( ids=ids, log=log or [], guest=ResultGuestData.from_test_invocation(invocation=invocation), - data_path=invocation.relative_test_data_path) + data_path=invocation.relative_test_data_path, + respect_checks=respect_checks, + check=invocation.check_results) return _result.interpret_result(ResultInterpret( invocation.test.result) if invocation.test.result else ResultInterpret.RESPECT) @@ -302,7 +327,10 @@ def interpret_result(self, interpret: ResultInterpret) -> 'Result': :returns: :py:class:`Result` instance containing the updated result. """ + self.original_result = self.result + if interpret in (ResultInterpret.RESPECT, ResultInterpret.CUSTOM): + self._update_result() return self # Extend existing note or set a new one @@ -331,6 +359,7 @@ def interpret_result(self, interpret: ResultInterpret) -> 'Result': raise tmt.utils.SpecificationError( f"Invalid result '{interpret.value}' in test '{self.name}'.") + self._update_result() return self @staticmethod @@ -388,6 +417,12 @@ def show(self, display_guest: bool = True) -> str: if self.note: components.append(f'({self.note})') + if self.respect_checks and any(check.result == ResultOutcome.FAIL for check in self.check): + components.append(click.style('(check failed)', fg='red')) + + if self.original_result and self.original_result != self.result: + components.append(f'(original: {self.original_result.value})') + return ' '.join(components) @staticmethod