fix(test): test_ollama_failover_manager pipeline mock 對齊 atomic 修復
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:
Your Name
2026-04-26 20:52:11 +08:00
parent 862c4d8676
commit bddf99a002

View File

@@ -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 mockatomic 修復後)
原 GET/INCR/EXPIRE 三步已改為 pipeline.set(NX)+incrmock 跟著更新。
"""
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 mockSET NX 返回 True首次INCR 返回 501500+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 mockatomic 修復後)
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):