From 5c14cac681fad750f5d9113c3815cd3927139c9d Mon Sep 17 00:00:00 2001 From: Kate Case Date: Tue, 25 Feb 2025 08:12:38 -0500 Subject: [PATCH] Store scenario results. --- src/molecule/provisioner/ansible_playbook.py | 11 +++++++++++ src/molecule/scenario.py | 2 ++ src/molecule/types.py | 12 ++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/molecule/provisioner/ansible_playbook.py b/src/molecule/provisioner/ansible_playbook.py index 3a94ac575..1b5693589 100644 --- a/src/molecule/provisioner/ansible_playbook.py +++ b/src/molecule/provisioner/ansible_playbook.py @@ -28,6 +28,7 @@ from molecule import util from molecule.api import MoleculeRuntimeWarning +from molecule.types import ScenarioResult if TYPE_CHECKING: @@ -120,6 +121,9 @@ def execute(self, action_args: list[str] | None = None) -> str: # noqa: ARG002 if not self._playbook: LOG.warning("Skipping, %s action has no playbook.", self._config.action) + self._config.scenario.results.append( + ScenarioResult(subcommand=self._config.action, state="SKIPPED"), + ) return "" with warnings.catch_warnings(record=True) as warns: @@ -134,6 +138,10 @@ def execute(self, action_args: list[str] | None = None) -> str: # noqa: ARG002 ) if result.returncode != 0: + self._config.scenario.results.append( + ScenarioResult(subcommand=self._config.action, state="FAILED"), + ) + from rich.markup import escape util.sysexit_with_message( @@ -142,6 +150,9 @@ def execute(self, action_args: list[str] | None = None) -> str: # noqa: ARG002 warns=warns, ) + self._config.scenario.results.append( + ScenarioResult(subcommand=self._config.action, state="PASSED"), + ) return result.stdout def add_cli_arg(self, name: str, value: str | bool) -> None: diff --git a/src/molecule/scenario.py b/src/molecule/scenario.py index 171eb2b70..4f2cbbe24 100644 --- a/src/molecule/scenario.py +++ b/src/molecule/scenario.py @@ -38,6 +38,7 @@ if TYPE_CHECKING: from molecule.config import Config + from molecule.types import ScenarioResult LOG = logging.getLogger(__name__) @@ -54,6 +55,7 @@ def __init__(self, config: Config) -> None: """ self._lock = None self.config = config + self.results: list[ScenarioResult] = [] self._setup() def __repr__(self) -> str: diff --git a/src/molecule/types.py b/src/molecule/types.py index 091b6e531..8fe104dbe 100644 --- a/src/molecule/types.py +++ b/src/molecule/types.py @@ -277,3 +277,15 @@ class CommandArgs(TypedDict, total=False): platform_name: str scenario_name: str subcommand: str + + +class ScenarioResult(TypedDict): + """Dictionary containing the result of a Scenario run. + + Attributes: + subcommand: The action that ran. + state: The outcome of the action ("PASSED", "FAILED", or "SKIPPED). + """ + + subcommand: str | None + state: Literal["PASSED", "FAILED", "SKIPPED"]