Respect SpaceDevs request limits and cooldowns
This commit is contained in:
parent
69992bebb7
commit
3f6ee4f2ec
3 changed files with 124 additions and 13 deletions
62
tests/test_spacedevs_budget.py
Normal file
62
tests/test_spacedevs_budget.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
"""Regression tests for the shared SpaceDevs request budget."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
|
||||
from agenda import thespacedevs
|
||||
|
||||
|
||||
def test_budget_survives_separate_calls(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
request = Mock(return_value=Mock(status_code=200))
|
||||
monkeypatch.setattr("agenda.thespacedevs.requests.get", request)
|
||||
monkeypatch.setattr("agenda.thespacedevs.time.time", lambda: 10000.0)
|
||||
for _ in range(12):
|
||||
thespacedevs.api_get(str(tmp_path), "https://example.com")
|
||||
with pytest.raises(thespacedevs.RateLimitDeferred):
|
||||
thespacedevs.api_get(str(tmp_path), "https://example.com")
|
||||
assert request.call_count == 12
|
||||
monkeypatch.setattr("agenda.thespacedevs.time.time", lambda: 13601.0)
|
||||
thespacedevs.api_get(str(tmp_path), "https://example.com")
|
||||
assert request.call_count == 13
|
||||
|
||||
|
||||
@pytest.mark.parametrize("headers", [{}, {"Retry-After": "1832"}])
|
||||
def test_throttle_persists_cooldown(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, headers: dict[str, str]
|
||||
) -> None:
|
||||
request = Mock(
|
||||
return_value=Mock(
|
||||
status_code=429,
|
||||
headers=headers,
|
||||
text='{"detail": "Request was throttled. Expected available in 1832 seconds."}',
|
||||
)
|
||||
)
|
||||
monkeypatch.setattr("agenda.thespacedevs.requests.get", request)
|
||||
monkeypatch.setattr("agenda.thespacedevs.time.time", lambda: 10000.0)
|
||||
with pytest.raises(thespacedevs.RateLimitDeferred):
|
||||
thespacedevs.api_get(str(tmp_path), "https://example.com")
|
||||
state = json.loads((tmp_path / "api_budget.json").read_text())
|
||||
assert state["retry_at"] == 11833.0
|
||||
monkeypatch.setattr("agenda.thespacedevs.time.time", lambda: 11000.0)
|
||||
with pytest.raises(thespacedevs.RateLimitDeferred):
|
||||
thespacedevs.api_get(str(tmp_path), "https://example.com")
|
||||
assert request.call_count == 1
|
||||
|
||||
|
||||
def test_incomplete_pagination_keeps_cached_flights(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
cached = [{"slug": "still-in-orbit"}]
|
||||
thespacedevs.write_active_crewed_flights_cache(str(tmp_path), cached)
|
||||
response = Mock(status_code=200, ok=True)
|
||||
response.json.return_value = {"results": [], "next": "https://example.com/page2"}
|
||||
request = Mock(side_effect=[response, thespacedevs.RateLimitDeferred()])
|
||||
monkeypatch.setattr(thespacedevs, "api_get", request)
|
||||
assert thespacedevs.get_active_crewed_flights(str(tmp_path), refresh=True) == cached
|
||||
loaded = thespacedevs.load_active_crewed_flights_cache(str(tmp_path))
|
||||
assert loaded is not None and loaded[1] == cached
|
||||
Loading…
Add table
Add a link
Reference in a new issue