95 lines
3.7 KiB
Python
95 lines
3.7 KiB
Python
"""offscreen 模式切换功能测试:DB 持久化 + 首条消息锁定 + worker 分派
|
|
运行: QT_QPA_PLATFORM=offscreen python tests/smoke_mode.py
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
|
|
os.environ.setdefault("HAOCODE_RENDER", "software")
|
|
os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--disable-gpu" # 绕过 AMD 核显 context lost
|
|
os.environ.setdefault("PYTHONIOENCODING", "utf-8")
|
|
|
|
# 铁律:测试不得污染真实 data/chat_history.db → DBManager 默认路径重定向到临时文件
|
|
import tempfile as _tf # noqa: E402
|
|
import core.db_manager as _dbm # noqa: E402
|
|
_dbm._DEFAULT_DB = os.path.join(_tf.gettempdir(), f"haocode_test_smoke_mode_{os.getpid()}.db")
|
|
|
|
from PyQt6.QtWidgets import QApplication # noqa: E402
|
|
from ui.views.main_window import MainWindow # noqa: E402 (QtWebEngine 须先于 QApplication import 完成)
|
|
|
|
app = QApplication(sys.argv)
|
|
ok = True
|
|
|
|
|
|
def check(name, cond):
|
|
global ok
|
|
print((" PASS " if cond else " FAIL ") + name)
|
|
if not cond:
|
|
ok = False
|
|
|
|
|
|
window = MainWindow()
|
|
|
|
# 本套件验证「默认锁定」语义:显式置 mode_switch=false,不受本机 data/config.json 影响
|
|
# (仅内存,不会写回配置文件)
|
|
window.config_data["mode_switch"] = False
|
|
window._refresh_mode_button()
|
|
|
|
# 1) 新建会话 → 未锁定
|
|
window.on_new_chat_clicked()
|
|
sid = window.current_session_id
|
|
check("新会话未锁定 (mode=None)", window._get_current_mode() is None)
|
|
check("按钮显示待选 Chat", "Chat" in window.btn_mode.text() and "🔒" not in window.btn_mode.text())
|
|
|
|
# 2) 浮动弹窗开/关 + 选择
|
|
window.show_mode_popup()
|
|
check("弹窗打开", window.mode_popup.isVisible())
|
|
window._select_mode("worker")
|
|
check("选 worker 后按钮更新", "Worker" in window.btn_mode.text())
|
|
check("选择后弹窗自动关闭", not window.mode_popup.isVisible())
|
|
|
|
# 3) 首条发送 → 锁定
|
|
window._lock_session_mode()
|
|
check("发送后锁定 worker", window.db.get_session_mode(sid) == "worker")
|
|
check("按钮显示锁定", "🔒" in window.btn_mode.text())
|
|
|
|
# 4) 锁定后不可改
|
|
window._select_mode("chat")
|
|
check("锁定后选择无效", window.db.get_session_mode(sid) == "worker")
|
|
|
|
# 5) worker 分派
|
|
w1 = window._create_stream_worker([], "worker")
|
|
w2 = window._create_stream_worker([], "chat")
|
|
from core.llm_engine import AgentWorker, ChatWorker # noqa: E402
|
|
check("worker 模式 → AgentWorker", isinstance(w1, AgentWorker))
|
|
check("chat 模式 → ChatWorker", isinstance(w2, ChatWorker))
|
|
check("ChatWorker 有基础信号", all(hasattr(w2, s) for s in
|
|
("chunk_received", "reasoning_received", "error_occurred")))
|
|
check("ChatWorker 无工具信号(chat 模式不暴露)",
|
|
not hasattr(w2, "tool_execution_started"))
|
|
|
|
# 6) 切回新会话 → 解锁
|
|
window.on_new_chat_clicked()
|
|
check("新会话恢复可选", window._get_current_mode() is None and "🔒" not in window.btn_mode.text())
|
|
|
|
# 7) 旧会话(无 mode 列值)→ 默认 chat 路径
|
|
window.load_messages_to_web(sid)
|
|
check("切回已锁定会话显示锁定", window._get_current_mode() == "worker" and "🔒" in window.btn_mode.text())
|
|
|
|
# 8) mode_switch=true → 中途切换放行(旧锁定会话解锁 + 选择立即落库)
|
|
window.config_data["mode_switch"] = True
|
|
window._refresh_mode_button()
|
|
check("开关开启后旧会话解锁显示", "🔒" not in window.btn_mode.text())
|
|
window._select_mode("chat")
|
|
check("开关开启后中途切换生效", window.db.get_session_mode(sid) == "chat")
|
|
window.config_data["mode_switch"] = False
|
|
|
|
try:
|
|
window.close()
|
|
except Exception:
|
|
pass
|
|
app.quit()
|
|
print("\n===== " + ("ALL PASS" if ok else "HAS FAILURES") + " =====")
|
|
sys.exit(0 if ok else 1)
|