summaryrefslogtreecommitdiffstats
path: root/test/conftest.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/conftest.py')
-rw-r--r--test/conftest.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/test/conftest.py b/test/conftest.py
new file mode 100644
index 0000000..a1e4893
--- /dev/null
+++ b/test/conftest.py
@@ -0,0 +1,127 @@
+"""Pytest fixtures."""
+import importlib.metadata
+import json
+import pathlib
+import subprocess
+import sys
+from collections.abc import Generator
+from pathlib import Path
+from typing import Callable
+
+import pytest
+
+from ansible_compat.runtime import Runtime
+
+
+@pytest.fixture()
+# pylint: disable=unused-argument
+def runtime(scope: str = "session") -> Generator[Runtime, None, None]: # noqa: ARG001
+ """Isolated runtime fixture."""
+ instance = Runtime(isolated=True)
+ yield instance
+ instance.clean()
+
+
+@pytest.fixture()
+# pylint: disable=unused-argument
+def runtime_tmp(
+ tmp_path: pathlib.Path,
+ scope: str = "session", # noqa: ARG001
+) -> Generator[Runtime, None, None]:
+ """Isolated runtime fixture using a temp directory."""
+ instance = Runtime(project_dir=tmp_path, isolated=True)
+ yield instance
+ instance.clean()
+
+
+def query_pkg_version(pkg: str) -> str:
+ """Get the version of a current installed package.
+
+ :param pkg: Package name
+ :return: Package version
+ """
+ return importlib.metadata.version(pkg)
+
+
+@pytest.fixture()
+def pkg_version() -> Callable[[str], str]:
+ """Get the version of a current installed package.
+
+ :return: Callable function to get package version
+ """
+ return query_pkg_version
+
+
+class VirtualEnvironment:
+ """Virtualenv wrapper."""
+
+ def __init__(self, path: Path) -> None:
+ """Initialize.
+
+ :param path: Path to virtualenv
+ """
+ self.project = path
+ self.venv_path = self.project / "venv"
+ self.venv_bin_path = self.venv_path / "bin"
+ self.venv_python_path = self.venv_bin_path / "python"
+
+ def create(self) -> None:
+ """Create virtualenv."""
+ cmd = [str(sys.executable), "-m", "venv", str(self.venv_path)]
+ subprocess.check_call(args=cmd)
+ # Install this package into the virtual environment
+ self.install(f"{__file__}/../..")
+
+ def install(self, *packages: str) -> None:
+ """Install packages in virtualenv.
+
+ :param packages: Packages to install
+ """
+ cmd = [str(self.venv_python_path), "-m", "pip", "install", *packages]
+ subprocess.check_call(args=cmd)
+
+ def python_script_run(self, script: str) -> subprocess.CompletedProcess[str]:
+ """Run command in project dir using venv.
+
+ :param args: Command to run
+ """
+ proc = subprocess.run(
+ args=[self.venv_python_path, "-c", script],
+ capture_output=True,
+ cwd=self.project,
+ check=False,
+ text=True,
+ )
+ return proc
+
+ def site_package_dirs(self) -> list[Path]:
+ """Get site packages.
+
+ :return: List of site packages dirs
+ """
+ script = "import json, site; print(json.dumps(site.getsitepackages()))"
+ proc = subprocess.run(
+ args=[self.venv_python_path, "-c", script],
+ capture_output=True,
+ check=False,
+ text=True,
+ )
+ dirs = json.loads(proc.stdout)
+ if not isinstance(dirs, list):
+ msg = "Expected list of site packages"
+ raise TypeError(msg)
+ sanitized = list({Path(d).resolve() for d in dirs})
+ return sanitized
+
+
+@pytest.fixture(scope="module")
+def venv_module(tmp_path_factory: pytest.TempPathFactory) -> VirtualEnvironment:
+ """Create a virtualenv in a temporary directory.
+
+ :param tmp_path: pytest fixture for temp path
+ :return: VirtualEnvironment instance
+ """
+ test_project = tmp_path_factory.mktemp(basename="test_project-", numbered=True)
+ _venv = VirtualEnvironment(test_project)
+ _venv.create()
+ return _venv