diff --git a/pytest_abra/coordinator.py b/pytest_abra/coordinator.py index 67cd776..f1e557a 100644 --- a/pytest_abra/coordinator.py +++ b/pytest_abra/coordinator.py @@ -2,6 +2,7 @@ import importlib import re import sys from pathlib import Path +from typing import NamedTuple from loguru import logger @@ -12,6 +13,11 @@ from pytest_abra.runner import Runner from pytest_abra.utils import rmtree +class RunnerMeta(NamedTuple): + cls: type[Runner] + path: Path + + class Coordinator: def __init__( self, @@ -54,8 +60,9 @@ class Coordinator: """Creates an instance of the correct Runner class for each given env file""" runners: list[Runner] = [] for index, env_file in enumerate(env_files): - RunnerClass = self.RUNNER_DICT[env_file.env_config["TYPE"]] - runners.append(RunnerClass(coordinator=self, runner_index=index)) + meta = self.RUNNER_DICT[env_file.env_config["TYPE"]] + RunnerClass = meta.cls + runners.append(RunnerClass(coordinator=self, runner_index=index, runner_dir=meta.path)) return runners def combine_html(self) -> None: @@ -89,21 +96,14 @@ class Coordinator: rmtree(trace_root_dir) @staticmethod - def create_runner_dict(recipes_dir: Path) -> dict[str, type["Runner"]]: + def create_runner_dict(recipes_dir: Path) -> dict[str, RunnerMeta]: """Creates a dictionary holding all the RunnerClasses that can be discovered in recipes_dir - example: - RUNNER_DICT: dict[str, type["Runner"]] = { - "authentik": RunnerAuthentik, - "wordpress": RunnerWordpress, - "nextcloud": RunnerNextcloud, - } - The Runner classes are automatically imported with importlib. The imports are successful because recipes_dir is added to sys.path. """ - RUNNER_DICT: dict[str, type["Runner"]] = dict() + RUNNER_DICT: dict[str, RunnerMeta] = dict() runner_discovery_pattern = re.compile("Runner.+") # make it possible to import modules from recipes_dir @@ -116,5 +116,5 @@ class Coordinator: assert len(runner_class_names) == 1 runner_class_name = runner_class_names[0] RunnerClass: type[Runner] = getattr(module, runner_class_name) - RUNNER_DICT[RunnerClass.env_type] = RunnerClass + RUNNER_DICT[RunnerClass.env_type] = RunnerMeta(cls=RunnerClass, path=module_path) return RUNNER_DICT diff --git a/pytest_abra/env_manager.py b/pytest_abra/env_manager.py index f9d79cd..2490462 100644 --- a/pytest_abra/env_manager.py +++ b/pytest_abra/env_manager.py @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, NamedTuple from dotenv import dotenv_values if TYPE_CHECKING: + from pytest_abra.coordinator import RunnerMeta from pytest_abra.dir_manager import DirManager from pytest_abra.runner import Runner @@ -24,7 +25,7 @@ class DependencyRule(NamedTuple): class EnvManager: - def __init__(self, env_paths: list[Path], RUNNER_DICT: dict[str, type["Runner"]]): + def __init__(self, env_paths: list[Path], RUNNER_DICT: dict[str, "RunnerMeta"]): self.env_files: list[EnvFile] = self._get_env_files(env_paths) self.dependency_rules: list[DependencyRule] = self._get_dependency_rules(self.env_files, RUNNER_DICT) self.env_files = self.sort_env_files_by_rule(self.env_files, self.dependency_rules) @@ -42,10 +43,10 @@ class EnvManager: return env_files @staticmethod - def _get_dependency_rules(env_files: list[EnvFile], RUNNER_DICT: dict[str, type["Runner"]]) -> list[DependencyRule]: + def _get_dependency_rules(env_files: list[EnvFile], RUNNER_DICT: dict[str, "RunnerMeta"]) -> list[DependencyRule]: dependency_rules: list[DependencyRule] = [] for env_file in env_files: - child_runner_class = RUNNER_DICT[env_file.env_type] + child_runner_class = RUNNER_DICT[env_file.env_type].cls for dependency in child_runner_class.dependencies: dependency_rule = DependencyRule(child=child_runner_class.env_type, dependency=dependency) dependency_rules.append(dependency_rule) diff --git a/pytest_abra/runner.py b/pytest_abra/runner.py index fb6d270..d2424ea 100644 --- a/pytest_abra/runner.py +++ b/pytest_abra/runner.py @@ -6,9 +6,8 @@ from typing import TYPE_CHECKING, Callable, NamedTuple import pytest from loguru import logger -from pytest_abra import DirManager - if TYPE_CHECKING: + from pytest_abra import DirManager from pytest_abra.coordinator import Coordinator from pytest_abra.env_manager import EnvFile @@ -33,9 +32,10 @@ class Runner: cleanups: list[Test] = [] dependencies: list[str] = [] - def __init__(self, coordinator: "Coordinator", runner_index: int): + def __init__(self, coordinator: "Coordinator", runner_index: int, runner_dir: Path): self.coordinator = coordinator self.runner_index = runner_index + self.runner_dir = runner_dir self.DIR = coordinator.DIR self.ENV = coordinator.ENV @@ -180,7 +180,7 @@ class Runner: @classmethod def create_result_file( cls, - DIR: DirManager, + DIR: "DirManager", result: int | str, identifier_string: str, ): @@ -201,7 +201,7 @@ class Runner: passed_tests = [r.name for r in self.DIR.RESULTS.glob("*") if "passed" in r.name] results = [] for dependency in self.dependencies: - dependency_runner = self.coordinator.RUNNER_DICT[dependency] + dependency_runner = self.coordinator.RUNNER_DICT[dependency].cls for setup_name in dependency_runner.setups: dependencie_identifier = self.combine_names(dependency_runner.env_type, setup_name.test_file) results.append(any(dependencie_identifier in f for f in passed_tests))