test(v1.4.0-p1): add failing tests for timeout and YAML config
RED phase: 4 new tests in test_client.py for graceful timeout on pagination, 12 new tests in test_config.py for YAML config module (import fails, module not created yet). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -427,3 +427,90 @@ class TestGetLatestCommit:
|
||||
result = client.get_latest_commit("admin", "missing-repo")
|
||||
|
||||
assert result is None
|
||||
|
||||
|
||||
class TestGetPaginatedGracefulTimeout:
|
||||
"""Test graceful degradation on timeout during pagination."""
|
||||
|
||||
def _make_client(self):
|
||||
return GiteaClient("http://gitea.local:3000", "tok")
|
||||
|
||||
@patch("time.sleep")
|
||||
def test_get_paginated_timeout_page2_returns_partial(self, mock_sleep):
|
||||
"""Timeout on page 2 returns partial data from page 1."""
|
||||
client = self._make_client()
|
||||
|
||||
page1 = [{"id": i} for i in range(50)] # Full page -> triggers page 2
|
||||
|
||||
mock_resp1 = MagicMock()
|
||||
mock_resp1.raise_for_status = MagicMock()
|
||||
mock_resp1.json.return_value = page1
|
||||
|
||||
# Page 2: _get_with_retry exhausts retries and raises ReadTimeout
|
||||
with patch.object(
|
||||
client,
|
||||
"_get_with_retry",
|
||||
side_effect=[mock_resp1, requests.exceptions.ReadTimeout("timeout page 2")],
|
||||
):
|
||||
result = client._get_paginated("/api/v1/user/repos")
|
||||
|
||||
assert result == page1
|
||||
|
||||
@patch("time.sleep")
|
||||
def test_get_paginated_timeout_page1_raises(self, mock_sleep):
|
||||
"""Timeout on page 1 raises the exception (no partial data possible)."""
|
||||
client = self._make_client()
|
||||
|
||||
with patch.object(
|
||||
client,
|
||||
"_get_with_retry",
|
||||
side_effect=requests.exceptions.ReadTimeout("timeout page 1"),
|
||||
):
|
||||
with pytest.raises(requests.exceptions.ReadTimeout):
|
||||
client._get_paginated("/api/v1/user/repos")
|
||||
|
||||
@patch("time.sleep")
|
||||
def test_get_paginated_connect_timeout_graceful(self, mock_sleep):
|
||||
"""ConnectTimeout on page 2 returns partial data gracefully."""
|
||||
client = self._make_client()
|
||||
|
||||
page1 = [{"id": i} for i in range(50)]
|
||||
|
||||
mock_resp1 = MagicMock()
|
||||
mock_resp1.raise_for_status = MagicMock()
|
||||
mock_resp1.json.return_value = page1
|
||||
|
||||
with patch.object(
|
||||
client,
|
||||
"_get_with_retry",
|
||||
side_effect=[mock_resp1, requests.exceptions.ConnectTimeout("connect timeout")],
|
||||
):
|
||||
result = client._get_paginated("/api/v1/user/repos")
|
||||
|
||||
assert result == page1
|
||||
|
||||
@patch("time.sleep")
|
||||
def test_get_paginated_partial_data_emits_warning(self, mock_sleep):
|
||||
"""Graceful degradation emits a warning about partial data."""
|
||||
import warnings
|
||||
|
||||
client = self._make_client()
|
||||
|
||||
page1 = [{"id": i} for i in range(50)]
|
||||
|
||||
mock_resp1 = MagicMock()
|
||||
mock_resp1.raise_for_status = MagicMock()
|
||||
mock_resp1.json.return_value = page1
|
||||
|
||||
with patch.object(
|
||||
client,
|
||||
"_get_with_retry",
|
||||
side_effect=[mock_resp1, requests.exceptions.ReadTimeout("timeout")],
|
||||
):
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
client._get_paginated("/api/v1/user/repos")
|
||||
|
||||
assert len(w) == 1
|
||||
assert "Partial data" in str(w[0].message)
|
||||
assert "page 2" in str(w[0].message)
|
||||
|
||||
Reference in New Issue
Block a user