build: tighten runtime contracts and dependency reproducibility
This commit is contained in:
@@ -172,3 +172,45 @@ printf '%s\n' "${{PRE_EXISTING_IGNORES[@]}}"
|
||||
assert ignores == [
|
||||
"tests/test_t5_performance.py::test_admin_locust_10_concurrency_success_rate_above_95"
|
||||
]
|
||||
|
||||
|
||||
def test_dev_verify_detects_python_bin_drift(tmp_path: Path):
|
||||
venv_dir = tmp_path / ".venv"
|
||||
subprocess.run(
|
||||
["python3", "-m", "venv", str(venv_dir)],
|
||||
check=True,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
)
|
||||
fake_python = tmp_path / "python-fake"
|
||||
fake_python.write_text(
|
||||
"""#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [[ \"${1:-}\" == \"--version\" ]]; then
|
||||
echo \"Python 9.9.9\"
|
||||
exit 0
|
||||
fi
|
||||
exec /usr/bin/python3 \"$@\"
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
fake_python.chmod(0o755)
|
||||
|
||||
probe = f"""
|
||||
set -euo pipefail
|
||||
export GAOKAO_SOURCE_ONLY=1
|
||||
source {SCRIPT}
|
||||
VENV_DIR={venv_dir}
|
||||
PYTHON_BIN={fake_python}
|
||||
ensure_venv
|
||||
"""
|
||||
proc = subprocess.run(
|
||||
[BASH, "-lc", probe],
|
||||
cwd=REPO_ROOT,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
combined = proc.stdout + proc.stderr
|
||||
assert proc.returncode != 0
|
||||
assert "python bin drift" in combined
|
||||
|
||||
@@ -36,3 +36,11 @@ def test_docker_compose_passes_prod_critical_gaokao_env_vars() -> None:
|
||||
|
||||
missing = sorted(required_keys - set(service_env))
|
||||
assert not missing, f"docker-compose.yml missing gaokao env pass-through: {missing}"
|
||||
|
||||
|
||||
def test_docker_compose_ports_follow_admin_bind_and_port() -> None:
|
||||
compose = yaml.safe_load(
|
||||
(PROJECT_ROOT / "docker-compose.yml").read_text(encoding="utf-8")
|
||||
)
|
||||
ports = compose["services"]["gaokao-admin"]["ports"]
|
||||
assert ports == ["${GAOKAO_ADMIN_BIND:-127.0.0.1}:${GAOKAO_ADMIN_PORT:-8000}:${GAOKAO_ADMIN_PORT:-8000}"]
|
||||
|
||||
38
tests/test_runtime_contracts.py
Normal file
38
tests/test_runtime_contracts.py
Normal file
@@ -0,0 +1,38 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||
CI_WORKFLOW = PROJECT_ROOT / ".github" / "workflows" / "ci.yml"
|
||||
DOCKERFILE = PROJECT_ROOT / "Dockerfile"
|
||||
CONSTRAINTS = PROJECT_ROOT / "constraints.txt"
|
||||
|
||||
|
||||
def test_ci_cache_key_tracks_all_runtime_requirement_inputs() -> None:
|
||||
text = CI_WORKFLOW.read_text(encoding="utf-8")
|
||||
assert "requirements-admin.txt" in text
|
||||
assert "requirements-dev.txt" in text
|
||||
assert "constraints.txt" in text
|
||||
assert "hashFiles(" in text
|
||||
|
||||
|
||||
def test_dockerfile_installs_with_constraints_and_runtime_env_contract() -> None:
|
||||
text = DOCKERFILE.read_text(encoding="utf-8")
|
||||
assert "constraints.txt" in text
|
||||
assert "requirements-admin.txt" in text
|
||||
assert 'GAOKAO_ADMIN_BIND' in text
|
||||
assert 'GAOKAO_ADMIN_PORT' in text
|
||||
|
||||
|
||||
def test_constraints_file_locks_runtime_and_dev_packages() -> None:
|
||||
text = CONSTRAINTS.read_text(encoding="utf-8")
|
||||
for needle in (
|
||||
"fastapi==",
|
||||
"uvicorn==",
|
||||
"weasyprint==",
|
||||
"pytest==",
|
||||
"ruff==",
|
||||
"mypy==",
|
||||
):
|
||||
assert needle in text
|
||||
Reference in New Issue
Block a user