litellm/tests/load_tests/test_linear_memory_growth.py
ryan-crabbe-berri e9d40a8f73 test: enforce F811 so a duplicate definition cannot silently replace the first
A name bound twice keeps only the second binding. In `tests/` that is nearly
always a repeated import, harmless but misleading, and the same rule is what
catches the cases that are not harmless: a local that shadows an import the
module still calls, and a second `def test_x` that quietly replaces the first.

311 of the 344 sites were repeated imports and came out with ruff's own fix.
The remaining 33 needed a decision. Four modules imported a name they never
used because a local definition below already shadowed it. Two comprehensions
bound `call` over `unittest.mock.call`, which those modules import and use.
One test rebound the two module handles its nested reload closure had captured.
One class attribute shadowed an unused `status` import.

The load-test fixtures move to a conftest, which is how pytest is meant to share
them, so the test module no longer imports three fixture names it never calls.
The nine `prisma_client` parameters keep a narrow `noqa`: pytest resolves that
fixture by name before the body runs, so the parameter never shadows anything.
2026-08-21 12:06:19 -07:00

115 lines
5.1 KiB
Python

"""
Memory Leak Detection Tests - Linear Memory Growth
Tests that check for linear/progressive memory growth by running different numbers
of requests (1k, 2k, 4k, 10k, 30k) with the same memory limit. If lower request
count tests pass but higher ones fail, it indicates linear memory growth per request.
These tests will fail if memory leaks are detected, helping catch OOM issues before production.
IMPORTANT: These tests should be run INDIVIDUALLY, not all together. Running them
together causes memory baseline drift between tests, making it difficult to detect
linear growth accurately. Each test should be run in isolation:
pytest tests/load_tests/test_linear_memory_growth.py::test_memory_baseline_1k -v
pytest tests/load_tests/test_linear_memory_growth.py::test_memory_baseline_2k -v
# etc.
NOTE: Not recommended for accurate results:
pytest tests/load_tests/test_linear_memory_growth.py -v
"""
import pytest
from tests.load_tests.memory_leak_utils import run_memory_baseline_test
# Memory limit for all linear memory growth tests
MEMORY_LIMIT = "40 MB"
@pytest.mark.asyncio
@pytest.mark.limit_leaks(MEMORY_LIMIT)
@pytest.mark.no_parallel # Must run sequentially - measures process memory
async def test_memory_baseline_1k(test_router, limit_memory):
"""
Memory baseline test with 1,000 requests.
Uses @pytest.mark.limit_leaks("40 MB") to enforce memory limit.
If this passes but higher request count tests fail, indicates progressive memory leak.
NOTE: This test should be run INDIVIDUALLY, not with other tests in this file.
Running multiple tests together causes memory baseline drift, making it difficult
to accurately detect linear memory growth. Run with:
pytest tests/load_tests/test_linear_memory_growth.py::test_memory_baseline_1k -v
"""
await run_memory_baseline_test(1000, test_router, limit_memory)
@pytest.mark.asyncio
@pytest.mark.limit_leaks(MEMORY_LIMIT)
@pytest.mark.no_parallel # Must run sequentially - measures process memory
async def test_memory_baseline_2k(test_router, limit_memory):
"""
Memory baseline test with 2,000 requests.
Uses @pytest.mark.limit_leaks("40 MB") to enforce memory limit.
If this passes but test_memory_baseline_4k fails, indicates progressive memory leak.
NOTE: This test should be run INDIVIDUALLY, not with other tests in this file.
Running multiple tests together causes memory baseline drift, making it difficult
to accurately detect linear memory growth. Run with:
pytest tests/load_tests/test_linear_memory_growth.py::test_memory_baseline_2k -v
"""
await run_memory_baseline_test(2000, test_router, limit_memory)
@pytest.mark.asyncio
@pytest.mark.limit_leaks(MEMORY_LIMIT)
@pytest.mark.no_parallel # Must run sequentially - measures process memory
async def test_memory_baseline_4k(test_router, limit_memory):
"""
Memory baseline test with 4,000 requests.
Uses @pytest.mark.limit_leaks("40 MB") to enforce memory limit.
If test_memory_baseline_1k and test_memory_baseline_2k pass but this fails,
it's a clear sign of sequential/progressive memory growth.
NOTE: This test should be run INDIVIDUALLY, not with other tests in this file.
Running multiple tests together causes memory baseline drift, making it difficult
to accurately detect linear memory growth. Run with:
pytest tests/load_tests/test_linear_memory_growth.py::test_memory_baseline_4k -v
"""
await run_memory_baseline_test(4000, test_router, limit_memory)
@pytest.mark.asyncio
@pytest.mark.limit_leaks(MEMORY_LIMIT)
@pytest.mark.no_parallel # Must run sequentially - measures process memory
async def test_memory_baseline_10k(test_router, limit_memory):
"""
Memory baseline test with 10,000 requests.
Uses @pytest.mark.limit_leaks("40 MB") to enforce memory limit.
If test_memory_baseline_1k and test_memory_baseline_2k pass but this fails,
it's a clear sign of sequential/progressive memory growth.
NOTE: This test should be run INDIVIDUALLY, not with other tests in this file.
Running multiple tests together causes memory baseline drift, making it difficult
to accurately detect linear memory growth. Run with:
pytest tests/load_tests/test_linear_memory_growth.py::test_memory_baseline_10k -v
"""
await run_memory_baseline_test(10000, test_router, limit_memory)
@pytest.mark.asyncio
@pytest.mark.limit_leaks(MEMORY_LIMIT)
@pytest.mark.no_parallel # Must run sequentially - measures process memory
async def test_memory_baseline_30k(test_router, limit_memory):
"""
Memory baseline test with 30,000 requests.
Uses @pytest.mark.limit_leaks("40 MB") to enforce memory limit.
If test_memory_baseline_1k and test_memory_baseline_2k pass but this fails,
it's a clear sign of sequential/progressive memory growth.
NOTE: This test should be run INDIVIDUALLY, not with other tests in this file.
Running multiple tests together causes memory baseline drift, making it difficult
to accurately detect linear memory growth. Run with:
pytest tests/load_tests/test_linear_memory_growth.py::test_memory_baseline_30k -v
"""
await run_memory_baseline_test(30000, test_router, limit_memory)