2 # Copyright 2016 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 # pylint: disable=protected-access
9 Unit tests for the contents of find_usb_devices.py.
11 Device tree for these tests is as follows:
19 2: Device 020 "My Test HUB" #hub 1
20 2:1: Device 021 "battor_p7_h1_t0" #physical port 7 on hub 1, on ttyUSB0
21 2:3: Device 022 "battor_p5_h1_t1" #physical port 5 on hub 1, on ttyUSB1
22 2:4: Device 023 "My Test Internal HUB" #internal section of hub 1
23 2:4:2: Device 024 "battor_p3_h1_t2" #physical port 3 on hub 1, on ttyUSB2
24 2:4:3: Device 026 "Not a Battery Monitor" #physical port 1 on hub 1, on ttyUSB3
25 2:4:4: Device 025 "battor_p1_h1_t3" #physical port 1 on hub 1, on ttyUSB3
26 3: Device 100 "My Test HUB" #hub 2
27 3:4: Device 101 "My Test Internal HUB" #internal section of hub 2
28 3:4:4: Device 102 "battor_p1_h2_t4" #physical port 1 on hub 2, on ttyusb4
35 from devil
import devil_env
36 from devil
.utils
import battor_device_mapping
37 from devil
.utils
import find_usb_devices
38 from devil
.utils
import lsusb
39 from devil
.utils
import usb_hubs
41 with devil_env
.SysPath(devil_env
.PYMOCK_PATH
):
42 import mock
# pylint: disable=import-error
44 # Output of lsusb.lsusb().
45 # We just test that the dictionary is working by creating an
46 # "ID number" equal to (bus_num*1000)+device_num and seeing if
47 # it is picked up correctly. Also we test the description
49 DEVLIST
= [(1, 11, 'foo'),
53 (2, 20, 'My Test HUB'),
54 (2, 21, 'ID 0403:6001 battor_p7_h1_t0'),
55 (2, 22, 'ID 0403:6001 battor_p5_h1_t1'),
56 (2, 23, 'My Test Internal HUB'),
57 (2, 24, 'ID 0403:6001 battor_p3_h1_t2'),
58 (2, 25, 'ID 0403:6001 battor_p1_h1_t3'),
59 (2, 26, 'Not a Battery Monitor'),
60 (2, 100, 'My Test HUB'),
61 (2, 101, 'My Test Internal HUB'),
62 (2, 102, 'ID 0403:6001 battor_p1_h1_t4')]
65 {'bus': b
, 'device': d
, 'desc': t
, 'id': (1000*b
)+d
}
66 for (b
, d
, t
) in DEVLIST
]
69 # Note: "Lev", "Cnt", "Spd", and "MxCh" are not used by parser,
70 # so we just leave them as zeros here. Also note that the port
71 # numbers reported here start at 0, so they're 1 less than the
72 # port numbers reported elsewhere.
73 USB_DEVICES_OUTPUT
= '''
74 T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 11 Spd=000 MxCh=00
75 S: SerialNumber=FooSerial
76 T: Bus=01 Lev=00 Prnt=00 Port=01 Cnt=00 Dev#= 12 Spd=000 MxCh=00
77 S: SerialNumber=BarSerial
78 T: Bus=01 Lev=00 Prnt=00 Port=02 Cnt=00 Dev#= 13 Spd=000 MxCh=00
79 S: SerialNumber=BazSerial
81 T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 11 Spd=000 MxCh=00
83 T: Bus=02 Lev=00 Prnt=00 Port=01 Cnt=00 Dev#= 20 Spd=000 MxCh=00
84 T: Bus=02 Lev=00 Prnt=20 Port=00 Cnt=00 Dev#= 21 Spd=000 MxCh=00
85 S: SerialNumber=BattOr0
86 T: Bus=02 Lev=00 Prnt=20 Port=02 Cnt=00 Dev#= 22 Spd=000 MxCh=00
87 S: SerialNumber=BattOr1
88 T: Bus=02 Lev=00 Prnt=20 Port=03 Cnt=00 Dev#= 23 Spd=000 MxCh=00
89 T: Bus=02 Lev=00 Prnt=23 Port=01 Cnt=00 Dev#= 24 Spd=000 MxCh=00
90 S: SerialNumber=BattOr2
91 T: Bus=02 Lev=00 Prnt=23 Port=03 Cnt=00 Dev#= 25 Spd=000 MxCh=00
92 S: SerialNumber=BattOr3
93 T: Bus=02 Lev=00 Prnt=23 Port=02 Cnt=00 Dev#= 26 Spd=000 MxCh=00
95 T: Bus=02 Lev=00 Prnt=00 Port=02 Cnt=00 Dev#=100 Spd=000 MxCh=00
96 T: Bus=02 Lev=00 Prnt=100 Port=03 Cnt=00 Dev#=101 Spd=000 MxCh=00
97 T: Bus=02 Lev=00 Prnt=101 Port=03 Cnt=00 Dev#=102 Spd=000 MxCh=00
100 RAW_LSUSB_OUTPUT
= '''
101 Bus 001 Device 011: FAST foo
102 Bus 001 Device 012: FAST bar
103 Bus 001 Device 013: baz
104 Bus 002 Device 011: quux
105 Bus 002 Device 020: My Test HUB
106 Bus 002 Device 021: ID 0403:6001 battor_p7_h1_t0
107 Bus 002 Device 022: ID 0403:6001 battor_p5_h1_t1
108 Bus 002 Device 023: My Test Internal HUB
109 Bus 002 Device 024: ID 0403:6001 battor_p3_h1_t2
110 Bus 002 Device 025: ID 0403:6001 battor_p1_h1_t3
111 Bus 002 Device 026: Not a Battery Monitor
112 Bus 002 Device 100: My Test HUB
113 Bus 002 Device 101: My Test Internal HUB
114 Bus 002 Device 102: ID 0403:6001 battor_p1_h1_t4
117 LIST_TTY_OUTPUT
= '''
129 # Note: The real output will have multiple lines with
130 # ATTRS{busnum} and ATTRS{devnum}, but only the first
131 # one counts. Thus the test output duplicates this.
132 UDEVADM_USBTTY0_OUTPUT
= '''
139 UDEVADM_USBTTY1_OUTPUT
= '''
146 UDEVADM_USBTTY2_OUTPUT
= '''
153 UDEVADM_USBTTY3_OUTPUT
= '''
160 UDEVADM_USBTTY4_OUTPUT
= '''
167 UDEVADM_USBTTY5_OUTPUT
= '''
174 UDEVADM_OUTPUT_DICT
= {
175 'ttyUSB0': UDEVADM_USBTTY0_OUTPUT
,
176 'ttyUSB1': UDEVADM_USBTTY1_OUTPUT
,
177 'ttyUSB2': UDEVADM_USBTTY2_OUTPUT
,
178 'ttyUSB3': UDEVADM_USBTTY3_OUTPUT
,
179 'ttyUSB4': UDEVADM_USBTTY4_OUTPUT
,
180 'ttyUSB5': UDEVADM_USBTTY5_OUTPUT
}
182 # Identification criteria for Plugable 7-Port Hub
184 """Check if a node is a Plugable 7-Port Hub
186 The topology of this device is a 4-port hub,
187 with another 4-port hub connected on port 4.
189 if not isinstance(node
, find_usb_devices
.USBDeviceNode
):
191 if 'Test HUB' not in node
.desc
:
193 if not node
.HasPort(4):
195 return 'Test Internal HUB' in node
.PortToDevice(4).desc
197 TEST_HUB
= usb_hubs
.HubType(isTestHub
,
201 4:{1:4, 2:3, 3:2, 4:1}})
203 class USBScriptTest(unittest
.TestCase
):
205 find_usb_devices
._GetTtyUSBInfo
= mock
.Mock(
206 side_effect
=lambda x
: UDEVADM_OUTPUT_DICT
[x
])
207 find_usb_devices
._GetParsedLSUSBOutput
= mock
.Mock(
208 return_value
=LSUSB_OUTPUT
)
209 find_usb_devices
._GetUSBDevicesOutput
= mock
.Mock(
210 return_value
=USB_DEVICES_OUTPUT
)
211 find_usb_devices
._GetCommList
= mock
.Mock(
212 return_value
=LIST_TTY_OUTPUT
)
213 lsusb
.raw_lsusb
= mock
.Mock(
214 return_value
=RAW_LSUSB_OUTPUT
)
216 def testIsBattOr(self
):
217 bd
= find_usb_devices
.GetBusNumberToDeviceTreeMap()
218 self
.assertTrue(battor_device_mapping
.IsBattOr('ttyUSB3', bd
))
219 self
.assertFalse(battor_device_mapping
.IsBattOr('ttyUSB5', bd
))
221 def testGetBattOrs(self
):
222 bd
= find_usb_devices
.GetBusNumberToDeviceTreeMap()
223 self
.assertEquals(battor_device_mapping
.GetBattOrList(bd
),
224 ['ttyUSB0', 'ttyUSB1', 'ttyUSB2',
225 'ttyUSB3', 'ttyUSB4'])
227 def testGetTTYDevices(self
):
228 pp
= find_usb_devices
.GetAllPhysicalPortToTTYMaps([TEST_HUB
])
230 self
.assertEquals(result
[0], {7:'ttyUSB0',
235 self
.assertEquals(result
[1], {1:'ttyUSB4'})
237 def testGetPortDeviceMapping(self
):
238 pp
= find_usb_devices
.GetAllPhysicalPortToBusDeviceMaps([TEST_HUB
])
240 self
.assertEquals(result
[0], {7:(2, 21),
245 self
.assertEquals(result
[1], {1:(2, 102)})
247 def testGetSerialMapping(self
):
248 pp
= find_usb_devices
.GetAllPhysicalPortToSerialMaps([TEST_HUB
])
250 self
.assertEquals(result
[0], {7:'BattOr0',
254 self
.assertEquals(result
[1], {})
256 def testFastDeviceDescriptions(self
):
257 bd
= find_usb_devices
.GetBusNumberToDeviceTreeMap()
258 dev_foo
= bd
[1].FindDeviceNumber(11)
259 dev_bar
= bd
[1].FindDeviceNumber(12)
260 dev_battor_p7_h1_t0
= bd
[2].FindDeviceNumber(21)
261 self
.assertEquals(dev_foo
.desc
, 'FAST foo')
262 self
.assertEquals(dev_bar
.desc
, 'FAST bar')
263 self
.assertEquals(dev_battor_p7_h1_t0
.desc
,
264 'ID 0403:6001 battor_p7_h1_t0')
266 def testDeviceDescriptions(self
):
267 bd
= find_usb_devices
.GetBusNumberToDeviceTreeMap(fast
=False)
268 dev_foo
= bd
[1].FindDeviceNumber(11)
269 dev_bar
= bd
[1].FindDeviceNumber(12)
270 dev_battor_p7_h1_t0
= bd
[2].FindDeviceNumber(21)
271 self
.assertEquals(dev_foo
.desc
, 'foo')
272 self
.assertEquals(dev_bar
.desc
, 'bar')
273 self
.assertEquals(dev_battor_p7_h1_t0
.desc
,
274 'ID 0403:6001 battor_p7_h1_t0')
276 def testDeviceInformation(self
):
277 bd
= find_usb_devices
.GetBusNumberToDeviceTreeMap(fast
=False)
278 dev_foo
= bd
[1].FindDeviceNumber(11)
279 dev_bar
= bd
[1].FindDeviceNumber(12)
280 dev_battor_p7_h1_t0
= bd
[2].FindDeviceNumber(21)
281 self
.assertEquals(dev_foo
.info
['id'], 1011)
282 self
.assertEquals(dev_bar
.info
['id'], 1012)
283 self
.assertEquals(dev_battor_p7_h1_t0
.info
['id'], 2021)
285 def testSerialNumber(self
):
286 bd
= find_usb_devices
.GetBusNumberToDeviceTreeMap(fast
=False)
287 dev_foo
= bd
[1].FindDeviceNumber(11)
288 dev_bar
= bd
[1].FindDeviceNumber(12)
289 dev_battor_p7_h1_t0
= bd
[2].FindDeviceNumber(21)
290 self
.assertEquals(dev_foo
.serial
, 'FooSerial')
291 self
.assertEquals(dev_bar
.serial
, 'BarSerial')
292 self
.assertEquals(dev_battor_p7_h1_t0
.serial
, 'BattOr0')
294 def testBattOrDictMapping(self
):
295 map_dict
= {'Phone1':'BattOr1', 'Phone2':'BattOr2', 'Phone3':'BattOr3'}
296 a1
= battor_device_mapping
.GetBattOrPathFromPhoneSerial(
297 'Phone1', serial_map
=map_dict
)
298 a2
= battor_device_mapping
.GetBattOrPathFromPhoneSerial(
299 'Phone2', serial_map
=map_dict
)
300 a3
= battor_device_mapping
.GetBattOrPathFromPhoneSerial(
301 'Phone3', serial_map
=map_dict
)
302 self
.assertEquals(a1
, '/dev/ttyUSB1')
303 self
.assertEquals(a2
, '/dev/ttyUSB2')
304 self
.assertEquals(a3
, '/dev/ttyUSB3')
306 def testBattOrDictFromFileMapping(self
):
308 map_dict
= {'Phone1':'BattOr1', 'Phone2':'BattOr2', 'Phone3':'BattOr3'}
309 curr_dir
= os
.path
.dirname(os
.path
.realpath(__file__
))
310 filename
= os
.path
.join(curr_dir
, 'test', 'data', 'test_write_map.json')
311 battor_device_mapping
.WriteSerialMapFile(filename
, map_dict
)
312 a1
= battor_device_mapping
.GetBattOrPathFromPhoneSerial(
313 'Phone1', serial_map_file
=filename
)
314 a2
= battor_device_mapping
.GetBattOrPathFromPhoneSerial(
315 'Phone2', serial_map_file
=filename
)
316 a3
= battor_device_mapping
.GetBattOrPathFromPhoneSerial(
317 'Phone3', serial_map_file
=filename
)
320 self
.assertEquals(a1
, '/dev/ttyUSB1')
321 self
.assertEquals(a2
, '/dev/ttyUSB2')
322 self
.assertEquals(a3
, '/dev/ttyUSB3')
324 def testReadSerialMapFile(self
):
325 curr_dir
= os
.path
.dirname(os
.path
.realpath(__file__
))
326 map_dict
= battor_device_mapping
.ReadSerialMapFile(
327 os
.path
.join(curr_dir
, 'test', 'data', 'test_serial_map.json'))
328 self
.assertEquals(len(map_dict
.keys()), 3)
329 self
.assertEquals(map_dict
['Phone1'], 'BattOr1')
330 self
.assertEquals(map_dict
['Phone2'], 'BattOr2')
331 self
.assertEquals(map_dict
['Phone3'], 'BattOr3')
333 original_PPTSM
= find_usb_devices
.GetAllPhysicalPortToSerialMaps
334 original_PPTTM
= find_usb_devices
.GetAllPhysicalPortToTTYMaps
335 original_GBL
= battor_device_mapping
.GetBattOrList
336 original_GBNDM
= find_usb_devices
.GetBusNumberToDeviceTreeMap
337 original_IB
= battor_device_mapping
.IsBattOr
338 original_GBSM
= battor_device_mapping
.GetBattOrSerialNumbers
340 def setup_battor_test(serial
, tty
, battor
, bser
=None):
341 serial_mapper
= mock
.Mock(return_value
=serial
)
342 tty_mapper
= mock
.Mock(return_value
=tty
)
343 battor_lister
= mock
.Mock(return_value
=battor
)
344 devtree
= mock
.Mock(return_value
=None)
345 is_battor
= mock
.Mock(side_effect
=lambda x
, y
: x
in battor
)
346 battor_serials
= mock
.Mock(return_value
=bser
)
347 find_usb_devices
.GetAllPhysicalPortToSerialMaps
= serial_mapper
348 find_usb_devices
.GetAllPhysicalPortToTTYMaps
= tty_mapper
349 battor_device_mapping
.GetBattOrList
= battor_lister
350 find_usb_devices
.GetBusNumberToDeviceTreeMap
= devtree
351 battor_device_mapping
.IsBattOr
= is_battor
352 battor_device_mapping
.GetBattOrSerialNumbers
= battor_serials
354 class BattOrMappingTest(unittest
.TestCase
):
356 find_usb_devices
.GetAllPhysicalPortToSerialMaps
= original_PPTSM
357 find_usb_devices
.GetAllPhysicalPortToTTYMaps
= original_PPTTM
358 battor_device_mapping
.GetBattOrList
= original_GBL
359 find_usb_devices
.GetBusNumberToDeviceTreeMap
= original_GBNDM
360 battor_device_mapping
.IsBattOr
= original_IB
361 battor_device_mapping
.GetBattOrSerialNumbers
= original_GBSM
363 def test_generate_serial_map(self
):
364 setup_battor_test([{1:'Phn1', 2:'Phn2', 3:'Phn3'},
365 {1:'Bat1', 2:'Bat2', 3:'Bat3'}],
367 {1:'ttyUSB0', 2:'ttyUSB1', 3:'ttyUSB2'}],
368 ['ttyUSB0', 'ttyUSB1', 'ttyUSB2'],
369 ['Bat1', 'Bat2', 'Bat3'])
370 result
= battor_device_mapping
.GenerateSerialMap()
371 self
.assertEqual(len(result
), 3)
372 self
.assertEqual(result
['Phn1'], 'Bat1')
373 self
.assertEqual(result
['Phn2'], 'Bat2')
374 self
.assertEqual(result
['Phn3'], 'Bat3')
377 if __name__
== "__main__":
378 logging
.getLogger().setLevel(logging
.DEBUG
)
379 unittest
.main(verbosity
=2)