test_internal_e2e.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import json
  2. from pathlib import Path
  3. import httpx
  4. import pytest
  5. from script_build_host.internal_e2e import _wait_for_root
  6. def test_recovery_checkpoint_fixtures_cover_all_segment_boundaries() -> None:
  7. path = Path(__file__).parent / "fixtures" / "recovery_checkpoints.json"
  8. payload = json.loads(path.read_text(encoding="utf-8"))
  9. assert set(payload["checkpoints"]) == {"direction", "structure", "portfolio", "root"}
  10. assert all(
  11. item["input_snapshot_digest"].startswith("sha256:")
  12. for item in payload["checkpoints"].values()
  13. )
  14. @pytest.mark.asyncio
  15. async def test_mission_poll_allows_only_bounded_startup_failures() -> None:
  16. calls = 0
  17. def handler(_request: httpx.Request) -> httpx.Response:
  18. nonlocal calls
  19. calls += 1
  20. if calls <= 5:
  21. return httpx.Response(500, json={"error_code": "LEDGER_NOT_READY"})
  22. return httpx.Response(
  23. 200,
  24. json={
  25. "root_task_id": "root",
  26. "tasks": [
  27. {
  28. "task_id": "root",
  29. "status": "blocked",
  30. "blocked_reason": "BOUNDARY",
  31. }
  32. ],
  33. },
  34. )
  35. async with httpx.AsyncClient(
  36. transport=httpx.MockTransport(handler), base_url="http://internal"
  37. ) as client:
  38. result = await _wait_for_root(
  39. client,
  40. 7,
  41. expected_status="blocked",
  42. expected_reason="BOUNDARY",
  43. timeout_seconds=1,
  44. poll_seconds=0,
  45. )
  46. assert result["task_id"] == "root"
  47. assert calls == 6
  48. @pytest.mark.asyncio
  49. async def test_mission_poll_surfaces_persistent_server_failure() -> None:
  50. def handler(_request: httpx.Request) -> httpx.Response:
  51. return httpx.Response(500, json={"error_code": "InternalServerError"})
  52. async with httpx.AsyncClient(
  53. transport=httpx.MockTransport(handler), base_url="http://internal"
  54. ) as client:
  55. with pytest.raises(RuntimeError, match="mission poll failed with HTTP 500"):
  56. await _wait_for_root(
  57. client,
  58. 7,
  59. expected_status="blocked",
  60. expected_reason="BOUNDARY",
  61. timeout_seconds=1,
  62. poll_seconds=0,
  63. )