mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-09 23:36:02 +00:00
test: add 105 new unit tests for untested core functionality
Add comprehensive tests for B-class issues (core functionality untested): Pipeline: - test_pool.py: QueryPool ID generation, caching, async context (12 tests) - test_ratelimit.py: Fixed timing-sensitive test tolerance - test_pipelinemgr.py: Use real Pydantic StageProcessResult instead of Mock Utils: - test_version.py: Version comparison functions (20 tests) - test_logcache.py: Log page management and retrieval (18 tests) - test_httpclient.py: HTTP session pool management (10 tests) - test_proxy.py: Proxy configuration from env and config (10 tests) - test_image.py: URL parsing and base64 extraction (12 tests) - test_pkgmgr.py: Pip command generation (8 tests) Discover: - test_engine.py: I18nString, Metadata, Component manifest (15 tests) Test count: 1193 → 1298 (+105 tests) Note: Some B-class issues cannot be tested due to circular import bugs filed as GitHub issues #2175 (pipeline) and #2176 (persistence).
This commit is contained in:
134
tests/unit_tests/utils/test_httpclient.py
Normal file
134
tests/unit_tests/utils/test_httpclient.py
Normal file
@@ -0,0 +1,134 @@
|
||||
"""
|
||||
Unit tests for HTTP client session pool.
|
||||
|
||||
Tests session management, reuse, and cleanup.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
import aiohttp
|
||||
|
||||
from langbot.pkg.utils import httpclient
|
||||
|
||||
|
||||
pytestmark = pytest.mark.asyncio
|
||||
|
||||
|
||||
class TestGetSession:
|
||||
"""Tests for get_session function."""
|
||||
|
||||
async def test_get_session_returns_client_session(self):
|
||||
"""get_session returns an aiohttp.ClientSession."""
|
||||
session = httpclient.get_session()
|
||||
|
||||
assert isinstance(session, aiohttp.ClientSession)
|
||||
assert not session.closed
|
||||
|
||||
# Cleanup
|
||||
await session.close()
|
||||
|
||||
async def test_get_session_returns_same_instance(self):
|
||||
"""get_session returns the same session for same trust_env."""
|
||||
session1 = httpclient.get_session(trust_env=False)
|
||||
session2 = httpclient.get_session(trust_env=False)
|
||||
|
||||
assert session1 is session2
|
||||
|
||||
# Cleanup
|
||||
await session1.close()
|
||||
|
||||
async def test_get_session_different_trust_env_creates_different(self):
|
||||
"""Different trust_env values create different sessions."""
|
||||
session1 = httpclient.get_session(trust_env=False)
|
||||
session2 = httpclient.get_session(trust_env=True)
|
||||
|
||||
assert session1 is not session2
|
||||
|
||||
# Cleanup
|
||||
await session1.close()
|
||||
await session2.close()
|
||||
|
||||
async def test_get_session_recreates_if_closed(self):
|
||||
"""get_session creates new session if previous is closed."""
|
||||
session1 = httpclient.get_session()
|
||||
await session1.close()
|
||||
|
||||
session2 = httpclient.get_session()
|
||||
|
||||
assert session2 is not session1
|
||||
assert not session2.closed
|
||||
|
||||
# Cleanup
|
||||
await session2.close()
|
||||
|
||||
|
||||
class TestCloseAll:
|
||||
"""Tests for close_all function."""
|
||||
|
||||
async def test_close_all_closes_all_sessions(self):
|
||||
"""close_all closes all sessions."""
|
||||
# Create multiple sessions
|
||||
session1 = httpclient.get_session(trust_env=False)
|
||||
session2 = httpclient.get_session(trust_env=True)
|
||||
|
||||
await httpclient.close_all()
|
||||
|
||||
assert session1.closed
|
||||
assert session2.closed
|
||||
|
||||
async def test_close_all_clears_pool(self):
|
||||
"""close_all clears the session pool."""
|
||||
httpclient.get_session()
|
||||
httpclient.get_session(trust_env=True)
|
||||
|
||||
await httpclient.close_all()
|
||||
|
||||
assert len(httpclient._sessions) == 0
|
||||
|
||||
async def test_close_all_handles_already_closed(self):
|
||||
"""close_all handles already closed sessions gracefully."""
|
||||
session = httpclient.get_session()
|
||||
await session.close()
|
||||
|
||||
# Should not raise
|
||||
await httpclient.close_all()
|
||||
|
||||
async def test_close_all_idempotent(self):
|
||||
"""close_all can be called multiple times."""
|
||||
httpclient.get_session()
|
||||
|
||||
await httpclient.close_all()
|
||||
await httpclient.close_all() # Should not raise
|
||||
|
||||
assert len(httpclient._sessions) == 0
|
||||
|
||||
|
||||
class TestSessionPoolIntegration:
|
||||
"""Integration tests for session pool behavior."""
|
||||
|
||||
async def test_session_can_make_request(self):
|
||||
"""Session can be used for actual HTTP requests."""
|
||||
session = httpclient.get_session()
|
||||
|
||||
# Make a simple request (using httpbin or similar)
|
||||
# This is a basic smoke test
|
||||
try:
|
||||
async with session.get('https://httpbin.org/get', timeout=aiohttp.ClientTimeout(total=5)) as resp:
|
||||
assert resp.status == 200
|
||||
except Exception:
|
||||
# Network may be unavailable in CI, just verify session is usable
|
||||
pass
|
||||
|
||||
await httpclient.close_all()
|
||||
|
||||
async def test_multiple_requests_same_session(self):
|
||||
"""Multiple requests can use the same session."""
|
||||
session = httpclient.get_session()
|
||||
|
||||
# Both calls return the same session
|
||||
session2 = httpclient.get_session()
|
||||
|
||||
assert session is session2
|
||||
|
||||
await httpclient.close_all()
|
||||
Reference in New Issue
Block a user