需求文档

Test Interface Client — 需求规格说明书

文档信息

项目 内容
项目名称 Test Interface Client
文档版本 1.0
编写日期 2026-04-02
目标读者 开发人员、实习生、测试人员

1. 项目概述

1.1 项目目标

Test Interface Client 是一个桌面 GUI 应用程序,用于通过 gRPC 协议与测试接口板(NIB / TIB3 / TCPe3)通信,实现对 DUT(Device Under Test,被测设备)的自动化测试控制。

1.2 设计原则

  • 轻量级:最小化外部依赖
  • 高可定制性:通过 Profile JSON 文件驱动 UI 动态配置
  • 非阻塞:所有 gRPC 操作在后台线程执行,UI 始终保持响应

1.3 技术栈

组件 技术 说明
编程语言 Python 3 核心实现语言
UI 框架 PySide6 (Qt6) 跨平台桌面 GUI
通信协议 gRPC + Protocol Buffers 遵循 Raptor2 标准
配置格式 YAML 面板状态持久化
Profile 格式 JSON 板卡配置文件(支持注释)
打包工具 PyInstaller 生成独立可执行文件
测试框架 pytest 单元测试和集成测试

1.4 支持的硬件

板卡类型 IP 范围 端口 说明
NIB 192.168.2.51 ~ 58 50053 Network Interface Board
TIB3 192.168.2.61 ~ 68 50050 Test Interface Board 3
TCPe3 192.168.2.71 ~ 78 50051 TCP enhanced 3

2. 系统架构

2.1 分层架构

┌─────────────────────────────────────────────────────────────┐
│                    UI 层 (PySide6 界面)                      │
│  MainWindow → 7 个 Tab 面板 + StatusIndicator + StatusBar    │
│  + TerminalWindow (独立日志窗口)                              │
├─────────────────────────────────────────────────────────────┤
│                Workers 层 (后台线程)                          │
│  GrpcWorker / ScanWorker / FirmwareUpgradeWorker /           │
│  DZLoadWorker / AutoConfigWorker                             │
├─────────────────────────────────────────────────────────────┤
│             Service Clients 层 (gRPC 客户端封装)              │
│  ConfigurationClient / GPIOClient / ModeSelectClient /       │
│  TriggerClient / StatusClient / DutConnectionClient /        │
│  PMBusClient / FirmwareUpdateClient /                        │
│  SoftwareRepositoryClient                                    │
├─────────────────────────────────────────────────────────────┤
│              gRPC 通信层 (Protobuf 生成代码)                  │
│  generated/ 目录下的 *_pb2.py 和 *_pb2_grpc.py               │
├─────────────────────────────────────────────────────────────┤
│              后端 (外部 gRPC 服务器)                          │
│  运行在测试接口板 (NIB/TIB3/TCPe3) 上的服务                   │
└─────────────────────────────────────────────────────────────┘

2.2 核心设计模式

  1. Signal/Slot 机制:Qt 信号槽连接 UI 事件与处理逻辑,实现松耦合
  2. Worker 线程模式:所有 gRPC 调用在 QThread 后台线程执行,通过信号返回结果
  3. 队列式执行:GrpcWorker 使用线程安全队列(queue.Queue),面板通过 submit() 提交操作
  4. Profile 驱动 UI:GPIO 和 DZ 面板根据 JSON Profile 文件动态填充内容
  5. YAML 配置持久化:用户可保存/加载整个应用状态

2.3 入口点

入口 文件 用途
GUI 入口 ui/app.py 桌面应用程序(打包时使用)
CLI 入口 main.py 命令行测试脚本(开发调试用)

3. 功能需求

3.1 主窗口 (MainWindow)

文件: ui/main_window.py

3.1.1 窗口布局

  • 使用 QMainWindow 作为主窗口
  • 中央区域:QTabWidget 包含 7 个功能 Tab
  • 底部:StatusIndicator(单行状态显示)
  • 状态栏:StatusBar(连接状态、板卡类型、DUT 位置)
  • 工具栏:Save Config / Load Config / Auto Config 按钮
  • 独立窗口:TerminalWindow(完整日志输出)

3.1.2 Tab 页列表

Tab 名称 面板类 功能
Connection ConnectionPanel 设备扫描、连接管理
Configuration ConfigurationPanel Profile 加载、HW/SW 信息
GPIO GPIOPanel GPIO 控制、启动模式、触发器
Firmware Update FirmwarePanel 固件升级
DZ Loading DZLoadingPanel 软件加载
DCDC FW DCDC_FW_Panel DC/DC 固件控制
Test Execution (占位) 测试执行(未实现)

3.1.3 配置工具栏

  • Save Config:将所有面板当前状态保存为 YAML 文件
  • Load Config:从 YAML 文件恢复面板状态(仅填充 UI,不执行 gRPC 操作)
  • Auto Config:一键自动配置序列(需已连接设备)

3.1.4 Profile 联动

  • ConnectionPanel 发出 board_type_changed 信号时,MainWindow 通过 ProfileSectionLoader 加载对应板卡类型的 Profile 配置段
  • 加载后自动刷新 GPIO 面板(IO 配置、触发器源)和 DZ Loading 面板(软件区域配置)

3.1.5 窗口几何持久化

  • 使用 QSettings 保存/恢复窗口位置和大小
  • 关闭时保存,启动时恢复

3.1.6 优雅关闭

  • closeEvent 中停止所有后台 Worker 线程
  • 每个 Worker 等待最多 3 秒,超时则强制终止
  • 关闭 TerminalWindow

3.2 连接面板 (ConnectionPanel)

文件: ui/panels/connection_panel.py

3.2.1 设备扫描

  • 点击 "Scan Devices" 按钮启动设备扫描
  • 扫描范围:3 个固定 IP 段(NIB: .51-.58, TIB3: .61-.68, TCPe3: .71-.78)
  • 并发扫描:使用 ThreadPoolExecutor(最多 24 个线程)同时探测所有地址
  • 每个地址超时 0.5 秒
  • 扫描过程中显示进度条,支持取消
  • 扫描完成后自动弹出设备下拉列表
  • 应用启动时自动触发一次扫描

3.2.2 自动连接

  • 用户从下拉列表选择设备后自动连接(无需单独点击 Connect 按钮)
  • 连接在后台线程 _ConnectWorker 中执行,超时 5 秒
  • 连接过程中显示不确定进度条
  • 连接成功后:
    • 创建所有 Service Client(Configuration、GPIO、ModeSelect、Trigger、Status、DutConnection、PMBus)
    • StatusLogHandler 安装到 service_client logger
    • 更新状态栏(连接状态、板卡类型、DUT 位置)
    • 发出 connected 信号
  • 连接失败后:重置设备下拉列表,显示错误日志

3.2.3 板卡类型自动识别

  • 根据 IP 地址最后一个字节自动判断板卡类型和 DUT 位置:
    • 51-58 → NIB, dut_position = last_octet - 50
    • 61-68 → TIB3, dut_position = last_octet - 60
    • 71-78 → TCPe3, dut_position = last_octet - 70
    • 其他 → UNKNOWN, dut_position = 1
  • 板卡类型变化时发出 board_type_changed 信号

3.2.4 断开连接

  • 点击 "Disconnect" 按钮断开当前连接
  • 关闭 gRPC channel,清空所有 Service Client
  • 更新状态栏,发出 disconnected 信号

3.2.5 配置文件下拉

  • 自动扫描 configuration/ 目录下的 *.yaml 文件
  • 选择配置文件后自动加载到所有面板

3.2.6 设备显示格式

  • 下拉列表显示格式:192.168.2.61:50050 TIB3#1
  • 包含 IP:端口 + 板卡类型 + DUT 编号

3.3 配置面板 (ConfigurationPanel)

文件: ui/panels/configuration_panel.py

3.3.1 Profile 加载

  • 通过 "Browse..." 按钮选择 Profile JSON 文件
  • 点击 "Load Profile" 按钮将 Profile 发送到设备
  • 加载时根据当前连接的板卡类型,只发送匹配的 Profile 段
  • 加载完成后发出 profile_loaded 信号,触发 GPIO 面板刷新

3.3.2 硬件信息管理 (HW Info)

  • 统一可编辑表格,列:HW Name / Serial Number / Product Number / R-State / Production Date / Comment / Actions
  • Read:从设备读取所有 HW Info 并填充表格
  • Write All:将表格中所有行写入设备
  • Write(单行):写入指定行的 HW Info
  • Erase(单行):根据 HW Name 擦除指定行
  • Add Row:手动添加空行
  • 表格高度根据行数动态调整(最少 4 行,最多 11 行)

3.3.3 软件信息查询 (SW Info)

  • 点击 "Get SW Info" 按钮从设备读取所有 SW Info
  • 只读表格,列:SW Name / Product Number / R-State / Comment
  • 表格高度根据行数动态调整

3.3.4 忙碌指示器

  • 所有 gRPC 操作期间显示不确定进度条 + Cancel 按钮
  • 支持取消正在执行的操作

3.4 GPIO 面板 (GPIOPanel)

文件: ui/panels/gpio_panel.py

3.4.1 GPIO 控制表格

支持两种填充模式:

Profile 驱动模式(首选):

  • 从 Profile JSON 的 IOConfigurationInitialSettingIOConfigurations 填充
  • 表格列:Alias / Actual Name / Direction / State / Action
  • Input IO:显示 "Get State" 按钮,点击读取当前状态
  • Output IO:显示 "True" / "False" 两个按钮,点击设置 GPIO 状态
  • 使用 IOConfigurations 中的 ActualName → Alias 映射

传统模式(向后兼容):

  • 从平面 alias 列表填充
  • Output:使用 QCheckBox 切换 High/Low
  • Input:使用 "Read Input" 按钮

3.4.2 安全默认值

  • "Restore Safe Defaults" 按钮:将所有 GPIO 恢复到安全默认状态

3.4.3 DUT 连接状态

  • "Get DUT Connection Status" 按钮:查询 DUT 是否已连接
  • 结果显示在只读文本框中(Connected / Not Connected)

3.4.4 启动模式选择 (Boot Mode)

  • 两个直接操作按钮:
    • "External Boot" → 发送 BOOT_MODE_SELECTION_ENTER_DUT_BOOT_MODE_EXTERNAL
    • "Internal Boot" → 发送 BOOT_MODE_SELECTION_ENTER_DUT_BOOT_MODE_INTERNAL
  • 按钮驱动,无持久化选择状态

3.4.5 接口状态查询 (Interface Status)

  • "Get Once" 按钮:单次查询接口状态
  • "Start Polling" 按钮:每 2 秒自动轮询接口状态
  • "Stop Polling" 按钮:停止自动轮询
  • 结果格式化为逗号分隔的键值对(snake_case → Title Case,布尔值 → Yes/No)

3.4.6 触发器控制 (Trigger Control)

  • 触发器状态:
    • "Enable" 按钮 → 发送 ENABLED
    • "Disable" 按钮 → 发送 DISABLED
  • 触发器源:
    • 动态按钮容器,从 Profile 的 TriggerConfigurations 填充
    • 每个触发器源一个按钮,点击直接设置

3.5 固件升级面板 (FirmwarePanel)

文件: ui/panels/firmware_panel.py

3.5.1 固件文件选择

  • "Browse..." 按钮选择 .tar 固件文件
  • 自动解析文件名提取:设备名、产品号、R-state、校验码
  • 文件名格式:{DeviceName}_software_package_{ProductNumber}-{Rstate}-{BuildInfo}-{CheckCode}
  • 选择文件后自动填充 Product Number 和 R-state 字段

3.5.2 固件信息对比

  • 左侧面板:新固件包信息(设备名、产品号、R-state、SHA、文件大小、SHA-256)
  • 右侧面板:当前设备固件信息(从设备 SW Info 读取)
  • 版本不匹配时显示橙色警告标签

3.5.3 固件升级流程

  1. 点击 "Start Update" 按钮启动升级
  2. 在后台线程 FirmwareUpgradeWorker 中执行:
    • 连接固件更新服务
    • 流式上传固件文件(显示百分比进度条)
    • 等待设备重启(显示等待时间)
    • 验证升级结果
  3. 升级完成后显示版本对比表格(Before / After)
  4. 支持取消操作

3.5.4 进度显示

  • 上传阶段:百分比进度条(0-100%)
  • 等待阶段:显示已等待秒数
  • 步骤标签:显示当前阶段(Step 1/2/3)

3.6 DZ 加载面板 (DZLoadingPanel)

文件: ui/panels/dz_loading_panel.py

3.6.1 DZ 容器选择

  • "Browse..." 按钮选择 DZ 容器目录
  • 参数输入:Product Number、R-state、Security Level(None / Secure Locked / Secure Unlocked)
  • "Load DZ Container" 按钮解析容器内容

3.6.2 软件区域表格 (Software Areas)

  • 从 Profile 的 SoftwareAreaConfigurations 填充
  • 列:SwType / StartAddress / AreaSize / EraseStartAddress / EraseAreaSize
  • 地址以十六进制格式显示

3.6.3 软件项表格 (Software Items)

  • 从 DZ 容器解析结果填充
  • 列:Send(复选框)/ Area / ProductNumber / R-state / Filename / Size / Hash / Browse
  • 每行可单独选择是否发送
  • 支持为缺失文件手动浏览选择替代文件

3.6.4 加载控制

  • "Start Loading" 按钮:开始上传选中的软件项
  • "Cancel Loading" 按钮:取消正在进行的上传
  • "Cleanup After Boot" 按钮:启动后清理
  • 每个软件项显示独立的进度条

3.6.5 安全级别

显示名称 API 值
None none
Secure Locked secure_locked
Secure Unlocked secure_unlocked

3.7 DCDC FW 面板 (DCDC_FW_Panel)

文件: ui/panels/dcdc_fw_panel.py

3.7.1 PMBus 控制模式

  • "Normal" 按钮:设置 PMBus 为正常模式
  • "Programming" 按钮:设置 PMBus 为编程模式

3.7.2 PMBus 时钟频率

  • "100KHz" 按钮:设置时钟频率为 100KHz
  • "400KHz" 按钮:设置时钟频率为 400KHz

3.7.3 DC/DC 固件加载

  • "Browse..." 按钮选择固件文件夹
  • "Load DC/DC Firmware" 按钮执行加载

3.8 自动配置 (Auto Config)

文件: ui/workers/auto_config_worker.py

3.8.1 执行序列

Auto Config 按顺序执行以下 5 个步骤:

步骤 名称 操作
1 Connect Server 验证 gRPC channel 就绪
2 Load Profile 加载 Profile 文件到设备
3 Set GPIO Outputs 设置所有 Output GPIO 状态
4 Select Boot Mode 选择启动模式(默认 Internal Boot)
5 Configure Trigger 设置触发器状态和源

3.8.2 前置条件

  • 必须已连接设备
  • 必须已设置 Profile 路径

3.8.3 信号通知

  • step_started(str):步骤开始
  • step_completed(str):步骤完成
  • auto_config_complete(list):全部完成,附带摘要
  • auto_config_error(str, str):步骤失败,附带步骤名和错误信息

4. 通信协议需求

4.1 gRPC 服务定义

文件: protos/service_ms_test_interface.proto

所有服务遵循 Raptor2 标准,使用 proto3 语法。

4.1.1 服务列表

服务名 功能 对应面板
TestInterfaceConfigurationService Profile 加载、HW/SW 信息管理 Configuration
TestInterfaceGPIOService GPIO 输出设置、输入读取、安全默认值 GPIO
TestInterfaceModeSelectService 启动模式选择 GPIO
TestInterfaceTriggerService 触发器状态/源设置 GPIO
TestInterfaceStatusService 接口状态查询 GPIO
TestInterfaceDutConnectionService DUT 连接状态查询 GPIO
TestInterfacePMBusService PMBus 控制模式、时钟频率、DC/DC 固件 DCDC FW
TestInterfaceFirmwareUpdateService 固件流式上传 Firmware Update
TestInterfaceSoftwareRepositoryService 软件仓库管理、DZ 加载 DZ Loading
TestInterfaceUartService UART 通信测试 (未实现)
TestInterfaceTspUartService TSP UART 配置 (未实现)
TestInterfaceExternalAlarmService 外部告警设置 (未实现)
TestInterfaceFanControlService 风扇控制 (未实现)
TestInterfaceMeasureVoltageService 电压测量 (未实现)
TestInterfaceBpmService BPM 编程 (未实现)
TestInterfaceModemService 调制解调器控制 (未实现)
TestInterfacePdbService PDB 通道配置 (未实现)
TestInterfacePaxService PAX 测量和开关控制 (未实现)

4.1.2 关键 RPC 方法

ConfigurationService:

  • SetProfile — 设置 HW Profile
  • SetHWInfo — 写入硬件信息
  • GetHWInfos — 读取硬件信息
  • GetSWInfos — 读取软件信息
  • EraseHwInfo — 擦除硬件信息
  • LoadConfigurationFile — 加载配置文件

GPIOService:

  • SetOutput — 设置 GPIO 输出状态
  • GetInput — 读取 GPIO 输入状态
  • SetSafeDefaults — 恢复安全默认值

FirmwareUpdateService:

  • FirmwareUpdate — 流式固件上传(client streaming)

SoftwareRepositoryService:

  • InitiateBootSoftwareRequest — 双向流式软件加载
  • CleanupAfterBoot — 启动后清理

4.2 连接方式

  • 使用 grpc.insecure_channel(非加密连接)
  • 连接超时:5 秒
  • 扫描探测超时:0.5 秒

5. UI/UX 需求

5.1 全局样式 (QSS Theme)

文件: ui/styles/theme.qss

  • 主题风格:Light Professional(浅色专业风格)
  • 主色调:蓝色系(#2563EB)
  • 背景色:白色(#FFFFFF)
  • 表面色:浅灰(#F5F7FA)
  • 边框色:中灰(#D1D5DB)
  • 字体:Segoe UI / Microsoft YaHei, 13px
  • 所有控件统一样式:按钮、表格、下拉框、进度条、Tab 页等
  • 按钮状态:正常 / 悬停 / 按下 / 禁用 / 聚焦
  • 表格内按钮使用紧凑样式(max-height: 18px, font-size: 10px)

5.2 状态指示器 (StatusIndicator)

文件: ui/widgets/status_indicator.py

  • 固定高度 28px 的单行状态显示
  • 始终显示最新一条日志消息
  • 根据日志级别显示不同颜色:
    • WARNING → 橙色 (#FFA500)
    • ERROR → 红色 (#FF0000)
    • DEBUG → 灰色 (#808080)
    • INFO → 默认颜色
  • 超过 200 字符的消息截断显示
  • 可通过 install_on_logger() 挂载到 Python logger

5.3 状态栏 (StatusBar)

文件: ui/widgets/status_bar.py

  • 三个永久标签:
    • gRPC 连接状态:gRPC: Connected (192.168.2.61:50050) / gRPC: Disconnected
    • DUT 位置:DUT Position: 1 / DUT Position: N/A
    • 板卡类型:Device: TIB3 / Device: N/A

5.4 终端日志窗口 (TerminalWindow)

文件: ui/widgets/terminal_window.py

  • 独立窗口,标题 "Terminal Log"
  • 默认大小 800×400
  • 等宽字体 Courier New 10pt
  • 深色背景(#1e1e1e)+ 浅色文字(#dcdcdc)
  • 只读 QTextEdit,禁用自动换行
  • 自动滚动到底部,水平滚动条重置到最左
  • 日志格式:YYYY-MM-DD HH:MM:SS [LEVEL] message
  • 挂载到根 logger,接收所有日志输出

5.5 表格紧凑设计

所有表格统一使用紧凑设计:

  • 字体大小:9pt
  • 最小行高:10px(部分 28px)
  • 默认行高:22-31px
  • 表格高度根据行数动态调整,避免空白区域
  • 行数 ≤ max_rows 时隐藏垂直滚动条

5.6 忙碌指示器

所有执行 gRPC 操作的面板统一使用:

  • 不确定进度条(setRange(0, 0)
  • Cancel 按钮
  • 操作开始时显示,完成/失败/取消时隐藏

6. 配置管理需求

6.1 YAML 配置文件格式

文件: ui/config_manager.py

# 连接信息
address: "192.168.2.61:50050"
dut_position: 1

# Profile 路径
profile_path: "configuration/profile.json"

# 硬件信息
test_hw_infos:
  - hw_name: "NIB"
    serial_number: "SN123"
    product_number: "PN456"
    product_rstate: "R1A"
    production_date: "2025-01-15"
    comment: "test comment"

# GPIO 配置
gpio:
  outputs:
    - alias: "GPIO_1"
      state: true
  inputs:
    - "GPIO_IN"

# 固件升级
upgrade_file: "/path/to/firmware.tar"
firmware:
  product_number: "PN789"
  product_rstate: "R2B"

# DZ 加载
dz_loading:
  dz_container_path: "/path/to/container"
  product_number: "CXP123"
  product_rstate: "R1A"
  security_level: "secure_locked"
  extra_sw_files:
    Pboot: "/path/to/pboot.bin"

# DC/DC 固件
dc_firmware:
  folder: "/path/to/dcdc"

6.2 保存行为

  • 遍历所有面板,收集当前 UI 状态
  • 空字段不写入 YAML
  • 启动模式和触发器状态不保存(按钮驱动,无持久化状态)

6.3 加载行为

  • 读取 YAML 文件,填充对应面板字段
  • 缺失字段保留面板当前值(不清空)
  • 加载时阻塞信号,防止触发自动连接等副作用
  • 记录未覆盖的字段列表到日志
  • 仅填充 UI,不执行任何 gRPC 操作

6.4 值映射

UI 显示 YAML 值
Internal Boot BOOT_MODE_SELECTION_ENTER_DUT_BOOT_MODE_INTERNAL
External Boot BOOT_MODE_SELECTION_ENTER_DUT_BOOT_MODE_EXTERNAL
None none
Secure Locked secure_locked
Secure Unlocked secure_unlocked
Normal NORMAL
Programming PROGRAMMING
100KHz 100KHZ
400KHz 400KHZ
Enabled ENABLED
Disabled DISABLED

7. Profile 文件需求

7.1 Profile JSON 结构

文件: ui/profile_section_loader.py

{
  "TestInterfaceConfiguration": {
    "<ProductName>": {
      "TIB3": {
        "IOConfigurationInitialSetting": [...],
        "IOConfigurations": [...],
        "TriggerConfigurations": [...],
        "SoftwareAreaConfigurations": [...]
      },
      "TCPE": { ... },
      "NIB": { ... }
    }
  }
}

7.2 板卡类型到 JSON 键映射

board_type JSON Section Key
TIB3 TIB3
TCPe3 TCPE
NIB NIB

7.3 JSON 注释支持

  • 支持 JavaScript 风格的 // 行注释
  • 支持行内注释(引号内的 // 不受影响)
  • 加载前自动剥离注释

7.4 Profile 加载后的面板刷新

  • GPIO 面板
    • IOConfigurationInitialSetting → GPIO 表格行
    • IOConfigurations → Alias 映射和初始状态
    • TriggerConfigurations → 触发器源按钮
  • DZ Loading 面板
    • SoftwareAreaConfigurations → 软件区域表格

8. 后台线程需求

8.1 GrpcWorker(通用 gRPC 执行器)

文件: ui/workers/grpc_worker.py

  • 继承 QThread,在后台线程中执行 gRPC 操作
  • 使用线程安全队列(queue.Queue)接收操作
  • 公共 API:
    • submit(name, callable, *args, **kwargs) — 提交操作到队列
    • stop() — 优雅停止(放入哨兵对象)
    • cancel() — 设置取消标志
    • is_cancelled() — 检查是否已取消
  • 信号:
    • result_ready(object) — 操作成功
    • error_occurred(str) — 操作失败
    • operation_started(str) — 操作开始
  • 被取消的操作结果会被丢弃
  • 使用面板:ConfigurationPanel、GPIOPanel、DCDC_FW_Panel

8.2 ScanWorker(设备扫描)

文件: ui/workers/scan_worker.py

  • 继承 QThread
  • 使用 ThreadPoolExecutor(24 线程)并发探测
  • 每个地址通过 grpc.channel_ready_future 探测,超时 0.5 秒
  • 支持中断请求(isInterruptionRequested()
  • 结果排序后发出
  • 信号:scan_progress(int, int) / scan_complete(list)

8.3 FirmwareUpgradeWorker(固件升级)

文件: ui/workers/firmware_worker.py

  • 继承 QThread
  • 创建独立的 FirmwareUpdateClient 实例
  • 通过日志拦截器 _ProgressCapture 捕获进度信息:
    • Progress: N%upload_progress 信号
    • Still waiting... Ns elapsedwaiting_device 信号
    • Step 3: Waiting for device to restartdevice_restarting 信号
  • 信号:upload_progress(int) / waiting_device(int) / device_restarting() / upgrade_complete(list, list) / upgrade_error(str)

8.4 DZLoadWorker(DZ 加载)

文件: ui/workers/dz_load_worker.py

  • 继承 QThread
  • 通过日志拦截器 _DZProgressCapture 捕获进度信息
  • 信号:item_progress(str, int) / load_complete(list) / load_error(str)

8.5 AutoConfigWorker(自动配置)

文件: ui/workers/auto_config_worker.py

  • 继承 QThread
  • 顺序执行 5 个步骤,任一步骤失败则中止
  • 使用传入的 gRPC channel(不创建新连接)
  • 信号:step_started(str) / step_completed(str) / auto_config_complete(list) / auto_config_error(str, str)

9. 工具模块需求

9.1 固件包解析器

文件: ui/utils/fw_package_parser.py

  • parse_fw_filename(filename) — 从文件名提取 FWPackageInfo(设备名、产品号、R-state、校验码)
  • parse_sw_info(sw_infos) — 从 protobuf SWInfos 响应提取 DeviceFWInfo
  • compare_fw_versions(package, device) — 比较包版本和设备版本是否一致

9.2 资源路径解析

文件: ui/utils/resource_path.py

  • resource_path(relative_path) — 统一解析资源文件路径
    • 开发环境:基于项目根目录
    • PyInstaller 打包环境:基于 sys._MEIPASS
  • is_frozen() — 检测是否在打包环境中运行

9.3 版本管理

文件: version.py

  • 版本读取优先级:setup.pypyproject.tomlsetup.cfg → 默认 0.1.0
  • 模块级常量 VERSION 在导入时计算一次

10. 打包与发布需求

10.1 PyInstaller 配置

文件: TestInterfaceClient.spec

  • 入口点:ui/app.py
  • 打包模式:onedir(单目录)
  • 输出目录:dist/TestInterfaceClient/
  • GUI 模式:console=False(无控制台窗口)

包含的数据文件

源路径 打包路径 说明
configuration/ configuration/ 配置文件模板
ui/styles/ ui/styles/ QSS 样式表
generated/ generated/ gRPC 生成代码

Hidden Imports

  • gRPC 核心:grpc, grpc._cython, grpc._cython.cygrpc
  • Protobuf:google.protobuf.*
  • 生成代码:所有 generated.*_pb2generated.*_pb2_grpc
  • 其他:yaml, PySide6.QtCore/QtGui/QtWidgets

排除的模块

  • 未使用的 Qt 模块:WebEngine, 3D, Quick, Multimedia, Bluetooth 等
  • 未使用的 Python 库:tkinter, unittest, pytest, matplotlib, numpy 等

10.2 发布脚本

文件: scripts/create_release.py

  • dist/TestInterfaceClient/ 创建 ZIP 包
  • 命名格式:TestInterfaceClient-vX.Y.Z.zip
  • 包含可选的 README.txt
  • 输出:版本号、文件数、包大小

10.3 构建命令

命令 说明
make build 编译 proto 文件 + PyInstaller 打包
make dist build + 创建发布 ZIP
make clean-dist 清理构建产物

11. 测试需求

11.1 测试框架

  • 使用 pytest
  • 共享 fixture:tests/conftest.py
    • qapp(session 级别):确保整个测试会话只有一个 QApplication
    • _cleanup_qt_objects(autouse):每个测试后处理 Qt 事件并垃圾回收

11.2 测试覆盖范围

测试文件 覆盖模块
test_config_manager.py YAML 配置保存/加载、往返一致性
test_connection_panel.py 设备扫描、自动连接、断开
test_configuration_panel.py Profile 加载、HW/SW 信息
test_gpio_panel.py GPIO 表格填充、按钮处理
test_firmware_panel.py 固件升级工作流
test_firmware_worker.py 固件升级后台线程
test_dz_loading_panel.py DZ 加载面板
test_dz_load_worker.py DZ 加载后台线程
test_dcdc_fw_panel.py DCDC FW 面板
test_main_window_config.py 主窗口配置工具栏
test_status_indicator.py 状态指示器
test_status_bar.py 状态栏
test_terminal_window.py 终端日志窗口
test_board_type_resolver.py 板卡类型解析
test_fw_package_parser.py 固件包文件名解析
test_grpc_worker.py 通用 gRPC Worker
test_scan_worker.py 设备扫描 Worker
test_auto_config_worker.py 自动配置 Worker
test_profile_section_loader.py Profile 加载器
test_resource_path.py 资源路径解析
test_version.py 版本管理
test_theme.py QSS 主题
test_visual_indicators.py 视觉指示器
test_table_compactness.py 表格紧凑性
test_polling_manager.py 轮询管理器(no-op stub)
test_release_script.py 发布脚本

11.3 测试原则

  • 不依赖真实 gRPC 服务器
  • 使用 Mock/Patch 隔离 gRPC 调用
  • GrpcWorker 线程在测试 teardown 中正确停止
  • Qt 对象在测试间正确清理

12. 非功能需求

12.1 性能

  • UI 线程不执行任何 gRPC 调用,保持界面响应
  • 设备扫描总时间约等于单次超时(~0.5s),而非 N × 超时
  • 表格高度动态调整,避免不必要的布局计算

12.2 可靠性

  • 所有 gRPC 操作支持取消
  • 连接失败时优雅降级(显示错误,不崩溃)
  • 关闭窗口时确保所有后台线程停止
  • Worker 线程超时后强制终止

12.3 可维护性

  • 模块化设计:每个面板独立文件
  • 统一的 Worker 模式:GrpcWorker 可复用
  • 统一的日志模式:所有面板通过 _log() 方法输出
  • 统一的忙碌指示器模式

12.4 可扩展性

  • 新面板只需创建 QWidget 子类并添加到 MainWindow 的 Tab
  • 新 gRPC 服务只需创建 Service Client 并在 ConnectionPanel 中实例化
  • Profile 驱动的 UI 支持不同板卡类型的差异化配置

12.5 平台支持

  • 主要支持 Windows
  • macOS / Linux 扩展点已预留但未完全验证
  • 资源路径兼容 PyInstaller 打包环境

12.6 安全性

  • 使用非加密 gRPC 连接(insecure_channel)— 适用于内网测试环境
  • 无用户认证机制

13. 目录结构参考

TestInterfaceClient/
├── main.py                          # CLI 入口(测试脚本)
├── version.py                       # 版本管理
├── TestInterfaceClient.spec         # PyInstaller 打包配置
├── README.md                        # 项目说明
│
├── ui/                              # GUI 应用
│   ├── app.py                       # GUI 入口
│   ├── main_window.py               # 主窗口
│   ├── config_manager.py            # YAML 配置管理
│   ├── board_type_resolver.py       # IP → 板卡类型映射
│   ├── profile_section_loader.py    # Profile JSON 解析
│   │
│   ├── panels/                      # 功能面板
│   │   ├── connection_panel.py      # 连接管理
│   │   ├── configuration_panel.py   # 配置管理
│   │   ├── gpio_panel.py            # GPIO 控制
│   │   ├── firmware_panel.py        # 固件升级
│   │   ├── dz_loading_panel.py      # DZ 加载
│   │   └── dcdc_fw_panel.py         # DC/DC 固件
│   │
│   ├── workers/                     # 后台线程
│   │   ├── grpc_worker.py           # 通用 gRPC 执行器
│   │   ├── scan_worker.py           # 设备扫描
│   │   ├── firmware_worker.py       # 固件升级
│   │   ├── dz_load_worker.py        # DZ 加载
│   │   ├── auto_config_worker.py    # 自动配置
│   │   └── polling_manager.py       # 轮询管理(已废弃)
│   │
│   ├── widgets/                     # 可复用组件
│   │   ├── status_indicator.py      # 单行状态显示
│   │   ├── status_bar.py            # 底部状态栏
│   │   └── terminal_window.py       # 终端日志窗口
│   │
│   ├── utils/                       # 工具函数
│   │   ├── fw_package_parser.py     # 固件文件名解析
│   │   └── resource_path.py         # 资源路径解析
│   │
│   └── styles/
│       └── theme.qss                # 全局 QSS 样式表
│
├── protos/                          # Protobuf 定义
│   ├── service_ms_test_interface.proto
│   ├── test_interface.proto
│   ├── status.proto
│   ├── enums.proto
│   ├── common_enums.proto
│   ├── common_types.proto
│   └── type.proto
│
├── generated/                       # Protobuf 生成代码
│   ├── *_pb2.py                     # 消息类
│   ├── *_pb2_grpc.py                # 服务桩
│   └── *_pb2.pyi                    # 类型提示
│
├── service_client/                  # gRPC 客户端封装
│   ├── configuration.py
│   ├── gpio.py
│   ├── mode_select.py
│   ├── trigger.py
│   ├── status.py
│   ├── dut_connect.py
│   ├── pm_bus.py
│   ├── fw_update.py
│   └── software_repository_client.py
│
├── test_case/                       # CLI 测试用例
│   ├── test_configuration.py
│   ├── test_gpio.py
│   ├── test_fw_update.py
│   └── ...
│
├── tests/                           # pytest 测试套件
│   ├── conftest.py
│   └── test_*.py (30+ 文件)
│
├── configuration/                   # YAML 配置文件模板
├── scripts/
│   └── create_release.py            # 发布脚本
└── util/
    └── logger_handler.py            # 日志处理器

14. 术语表

术语 全称 说明
DUT Device Under Test 被测设备
NIB Network Interface Board 网络接口板
TIB3 Test Interface Board 3 测试接口板第三代
TCPe3 TCP enhanced 3 TCP 增强板第三代
GPIO General Purpose Input/Output 通用输入输出
gRPC Google Remote Procedure Call 远程过程调用框架
Protobuf Protocol Buffers 序列化协议
DZ (内部术语) 软件容器/部署包
FAAP (内部术语) 应用固件包
PMBus Power Management Bus 电源管理总线
DCDC DC-to-DC Converter 直流-直流转换器
R-state Revision State 版本修订状态
Profile 配置文件 JSON 格式的板卡配置描述
QSS Qt Style Sheets Qt 样式表
posted @ 2026-04-02 16:27  mo686  阅读(32)  评论(0)    收藏  举报