test_timeout.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. """Tests du délai maximal d'attente (API_TIMEOUT). Lancer depuis la racine du projet : python -m unittest"""
  2. import asyncio
  3. import unittest
  4. from types import SimpleNamespace
  5. from unittest import mock
  6. import anthropic
  7. from bot.claude_client import ClaudeClient, ClaudeError
  8. def fake_client(create) -> ClaudeClient:
  9. # Sans __init__ : pas de client Anthropic à créer.
  10. client = ClaudeClient.__new__(ClaudeClient)
  11. client.settings = SimpleNamespace(api_timeout=0.2)
  12. client._client = SimpleNamespace(messages=SimpleNamespace(create=create))
  13. return client
  14. class TimeoutTest(unittest.IsolatedAsyncioTestCase):
  15. async def test_total_wait_is_capped(self):
  16. # Le SDK relancerait la requête après chaque délai dépassé : l'attente totale reste bornée.
  17. async def slow(**_):
  18. await asyncio.sleep(10)
  19. client = fake_client(slow)
  20. loop = asyncio.get_running_loop()
  21. start = loop.time()
  22. with self.assertLogs("chatbot.claude", "WARNING"), self.assertRaises(ClaudeError) as ctx:
  23. await client._call({})
  24. self.assertLess(loop.time() - start, 2)
  25. self.assertIn("trop de temps", ctx.exception.user_message)
  26. async def test_sdk_timeout_same_message(self):
  27. create = mock.AsyncMock(side_effect=anthropic.APITimeoutError(request=mock.Mock()))
  28. with self.assertLogs("chatbot.claude", "WARNING"), self.assertRaises(ClaudeError) as ctx:
  29. await fake_client(create)._call({})
  30. self.assertIn("trop de temps", ctx.exception.user_message)
  31. async def test_fast_answer_returned(self):
  32. create = mock.AsyncMock(return_value="réponse")
  33. self.assertEqual(await fake_client(create)._call({}), "réponse")
  34. if __name__ == "__main__":
  35. unittest.main()