test_internal_e2e.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. from __future__ import annotations
  2. import httpx
  3. import pytest
  4. from script_build_host.internal_e2e import _wait_for_root
  5. @pytest.mark.asyncio
  6. async def test_mission_poll_allows_only_bounded_startup_failures() -> None:
  7. calls = 0
  8. def handler(_request: httpx.Request) -> httpx.Response:
  9. nonlocal calls
  10. calls += 1
  11. if calls <= 5:
  12. return httpx.Response(500, json={"error_code": "LEDGER_NOT_READY"})
  13. return httpx.Response(
  14. 200,
  15. json={
  16. "root_task_id": "root",
  17. "tasks": [
  18. {
  19. "task_id": "root",
  20. "status": "blocked",
  21. "blocked_reason": "BOUNDARY",
  22. }
  23. ],
  24. },
  25. )
  26. async with httpx.AsyncClient(
  27. transport=httpx.MockTransport(handler), base_url="http://internal"
  28. ) as client:
  29. result = await _wait_for_root(
  30. client,
  31. 7,
  32. expected_status="blocked",
  33. expected_reason="BOUNDARY",
  34. timeout_seconds=1,
  35. poll_seconds=0,
  36. )
  37. assert result["task_id"] == "root"
  38. assert calls == 6
  39. @pytest.mark.asyncio
  40. async def test_mission_poll_surfaces_persistent_server_failure() -> None:
  41. def handler(_request: httpx.Request) -> httpx.Response:
  42. return httpx.Response(500, json={"error_code": "InternalServerError"})
  43. async with httpx.AsyncClient(
  44. transport=httpx.MockTransport(handler), base_url="http://internal"
  45. ) as client:
  46. with pytest.raises(RuntimeError, match="mission poll failed with HTTP 500"):
  47. await _wait_for_root(
  48. client,
  49. 7,
  50. expected_status="blocked",
  51. expected_reason="BOUNDARY",
  52. timeout_seconds=1,
  53. poll_seconds=0,
  54. )