- TesterDriver interface: Connect/Read/Disconnect - StreamingTesterDriver interface: embeds TesterDriver, adds Stream() - TestResult struct: CableType, versions, speed, power, continuity, eMarker, resistance - LiveReading struct: Voltage, CurrentAmps, PowerWatts, PDProtocol, Timestamp - MockUSBDriver: deterministic USB 3.2 Gen 2 result, ErrNotConnected guard - MockDPDriver: deterministic DP 1.4 result - MockHDMIDriver: deterministic HDMI 2.1 result - MockFNB58Driver: 3 LiveReading samples at 100ms, context-cancelled via Disconnect() - KnownDevices: 4 RoleCableTester placeholder entries (dead0:0001-0004)
175 lines
4 KiB
Go
175 lines
4 KiB
Go
package tester
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// MockUSBDriver simulates a Treedix USB cable tester.
|
|
// Returns deterministic USB 3.2 Gen 2 test results.
|
|
// All fields are exported so test code can construct zero values directly.
|
|
type MockUSBDriver struct {
|
|
connected bool
|
|
}
|
|
|
|
// Compile-time interface assertion.
|
|
var _ TesterDriver = (*MockUSBDriver)(nil)
|
|
|
|
func (d *MockUSBDriver) Connect() error {
|
|
d.connected = true
|
|
return nil
|
|
}
|
|
|
|
func (d *MockUSBDriver) Read() (TestResult, error) {
|
|
if !d.connected {
|
|
return TestResult{}, ErrNotConnected
|
|
}
|
|
return TestResult{
|
|
CableType: CableTypeUSB,
|
|
USBVersion: "USB 3.2 Gen 2",
|
|
SpeedGbps: 10.0,
|
|
MaxWatts: 100,
|
|
PinContinuity: true,
|
|
HasEMarker: true,
|
|
ResistanceOhm: 0.12,
|
|
}, nil
|
|
}
|
|
|
|
func (d *MockUSBDriver) Disconnect() error {
|
|
d.connected = false
|
|
return nil
|
|
}
|
|
|
|
// MockDPDriver simulates a Treedix DisplayPort cable tester.
|
|
// Returns deterministic DP 1.4 test results.
|
|
type MockDPDriver struct {
|
|
connected bool
|
|
}
|
|
|
|
// Compile-time interface assertion.
|
|
var _ TesterDriver = (*MockDPDriver)(nil)
|
|
|
|
func (d *MockDPDriver) Connect() error {
|
|
d.connected = true
|
|
return nil
|
|
}
|
|
|
|
func (d *MockDPDriver) Read() (TestResult, error) {
|
|
if !d.connected {
|
|
return TestResult{}, ErrNotConnected
|
|
}
|
|
return TestResult{
|
|
CableType: CableTypeDP,
|
|
DPVersion: "1.4",
|
|
PinContinuity: true,
|
|
}, nil
|
|
}
|
|
|
|
func (d *MockDPDriver) Disconnect() error {
|
|
d.connected = false
|
|
return nil
|
|
}
|
|
|
|
// MockHDMIDriver simulates a Treedix HDMI cable tester.
|
|
// Returns deterministic HDMI 2.1 test results.
|
|
type MockHDMIDriver struct {
|
|
connected bool
|
|
}
|
|
|
|
// Compile-time interface assertion.
|
|
var _ TesterDriver = (*MockHDMIDriver)(nil)
|
|
|
|
func (d *MockHDMIDriver) Connect() error {
|
|
d.connected = true
|
|
return nil
|
|
}
|
|
|
|
func (d *MockHDMIDriver) Read() (TestResult, error) {
|
|
if !d.connected {
|
|
return TestResult{}, ErrNotConnected
|
|
}
|
|
return TestResult{
|
|
CableType: CableTypeHDMI,
|
|
HDMIVersion: "2.1",
|
|
PinContinuity: true,
|
|
}, nil
|
|
}
|
|
|
|
func (d *MockHDMIDriver) Disconnect() error {
|
|
d.connected = false
|
|
return nil
|
|
}
|
|
|
|
// MockFNB58Driver simulates an FNIRSI FNB58 USB power meter.
|
|
// Stream() emits 3 deterministic LiveReading samples at 100ms intervals,
|
|
// then closes the channel. Disconnect() cancels the goroutine early.
|
|
type MockFNB58Driver struct {
|
|
connected bool
|
|
streamCh chan LiveReading
|
|
cancelFunc context.CancelFunc
|
|
}
|
|
|
|
// Compile-time interface assertion.
|
|
var _ StreamingTesterDriver = (*MockFNB58Driver)(nil)
|
|
|
|
func (d *MockFNB58Driver) Connect() error {
|
|
d.connected = true
|
|
d.streamCh = make(chan LiveReading, 8)
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
d.cancelFunc = cancel
|
|
go d.runStream(ctx)
|
|
return nil
|
|
}
|
|
|
|
func (d *MockFNB58Driver) runStream(ctx context.Context) {
|
|
defer close(d.streamCh)
|
|
samples := []LiveReading{
|
|
{Voltage: 5.1, CurrentAmps: 3.0, PowerWatts: 15.3, PDProtocol: "PD3.0", Timestamp: time.Now()},
|
|
{Voltage: 5.1, CurrentAmps: 3.0, PowerWatts: 15.3, PDProtocol: "PD3.0", Timestamp: time.Now()},
|
|
{Voltage: 5.1, CurrentAmps: 3.0, PowerWatts: 15.3, PDProtocol: "PD3.0", Timestamp: time.Now()},
|
|
}
|
|
for _, s := range samples {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-time.After(100 * time.Millisecond):
|
|
s.Timestamp = time.Now()
|
|
select {
|
|
case d.streamCh <- s:
|
|
case <-ctx.Done():
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (d *MockFNB58Driver) Read() (TestResult, error) {
|
|
if !d.connected {
|
|
return TestResult{}, ErrNotConnected
|
|
}
|
|
// FNB58 is a streaming device; discrete Read returns a snapshot.
|
|
return TestResult{
|
|
CableType: CableTypeUSB,
|
|
MaxWatts: 100,
|
|
}, nil
|
|
}
|
|
|
|
func (d *MockFNB58Driver) Disconnect() error {
|
|
if d.cancelFunc != nil {
|
|
d.cancelFunc()
|
|
d.cancelFunc = nil
|
|
}
|
|
d.connected = false
|
|
return nil
|
|
}
|
|
|
|
// Stream returns the live reading channel. If called before Connect(),
|
|
// returns a pre-closed channel (never nil, never blocking).
|
|
func (d *MockFNB58Driver) Stream() <-chan LiveReading {
|
|
if !d.connected || d.streamCh == nil {
|
|
closed := make(chan LiveReading)
|
|
close(closed)
|
|
return closed
|
|
}
|
|
return d.streamCh
|
|
}
|