feat: SSHClient v1.0.0 - PyQt5 + paramiko 跨平台 SSH 客户端
功能: - 多主机管理 (增删改查, 密码/私钥双认证, 导入导出) - 远程终端 (命令执行 + 常用命令快捷栏 + 超时控制) - SFTP 文件浏览 (上传/下载带进度, 新建/删除/重命名) - 实时监控 (CPU/内存/磁盘/网络, 1-10秒可调刷新) - AI Agent (OpenAI 兼容 API, 5 工具自动调用: 命令/指标/列文件/读文件/上传) 技术栈: PyQt5 + paramiko + psutil + requests + PyInstaller 打包: build_windows.bat / build.sh 一键产出 ~57MB 单文件 exe 测试: core 6/6 + UI 3/3 + E2E 6/6 全部通过
This commit is contained in:
+68
@@ -0,0 +1,68 @@
|
||||
"""
|
||||
UI 启动 smoke test:
|
||||
- 所有模块可正常 import
|
||||
- QApplication 能用 offscreen 平台创建
|
||||
- MainWindow 能实例化、各 Tab 能构建
|
||||
- AIConfigDialog 能弹出
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
# offscreen 平台:允许在没有显示器的环境(CI/容器)跑 Qt
|
||||
os.environ["QT_QPA_PLATFORM"] = "offscreen"
|
||||
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from PyQt5.QtCore import QTimer
|
||||
|
||||
from ui.main_window import MainWindow, APP_NAME
|
||||
from ui.host_dialog import HostDialog
|
||||
from ui.config_dialog import AIConfigDialog, PRESETS
|
||||
from ui.widgets import FileBrowser, MonitorPanel, AIChatPanel
|
||||
from core.ai_agent import AIAgent
|
||||
|
||||
|
||||
def main():
|
||||
app = QApplication(sys.argv)
|
||||
app.setApplicationName(APP_NAME)
|
||||
|
||||
print("[1/3] 验证 MainWindow 实例化")
|
||||
w = MainWindow()
|
||||
assert w.windowTitle().startswith(APP_NAME), w.windowTitle()
|
||||
assert w.tabs.count() == 4, f"应有 4 个 Tab,实际 {w.tabs.count()}"
|
||||
print(f" ✓ 主窗口创建,Tab 数量 = {w.tabs.count()}")
|
||||
|
||||
print("[2/3] 验证子组件")
|
||||
assert isinstance(w.file_browser, FileBrowser)
|
||||
assert isinstance(w.monitor, MonitorPanel)
|
||||
assert isinstance(w.ai_panel, AIChatPanel)
|
||||
print(f" ✓ FileBrowser / MonitorPanel / AIChatPanel 全部就位")
|
||||
|
||||
print("[3/3] 验证对话框")
|
||||
# 主机对话框
|
||||
hd = HostDialog(current={"name": "test", "host": "1.2.3.4", "port": 22,
|
||||
"username": "u", "password": "p", "key_path": ""})
|
||||
assert hd.name_edit.text() == "test"
|
||||
assert hd.host_edit.text() == "1.2.3.4"
|
||||
hd.close()
|
||||
print(" ✓ HostDialog 编辑模式可读字段")
|
||||
|
||||
# AI 配置对话框
|
||||
agent = AIAgent(api_key="test-key", base_url="http://localhost:1/v1", model="x")
|
||||
cd = AIConfigDialog(agent)
|
||||
assert cd.api_key_edit.text() == "test-key"
|
||||
assert len(PRESETS) >= 6
|
||||
cd.close()
|
||||
print(f" ✓ AIConfigDialog + {len(PRESETS)} 个预设")
|
||||
|
||||
# 不真正 show,只确保不崩
|
||||
w.close()
|
||||
print("\n所有 UI 组件加载正常 ✓")
|
||||
# 不进入事件循环,强制退出
|
||||
QTimer.singleShot(0, app.quit)
|
||||
app.exec_()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user