fix(test): test_ollama_failover_manager pipeline mock 對齊 atomic 修復
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
Wave5 B3-fix(commit 02362edd)改 _check_gemini_quota 用 redis.pipeline() 原測試 mock redis.incr.assert_awaited_once 失敗,因 incr 改在 pipeline 內。 修法(Engineer-A4 已同步寫好): - mock_pipe.set / incr 返回 mock_pipe(chain) - mock_pipe.execute 返回 [True, count] list - assertion 改 mock_pipe.execute.assert_awaited_once Tests: 37/37 PASSED Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-Authored-By: Engineer-A4 <noreply@anthropic.com>
This commit is contained in:
@@ -610,40 +610,49 @@ class TestGeminiQuota:
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_gemini_quota_under_limit(self):
|
||||
"""count=500 < quota=1000 → 返回 True(允許走 Gemini)"""
|
||||
"""count=500 < quota=1000 → 返回 True(允許走 Gemini)
|
||||
2026-04-26 Wave5 B3-fix by Claude Engineer-A4 — 改用 pipeline mock(atomic 修復後)
|
||||
原 GET/INCR/EXPIRE 三步已改為 pipeline.set(NX)+incr,mock 跟著更新。
|
||||
"""
|
||||
manager = _make_manager()
|
||||
manager._settings.GEMINI_DAILY_QUOTA = 1000
|
||||
|
||||
mock_redis = AsyncMock()
|
||||
mock_redis.get = AsyncMock(return_value=b"500")
|
||||
mock_redis.incr = AsyncMock(return_value=501)
|
||||
mock_redis.expire = AsyncMock()
|
||||
# pipeline mock:SET NX 返回 True(首次),INCR 返回 501(500+1,未達 quota=1000)
|
||||
mock_pipe = MagicMock()
|
||||
mock_pipe.set = MagicMock(return_value=mock_pipe)
|
||||
mock_pipe.incr = MagicMock(return_value=mock_pipe)
|
||||
mock_pipe.execute = AsyncMock(return_value=[True, 501])
|
||||
|
||||
mock_redis = MagicMock()
|
||||
mock_redis.pipeline = MagicMock(return_value=mock_pipe)
|
||||
|
||||
# lazy import patch:_check_gemini_quota 內用 `from src.core.redis_client import get_redis`
|
||||
with patch("src.core.redis_client.get_redis", return_value=mock_redis):
|
||||
ok = await manager._check_gemini_quota()
|
||||
|
||||
assert ok is True
|
||||
mock_redis.incr.assert_awaited_once()
|
||||
mock_redis.expire.assert_awaited_once()
|
||||
mock_pipe.execute.assert_awaited_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_gemini_quota_exactly_at_limit(self):
|
||||
"""count=1000 >= quota=1000 → 返回 False(熔斷,不再呼叫 Gemini)"""
|
||||
"""count=1001 > quota=1000 → 返回 False(熔斷,不再呼叫 Gemini)
|
||||
2026-04-26 Wave5 B3-fix by Claude Engineer-A4 — 改用 pipeline mock(atomic 修復後)
|
||||
pipeline.incr 返回 1001(> quota=1000),應返回 False。
|
||||
"""
|
||||
manager = _make_manager()
|
||||
manager._settings.GEMINI_DAILY_QUOTA = 1000
|
||||
|
||||
mock_redis = AsyncMock()
|
||||
mock_redis.get = AsyncMock(return_value=b"1000")
|
||||
mock_redis.incr = AsyncMock()
|
||||
mock_redis.expire = AsyncMock()
|
||||
mock_pipe = MagicMock()
|
||||
mock_pipe.set = MagicMock(return_value=mock_pipe)
|
||||
mock_pipe.incr = MagicMock(return_value=mock_pipe)
|
||||
mock_pipe.execute = AsyncMock(return_value=[True, 1001]) # 超過 quota
|
||||
|
||||
mock_redis = MagicMock()
|
||||
mock_redis.pipeline = MagicMock(return_value=mock_pipe)
|
||||
|
||||
with patch("src.core.redis_client.get_redis", return_value=mock_redis):
|
||||
ok = await manager._check_gemini_quota()
|
||||
|
||||
assert ok is False
|
||||
# 超過配額不應再 incr
|
||||
mock_redis.incr.assert_not_awaited()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_gemini_quota_redis_unavailable_fail_open(self):
|
||||
|
||||
Reference in New Issue
Block a user