mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-02 03:55:55 +00:00
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).
135 lines
3.8 KiB
Python
135 lines
3.8 KiB
Python
"""
|
|
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()
|