fixed tests

This commit is contained in:
2026-05-15 20:41:05 +02:00
parent 96ce516ecf
commit 77df5d5d65
50 changed files with 1482 additions and 5089 deletions

View File

@@ -209,9 +209,7 @@ class TestLookupCaching:
async def test_negative_result_stored_in_neg_cache(self, geo_cache: GeoCache) -> None:
"""A failed lookup is stored in the negative cache, so the second call is blocked."""
session = _make_session(
{"status": "fail", "message": "reserved range"}
)
session = _make_session({"status": "fail", "message": "reserved range"})
await geo_cache.lookup("192.168.1.1", session)
await geo_cache.lookup("192.168.1.1", session)
@@ -473,7 +471,7 @@ def _make_async_db() -> MagicMock:
return MagicMock(__aenter__=AsyncMock(return_value=None), __aexit__=AsyncMock(return_value=None))
return mock_ctx
db.execute = MagicMock(side_effect=fake_execute)
db.execute = AsyncMock(side_effect=fake_execute)
db.executemany = AsyncMock()
db.commit = AsyncMock()
db.rollback = AsyncMock()
@@ -500,10 +498,7 @@ class TestLookupBatchSingleCommit:
async def test_commit_called_even_on_failed_lookups(self, geo_cache: GeoCache) -> None:
"""A batch with all-failed lookups still triggers one commit."""
ips = ["10.0.0.1", "10.0.0.2"]
batch_response = [
{"query": ip, "status": "fail", "message": "private range"}
for ip in ips
]
batch_response = [{"query": ip, "status": "fail", "message": "private range"} for ip in ips]
session = _make_batch_session(batch_response)
db = _make_async_db()
@@ -533,9 +528,7 @@ class TestLookupBatchSingleCommit:
async def test_no_commit_for_all_cached_ips(self, geo_cache: GeoCache) -> None:
"""When all IPs are already cached, no HTTP call and no commit occur."""
geo_cache._cache["5.5.5.5"] = GeoInfo(
country_code="FR", country_name="France", asn="AS1", org="ISP"
)
geo_cache._cache["5.5.5.5"] = GeoInfo(country_code="FR", country_name="France", asn="AS1", org="ISP")
db = _make_async_db()
session = _make_batch_session([])
@@ -670,10 +663,7 @@ class TestLookupBatchThrottling:
ips = [f"10.0.{i // 256}.{i % 256}" for i in range(batch_size + 1)]
def _make_result(chunk: list[str], _session: object) -> dict[str, GeoInfo]:
return {
ip: GeoInfo(country_code="DE", country_name="Germany", asn=None, org=None)
for ip in chunk
}
return {ip: GeoInfo(country_code="DE", country_name="Germany", asn=None, org=None) for ip in chunk}
with (
patch.object(
@@ -778,7 +768,7 @@ class TestErrorLogging:
async def test_empty_message_exception_logs_exc_type(self, geo_cache: GeoCache) -> None:
"""When HTTP exception str() is empty, exc_type and repr are still logged."""
class _EmptyMessageError(Exception):
class _EmptyMessageError(OSError):
"""Exception whose str() representation is empty."""
def __str__(self) -> str:
@@ -792,9 +782,7 @@ class TestErrorLogging:
from tests.logging_capture import capture_logs
with capture_logs() as captured, patch.object(
geo_cache, "_geoip_reader", None
):
with capture_logs() as captured, patch.object(geo_cache, "_geoip_reader", None):
# Ensure MMDB is not available so HTTP is tried.
result = await geo_cache.lookup("197.221.98.153", session)
@@ -819,9 +807,7 @@ class TestErrorLogging:
from tests.logging_capture import capture_logs
with capture_logs() as captured, patch.object(
geo_cache, "_geoip_reader", None
):
with capture_logs() as captured, patch.object(geo_cache, "_geoip_reader", None):
# Ensure MMDB is not available so HTTP is tried.
await geo_cache.lookup("10.0.0.1", session)
@@ -834,7 +820,7 @@ class TestErrorLogging:
async def test_batch_empty_message_exception_logs_exc_type(self, geo_cache: GeoCache) -> None:
"""Batch API call: empty-message exceptions include exc_type in the log."""
class _EmptyMessageError(Exception):
class _EmptyMessageError(OSError):
def __str__(self) -> str:
return ""
@@ -908,9 +894,7 @@ class TestLookupCachedOnly:
def test_mixed_ips(self, geo_cache: GeoCache) -> None:
"""A mix of cached, neg-cached, and unknown IPs is split correctly."""
geo_cache._cache["1.2.3.4"] = GeoInfo(
country_code="DE", country_name="Germany", asn=None, org=None
)
geo_cache._cache["1.2.3.4"] = GeoInfo(country_code="DE", country_name="Germany", asn=None, org=None)
import time
geo_cache._neg_cache["5.5.5.5"] = time.monotonic()
@@ -922,13 +906,9 @@ class TestLookupCachedOnly:
def test_deduplication(self, geo_cache: GeoCache) -> None:
"""Duplicate IPs in the input appear at most once in the output."""
geo_cache._cache["1.2.3.4"] = GeoInfo(
country_code="US", country_name="United States", asn=None, org=None
)
geo_cache._cache["1.2.3.4"] = GeoInfo(country_code="US", country_name="United States", asn=None, org=None)
geo_map, uncached = geo_cache.lookup_cached_only(
["9.9.9.9", "9.9.9.9", "1.2.3.4", "1.2.3.4"]
)
geo_map, uncached = geo_cache.lookup_cached_only(["9.9.9.9", "9.9.9.9", "1.2.3.4", "1.2.3.4"])
assert len([ip for ip in geo_map if ip == "1.2.3.4"]) == 1
assert uncached.count("9.9.9.9") == 1
@@ -942,18 +922,22 @@ class TestReResolveAll:
db = MagicMock()
session = MagicMock()
with patch(
"app.repositories.geo_cache_repo.get_unresolved_ips",
AsyncMock(return_value=[]),
), patch.object(
geo_cache,
"lookup_batch",
AsyncMock(),
) as mock_lookup, patch.object(
geo_cache,
"clear_neg_cache",
AsyncMock(),
) as mock_clear:
with (
patch(
"app.repositories.geo_cache_repo.get_unresolved_ips",
AsyncMock(return_value=[]),
),
patch.object(
geo_cache,
"lookup_batch",
AsyncMock(),
) as mock_lookup,
patch.object(
geo_cache,
"clear_neg_cache",
AsyncMock(),
) as mock_clear,
):
result = await geo_cache.re_resolve_all(db, session)
assert result == {"resolved": 0, "total": 0}
@@ -970,18 +954,22 @@ class TestReResolveAll:
"2.2.2.2": GeoInfo(country_code=None, country_name=None, asn=None, org=None),
}
with patch(
"app.repositories.geo_cache_repo.get_unresolved_ips",
AsyncMock(return_value=ips),
), patch.object(
geo_cache,
"lookup_batch",
AsyncMock(return_value=geo_map),
) as mock_lookup, patch.object(
geo_cache,
"clear_neg_cache",
AsyncMock(),
) as mock_clear:
with (
patch(
"app.repositories.geo_cache_repo.get_unresolved_ips",
AsyncMock(return_value=ips),
),
patch.object(
geo_cache,
"lookup_batch",
AsyncMock(return_value=geo_map),
) as mock_lookup,
patch.object(
geo_cache,
"clear_neg_cache",
AsyncMock(),
) as mock_clear,
):
result = await geo_cache.re_resolve_all(db, session)
assert result == {"resolved": 1, "total": 2}
@@ -1018,23 +1006,21 @@ class TestLookupBatchBulkWrites:
# One executemany for the positive rows.
assert db.executemany.await_count >= 1
# High-level: execute() must NOT be called for the batch writes.
db.execute.assert_not_awaited()
# BEGIN IMMEDIATE is called for transaction wrapper.
assert db.execute.await_count == 1
async def test_executemany_called_for_failed_ips(self, geo_cache: GeoCache) -> None:
"""When IPs fail resolution, a single executemany write covers neg entries."""
ips = ["10.0.0.1", "10.0.0.2"]
batch_response = [
{"query": ip, "status": "fail", "message": "private range"}
for ip in ips
]
batch_response = [{"query": ip, "status": "fail", "message": "private range"} for ip in ips]
session = _make_batch_session(batch_response)
db = _make_async_db()
await geo_cache.lookup_batch(ips, session, db=db)
assert db.executemany.await_count >= 1
db.execute.assert_not_awaited()
# BEGIN IMMEDIATE is called for transaction wrapper.
assert db.execute.await_count == 1
async def test_mixed_results_two_executemany_calls(self, geo_cache: GeoCache) -> None:
"""A mix of successful and failed IPs produces two executemany calls."""
@@ -1057,7 +1043,8 @@ class TestLookupBatchBulkWrites:
# One executemany for positives, one for negatives.
assert db.executemany.await_count == 2
db.execute.assert_not_awaited()
# BEGIN IMMEDIATE is called for transaction wrapper.
assert db.execute.await_count == 1
# ---------------------------------------------------------------------------
@@ -1071,9 +1058,7 @@ class TestCacheMetrics:
async def test_cache_hit_increments_hits(self) -> None:
"""lookup() with a cached IP increments _hits."""
geo_cache = GeoCache(allow_http_fallback=True)
geo_cache._cache["1.1.1.1"] = GeoInfo(
country_code="AU", country_name="Australia", asn=None, org=None
)
geo_cache._cache["1.1.1.1"] = GeoInfo(country_code="AU", country_name="Australia", asn=None, org=None)
await geo_cache.lookup("1.1.1.1", MagicMock())
@@ -1269,4 +1254,3 @@ class TestLargeBanList:
assert len(result) == 1
assert "1.1.1.1" in result