1#!/usr/bin/env python
2# Copyright 2013 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.
5
6"""Tests for the cmd_helper module."""
7
8import unittest
9
10from devil import devil_env
11from devil.utils import lsusb
12from devil.utils import mock_calls
13
14with devil_env.SysPath(devil_env.PYMOCK_PATH):
15  import mock # pylint: disable=import-error
16
17RAW_OUTPUT = """
18Bus 003 Device 007: ID 18d1:4ee2 Google Inc. Nexus 4 (debug)
19Device Descriptor:
20  bLength                18
21  bDescriptorType         1
22  bcdUSB               2.00
23  bDeviceClass            0 (Defined at Interface level)
24  bDeviceSubClass         0
25  bDeviceProtocol         0
26  bMaxPacketSize0        64
27  idVendor           0x18d1 Google Inc.
28  idProduct          0x4ee2 Nexus 4 (debug)
29  bcdDevice            2.28
30  iManufacturer           1 LGE
31  iProduct                2 Nexus 4
32  iSerial                 3 01d2450ea194a93b
33  bNumConfigurations      1
34  Configuration Descriptor:
35    bLength                 9
36    bDescriptorType         2
37    wTotalLength           62
38    bNumInterfaces          2
39    bConfigurationValue     1
40    iConfiguration          0
41    bmAttributes         0x80
42      (Bus Powered)
43    MaxPower              500mA
44    Interface Descriptor:
45      bLength                 9
46      bDescriptorType         4
47      bInterfaceNumber        0
48      bAlternateSetting       0
49      bNumEndpoints           3
50      bInterfaceClass       255 Vendor Specific Class
51      bInterfaceSubClass    255 Vendor Specific Subclass
52      bInterfaceProtocol      0
53      iInterface              4 MTP
54      Endpoint Descriptor:
55        bLength                 7
56        bDescriptorType         5
57        bEndpointAddress     0x81  EP 1 IN
58        bmAttributes            2
59          Transfer Type            Bulk
60          Synch Type               None
61          Usage Type               Data
62        wMaxPacketSize     0x0040  1x 64 bytes
63        bInterval               0
64      Endpoint Descriptor:
65        bLength                 7
66        bDescriptorType         5
67        bEndpointAddress     0x01  EP 1 OUT
68        bmAttributes            2
69          Transfer Type            Bulk
70          Synch Type               None
71          Usage Type               Data
72        wMaxPacketSize     0x0040  1x 64 bytes
73        bInterval               0
74      Endpoint Descriptor:
75        bLength                 7
76        bDescriptorType         5
77        bEndpointAddress     0x82  EP 2 IN
78        bmAttributes            3
79          Transfer Type            Interrupt
80          Synch Type               None
81          Usage Type               Data
82        wMaxPacketSize     0x001c  1x 28 bytes
83        bInterval               6
84    Interface Descriptor:
85      bLength                 9
86      bDescriptorType         4
87      bInterfaceNumber        1
88      bAlternateSetting       0
89      bNumEndpoints           2
90      bInterfaceClass       255 Vendor Specific Class
91      bInterfaceSubClass     66
92      bInterfaceProtocol      1
93      iInterface              0
94      Endpoint Descriptor:
95        bLength                 7
96        bDescriptorType         5
97        bEndpointAddress     0x83  EP 3 IN
98        bmAttributes            2
99          Transfer Type            Bulk
100          Synch Type               None
101          Usage Type               Data
102        wMaxPacketSize     0x0040  1x 64 bytes
103        bInterval               0
104      Endpoint Descriptor:
105        bLength                 7
106        bDescriptorType         5
107        bEndpointAddress     0x02  EP 2 OUT
108        bmAttributes            2
109          Transfer Type            Bulk
110          Synch Type               None
111          Usage Type               Data
112        wMaxPacketSize     0x0040  1x 64 bytes
113        bInterval               0
114Device Qualifier (for other device speed):
115  bLength                10
116  bDescriptorType         6
117  bcdUSB               2.00
118  bDeviceClass            0 (Defined at Interface level)
119  bDeviceSubClass         0
120  bDeviceProtocol         0
121  bMaxPacketSize0        64
122  bNumConfigurations      1
123Device Status:     0x0000
124  (Bus Powered)
125"""
126DEVICE_LIST = 'Bus 003 Device 007: ID 18d1:4ee2 Google Inc. Nexus 4 (debug)'
127
128EXPECTED_RESULT = {
129    'device': '007',
130    'bus': '003',
131    'desc': 'ID 18d1:4ee2 Google Inc. Nexus 4 (debug)',
132    'Device': {
133        '_value': 'Status:',
134        '_desc': '0x0000',
135        '(Bus': {
136            '_value': 'Powered)',
137            '_desc': None
138        }
139    },
140    'Device Descriptor': {
141        'bLength': {'_value': '18', '_desc': None},
142        'bcdDevice': {'_value': '2.28', '_desc': None},
143        'bDeviceSubClass': {'_value': '0', '_desc': None},
144        'idVendor': {'_value': '0x18d1', '_desc': 'Google Inc.'},
145        'bcdUSB': {'_value': '2.00', '_desc': None},
146        'bDeviceProtocol': {'_value': '0', '_desc': None},
147        'bDescriptorType': {'_value': '1', '_desc': None},
148        'Configuration Descriptor': {
149            'bLength': {'_value': '9', '_desc': None},
150            'wTotalLength': {'_value': '62', '_desc': None},
151            'bConfigurationValue': {'_value': '1', '_desc': None},
152            'Interface Descriptor': {
153                'bLength': {'_value': '9', '_desc': None},
154                'bAlternateSetting': {'_value': '0', '_desc': None},
155                'bInterfaceNumber': {'_value': '1', '_desc': None},
156                'bNumEndpoints': {'_value': '2', '_desc': None},
157                'bDescriptorType': {'_value': '4', '_desc': None},
158                'bInterfaceSubClass': {'_value': '66', '_desc': None},
159                'bInterfaceClass': {
160                    '_value': '255',
161                    '_desc': 'Vendor Specific Class'
162                },
163                'bInterfaceProtocol': {'_value': '1', '_desc': None},
164                'Endpoint Descriptor': {
165                    'bLength': {'_value': '7', '_desc': None},
166                    'bEndpointAddress': {'_value': '0x02', '_desc': 'EP 2 OUT'},
167                    'bInterval': {'_value': '0', '_desc': None},
168                    'bDescriptorType': {'_value': '5', '_desc': None},
169                    'bmAttributes': {
170                        '_value': '2',
171                        'Transfer': {'_value': 'Type', '_desc': 'Bulk'},
172                        'Usage': {'_value': 'Type', '_desc': 'Data'},
173                        '_desc': None,
174                        'Synch': {'_value': 'Type', '_desc': 'None'}
175                    },
176                    'wMaxPacketSize': {
177                        '_value': '0x0040',
178                        '_desc': '1x 64 bytes'
179                    }
180                },
181                'iInterface': {'_value': '0', '_desc': None}
182            },
183            'bDescriptorType': {'_value': '2', '_desc': None},
184            'iConfiguration': {'_value': '0', '_desc': None},
185            'bmAttributes': {
186                '_value': '0x80',
187                '_desc': None,
188                '(Bus': {'_value': 'Powered)', '_desc': None}
189            },
190            'bNumInterfaces': {'_value': '2', '_desc': None},
191            'MaxPower': {'_value': '500mA', '_desc': None}
192        },
193        'iSerial': {'_value': '3', '_desc': '01d2450ea194a93b'},
194        'idProduct': {'_value': '0x4ee2', '_desc': 'Nexus 4 (debug)'},
195        'iManufacturer': {'_value': '1', '_desc': 'LGE'},
196        'bDeviceClass': {
197            '_value': '0',
198            '_desc': '(Defined at Interface level)'
199        },
200        'iProduct': {'_value': '2', '_desc': 'Nexus 4'},
201        'bMaxPacketSize0': {'_value': '64', '_desc': None},
202        'bNumConfigurations': {'_value': '1', '_desc': None}
203    },
204    'Device Qualifier (for other device speed)': {
205        'bLength': {'_value': '10', '_desc': None},
206        'bNumConfigurations': {'_value': '1', '_desc': None},
207        'bDeviceSubClass': {'_value': '0', '_desc': None},
208        'bcdUSB': {'_value': '2.00', '_desc': None},
209        'bDeviceProtocol': {'_value': '0', '_desc': None},
210        'bDescriptorType': {'_value': '6', '_desc': None},
211        'bDeviceClass': {
212            '_value': '0',
213            '_desc': '(Defined at Interface level)'
214        },
215        'bMaxPacketSize0': {'_value': '64', '_desc': None}
216    }
217}
218
219
220class LsusbTest(mock_calls.TestCase):
221  """Test Lsusb parsing."""
222
223  def testLsusb(self):
224    with self.assertCalls(
225        (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutputWithTimeout(
226            ['lsusb'], timeout=10), (None, DEVICE_LIST)),
227        (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutputWithTimeout(
228          ['lsusb', '-v', '-s', '003:007'], timeout=10), (None, RAW_OUTPUT))):
229      self.assertDictEqual(lsusb.lsusb().pop(), EXPECTED_RESULT)
230
231  def testGetSerial(self):
232    with self.assertCalls(
233        (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutputWithTimeout(
234            ['lsusb'], timeout=10), (None, DEVICE_LIST)),
235        (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutputWithTimeout(
236          ['lsusb', '-v', '-s', '003:007'], timeout=10), (None, RAW_OUTPUT))):
237      self.assertEqual(lsusb.get_android_devices(), ['01d2450ea194a93b'])
238
239  def testGetLsusbSerial(self):
240    with self.assertCalls(
241        (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutputWithTimeout(
242            ['lsusb'], timeout=10), (None, DEVICE_LIST)),
243        (mock.call.devil.utils.cmd_helper.GetCmdStatusAndOutputWithTimeout(
244          ['lsusb', '-v', '-s', '003:007'], timeout=10), (None, RAW_OUTPUT))):
245      out = lsusb.lsusb().pop()
246      self.assertEqual(lsusb.get_lsusb_serial(out), '01d2450ea194a93b')
247
248
249if __name__ == '__main__':
250  unittest.main()
251