Final_Assignment_Template / tests /test_scoring_client.py
yc1838
GAIA_DATASET_SPLIT=validation
4787daf
Raw
History Blame Contribute Delete
7.55 kB
from __future__ import annotations
import os
import tempfile
import unittest
from pathlib import Path
from unittest.mock import Mock, patch
import requests
from lilith_agent.scoring_client import ScoringApiClient
class ScoringApiClientTests(unittest.TestCase):
def test_get_questions_returns_api_payload_on_success(self) -> None:
response = Mock()
response.json.return_value = [{"task_id": "t1", "question": "Q"}]
response.raise_for_status.return_value = None
session = Mock()
session.get.return_value = response
client = ScoringApiClient(api_url="https://example.com", session=session)
payload = client.get_questions()
self.assertEqual(payload, [{"task_id": "t1", "question": "Q"}])
self.assertIsNone(client.last_warning)
session.get.assert_called_once_with("https://example.com/questions", timeout=30)
def test_get_questions_falls_back_to_dataset_on_429(self) -> None:
response = Mock(status_code=429, headers={})
error = requests.HTTPError("Too Many Requests", response=response)
response.raise_for_status.side_effect = error
session = Mock()
session.get.return_value = response
dataset_client = Mock()
dataset_client.get_questions.return_value = [{"task_id": "fallback", "question": "Q2"}]
client = ScoringApiClient(
api_url="https://example.com",
session=session,
dataset_client=dataset_client,
)
payload = client.get_questions()
self.assertEqual(payload, [{"task_id": "fallback", "question": "Q2"}])
self.assertIn("429", client.last_warning or "")
dataset_client.get_questions.assert_called_once_with()
def test_fallback_prints_hf_visible_warning(self) -> None:
response = Mock(status_code=503, headers={})
error = requests.HTTPError("Service Unavailable", response=response)
response.raise_for_status.side_effect = error
session = Mock()
session.get.return_value = response
dataset_client = Mock()
dataset_client.get_questions.return_value = []
client = ScoringApiClient(
api_url="https://example.com",
session=session,
dataset_client=dataset_client,
)
with patch("builtins.print") as printed:
client.get_questions()
printed.assert_any_call(
"Scoring API unavailable while trying to fetch questions (status=503); falling back to GAIA dataset.",
flush=True,
)
def test_download_file_falls_back_to_dataset_on_429(self) -> None:
response = Mock(status_code=429, headers={})
error = requests.HTTPError("Too Many Requests", response=response)
response.raise_for_status.side_effect = error
session = Mock()
session.get.return_value = response
dataset_client = Mock()
with tempfile.TemporaryDirectory() as tmpdir:
fallback_path = Path(tmpdir) / "from-dataset.txt"
fallback_path.write_text("ok")
dataset_client.download_file.return_value = fallback_path
client = ScoringApiClient(
api_url="https://example.com",
session=session,
dataset_client=dataset_client,
)
payload = client.download_file("task-123", tmpdir)
self.assertEqual(payload, fallback_path)
self.assertIn("429", client.last_warning or "")
dataset_client.download_file.assert_called_once_with("task-123", Path(tmpdir))
def test_download_file_falls_back_to_dataset_on_404(self) -> None:
response = Mock(status_code=404, headers={})
error = requests.HTTPError("Not Found", response=response)
response.raise_for_status.side_effect = error
session = Mock()
session.get.return_value = response
dataset_client = Mock()
with tempfile.TemporaryDirectory() as tmpdir:
fallback_path = Path(tmpdir) / "from-dataset.png"
fallback_path.write_bytes(b"image-bytes")
dataset_client.download_file.return_value = fallback_path
client = ScoringApiClient(
api_url="https://example.com",
session=session,
dataset_client=dataset_client,
)
with patch("builtins.print") as printed:
payload = client.download_file("task-404", tmpdir)
self.assertEqual(payload, fallback_path)
self.assertIn("404", client.last_warning or "")
dataset_client.download_file.assert_called_once_with("task-404", Path(tmpdir))
printed.assert_any_call(
"Scoring API unavailable while trying to download file for task-404 (status=404); falling back to GAIA dataset.",
flush=True,
)
def test_download_file_falls_back_when_api_returns_tiny_json_payload(self) -> None:
response = Mock(status_code=200, headers={"content-type": "application/json"})
response.content = b'{"detail":"file not found"}'
response.raise_for_status.return_value = None
session = Mock()
session.get.return_value = response
dataset_client = Mock()
with tempfile.TemporaryDirectory() as tmpdir:
fallback_path = Path(tmpdir) / "from-dataset.png"
fallback_path.write_bytes(b"image-bytes")
dataset_client.download_file.return_value = fallback_path
client = ScoringApiClient(
api_url="https://example.com",
session=session,
dataset_client=dataset_client,
)
with patch("builtins.print") as printed:
payload = client.download_file("task-json", tmpdir)
self.assertEqual(payload, fallback_path)
dataset_client.download_file.assert_called_once_with("task-json", Path(tmpdir))
printed.assert_any_call(
"[scoring] invalid file payload task=task-json status=200 bytes=27 content_type='application/json'; trying dataset fallback",
flush=True,
)
def test_default_dataset_client_is_built_lazily(self) -> None:
session = Mock()
response = Mock(status_code=429, headers={})
error = requests.HTTPError("Too Many Requests", response=response)
response.raise_for_status.side_effect = error
session.get.return_value = response
dataset_instance = Mock()
dataset_instance.get_questions.return_value = []
with patch.object(ScoringApiClient, "_get_dataset_client", return_value=dataset_instance) as getter:
client = ScoringApiClient(api_url="https://example.com", session=session)
client.get_questions()
getter.assert_called_once_with()
def test_default_dataset_client_uses_validation_split(self) -> None:
dataset_instance = Mock()
with patch.dict(os.environ, {}, clear=True), patch(
"lilith_agent.gaia_dataset.GaiaDatasetClient",
return_value=dataset_instance,
) as dataset_client:
client = ScoringApiClient(api_url="https://example.com", session=Mock())
payload = client._get_dataset_client()
self.assertIs(payload, dataset_instance)
dataset_client.assert_called_once_with(
config="2023_all",
split="validation",
level=None,
token=None,
)
if __name__ == "__main__":
unittest.main()