import re import importlib.util import os import subprocess import sys from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[2] WORKFLOW = ROOT / ".gitea" / "workflows" / "managed-validation.yml" def test_managed_validation_keeps_parallel_lanes_and_full_gate(): text = WORKFLOW.read_text(encoding="utf-8") for job in ("preflight:", "backend:", "frontend:", "security:", "polyglot:", "full:"): assert f" {job}" in text assert "needs: [preflight, backend, frontend, security, polyglot]" in text assert "All managed validation lanes passed." in text def test_preflight_preserves_docs_only_fast_path(): text = WORKFLOW.read_text(encoding="utf-8") assert "runtime_change" in text assert "*.md|*.mdx|docs/*" in text def test_backend_budget_is_bounded_without_weakening_validation(): text = WORKFLOW.read_text(encoding="utf-8") expected_timeouts = { "preflight": 10, "backend": 60, "frontend": 30, "security": 20, "polyglot": 30, "full": 10, } for job, expected_minutes in expected_timeouts.items(): match = re.search( rf"(?ms)^ {re.escape(job)}:\n(?P.*?)(?=^ [a-z][a-z0-9_-]*:\n|\Z)", text, ) assert match is not None, f"missing managed-validation job {job}" timeout = re.search(r"(?m)^ timeout-minutes: (\d+)\s*$", match["body"]) assert timeout is not None, f"missing timeout for {job}" assert int(timeout.group(1)) == expected_minutes for lane in ("preflight", "backend", "frontend", "security", "polyglot", "full"): assert f" {lane}:" in text assert "needs: [preflight, backend, frontend, security, polyglot]" in text assert "All managed validation lanes passed." in text backend = re.search( r"(?ms)^ backend:\n(?P.*?)(?=^ [a-z][a-z0-9_-]*:\n|\Z)", text, ) assert backend is not None backend_body = backend["body"] assert 'if [[ "${profile}" == test || "${profile}" == full ]]; then' in backend_body pytest_commands = [ line.strip() for line in backend_body.splitlines() if "-m pytest " in line ] assert pytest_commands == [ '"${py}" -m pytest backend/tests -q --durations=20 --maxfail=1' ] assert "continue-on-error" not in backend_body assert "--ignore" not in backend_body assert "--deselect" not in backend_body def _job_body(job): text = WORKFLOW.read_text(encoding="utf-8") match = re.search(rf"(?ms)^ {re.escape(job)}:\n(?P.*?)(?=^ [a-z][a-z0-9_-]*:\n|\Z)", text) assert match is not None return match["body"] def test_light_checks_use_existing_single_checks_profile(): spec = importlib.util.spec_from_file_location( "appops_light_checks_profiles", ROOT / "ops/gitea-deploy-broker/runner_profiles.py" ) profiles = importlib.util.module_from_spec(spec) sys.modules[spec.name] = profiles spec.loader.exec_module(profiles) try: for job in ("preflight", "full"): label = re.search(r"(?m)^ runs-on: (\S+)\s*$", _job_body(job)).group(1) assert tuple(profile.id for profile in profiles.profiles_for_labels((label,))) == ("checks",) assert profiles.RUNNER_PROFILES["checks"].memory_mib == 1536 for job in ("backend", "frontend", "security", "polyglot"): assert " runs-on: linux-validation\n" in _job_body(job) finally: sys.modules.pop(spec.name, None) def _bash_script(job): body = _job_body(job) script = body.split(" run: |\n", 1)[1] return "\n".join(line[10:] if line.startswith(" ") else line for line in script.splitlines()) @pytest.mark.skipif(os.name == "nt", reason="Execute actual workflow Bash on Linux") @pytest.mark.parametrize("failed_lane", [None, "PREFLIGHT", "BACKEND", "FRONTEND", "SECURITY", "POLYGLOT"]) def test_light_full_gate_executes_all_required_lane_results(tmp_path, failed_lane): environment = {"PATH": os.defpath, **{name: "success" for name in ("PREFLIGHT", "BACKEND", "FRONTEND", "SECURITY", "POLYGLOT")}} if failed_lane: environment[failed_lane] = "failure" result = subprocess.run(["bash", "-c", _bash_script("full")], cwd=tmp_path, env=environment, capture_output=True, text=True, timeout=10) assert (result.returncode == 0) is (failed_lane is None) assert ("All managed validation lanes passed." in result.stdout) is (failed_lane is None) @pytest.mark.skipif(os.name == "nt", reason="Execute actual workflow Bash/Git on Linux") @pytest.mark.parametrize("change", ["clean", "whitespace", "conflict"]) def test_light_preflight_executes_git_and_rejects_bad_source(tmp_path, change): environment = {"PATH": os.defpath, "HOME": str(tmp_path), "GITHUB_OUTPUT": str(tmp_path / "output")} for args in (["init", "--quiet"], ["config", "user.name", "CI fixture"], ["config", "user.email", "ci@example.invalid"]): subprocess.run(["git", *args], cwd=tmp_path, env=environment, check=True, capture_output=True) readme = tmp_path / "README.md" readme.write_text("Clean source\n") subprocess.run(["git", "add", "README.md"], cwd=tmp_path, env=environment, check=True, capture_output=True) subprocess.run(["git", "commit", "--quiet", "-m", "fixture"], cwd=tmp_path, env=environment, check=True, capture_output=True) if change == "whitespace": readme.write_text("Trailing whitespace \n") elif change == "conflict": readme.write_text("<<<<<<< fixture\n") result = subprocess.run(["bash", "-c", _bash_script("preflight")], cwd=tmp_path, env=environment, capture_output=True, text=True, timeout=10) assert (result.returncode == 0) is (change == "clean") if change == "clean": assert "runtime_change=true" in (tmp_path / "output").read_text()