Files
NanoKVM-MIRROR/server/service/ws/keyboard_led_status_test.go
肆月 eb20fb41aa feat: show remote keyboard lock status (#838)
* feat: show remote keyboard lock status

* fix(keyboard-led-status): eliminate polling and improve delivery

* fix(keyboard-led-status): simplify indicator labels
2026-08-04 09:28:14 +08:00

80 lines
2.0 KiB
Go

package ws
import (
"testing"
"time"
"NanoKVM-Server/service/hid"
)
func TestKeyboardLedStatusQueueKeepsLatestStatus(t *testing.T) {
client := &Client{
keyboardLedNotify: make(chan struct{}, 1),
keyboardLedDone: make(chan struct{}),
}
first := hid.KeyboardLedStatus{NumLock: true}
latest := hid.KeyboardLedStatus{CapsLock: true}
client.enqueueKeyboardLedStatus(first)
client.enqueueKeyboardLedStatus(latest)
status, ok := client.takeKeyboardLedStatus()
if !ok {
t.Fatal("queued LED status was not available")
}
if status != latest {
t.Fatalf("queued status = %#v, want latest %#v", status, latest)
}
if _, ok := client.takeKeyboardLedStatus(); ok {
t.Fatal("queue retained more than one LED status")
}
}
func TestKeyboardLedStatusQueueDoesNotBlockWhenWorkerIsBusy(t *testing.T) {
client := &Client{
keyboardLedNotify: make(chan struct{}, 1),
keyboardLedDone: make(chan struct{}),
}
// A pending notification models a worker currently busy writing the prior
// status to a slow websocket client.
client.keyboardLedNotify <- struct{}{}
finished := make(chan struct{})
go func() {
client.enqueueKeyboardLedStatus(hid.KeyboardLedStatus{CapsLock: true})
close(finished)
}()
select {
case <-finished:
case <-time.After(time.Second):
t.Fatal("enqueue blocked while the keyboard LED worker was busy")
}
}
func TestKeyboardLedStatusWorkerStopsOnClientClose(t *testing.T) {
client := &Client{
keyboardLedNotify: make(chan struct{}, 1),
keyboardLedDone: make(chan struct{}),
}
client.startKeyboardLedStatusWorker()
client.stopKeyboardLedStatusWorker()
done := make(chan struct{})
go func() {
client.workers.Wait()
close(done)
}()
select {
case <-done:
case <-time.After(time.Second):
t.Fatal("keyboard LED worker did not stop after client close")
}
client.enqueueKeyboardLedStatus(hid.KeyboardLedStatus{ScrollLock: true})
if _, ok := client.takeKeyboardLedStatus(); ok {
t.Fatal("closed client accepted a keyboard LED status")
}
}