usb_test.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package isolated_device
  15. import (
  16. "reflect"
  17. "strings"
  18. "testing"
  19. "github.com/stretchr/testify/assert"
  20. )
  21. func Test_parseLsusbLine(t *testing.T) {
  22. tests := []struct {
  23. name string
  24. lines []string
  25. want []*sLsusbLine
  26. wantErr bool
  27. }{
  28. {
  29. name: "test",
  30. lines: []string{
  31. "Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub",
  32. "Bus 003 Device 005: ID 13d3:3563 IMC Networks Wireless_Device",
  33. "Bus 003 Device 003: ID 27c6:521d Shenzhen Goodix Technology Co.,Ltd. FingerPrint",
  34. "Bus 003 Device 006: ID 0451:82ff Texas Instruments, Inc.",
  35. "Bus 003 Device 008: ID feed:19c0 YANG HHKB BLE S (USB_DL1K)",
  36. "Bus 003 Device 007: ID 214b:7250 Huasheng Electronics USB2.0 HUB",
  37. "Bus 003 Device 002: ID 0451:8442 Texas Instruments, Inc.",
  38. "Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub",
  39. "Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub",
  40. "Bus 001 Device 004: ID 0b05:193b ASUSTek Computer, Inc. ITE Device(8910)",
  41. "Bus 001 Device 003: ID 0b05:19b6 ASUSTek Computer, Inc. N-KEY Device",
  42. "Bus 001 Device 002: ID 046d:c52f Logitech, Inc. Unifying Receiver",
  43. "Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub",
  44. },
  45. want: []*sLsusbLine{
  46. {BusId: "004", Device: "001", VendorId: "1d6b", DeviceId: "0003", Name: "Linux Foundation 3.0 root hub"},
  47. {BusId: "003", Device: "005", VendorId: "13d3", DeviceId: "3563", Name: "IMC Networks Wireless_Device"},
  48. {BusId: "003", Device: "003", VendorId: "27c6", DeviceId: "521d", Name: "Shenzhen Goodix Technology Co.,Ltd. FingerPrint"},
  49. {BusId: "003", Device: "006", VendorId: "0451", DeviceId: "82ff", Name: "Texas Instruments, Inc."},
  50. {BusId: "003", Device: "008", VendorId: "feed", DeviceId: "19c0", Name: "YANG HHKB BLE S (USB_DL1K)"},
  51. {BusId: "003", Device: "007", VendorId: "214b", DeviceId: "7250", Name: "Huasheng Electronics USB2.0 HUB"},
  52. {BusId: "003", Device: "002", VendorId: "0451", DeviceId: "8442", Name: "Texas Instruments, Inc."},
  53. {BusId: "003", Device: "001", VendorId: "1d6b", DeviceId: "0002", Name: "Linux Foundation 2.0 root hub"},
  54. {BusId: "002", Device: "001", VendorId: "1d6b", DeviceId: "0003", Name: "Linux Foundation 3.0 root hub"},
  55. {BusId: "001", Device: "004", VendorId: "0b05", DeviceId: "193b", Name: "ASUSTek Computer, Inc. ITE Device(8910)"},
  56. {BusId: "001", Device: "003", VendorId: "0b05", DeviceId: "19b6", Name: "ASUSTek Computer, Inc. N-KEY Device"},
  57. {BusId: "001", Device: "002", VendorId: "046d", DeviceId: "c52f", Name: "Logitech, Inc. Unifying Receiver"},
  58. {BusId: "001", Device: "001", VendorId: "1d6b", DeviceId: "0002", Name: "Linux Foundation 2.0 root hub"},
  59. },
  60. wantErr: false,
  61. },
  62. {
  63. name: "with_incomplete_line",
  64. lines: []string{
  65. "Bus 004 Device 002: ID 17aa:1033",
  66. "Bus 003 Device 002: ID 17aa:1033",
  67. },
  68. want: []*sLsusbLine{
  69. {BusId: "004", Device: "002", VendorId: "17aa", DeviceId: "1033", Name: ""},
  70. {BusId: "003", Device: "002", VendorId: "17aa", DeviceId: "1033", Name: ""},
  71. },
  72. },
  73. }
  74. for _, tt := range tests {
  75. t.Run(tt.name, func(t *testing.T) {
  76. for i, line := range tt.lines {
  77. got, err := parseLsusbLine(line)
  78. if (err != nil) != tt.wantErr {
  79. t.Errorf("parseLsusb() error = %v, wantErr %v", err, tt.wantErr)
  80. return
  81. }
  82. busNum, _ := got.GetBusNumber()
  83. devNum, _ := got.GetDeviceNumber()
  84. t.Logf("line result: %#v, busNum: %d, devNum: %d", got, busNum, devNum)
  85. if !reflect.DeepEqual(got, tt.want[i]) {
  86. t.Errorf("parseLsusb() = %v, want %v", got, tt.want[i])
  87. }
  88. }
  89. })
  90. }
  91. }
  92. func Test_isUSBLinuxRootHub(t *testing.T) {
  93. type args struct {
  94. vendorId string
  95. deviceId string
  96. }
  97. tests := []struct {
  98. name string
  99. args args
  100. want bool
  101. }{
  102. {
  103. name: "1d6b:0001",
  104. args: args{
  105. "1d6b",
  106. "0001",
  107. },
  108. want: true,
  109. },
  110. {
  111. name: "1d6b:0002",
  112. args: args{
  113. "1d6b",
  114. "0002",
  115. },
  116. want: true,
  117. },
  118. {
  119. name: "1d6b:0003",
  120. args: args{
  121. "1d6b",
  122. "0003",
  123. },
  124. want: true,
  125. },
  126. {
  127. name: "1d6b:0004",
  128. args: args{
  129. "1d6b",
  130. "0004",
  131. },
  132. want: false,
  133. },
  134. }
  135. for _, tt := range tests {
  136. t.Run(tt.name, func(t *testing.T) {
  137. if got := isUSBLinuxRootHub(tt.args.vendorId, tt.args.deviceId); got != tt.want {
  138. t.Errorf("isUSBLinuxRootHub() = %v, want %v", got, tt.want)
  139. }
  140. })
  141. }
  142. }
  143. func Test_getUSBDevQemuOptions(t *testing.T) {
  144. type args struct {
  145. vendorId string
  146. deviceId string
  147. bus string
  148. addr string
  149. }
  150. tests := []struct {
  151. name string
  152. args args
  153. want map[string]string
  154. }{
  155. {
  156. name: "",
  157. args: args{
  158. vendorId: "1d6b",
  159. deviceId: "0001",
  160. bus: "001",
  161. addr: "009",
  162. },
  163. want: map[string]string{
  164. "vendorid": "0x1d6b",
  165. "productid": "0x0001",
  166. "hostbus": "1",
  167. "hostaddr": "9",
  168. },
  169. },
  170. }
  171. for _, tt := range tests {
  172. t.Run(tt.name, func(t *testing.T) {
  173. if got, _ := getUSBDevQemuOptions(tt.args.vendorId, tt.args.deviceId, tt.args.bus, tt.args.addr); !reflect.DeepEqual(got, tt.want) {
  174. t.Errorf("getUSBDevQemuOptions() = %v, want %v", got, tt.want)
  175. }
  176. })
  177. }
  178. }
  179. func Test_newLsusbRootBusTreeByLine(t *testing.T) {
  180. assert := assert.New(t)
  181. tree, _ := newLsusbTreeByLine("/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M")
  182. assert.Equal(4, tree.Bus)
  183. assert.Equal(1, tree.Port)
  184. assert.Equal(1, tree.Dev)
  185. assert.Equal(true, tree.IsRootBus)
  186. assert.Equal("xhci_hcd/2p", tree.Driver)
  187. tree, _ = newLsusbTreeByLine(" |__ Port 3: Dev 2, If 0, Class=Vendor Specific Class, Driver=, 12M")
  188. assert.Equal(false, tree.IsRootBus)
  189. assert.Equal("", tree.Driver)
  190. assert.Equal("Vendor Specific Class", tree.Class)
  191. assert.Equal(3, tree.Port)
  192. assert.Equal(2, tree.Dev)
  193. assert.Equal(0, tree.If)
  194. }
  195. func Test_parseLsusbTrees(t *testing.T) {
  196. assert := assert.New(t)
  197. input := `
  198. /: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M
  199. /: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
  200. |__ Port 3: Dev 2, If 0, Class=Vendor Specific Class, Driver=, 12M
  201. |__ Port 4: Dev 3, If 0, Class=Wireless, Driver=btusb, 480M
  202. |__ Port 4: Dev 3, If 1, Class=Wireless, Driver=btusb, 480M
  203. |__ Port 4: Dev 3, If 2, Class=Wireless, Driver=, 480M
  204. /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M
  205. /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
  206. |__ Port 3: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 12M
  207. |__ Port 3: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 12M
  208. |__ Port 3: Dev 2, If 2, Class=Human Interface Device, Driver=usbhid, 12M
  209. |__ Port 4: Dev 3, If 0, Class=Human Interface Device, Driver=usbfs, 12M
  210. `
  211. ts, err := parseLsusbTrees(strings.Split(input, "\n"))
  212. assert.Equal(nil, err)
  213. assert.Equal(
  214. `/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
  215. |__ Port 3: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 12M
  216. |__ Port 3: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 12M
  217. |__ Port 3: Dev 2, If 2, Class=Human Interface Device, Driver=usbhid, 12M
  218. |__ Port 4: Dev 3, If 0, Class=Human Interface Device, Driver=usbfs, 12M
  219. /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M
  220. /: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
  221. |__ Port 3: Dev 2, If 0, Class=Vendor Specific Class, Driver=, 12M
  222. |__ Port 4: Dev 3, If 0, Class=Wireless, Driver=btusb, 480M
  223. |__ Port 4: Dev 3, If 1, Class=Wireless, Driver=btusb, 480M
  224. |__ Port 4: Dev 3, If 2, Class=Wireless, Driver=, 480M
  225. /: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M`, ts.GetContent())
  226. bus, ok := ts.GetBus(3)
  227. assert.Equal(true, ok)
  228. dt := bus.GetDevice(1)
  229. assert.Equal("root_hub", dt.Class)
  230. dt = bus.GetDevice(2)
  231. assert.Equal("Vendor Specific Class", dt.Class)
  232. input2 := `
  233. /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/10p, 5000M
  234. /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/16p, 480M
  235. |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/7p, 480M
  236. |__ Port 10: Dev 6, If 0, Class=Human Interface Device, Driver=usbfs, 12M
  237. `
  238. ts, err = parseLsusbTrees(strings.Split(input2, "\n"))
  239. assert.Equal(nil, err)
  240. bus, ok = ts.GetBus(1)
  241. assert.Equal(true, ok)
  242. dt = bus.GetDevice(6)
  243. assert.Equal("Human Interface Device", dt.Class)
  244. }