ituoke/internal/device/usb_test.go

125 lines
4.4 KiB
Go

package device
import (
"os"
"path/filepath"
"runtime"
"strings"
"testing"
)
func TestUSBDiscoverySelectionAndHotplug(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("fake ADB uses a POSIX shell")
}
dir := t.TempDir()
state := filepath.Join(dir, "devices")
calls := filepath.Join(dir, "calls")
bin := filepath.Join(dir, "adb")
t.Setenv("FAKE_ADB_DEVICES", state)
t.Setenv("FAKE_ADB_CALLS", calls)
script := `#!/bin/sh
printf '%s\n' "$*" >> "$FAKE_ADB_CALLS"
if [ "$1" != -P ] || [ "$2" != 17891 ]; then exit 42; fi
shift 2
case "$1" in
devices) printf 'List of devices attached\n'; cat "$FAKE_ADB_DEVICES" ;;
-s)
if [ "$4" = wm ]; then printf 'Physical size: 1080x2400\n'; fi
;;
esac
`
if err := os.WriteFile(bin, []byte(script), 0700); err != nil {
t.Fatal(err)
}
previous := adbPathOverride
SetAdbPath(bin)
t.Cleanup(func() { SetAdbPath(previous) })
writeDevices := func(devices string) {
t.Helper()
if err := os.WriteFile(state, []byte(devices), 0600); err != nil {
t.Fatal(err)
}
}
const usbA = "USB_A device usb:1 model:Phone_A transport_id:1\n"
const usbZ = "USB_Z device usb:2 model:Phone_Z transport_id:2\n"
const locked = "USB_LOCKED unauthorized usb:3 transport_id:3\n"
const wifiID = "adb-WIFI-random._adb-tls-connect._tcp"
const wifi = wifiID + " device model:Wireless_Phone transport_id:4\n"
writeDevices(wifi + usbZ + locked + usbA)
s := &Service{devices: map[string]DeviceInfo{}}
devices, err := s.ListDevices()
if err != nil || len(devices) != 4 {
t.Fatalf("list: %+v %v", devices, err)
}
if devices[0].ID != "USB_A" || devices[1].ID != "USB_Z" || devices[2].ID != wifiID || devices[3].ID != "USB_LOCKED" {
t.Fatalf("unstable USB/online ordering: %+v", devices)
}
if devices[3].Online || devices[3].State != "unauthorized" || devices[3].Mode != ConnUSB || devices[3].Width != 0 {
t.Fatalf("unauthorized USB not preserved: %+v", devices[3])
}
if active := s.GetActiveDevice(); active.ID != "USB_A" || active.Mode != ConnUSB || active.Width != 1080 {
t.Fatalf("initial USB selection: %+v", active)
}
if err := s.SelectDevice(wifiID); err != nil {
t.Fatal(err)
}
if _, err := s.ListDevices(); err != nil || s.GetActiveDevice().ID != wifiID {
t.Fatal("refresh changed an explicitly selected online wireless device")
}
writeDevices(usbZ + usbA + wifiID + " offline\n" + locked)
if _, err := s.ListDevices(); err != nil || s.GetActiveDevice().ID != "USB_A" {
t.Fatal("offline wireless selection did not fall back to online USB")
}
if err := s.Tap(TapRequest{DeviceID: "USB_A", X: 10, Y: 20}); err != nil {
t.Fatalf("USB input: %v", err)
}
writeDevices(wifi + locked)
if _, err := s.ListDevices(); err != nil || s.GetActiveDevice().ID != wifiID {
t.Fatal("unplugged USB selection did not fall back to online wireless")
}
writeDevices("USB_LOCKED device usb:3 model:Authorized_Phone\n")
if _, err := s.ListDevices(); err != nil || s.GetActiveDevice().ID != "USB_LOCKED" || !s.GetActiveDevice().Online {
t.Fatal("USB authorization change was not discovered")
}
if result := s.DisconnectDevice("USB_LOCKED"); !result.OK {
t.Fatalf("USB session disconnect: %+v", result)
}
if devices, err := s.ListDevices(); err != nil || len(devices) != 1 || devices[0].Online || devices[0].State != "disconnected" {
t.Fatalf("refresh reconnected USB session: %+v %v", devices, err)
}
if result := s.StartPreviewStream("USB_LOCKED", false); result.OK {
t.Fatal("preview opened a disconnected USB session")
}
if err := s.SelectDevice("USB_LOCKED"); err != nil || !s.GetActiveDevice().Online {
t.Fatalf("USB reconnect failed: %v", err)
}
history, err := os.ReadFile(calls)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(history), "-P 17891 -s USB_A shell input tap 10 20\n") {
t.Fatalf("input did not target USB serial: %s", history)
}
if strings.Contains(string(history), "disconnect") || strings.Contains(string(history), "connect ") || strings.Contains(string(history), "kill-server") {
t.Fatalf("USB discovery interfered with ADB transports: %s", history)
}
}
func TestInferUSBAndWirelessMode(t *testing.T) {
for _, tc := range []struct {
serial string
want ConnMode
}{
{"bdeafa21", ConnUSB},
{"192.0.2.1:5555", ConnLAN},
{"[2001:db8::1]:5555", ConnLAN},
{"adb-serial-random._adb-tls-connect._tcp", ConnLAN},
{"phone._adb._tcp", ConnLAN},
} {
if got := inferMode(tc.serial); got != tc.want {
t.Errorf("%s: got %s, want %s", tc.serial, got, tc.want)
}
}
}