cluster4npu/tests/unit/test_device_management_panel.py
abin 55040733fe feat: implement Phase 1-4 performance visualization and device management
Phase 1 — Performance Benchmarking:
- PerformanceBenchmarker: sequential vs parallel benchmark with injectable runner
- PerformanceHistory: JSON-backed benchmark history with regression support
- PerformanceDashboard: real-time FPS/latency display widget
- BenchmarkDialog: one-click benchmark with 3-phase progress bar

Phase 2 — Device Management:
- DeviceManager: NPU dongle scan, assign/unassign, load balance recommendation
- DeviceManagementPanel: live device status cards with auto-refresh
- BottleneckAlert: dataclass for pipeline bottleneck detection

Phase 3 — Advanced Features:
- OptimizationEngine: 3 optimization rules (rebalance/adjust_queue/add_devices)
- TemplateManager: 3 built-in pipeline templates (YOLOv5, fire detection, dual-model)

Phase 4 — Report Export:
- ReportExporter: PDF (reportlab, optional) and CSV export
- ExportReportDialog: format selection + path picker UI

192 unit tests, all passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 19:32:05 +08:00

107 lines
3.8 KiB
Python

"""
tests/unit/test_device_management_panel.py
Unit tests for DeviceManagementPanel QWidget.
TDD: Red phase — tests written before implementation.
Uses conftest.py Stubs for PyQt5 so no display hardware is needed.
"""
from unittest.mock import MagicMock, patch
import pytest
from core.device.device_manager import DeviceInfo, DeviceManager
from ui.components.device_management_panel import DeviceManagementPanel
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _make_device_manager(devices=None):
"""Return a DeviceManager-like mock with controllable scan_devices()."""
mgr = MagicMock(spec=DeviceManager)
if devices is None:
devices = [
DeviceInfo(
device_id="usb-1",
series="KL520",
product_id=0x100,
status="online",
gops=2,
assigned_stage=None,
current_fps=15.0,
utilization_pct=50.0,
)
]
mgr.scan_devices.return_value = devices
mgr.get_device_statistics.return_value = {d.device_id: d for d in devices}
mgr.get_load_balance_recommendation.return_value = {}
return mgr
# ---------------------------------------------------------------------------
# Panel instantiation
# ---------------------------------------------------------------------------
class TestDeviceManagementPanelInit:
def test_panel_creates_without_error(self):
mgr = _make_device_manager()
panel = DeviceManagementPanel(device_manager=mgr)
assert panel is not None
def test_panel_has_auto_balance_button(self):
mgr = _make_device_manager()
panel = DeviceManagementPanel(device_manager=mgr)
# auto_balance_button must exist
assert hasattr(panel, "auto_balance_button")
def test_auto_balance_button_text(self):
mgr = _make_device_manager()
panel = DeviceManagementPanel(device_manager=mgr)
assert panel.auto_balance_button._text == "Auto Balance"
# ---------------------------------------------------------------------------
# refresh()
# ---------------------------------------------------------------------------
class TestDeviceManagementPanelRefresh:
def test_refresh_calls_scan_devices(self):
mgr = _make_device_manager()
panel = DeviceManagementPanel(device_manager=mgr)
mgr.scan_devices.reset_mock()
panel.refresh()
mgr.scan_devices.assert_called_once()
def test_refresh_updates_known_devices(self):
mgr = _make_device_manager()
panel = DeviceManagementPanel(device_manager=mgr)
panel.refresh()
# After refresh, panel should have device data accessible
assert len(panel._devices) == 1
assert panel._devices[0].device_id == "usb-1"
def test_refresh_with_no_devices_sets_empty_list(self):
mgr = _make_device_manager(devices=[])
panel = DeviceManagementPanel(device_manager=mgr)
panel.refresh()
assert panel._devices == []
# ---------------------------------------------------------------------------
# set_auto_refresh()
# ---------------------------------------------------------------------------
class TestSetAutoRefresh:
def test_set_auto_refresh_stores_interval(self):
mgr = _make_device_manager()
panel = DeviceManagementPanel(device_manager=mgr)
panel.set_auto_refresh(interval_ms=3000)
assert panel._auto_refresh_interval_ms == 3000
def test_set_auto_refresh_default_interval(self):
mgr = _make_device_manager()
panel = DeviceManagementPanel(device_manager=mgr)
panel.set_auto_refresh()
assert panel._auto_refresh_interval_ms == 2000