gengx
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
"""端到端验证任务池闭环:投递 → 发送完成移除 → 新消息重新投递。
|
||||
|
||||
覆盖用户核心诉求:
|
||||
1. AI 回复成功(sent)后任务从队列移除
|
||||
2. 对方发新消息 = 新 dedup_key → 重新投递新任务(不被 _recently 防抖挡住)
|
||||
3. 同一消息不会被重复投递(防抖生效)
|
||||
4. has_active_pending 对已移除任务返回 False → 允许新投递
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + "/..")
|
||||
|
||||
from engine_b import DataEngine # noqa: E402
|
||||
|
||||
|
||||
class FakeBot:
|
||||
"""最小化 bot 桩:记录投递、模拟任务完成移除。"""
|
||||
|
||||
def __init__(self):
|
||||
self.pending = {} # fp_hex -> state
|
||||
self.enqueued = []
|
||||
self.removed = []
|
||||
|
||||
def has_active_pending(self, fp_hex):
|
||||
state = self.pending.get(fp_hex)
|
||||
if state is None:
|
||||
return False
|
||||
return str(state.get("stage") or "") not in {
|
||||
"sent", "cancelled", "expired", "cleared",
|
||||
}
|
||||
|
||||
def enqueue_detected(self, fp_hex, dedup_key="", detected_by="engine_b",
|
||||
chat_text="", display_name="", last_lines=None):
|
||||
if fp_hex in self.pending and self.has_active_pending(fp_hex):
|
||||
return False, "已有活跃任务"
|
||||
self.pending[fp_hex] = {
|
||||
"stage": "queued",
|
||||
"dedup_key": dedup_key,
|
||||
"chat_text": chat_text,
|
||||
"display_name": display_name,
|
||||
}
|
||||
self.enqueued.append({
|
||||
"fp_hex": fp_hex, "dedup_key": dedup_key,
|
||||
"chat_text": chat_text, "display_name": display_name,
|
||||
})
|
||||
return True, "ok"
|
||||
|
||||
def mark_sent_and_remove(self, fp_hex):
|
||||
"""模拟发送成功 → 任务移除。"""
|
||||
self.pending.pop(fp_hex, None)
|
||||
self.removed.append(fp_hex)
|
||||
|
||||
|
||||
def run():
|
||||
passed = 0
|
||||
|
||||
def check(name, cond):
|
||||
nonlocal passed
|
||||
if cond:
|
||||
passed += 1
|
||||
print(f" [PASS] {name}")
|
||||
else:
|
||||
print(f" [FAIL] {name}")
|
||||
|
||||
bot = FakeBot()
|
||||
eng = DataEngine.__new__(DataEngine)
|
||||
eng.bot = bot
|
||||
eng._recently = {}
|
||||
eng.processed_count = 0
|
||||
eng.enqueued_count = 0
|
||||
eng.last_error = ""
|
||||
|
||||
fp = "ab" * 40 # 80 hex chars
|
||||
now = int(time.time())
|
||||
|
||||
print("== 场景1:新消息投递 ==")
|
||||
entry1 = {
|
||||
"display_name": "测试客户",
|
||||
"history": [{"content": "第一条", "ts": now - 300}],
|
||||
}
|
||||
last_user = entry1["history"][-1]
|
||||
eng._maybe_enqueue(fp, entry1, last_user)
|
||||
check("消息1 投递成功", len(bot.enqueued) == 1 and bot.enqueued[0]["chat_text"] == "第一条")
|
||||
check("任务已入队", bot.pending.get(fp, {}).get("stage") == "queued")
|
||||
|
||||
print("== 场景2:同一消息重复轮询不重复投递(防抖) ==")
|
||||
eng._maybe_enqueue(fp, entry1, last_user)
|
||||
check("同 dedup_key 300s 内不重复投递", len(bot.enqueued) == 1)
|
||||
|
||||
print("== 场景3:AI 回复成功 → 任务移除 ==")
|
||||
bot.mark_sent_and_remove(fp)
|
||||
check("发送成功任务被移除", fp not in bot.pending and fp in bot.removed)
|
||||
check("has_active_pending 返回 False", bot.has_active_pending(fp) is False)
|
||||
|
||||
print("== 场景4:对方发新消息 → 重新投递新任务 ==")
|
||||
entry2 = {
|
||||
"display_name": "测试客户",
|
||||
"history": [
|
||||
{"content": "第一条", "ts": now - 300},
|
||||
{"content": "在吗", "ts": now - 60},
|
||||
],
|
||||
}
|
||||
last_user2 = entry2["history"][-1]
|
||||
eng._maybe_enqueue(fp, entry2, last_user2)
|
||||
check("新消息(新时间戳)重新投递", len(bot.enqueued) == 2)
|
||||
check("新任务入队", bot.pending.get(fp, {}).get("chat_text") == "在吗")
|
||||
check("新 dedup_key 不同", bot.enqueued[0]["dedup_key"] != bot.enqueued[1]["dedup_key"])
|
||||
|
||||
print("== 场景5:消息B在防抖窗口内第二次轮询不重复 ==")
|
||||
eng._maybe_enqueue(fp, entry2, last_user2)
|
||||
check("消息2 防抖生效", len(bot.enqueued) == 2)
|
||||
|
||||
print("== 场景6:队列已有活跃任务时引擎B只补标记不重复投递 ==")
|
||||
# 场景4 后任务已入队(活跃),此时再检测到同一条消息不应重复投递
|
||||
bot.enqueued_count_before = len(bot.enqueued)
|
||||
eng._maybe_enqueue(fp, entry2, last_user2)
|
||||
check("活跃任务存在时不重复投递", len(bot.enqueued) == 2)
|
||||
|
||||
print(f"\n结果: {passed}/10 通过")
|
||||
return passed == 10
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ok = run()
|
||||
sys.exit(0 if ok else 1)
|
||||
Reference in New Issue
Block a user