Spaces:
Sleeping
Sleeping
| import importlib.util | |
| from pathlib import Path | |
| SCRIPT_PATH = Path(__file__).resolve().parents[1] / "scripts" / "docker_smoke.py" | |
| SPEC = importlib.util.spec_from_file_location("docker_smoke", SCRIPT_PATH) | |
| docker_smoke = importlib.util.module_from_spec(SPEC) | |
| assert SPEC.loader is not None | |
| SPEC.loader.exec_module(docker_smoke) | |
| def write_dockerignore(root: Path) -> None: | |
| (root / ".dockerignore").write_text( | |
| "\n".join( | |
| [ | |
| ".git/", | |
| ".env", | |
| ".env.*", | |
| "!.env.example", | |
| "!.env.final.example", | |
| ".env.final.local", | |
| ".venv/", | |
| "var/", | |
| "output/", | |
| ] | |
| ) | |
| + "\n", | |
| encoding="utf-8", | |
| ) | |
| def fake_runner(args, cwd, timeout, env=None): | |
| if args[:2] == ["docker", "info"]: | |
| return {"ok": True, "returncode": 0, "stdout_tail": '"29.3.0"', "stderr_tail": ""} | |
| if args[:2] == ["docker", "build"]: | |
| return {"ok": True, "returncode": 0, "stdout_tail": "Successfully tagged", "stderr_tail": ""} | |
| if args[:2] == ["docker", "run"]: | |
| return {"ok": True, "returncode": 0, "stdout_tail": "container-id", "stderr_tail": ""} | |
| if args[:2] == ["docker", "logs"]: | |
| return {"ok": True, "returncode": 0, "stdout_tail": "Uvicorn running", "stderr_tail": ""} | |
| if args[:3] == ["docker", "rm", "-f"]: | |
| return {"ok": True, "returncode": 0, "stdout_tail": "removed", "stderr_tail": ""} | |
| if args[-1].startswith("http://127.0.0.1:"): | |
| assert env and env["PYTHONPATH"] == "src" | |
| return {"ok": True, "returncode": 0, "stdout_tail": '{"ok": true}', "stderr_tail": ""} | |
| raise AssertionError(f"unexpected command: {args}") | |
| def recording_runner(calls, overrides=None): | |
| overrides = overrides or {} | |
| def runner(args, cwd, timeout, env=None): | |
| calls.append(args) | |
| command_id = "_".join(args[:2]) if args[:2] != ["docker", "rm"] else "docker_rm" | |
| if command_id in overrides: | |
| return overrides[command_id] | |
| return fake_runner(args, cwd, timeout, env) | |
| return runner | |
| def healthy_fetcher(url, timeout): | |
| return { | |
| "ok": True, | |
| "status": 200, | |
| "json": { | |
| "ready": True, | |
| "storage_backend": "local", | |
| "generation_backend": "mock", | |
| "b2_configured": False, | |
| "genblaze_configured": False, | |
| }, | |
| "error": None, | |
| } | |
| def test_fetch_health_treats_connection_reset_as_transient(monkeypatch): | |
| def broken_urlopen(request, timeout): | |
| raise ConnectionResetError("reset by peer") | |
| monkeypatch.setattr(docker_smoke, "urlopen", broken_urlopen) | |
| result = docker_smoke.fetch_health("http://127.0.0.1:18088/api/health", 1) | |
| assert result["ok"] is False | |
| assert "reset by peer" in result["error"] | |
| def test_docker_smoke_report_passes_with_fake_runner(tmp_path): | |
| write_dockerignore(tmp_path) | |
| report = docker_smoke.build_report( | |
| root=tmp_path, | |
| command_runner=fake_runner, | |
| health_fetcher=healthy_fetcher, | |
| sleep_fn=lambda seconds: None, | |
| ) | |
| assert report["schema"] == "proofframe.docker_smoke.v1" | |
| assert report["ok"] is True | |
| assert report["mode"] == "docker_smoke_ready" | |
| assert report["dockerignore"]["missing_required_patterns"] == [] | |
| assert report["dockerignore"]["missing_allow_patterns"] == [] | |
| assert {check["id"] for check in report["checks"]} >= { | |
| "dockerignore_secret_exclusions", | |
| "docker_build", | |
| "docker_health", | |
| "api_smoke", | |
| } | |
| assert "does not read .env.final.local" in report["secret_policy"] | |
| def test_docker_smoke_cleans_up_after_health_exception(tmp_path): | |
| write_dockerignore(tmp_path) | |
| calls = [] | |
| def broken_fetcher(url, timeout): | |
| raise RuntimeError("health exploded") | |
| report = docker_smoke.build_report( | |
| root=tmp_path, | |
| command_runner=recording_runner(calls), | |
| health_fetcher=broken_fetcher, | |
| sleep_fn=lambda seconds: None, | |
| ) | |
| failed = {check["id"] for check in report["checks"] if not check["ok"]} | |
| assert report["ok"] is False | |
| assert "docker_health" in failed | |
| assert ["docker", "rm", "-f", "proofframe-submission-smoke"] in calls | |
| cleanup = next(command for command in report["commands"] if command["id"] == "docker_cleanup") | |
| assert cleanup["ok"] is True | |
| logs = next(command for command in report["commands"] if command["id"] == "docker_logs") | |
| assert "health exploded" in logs["stderr_tail"] | |
| def test_docker_smoke_cleans_up_when_api_smoke_fails(tmp_path): | |
| write_dockerignore(tmp_path) | |
| calls = [] | |
| report = docker_smoke.build_report( | |
| root=tmp_path, | |
| command_runner=recording_runner( | |
| calls, | |
| overrides={ | |
| f"{docker_smoke.sys.executable}_scripts/api_smoke.py": { | |
| "ok": False, | |
| "returncode": 1, | |
| "stdout_tail": "", | |
| "stderr_tail": "api failed", | |
| } | |
| }, | |
| ), | |
| health_fetcher=healthy_fetcher, | |
| sleep_fn=lambda seconds: None, | |
| ) | |
| failed = {check["id"] for check in report["checks"] if not check["ok"]} | |
| assert report["ok"] is False | |
| assert "api_smoke" in failed | |
| assert ["docker", "rm", "-f", "proofframe-submission-smoke"] in calls | |
| def test_docker_smoke_fails_closed_without_dockerignore(tmp_path): | |
| report = docker_smoke.build_report( | |
| root=tmp_path, | |
| command_runner=fake_runner, | |
| health_fetcher=healthy_fetcher, | |
| sleep_fn=lambda seconds: None, | |
| ) | |
| failed = {check["id"] for check in report["checks"] if not check["ok"]} | |
| assert report["ok"] is False | |
| assert "dockerignore_secret_exclusions" in failed | |
| def test_docker_smoke_writes_json_and_markdown(tmp_path): | |
| write_dockerignore(tmp_path) | |
| report = docker_smoke.build_report( | |
| root=tmp_path, | |
| command_runner=fake_runner, | |
| health_fetcher=healthy_fetcher, | |
| sleep_fn=lambda seconds: None, | |
| ) | |
| json_path = tmp_path / "docker-smoke.json" | |
| markdown_path = tmp_path / "docker-smoke.md" | |
| docker_smoke.write_outputs(report, json_path, markdown_path) | |
| assert json_path.read_text(encoding="utf-8").startswith("{") | |
| assert "# ProofFrame Docker Smoke Report" in markdown_path.read_text(encoding="utf-8") | |