Update sdk/platform-tools to version 26.0.0.
[android_tools.git] / sdk / platform-tools / systrace / catapult / devil / devil / utils / find_usb_devices_test.py
blobe8b00c85ee12ccfdca19030661b0e211bf0f690c
1 #!/usr/bin/env python
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
8 """
9 Unit tests for the contents of find_usb_devices.py.
11 Device tree for these tests is as follows:
12 Bus 001:
13 1: Device 011 "foo"
14 2: Device 012 "bar"
15 3: Device 013 "baz"
17 Bus 002:
18 1: Device 011 "quux"
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
29 """
31 import logging
32 import os
33 import unittest
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'),
50 (1, 12, 'bar'),
51 (1, 13, 'baz'),
52 (2, 11, 'quux'),
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')]
64 LSUSB_OUTPUT = [
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
98 '''
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 = '''
118 ttyUSB0
119 Something-else-0
120 ttyUSB1
121 ttyUSB2
122 Something-else-1
123 ttyUSB3
124 ttyUSB4
125 Something-else-2
126 ttyUSB5
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 = '''
133 ATTRS{busnum}=="2"
134 ATTRS{devnum}=="21"
135 ATTRS{busnum}=="0"
136 ATTRS{devnum}=="0"
139 UDEVADM_USBTTY1_OUTPUT = '''
140 ATTRS{busnum}=="2"
141 ATTRS{devnum}=="22"
142 ATTRS{busnum}=="0"
143 ATTRS{devnum}=="0"
146 UDEVADM_USBTTY2_OUTPUT = '''
147 ATTRS{busnum}=="2"
148 ATTRS{devnum}=="24"
149 ATTRS{busnum}=="0"
150 ATTRS{devnum}=="0"
153 UDEVADM_USBTTY3_OUTPUT = '''
154 ATTRS{busnum}=="2"
155 ATTRS{devnum}=="25"
156 ATTRS{busnum}=="0"
157 ATTRS{devnum}=="0"
160 UDEVADM_USBTTY4_OUTPUT = '''
161 ATTRS{busnum}=="2"
162 ATTRS{devnum}=="102"
163 ATTRS{busnum}=="0"
164 ATTRS{devnum}=="0"
167 UDEVADM_USBTTY5_OUTPUT = '''
168 ATTRS{busnum}=="2"
169 ATTRS{devnum}=="26"
170 ATTRS{busnum}=="0"
171 ATTRS{devnum}=="0"
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
183 def isTestHub(node):
184 """Check if a node is a Plugable 7-Port Hub
185 (Model USB2-HUB7BC)
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):
190 return False
191 if 'Test HUB' not in node.desc:
192 return False
193 if not node.HasPort(4):
194 return False
195 return 'Test Internal HUB' in node.PortToDevice(4).desc
197 TEST_HUB = usb_hubs.HubType(isTestHub,
198 {1:7,
199 2:6,
200 3:5,
201 4:{1:4, 2:3, 3:2, 4:1}})
203 class USBScriptTest(unittest.TestCase):
204 def setUp(self):
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])
229 result = list(pp)
230 self.assertEquals(result[0], {7:'ttyUSB0',
231 5:'ttyUSB1',
232 3:'ttyUSB2',
233 2:'ttyUSB5',
234 1:'ttyUSB3'})
235 self.assertEquals(result[1], {1:'ttyUSB4'})
237 def testGetPortDeviceMapping(self):
238 pp = find_usb_devices.GetAllPhysicalPortToBusDeviceMaps([TEST_HUB])
239 result = list(pp)
240 self.assertEquals(result[0], {7:(2, 21),
241 5:(2, 22),
242 3:(2, 24),
243 2:(2, 26),
244 1:(2, 25)})
245 self.assertEquals(result[1], {1:(2, 102)})
247 def testGetSerialMapping(self):
248 pp = find_usb_devices.GetAllPhysicalPortToSerialMaps([TEST_HUB])
249 result = list(pp)
250 self.assertEquals(result[0], {7:'BattOr0',
251 5:'BattOr1',
252 3:'BattOr2',
253 1:'BattOr3'})
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):
307 try:
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)
318 finally:
319 os.remove(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):
355 def tearDown(self):
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'}],
366 [{},
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)