refactor: close transactional boundary debt batch

This commit is contained in:
jxxghp
2026-08-28 10:36:12 +08:00
parent 3f8d5990e7
commit aa8751f775
105 changed files with 6507 additions and 1691 deletions
+110 -1
View File
@@ -2,6 +2,7 @@ import asyncio
import os
import threading
import time
from concurrent.futures import ThreadPoolExecutor
from types import SimpleNamespace
from unittest.mock import AsyncMock
@@ -13,15 +14,17 @@ from app.adapters.cache.backends import (
FileBackend,
RedisBackend,
)
from app.adapters.cache.redis import AsyncRedisHelper, RedisHelper, serialize
from app.runtime.cache import (
AsyncFileCache,
AsyncMemoryBackend,
FileCache,
MemoryBackend,
TTLCache,
cached,
)
from app.runtime.config import settings
from app.adapters.cache.redis import AsyncRedisHelper, RedisHelper, serialize
def test_file_backend_items_keep_relative_keys_and_bytes(tmp_path):
"""
@@ -720,6 +723,112 @@ def test_redis_helper_pop_uses_atomic_getdel():
assert calls == ["region:passkey_challenge:key:token"]
def test_redis_helper_strict_consume_propagates_backend_failure():
"""严格领取必须区分 Redis 故障与键不存在,旧 pop 仍保持兼容返回值。"""
class FailingClient:
"""模拟 GETDEL 连接故障。"""
def getdel(self, _key):
"""报告 Redis 命令失败。"""
raise ConnectionError("redis unavailable")
helper = RedisHelper()
helper.client = FailingClient()
try:
with pytest.raises(ConnectionError, match="redis unavailable"):
helper.consume("token", region="passkey_challenge")
assert helper.pop("token", region="passkey_challenge") is None
finally:
helper.client = None
def test_redis_helper_strict_store_requires_backend_acknowledgement():
"""严格写入不得把 Redis 未确认写入当成成功签发。"""
class RejectingClient:
"""模拟 Redis 拒绝确认 SET。"""
def set(self, *_args, **_kwargs):
"""返回未写入状态。"""
return False
helper = RedisHelper()
helper.client = RejectingClient()
try:
with pytest.raises(RuntimeError, match="not acknowledged"):
helper.store("token", "challenge", region="passkey_challenge")
helper.set("token", "challenge", region="passkey_challenge")
finally:
helper.client = None
def test_memory_atomic_cache_consume_has_single_winner_and_honors_ttl():
"""内存原子缓存与 Redis 一样只允许一次领取并服从 TTL。"""
cache = MemoryBackend(ttl=60)
region = "atomic_memory_contract"
cache.clear(region=region)
cache.store("token", "challenge", region=region)
with ThreadPoolExecutor(max_workers=8) as executor:
results = list(executor.map(
lambda _: cache.consume("token", region=region),
range(8),
))
assert results.count("challenge") == 1
assert results.count(None) == 7
cache.store("expired", "challenge", ttl=0, region=region)
assert cache.consume("expired", region=region) is None
def test_ttl_cache_legacy_pop_uses_atomic_consume_contract():
"""插件既有 TTLCache.pop 入口保持可用并获得原子领取语义。"""
cache = TTLCache(region="legacy_atomic_pop", maxsize=8, ttl=60)
cache.clear()
cache.set("token", "challenge")
def pop_token(_index):
"""兼容入口不存在时返回空值,便于汇总并发结果。"""
try:
return cache.pop("token")
except KeyError:
return None
with ThreadPoolExecutor(max_workers=8) as executor:
results = list(executor.map(pop_token, range(8)))
assert results.count("challenge") == 1
assert results.count(None) == 7
def test_redis_backend_strict_store_and_consume_use_atomic_helper():
"""Redis 适配器将严格缓存契约完整委托给底层原子实现。"""
calls = []
class FakeHelper:
"""记录严格 Redis 缓存调用。"""
def store(self, key, value, ttl=None, region=None, **kwargs):
"""记录严格写入。"""
calls.append(("store", key, value, ttl, region, kwargs))
def consume(self, key, region=None):
"""记录原子领取。"""
calls.append(("consume", key, region))
return "challenge"
backend = RedisBackend(ttl=60)
backend.redis_helper = FakeHelper()
backend.store("token", "challenge", region="passkey_challenge")
assert backend.consume("token", region="passkey_challenge") == "challenge"
assert calls == [
("store", "token", "challenge", 60, "passkey_challenge", {}),
("consume", "token", "passkey_challenge"),
]
def test_async_redis_helper_uses_blocking_pool_settings(monkeypatch):
"""
Redis 异步客户端应使用阻塞连接池,避免高并发缓存读取立刻抛出连接耗尽错误。