99 lines
3.8 KiB
Python
99 lines
3.8 KiB
Python
"""验证 _expire_unreachable_pending 的快速放弃逻辑。
|
|
|
|
覆盖场景:
|
|
1. 有 staged_reply_text 的任务:失败 >=3 次即放弃(阈值 3)
|
|
2. 有 staged_reply_text 的任务:失败 <3 次保留
|
|
3. 无 staged_reply_text 的任务:失败 <8 次保留(原阈值 8)
|
|
4. 无 staged_reply_text 的任务:失败 >=8 次放弃
|
|
5. 放弃后任务从队列移除(_clear_reply_pending 被调用)
|
|
6. 放弃后不落档(_commit_staged_exchange 不被调用)
|
|
"""
|
|
import os
|
|
import sys
|
|
import time
|
|
from unittest import mock
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + "/..")
|
|
|
|
from wechat_bot import WeChatBot # noqa: E402
|
|
|
|
|
|
def make_bot():
|
|
bot = WeChatBot.__new__(WeChatBot)
|
|
bot._pending_lock = None
|
|
bot._pending_reply_sessions = {}
|
|
bot._pending_reply_path = ""
|
|
bot._pending_scan_progress = {}
|
|
bot._pending_exchanges = {}
|
|
bot._cancelled_reply_sessions = set()
|
|
bot._unrepliable_sessions = {}
|
|
bot._uncertain_tracking = {}
|
|
bot._last_send_receipt_visible_text = ""
|
|
bot._reset_pending_batch = lambda fp: None
|
|
bot._forget_uncertain_tracking = lambda fp: None
|
|
bot._persist_pending_replies = lambda: None
|
|
bot._persist_unrepliable_sessions = lambda: None
|
|
bot.store = mock.MagicMock()
|
|
bot.remember_exchange = mock.MagicMock()
|
|
bot._commit_staged_exchange = mock.MagicMock()
|
|
return bot
|
|
|
|
|
|
def run():
|
|
passed = 0
|
|
|
|
def check(name, cond):
|
|
nonlocal passed
|
|
if cond:
|
|
passed += 1
|
|
print(f" [PASS] {name}")
|
|
else:
|
|
print(f" [FAIL] {name}")
|
|
|
|
print("== 有 AI 回复的任务快速放弃 ==")
|
|
bot = make_bot()
|
|
fp = bytes.fromhex("a1" * 20)
|
|
# 失败 2 次 + 有回复 → 保留
|
|
state = {"resume_failures": 2, "staged_reply_text": "在呢,有什么事你慢慢说"}
|
|
bot._pending_reply_sessions[fp.hex()] = state
|
|
r = bot._expire_unreachable_pending(fp, state)
|
|
check("staged 回复失败2次 → 保留", r is False and fp.hex() in bot._pending_reply_sessions)
|
|
# 失败 3 次 + 有回复 → 放弃
|
|
state["resume_failures"] = 3
|
|
r = bot._expire_unreachable_pending(fp, state)
|
|
check("staged 回复失败3次 → 放弃", r is True and fp.hex() not in bot._pending_reply_sessions)
|
|
check("放弃时不落档(回复未发出)", bot._commit_staged_exchange.call_count == 0)
|
|
|
|
print("== 纯定位任务保持原阈值 8 ==")
|
|
bot = make_bot()
|
|
fp2 = bytes.fromhex("b2" * 20)
|
|
state2 = {"resume_failures": 7} # 无 staged_reply_text
|
|
bot._pending_reply_sessions[fp2.hex()] = state2
|
|
r = bot._expire_unreachable_pending(fp2, state2)
|
|
check("无回复失败7次 → 保留", r is False and fp2.hex() in bot._pending_reply_sessions)
|
|
state2["resume_failures"] = 8
|
|
r = bot._expire_unreachable_pending(fp2, state2)
|
|
check("无回复失败8次 → 放弃", r is True and fp2.hex() not in bot._pending_reply_sessions)
|
|
|
|
print("== 边界与异常 ==")
|
|
bot = make_bot()
|
|
fp3 = bytes.fromhex("c3" * 20)
|
|
state3 = {"resume_failures": "invalid", "staged_reply_text": " "}
|
|
bot._pending_reply_sessions[fp3.hex()] = state3
|
|
r = bot._expire_unreachable_pending(fp3, state3)
|
|
check("非法 failures 且空回复 → 按0处理保留", r is False and fp3.hex() in bot._pending_reply_sessions)
|
|
bot = make_bot()
|
|
fp4 = bytes.fromhex("d4" * 20)
|
|
state4 = {"resume_failures": 3, "staged_reply_text": " ", "reply_text": "x"}
|
|
bot._pending_reply_sessions[fp4.hex()] = state4
|
|
r = bot._expire_unreachable_pending(fp4, state4)
|
|
check("空白 staged 回复按纯定位处理(3次保留)", r is False and fp4.hex() in bot._pending_reply_sessions)
|
|
|
|
print(f"\n结果: {passed}/7 通过")
|
|
return passed == 7
|
|
|
|
|
|
if __name__ == "__main__":
|
|
ok = run()
|
|
sys.exit(0 if ok else 1)
|