from __future__ import annotations from pathlib import Path from unittest.mock import patch import pytest from click.testing import CliRunner import devx.molecule.molecule_all as molecule_all class TestRunMolecule: def test_success(self) -> None: import subprocess mock_result = subprocess.CompletedProcess(args=[], returncode=0, stdout="", stderr="") with patch("subprocess.run", return_value=mock_result) as mock_run: rc = molecule_all._run_molecule("/bin/molecule", "default", Path("/tmp/role"), {}) assert rc == 0 mock_run.assert_called_once() def test_failure(self) -> None: import subprocess mock_result = subprocess.CompletedProcess(args=[], returncode=1, stdout="", stderr="") with patch("subprocess.run", return_value=mock_result): rc = molecule_all._run_molecule("/bin/molecule", "default", Path("/tmp/role"), {}) assert rc == 1 def test_non_default_scenario_adds_flag(self) -> None: import subprocess mock_result = subprocess.CompletedProcess(args=[], returncode=0, stdout="", stderr="") with patch("subprocess.run", return_value=mock_result) as mock_run: molecule_all._run_molecule("/bin/molecule", "lifecycle", Path("/tmp/role"), {}) cmd = mock_run.call_args[0][0] assert "-s" in cmd assert "lifecycle" in cmd class TestRunPlatform: def test_all_scenarios_pass(self) -> None: platform = {"name": "ubuntu-2204", "image": "ubuntu:22.04", "command": "/lib/systemd/systemd"} with patch("devx.molecule.molecule_all._run_molecule", return_value=0) as mock_run: rc = molecule_all._run_platform("/bin/molecule", platform, Path("/tmp/role"), ["default", "lifecycle"], {}) assert rc == 0 assert mock_run.call_count == 2 def test_stops_on_failure(self) -> None: platform = {"name": "ubuntu-2204", "image": "ubuntu:22.04", "command": "/lib/systemd/systemd"} with patch("devx.molecule.molecule_all._run_molecule", side_effect=[1, 0]) as mock_run: rc = molecule_all._run_platform("/bin/molecule", platform, Path("/tmp/role"), ["default", "lifecycle"], {}) assert rc == 1 assert mock_run.call_count == 1 def test_sets_env_vars(self) -> None: platform = {"name": "ubuntu-2204", "image": "ubuntu:22.04", "command": "/lib/systemd/systemd"} captured_env: dict[str, str] = {} def _capture_env(cmd, cwd, env): captured_env.update(env) import subprocess return subprocess.CompletedProcess(args=cmd, returncode=0, stdout="", stderr="") with patch("subprocess.run", side_effect=_capture_env): molecule_all._run_platform("/bin/molecule", platform, Path("/tmp/role"), ["default"], {"PATH": "/usr/bin"}) assert captured_env["MOLECULE_PLATFORM_NAME"] == "ubuntu-2204" assert captured_env["MOLECULE_PLATFORM_IMAGE"] == "ubuntu:22.04" assert captured_env["MOLECULE_PLATFORM_COMMAND"] == "/lib/systemd/systemd" def test_empty_command_removes_env(self) -> None: platform = {"name": "custom", "image": "custom:latest", "command": ""} captured_env: dict[str, str] = {} def _capture_env(cmd, cwd, env): captured_env.update(env) import subprocess return subprocess.CompletedProcess(args=cmd, returncode=0, stdout="", stderr="") with patch("subprocess.run", side_effect=_capture_env): molecule_all._run_platform( "/bin/molecule", platform, Path("/tmp/role"), ["default"], {"MOLECULE_PLATFORM_COMMAND": "old"} ) assert "MOLECULE_PLATFORM_COMMAND" not in captured_env class TestMain: def test_molecule_not_found(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.chdir(tmp_path) runner = CliRunner() result = runner.invoke(molecule_all.main, ["--bin", "nonexistent/bin"]) assert result.exit_code != 0 assert "molecule not found" in result.output def test_role_dir_not_found(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.chdir(tmp_path) bin_dir = tmp_path / ".venv" / "bin" bin_dir.mkdir(parents=True) (bin_dir / "molecule").touch() runner = CliRunner() result = runner.invoke(molecule_all.main, ["--bin", str(bin_dir)]) assert result.exit_code != 0 assert "Role directory not found" in result.output def test_all_pass(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.chdir(tmp_path) bin_dir = tmp_path / ".venv" / "bin" bin_dir.mkdir(parents=True) (bin_dir / "molecule").touch() (tmp_path / "ansible" / "roles" / "gitea-runner").mkdir(parents=True) runner = CliRunner() with patch("devx.molecule.molecule_all._run_platform", return_value=0): result = runner.invoke(molecule_all.main, ["--bin", str(bin_dir)]) assert result.exit_code == 0 assert "All molecule scenarios passed" in result.output def test_platform_failure(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.chdir(tmp_path) bin_dir = tmp_path / ".venv" / "bin" bin_dir.mkdir(parents=True) (bin_dir / "molecule").touch() (tmp_path / "ansible" / "roles" / "gitea-runner").mkdir(parents=True) runner = CliRunner() with patch("devx.molecule.molecule_all._run_platform", return_value=1): result = runner.invoke(molecule_all.main, ["--bin", str(bin_dir)]) assert result.exit_code != 0