Test Interface Client — Requirements Specification
Document Information
| Item | Details |
|---|---|
| Project Name | Test Interface Client |
| Version | 1.0 |
| Date | 2026-04-02 |
| Audience | Developers, Test Engineers |
1. Project Overview
1.1 Objectives
Test Interface Client serves as a desktop GUI application designed to communicate with test interface boards (NIB, TIB3, TCPe3) via gRPC protocol. The system enables automated testing and control operations for Devices Under Test (DUT).
1.2 Design Principles
- Lightweight: Minimal external dependencies
- Configurable: Profile JSON files drive dynamic UI configuration
- Responsive: All gRPC operations execute in background threads to maintain UI responsiveness
1.3 Technology Stack
| Component | Technology | Description |
|---|---|---|
| Language | Python 3 | Primary implementation |
| GUI Framework | PySide6 (Qt6) | Cross-platform desktop interface |
| Communication | gRPC + Protocol Buffers | Raptor2 standard compliant |
| Configuration | YAML | Panel state persistence |
| Profile Format | JSON | Board configuration files |
| Packaging | PyInstaller | Standalone executable generation |
| Testing | pytest | Unit and integration tests |
1.4 Supported Hardware
| Board Type | IP Range | Port | Description |
|---|---|---|---|
| NIB | 192.168.2.51 - 192.168.2.58 | 50053 | Network Interface Board |
| TIB3 | 192.168.2.61 - 192.168.2.68 | 50050 | Test Interface Board 3 |
| TCPe3 | 192.168.2.71 - 192.168.2.78 | 50051 | TCP Enhanced 3 |
2. System Architecture
2.1 Layered Architecture
+---------------------------------------------------------------+ | Presentation Layer | | MainWindow → 7 Tab Panels + StatusIndicator | | + TerminalWindow (Independent Log Window) | +---------------------------------------------------------------+ | Worker Layer (Background) | | GrpcWorker / ScanWorker / FirmwareUpgradeWorker | | DZLoadWorker / AutoConfigWorker | +---------------------------------------------------------------+ | Service Client Layer (gRPC Wrappers) | | ConfigurationClient / GPIOClient / ModeSelectClient | | TriggerClient / StatusClient / DutConnectionClient | +---------------------------------------------------------------+ | gRPC Communication Layer | | generated/ directory - *_pb2.py and *_pb2_grpc.py | +---------------------------------------------------------------+ | Backend (External gRPC Servers) | | Services running on NIB/TIB3/TCPe3 boards | +---------------------------------------------------------------+
2.2 Core Design Patterns
- Signal/Slot Pattern: Qt signal-slot connections decouple UI events from business logic
- Worker Thread Pattern: All gRPC calls execute in QThread background workers, results returned via signals
- Queue-Based Execution: GrpcWorker employs thread-safe queue (queue.Queue), panels submit operations via submit()
- Profile-Driven UI: GPIO and DZ panels populate dynamically based on JSON Profile configuration
- YAML Configuration Persistence: Users can save/load complete application state
2.3 Application Entry Points
| Entry Type | File | Purpose |
|---|---|---|
| GUI Entry | ui/app.py | Desktop application (used for packaging) |
| CLI Entry | main.py | Command-line testing script (development use) |
3. Functional Requirements
3.1 Main Window (MainWindow)
File: ui/main_window.py
3.1.1 Window Layout
- QMainWindow as the primary window container
- Central area: QTabWidget containing 7 functional tabs
- Bottom: StatusIndicator (single-line status display)
- Status bar: Connection status, board type, DUT position
- Toolbar: Save Config, Load Config, Auto Config buttons
- Independent window: TerminalWindow (full log output)
3.1.2 Tab Pages
| Tab Name | Panel Class | Functionality |
|---|---|---|
| Connection | ConnectionPanel | Device scanning, connection management |
| Configuration | ConfigurationPanel | Profile loading, HW/SW information |
| GPIO | GPIOPanel | GPIO control, boot mode, triggers |
| Firmware Update | FirmwarePanel | Firmware upgrade operations |
| DZ Loading | DZLoadingPanel | Software loading |
| DCDC FW | DCDC_FW_Panel | DC/DC firmware control |
| Test Execution | (Placeholder) | Test execution (not implemented) |
3.1.3 Configuration Toolbar
- Save Config: Persist all panel states to YAML file
- Load Config: Restore panel states from YAML (UI only, no gRPC execution)
- Auto Config: Execute one-click automatic configuration sequence (requires connected device)
3.1.4 Profile Linkage
When ConnectionPanel emits board_type_changed signal, MainWindow loads corresponding board type Profile configuration via ProfileSectionLoader. This automatically refreshes GPIO panel (IO configuration, trigger sources) and DZ Loading panel (software area configuration).
3.1.5 Window Geometry Persistence
QSettings saves/restores window position and size. State saved on close, restored on startup.
3.1.6 Graceful Shutdown
- closeEvent stops all background Worker threads
- Each Worker waits maximum 3 seconds, force-terminates on timeout
- TerminalWindow closed
3.2 Connection Panel (ConnectionPanel)
File: ui/panels/connection_panel.py
3.2.1 Device Scanning
- "Scan Devices" button initiates device discovery
- Scan range: 3 fixed IP segments (NIB: .51-.58, TIB3: .61-.68, TCPe3: .71-.78)
- Concurrent scanning using ThreadPoolExecutor (max 24 threads)
- Per-address timeout: 0.5 seconds
- Progress bar displayed during scan, supports cancellation
- Device dropdown auto-populated on completion
- Automatic scan triggered on application startup
3.2.2 Automatic Connection
- Auto-connect on device selection (no separate Connect button needed)
- Connection executes in background _ConnectWorker thread, 5 second timeout
- Indeterminate progress bar during connection
- On success: Creates all Service Clients, attaches StatusLogHandler, updates status bar, emits connected signal
- On failure: Resets device dropdown, displays error log
3.2.3 Board Type Auto-Detection
Board type and DUT position determined by IP address last octet:
- 51-58 → NIB, dut_position = last_octet - 50
- 61-68 → TIB3, dut_position = last_octet - 60
- 71-78 → TCPe3, dut_position = last_octet - 70
- Other → UNKNOWN, dut_position = 1
board_type_changed signal emitted on type change.
3.2.4 Disconnection
- "Disconnect" button closes current connection
- Closes gRPC channel, clears all Service Clients
- Updates status bar, emits disconnected signal
3.2.5 Configuration File Dropdown
- Auto-scans configuration/ directory for *.yaml files
- Selecting config file auto-loads to all panels
3.2.6 Device Display Format
Dropdown format: 192.168.2.61:50050 TIB3#1 (IP:Port + Board Type + DUT Number)
3.3 Configuration Panel (ConfigurationPanel)
File: ui/panels/configuration_panel.py
3.3.1 Profile Loading
- "Browse..." button selects Profile JSON file
- "Load Profile" button sends Profile to device
- Only matching board type Profile sections sent
- profile_loaded signal emitted on completion, triggers GPIO panel refresh
3.3.2 Hardware Information Management (HW Info)
- Editable table columns: HW Name, Serial Number, Product Number, R-State, Production Date, Comment, Actions
- Read: Fetches all HW Info from device, populates table
- Write All: Writes all rows to device
- Write (Single): Writes specified row HW Info
- Erase (Single): Erases specified row by HW Name
- Add Row: Manually adds empty row
- Table height dynamically adjusts (minimum 4 rows, maximum 11 rows)
3.3.3 Software Information Query (SW Info)
- "Get SW Info" button reads all SW Info from device
- Read-only table columns: SW Name, Product Number, R-State, Comment
- Table height dynamically adjusts based on row count
3.3.4 Busy Indicator
- Indeterminate progress bar + Cancel button during all gRPC operations
- Supports cancelling in-progress operations
3.4 GPIO Panel (GPIOPanel)
File: ui/panels/gpio_panel.py
3.4.1 GPIO Control Table
Two population modes supported:
Profile-Driven Mode (Preferred):
- Populated from Profile JSON IOConfigurationInitialSetting and IOConfigurations
- Table columns: Alias, Actual Name, Direction, State, Action
- Input IO: Displays "Get State" button to read current state
- Output IO: Displays "True" / "False" buttons to set GPIO state
- Uses ActualName → Alias mapping from IOConfigurations
Legacy Mode (Backward Compatible):
- Populated from flat alias list
- Output: QCheckBox toggles High/Low
- Input: "Read Input" button
3.4.2 Safe Defaults
"Restore Safe Defaults" button restores all GPIO to safe default state.
3.4.3 DUT Connection Status
"Get DUT Connection Status" button queries DUT connection state. Result displayed in read-only text field (Connected / Not Connected).
3.4.4 Boot Mode Selection
- "External Boot" → sends BOOT_MODE_SELECTION_ENTER_DUT_BOOT_MODE_EXTERNAL
- "Internal Boot" → sends BOOT_MODE_SELECTION_ENTER_DUT_BOOT_MODE_INTERNAL
- Button-driven, no persistent selection state
3.4.5 Interface Status Query
- "Get Once" button: Single interface status query
- "Start Polling" button: Auto-poll every 2 seconds
- "Stop Polling" button: Stop auto-polling
- Result formatted as comma-separated key-value pairs (snake_case → Title Case, boolean → Yes/No)
3.4.6 Trigger Control
- Trigger State: "Enable" / "Disable" buttons send ENABLED/DISABLED
- Trigger Source: Dynamic button container populated from Profile TriggerConfigurations
3.5 Firmware Update Panel (FirmwarePanel)
File: ui/panels/firmware_panel.py
3.5.1 Firmware File Selection
- "Browse..." button selects .tar firmware file
- Auto-parses filename: DeviceName, Product Number, R-state, Check Code
- Filename format: {DeviceName}_software_package_{ProductNumber}-{Rstate}-{BuildInfo}-{CheckCode}
- Auto-fills Product Number and R-state fields on selection
3.5.2 Firmware Information Comparison
- Left panel: New firmware package info (device name, product number, R-state, SHA, file size, SHA-256)
- Right panel: Current device firmware info (from device SW Info)
- Orange warning label displayed on version mismatch
3.5.3 Firmware Upgrade Process
- "Start Update" button initiates upgrade
- Background thread FirmwareUpgradeWorker executes:
- Connects to firmware update service
- Streams firmware file (displays percentage progress)
- Waits for device reboot (displays elapsed time)
- Verifies upgrade result
- Version comparison table displayed on completion (Before / After)
- Supports operation cancellation
3.5.4 Progress Display
- Upload phase: Percentage progress bar (0-100%)
- Wait phase: Displays elapsed seconds
- Step label: Shows current phase (Step 1/2/3)
3.6 DZ Loading Panel (DZLoadingPanel)
File: ui/panels/dz_loading_panel.py
3.6.1 DZ Container Selection
- "Browse..." button selects DZ container directory
- Parameters: Product Number, R-state, Security Level (None / Secure Locked / Secure Unlocked)
- "Load DZ Container" button parses container contents
3.6.2 Software Areas Table
- Populated from Profile SoftwareAreaConfigurations
- Columns: SwType, StartAddress, AreaSize, EraseStartAddress, EraseAreaSize
- Addresses displayed in hexadecimal format
3.6.3 Software Items Table
- Populated from DZ container parse results
- Columns: Send (checkbox), Area, ProductNumber, R-state, Filename, Size, Hash, Browse
- Each row individually selectable for transmission
- Supports manual file browse for missing files
3.6.4 Loading Controls
- "Start Loading" button: Begin uploading selected software items
- "Cancel Loading" button: Cancel in-progress upload
- "Cleanup After Boot" button: Post-boot cleanup
- Individual progress bar per software item
3.6.5 Security Level Mapping
| Display Name | API Value |
|---|---|
| None | none |
| Secure Locked | secure_locked |
| Secure Unlocked | secure_unlocked |
3.7 DCDC FW Panel (DCDC_FW_Panel)
File: ui/panels/dcdc_fw_panel.py
3.7.1 PMBus Control Mode
- "Normal" button: Sets PMBus to normal mode
- "Programming" button: Sets PMBus to programming mode
3.7.2 PMBus Clock Frequency
- "100KHz" button: Sets clock to 100KHz
- "400KHz" button: Sets clock to 400KHz
3.7.3 DC/DC Firmware Loading
- "Browse..." button selects firmware folder
- "Load DC/DC Firmware" button executes loading
3.8 Auto Configuration
File: ui/workers/auto_config_worker.py
3.8.1 Execution Sequence
Auto Config executes 5 steps sequentially:
| Step | Name | Operation |
|---|---|---|
| 1 | Connect Server | Verify gRPC channel ready |
| 2 | Load Profile | Load Profile file to device |
| 3 | Set GPIO Outputs | Set all Output GPIO states |
| 4 | Select Boot Mode | Select boot mode (default Internal Boot) |
| 5 | Configure Trigger | Set trigger state and source |
3.8.2 Prerequisites
- Device must be connected
- Profile path must be set
3.8.3 Signal Notifications
- step_started(str): Step began
- step_completed(str): Step finished
- auto_config_complete(list): All complete with summary
- auto_config_error(str, str): Step failed with name and error
4. Communication Protocol Requirements
4.1 gRPC Service Definitions
File: protos/service_ms_test_interface.proto
All services follow Raptor2 standard using proto3 syntax.
4.1.1 Service List
| Service Name | Function | Panel |
|---|---|---|
| TestInterfaceConfigurationService | Profile loading, HW/SW info management | Configuration |
| TestInterfaceGPIOService | GPIO output set, input read, safe defaults | GPIO |
| TestInterfaceModeSelectService | Boot mode selection | GPIO |
| TestInterfaceTriggerService | Trigger state/source setting | GPIO |
| TestInterfaceStatusService | Interface status query | GPIO |
| TestInterfaceDutConnectionService | DUT connection status query | GPIO |
| TestInterfacePMBusService | PMBus control mode, clock frequency | DCDC FW |
| TestInterfaceFirmwareUpdateService | Firmware stream upload | Firmware Update |
| TestInterfaceSoftwareRepositoryService | Software repository, DZ loading | DZ Loading |
4.1.2 Key RPC Methods
ConfigurationService:
- SetProfile — Set HW Profile
- SetHWInfo — Write hardware information
- GetHWInfos — Read hardware information
- GetSWInfos — Read software information
- EraseHwInfo — Erase hardware information
GPIOService:
- SetOutput — Set GPIO output state
- GetInput — Read GPIO input state
- SetSafeDefaults — Restore safe defaults
FirmwareUpdateService:
- FirmwareUpdate — Stream firmware upload (client streaming)
SoftwareRepositoryService:
- InitiateBootSoftwareRequest — Bidirectional stream software loading
- CleanupAfterBoot — Post-boot cleanup
4.2 Connection Parameters
- Uses grpc.insecure_channel (unencrypted connection)
- Connection timeout: 5 seconds
- Scan probe timeout: 0.5 seconds
5. UI/UX Requirements
5.1 Global QSS Theme
File: ui/styles/theme.qss
- Theme: Light Professional
- Primary color: Blue (#2563EB)
- Background: White (#FFFFFF)
- Surface: Light gray (#F5F7FA)
- Border: Medium gray (#D1D5DB)
- Font: Segoe UI / Microsoft YaHei, 13px
- Consistent styling for all controls
5.2 Status Indicator (StatusIndicator)
File: ui/widgets/status_indicator.py
- Fixed height 28px single-line display
- Always shows latest log message
- Color by log level: WARNING (orange), ERROR (red), DEBUG (gray), INFO (default)
- Messages over 200 characters truncated
5.3 Status Bar (StatusBar)
File: ui/widgets/status_bar.py
- Three permanent labels: gRPC connection status, DUT position, Board type
5.4 Terminal Log Window (TerminalWindow)
File: ui/widgets/terminal_window.py
- Independent window titled "Terminal Log"
- Default size 800x400
- Monospace font Courier New 10pt
- Dark background (#1e1e1e) + Light text (#dcdcdc)
- Read-only QTextEdit, no auto-wrap
- Auto-scroll to bottom
- Log format: YYYY-MM-DD HH:MM:SS [LEVEL] message
5.5 Compact Table Design
- Font size: 9pt
- Minimum row height: 10px
- Default row height: 22-31px
- Dynamic height adjustment based on row count
6. Configuration Management
6.1 YAML Configuration Format
File: ui/config_manager.py
# Connection info
address: "192.168.2.61:50050"
dut_position: 1
# Profile path
profile_path: "configuration/profile.json"
# Hardware info
test_hw_infos:
- hw_name: "NIB"
serial_number: "SN123"
product_number: "PN456"
product_rstate: "R1A"
# GPIO configuration
gpio:
outputs:
- alias: "GPIO_1"
state: true
# Firmware upgrade
upgrade_file: "/path/to/firmware.tar"
# DZ loading
dz_loading:
dz_container_path: "/path/to/container"
security_level: "secure_locked"
6.2 Save Behavior
- Iterates all panels, collects current UI state
- Empty fields not written to YAML
- Boot mode and trigger states not saved (button-driven, no persistent state)
6.3 Load Behavior
- Reads YAML file, populates corresponding panel fields
- Missing fields retain current panel values
- Blocks signals during load to prevent side effects
- Only fills UI, executes no gRPC operations
7. Profile File Requirements
7.1 Profile JSON Structure
File: ui/profile_section_loader.py
{
"TestInterfaceConfiguration": {
"<ProductName>": {
"TIB3": {
"IOConfigurationInitialSetting": [...],
"IOConfigurations": [...],
"TriggerConfigurations": [...],
"SoftwareAreaConfigurations": [...]
},
"TCPE": { ... },
"NIB": { ... }
}
}
}
7.2 Board Type to JSON Key Mapping
| board_type | JSON Section Key |
|---|---|
| TIB3 | TIB3 |
| TCPe3 | TCPE |
| NIB | NIB |
7.3 JSON Comment Support
- Supports JavaScript-style // line comments
- Supports inline comments
- Comments stripped before parsing
8. Background Thread Requirements
8.1 GrpcWorker (Generic gRPC Executor)
File: ui/workers/grpc_worker.py
- Extends QThread, executes gRPC operations in background
- Uses thread-safe queue.Queue to receive operations
- Public API: submit(), stop(), cancel(), is_cancelled()
- Signals: result_ready(object), error_occurred(str), operation_started(str)
- Cancelled operation results discarded
- Used by: ConfigurationPanel, GPIOPanel, DCDC_FW_Panel
8.2 ScanWorker (Device Scanner)
File: ui/workers/scan_worker.py
- Extends QThread
- ThreadPoolExecutor (24 threads) for concurrent probing
- Uses grpc.channel_ready_future for probing, 0.5s timeout
- Supports interruption via isInterruptionRequested()
- Signals: scan_progress(int, int), scan_complete(list)
8.3 FirmwareUpgradeWorker
File: ui/workers/firmware_worker.py
- Extends QThread
- Creates independent FirmwareUpdateClient instance
- Progress captured via log interceptor
- Signals: upload_progress(int), waiting_device(int), device_restarting(), upgrade_complete(list, list), upgrade_error(str)
8.4 DZLoadWorker
File: ui/workers/dz_load_worker.py
- Extends QThread
- Progress captured via log interceptor
- Signals: item_progress(str, int), load_complete(list), load_error(str)
8.5 AutoConfigWorker
File: ui/workers/auto_config_worker.py
- Extends QThread
- Sequential execution of 5 steps, aborts on any failure
- Uses passed gRPC channel (no new connection)
- Signals: step_started(str), step_completed(str), auto_config_complete(list), auto_config_error(str, str)
9. Utility Module Requirements
9.1 Firmware Package Parser
File: ui/utils/fw_package_parser.py
- parse_fw_filename(filename) — Extract FWPackageInfo from filename
- parse_sw_info(sw_infos) — Extract DeviceFWInfo from protobuf response
- compare_fw_versions(package, device) — Compare versions for consistency
9.2 Resource Path Resolver
File: ui/utils/resource_path.py
- resource_path(relative_path) — Unified resource file path resolution
- Development: project root based
- PyInstaller: sys._MEIPASS based
- is_frozen() — Detect packaged environment
9.3 Version Management
File: version.py
- Priority: setup.py → pyproject.toml → setup.cfg → default 0.1.0
- Module constant VERSION computed on import
10. Packaging and Distribution
10.1 PyInstaller Configuration
File: TestInterfaceClient.spec
- Entry: ui/app.py
- Mode: onedir (single directory)
- Output: dist/TestInterfaceClient/
- GUI mode: console=False
Data Files Included
| Source | Target | Description |
|---|---|---|
| configuration/ | configuration/ | Config templates |
| ui/styles/ | ui/styles/ | QSS stylesheets |
| generated/ | generated/ | gRPC generated code |
Hidden Imports
- gRPC core: grpc, grpc._cython, grpc._cython.cygrpc
- Protobuf: google.protobuf.*
- Generated: generated.*_pb2, generated.*_pb2_grpc
- Others: yaml, PySide6.QtCore/QtGui/QtWidgets
11. Testing Requirements
11.1 Test Framework
- pytest framework
- Shared fixtures in tests/conftest.py
- qapp fixture (session scope): Single QApplication per session
- Qt object cleanup after each test
11.2 Test Coverage
| Test File | Coverage |
|---|---|
| test_config_manager.py | YAML save/load, round-trip consistency |
| test_connection_panel.py | Device scanning, auto-connect, disconnect |
| test_gpio_panel.py | GPIO table population, button handling |
| test_firmware_worker.py | Firmware upgrade background thread |
| test_grpc_worker.py | Generic gRPC Worker |
| test_scan_worker.py | Device scan Worker |
11.3 Test Principles
- No dependency on real gRPC server
- Mock/Patch isolates gRPC calls
- GrpcWorker threads properly stopped in teardown
- Qt objects properly cleaned between tests
12. Non-Functional Requirements
12.1 Performance
- UI thread never executes gRPC calls
- Device scan time approximately equals single timeout (~0.5s)
- Dynamic table height avoids unnecessary layout calculations
12.2 Reliability
- All gRPC operations cancellable
- Graceful degradation on connection failure
- Background threads stopped on window close
- Worker threads force-terminated on timeout
12.3 Maintainability
- Modular design: each panel independent file
- Unified Worker pattern: GrpcWorker reusable
- Unified logging: all panels use _log() method
12.4 Extensibility
- New panels: QWidget subclass added to MainWindow Tab
- New gRPC services: Service Client created, instantiated in ConnectionPanel
- Profile-driven UI supports board type differentiation
13. Glossary
| Term | Full Name | Description |
|---|---|---|
| DUT | Device Under Test | Target device being tested |
| NIB | Network Interface Board | Network interface hardware |
| TIB3 | Test Interface Board 3 | Third generation test interface |
| TCPe3 | TCP Enhanced 3 | Third generation TCP enhanced board |
| GPIO | General Purpose Input/Output | General purpose I/O pins |
| gRPC | Google Remote Procedure Call | RPC framework |
| Protobuf | Protocol Buffers | Serialization protocol |
| PMBus | Power Management Bus | Power management communication |
| DCDC | DC-to-DC Converter | DC voltage converter |
| Profile | Configuration file | JSON format board configuration |