MD Downloads: only show "Today" or "Yesterday" when available
[chromium-blink-merge.git] / tools / usb_gadget / gadget_test.py
blob2440983baefc165a3bb44639f73f58656a6114b6
1 #!/usr/bin/python
2 # Copyright 2014 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 import unittest
7 import uuid
9 import mock
11 import gadget
12 import usb_constants
13 import usb_descriptors
16 device_desc = usb_descriptors.DeviceDescriptor(
17 idVendor=0x18D1, # Google Inc.
18 idProduct=0xFF00,
19 bcdUSB=0x0200,
20 iManufacturer=1,
21 iProduct=2,
22 iSerialNumber=3,
23 bNumConfigurations=1,
24 bcdDevice=0x0100)
26 fs_config_desc = usb_descriptors.ConfigurationDescriptor(
27 bmAttributes=0xC0,
28 MaxPower=50)
30 fs_interface_desc = usb_descriptors.InterfaceDescriptor(
31 bInterfaceNumber=0
33 fs_config_desc.AddInterface(fs_interface_desc)
35 fs_bulk_in_endpoint_desc = usb_descriptors.EndpointDescriptor(
36 bEndpointAddress=0x01,
37 bmAttributes=usb_constants.TransferType.BULK,
38 wMaxPacketSize=64,
39 bInterval=0
41 fs_interface_desc.AddEndpoint(fs_bulk_in_endpoint_desc)
43 fs_bulk_out_endpoint_desc = usb_descriptors.EndpointDescriptor(
44 bEndpointAddress=0x81,
45 bmAttributes=usb_constants.TransferType.BULK,
46 wMaxPacketSize=64,
47 bInterval=0
49 fs_interface_desc.AddEndpoint(fs_bulk_out_endpoint_desc)
51 fs_alt_interface_desc = usb_descriptors.InterfaceDescriptor(
52 bInterfaceNumber=0,
53 bAlternateSetting=1
55 fs_config_desc.AddInterface(fs_alt_interface_desc)
57 fs_interrupt_in_endpoint_desc = usb_descriptors.EndpointDescriptor(
58 bEndpointAddress=0x01,
59 bmAttributes=usb_constants.TransferType.INTERRUPT,
60 wMaxPacketSize=64,
61 bInterval=1
63 fs_alt_interface_desc.AddEndpoint(fs_interrupt_in_endpoint_desc)
65 fs_interrupt_out_endpoint_desc = usb_descriptors.EndpointDescriptor(
66 bEndpointAddress=0x81,
67 bmAttributes=usb_constants.TransferType.INTERRUPT,
68 wMaxPacketSize=64,
69 bInterval=1
71 fs_alt_interface_desc.AddEndpoint(fs_interrupt_out_endpoint_desc)
73 hs_config_desc = usb_descriptors.ConfigurationDescriptor(
74 bmAttributes=0xC0,
75 MaxPower=50)
77 hs_interface_desc = usb_descriptors.InterfaceDescriptor(
78 bInterfaceNumber=0
80 hs_config_desc.AddInterface(hs_interface_desc)
82 hs_bulk_in_endpoint_desc = usb_descriptors.EndpointDescriptor(
83 bEndpointAddress=0x01,
84 bmAttributes=usb_constants.TransferType.BULK,
85 wMaxPacketSize=512,
86 bInterval=0
88 hs_interface_desc.AddEndpoint(hs_bulk_in_endpoint_desc)
90 hs_bulk_out_endpoint_desc = usb_descriptors.EndpointDescriptor(
91 bEndpointAddress=0x81,
92 bmAttributes=usb_constants.TransferType.BULK,
93 wMaxPacketSize=512,
94 bInterval=0
96 hs_interface_desc.AddEndpoint(hs_bulk_out_endpoint_desc)
98 hs_alt_interface_desc = usb_descriptors.InterfaceDescriptor(
99 bInterfaceNumber=0,
100 bAlternateSetting=1
102 hs_config_desc.AddInterface(hs_alt_interface_desc)
104 hs_interrupt_in_endpoint_desc = usb_descriptors.EndpointDescriptor(
105 bEndpointAddress=0x01,
106 bmAttributes=usb_constants.TransferType.INTERRUPT,
107 wMaxPacketSize=256,
108 bInterval=1
110 hs_alt_interface_desc.AddEndpoint(hs_interrupt_in_endpoint_desc)
112 hs_interrupt_out_endpoint_desc = usb_descriptors.EndpointDescriptor(
113 bEndpointAddress=0x81,
114 bmAttributes=usb_constants.TransferType.INTERRUPT,
115 wMaxPacketSize=256,
116 bInterval=1
118 hs_alt_interface_desc.AddEndpoint(hs_interrupt_out_endpoint_desc)
121 class GadgetTest(unittest.TestCase):
123 def test_get_descriptors(self):
124 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
125 self.assertEquals(g.GetDeviceDescriptor(), device_desc)
126 self.assertEquals(g.GetFullSpeedConfigurationDescriptor(), fs_config_desc)
127 self.assertEquals(g.GetHighSpeedConfigurationDescriptor(), hs_config_desc)
128 with self.assertRaisesRegexp(RuntimeError, 'not connected'):
129 g.GetConfigurationDescriptor()
131 def test_connect_full_speed(self):
132 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
133 g.Connected(mock.Mock(), usb_constants.Speed.FULL)
134 self.assertTrue(g.IsConnected())
135 self.assertEquals(g.GetSpeed(), usb_constants.Speed.FULL)
136 self.assertEquals(g.GetConfigurationDescriptor(), fs_config_desc)
137 g.Disconnected()
138 self.assertFalse(g.IsConnected())
140 def test_connect_high_speed(self):
141 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
142 g.Connected(mock.Mock(), usb_constants.Speed.HIGH)
143 self.assertTrue(g.IsConnected())
144 self.assertEquals(g.GetSpeed(), usb_constants.Speed.HIGH)
145 self.assertEquals(g.GetConfigurationDescriptor(), hs_config_desc)
146 g.Disconnected()
147 self.assertFalse(g.IsConnected())
149 def test_string_index_out_of_range(self):
150 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
151 with self.assertRaisesRegexp(ValueError, 'index out of range'):
152 g.AddStringDescriptor(0, 'Hello world!')
154 def test_language_id_out_of_range(self):
155 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
156 with self.assertRaisesRegexp(ValueError, 'language code out of range'):
157 g.AddStringDescriptor(1, 'Hello world!', lang=-1)
159 def test_get_languages(self):
160 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
161 g.AddStringDescriptor(1, 'Hello world!')
162 desc = g.ControlRead(0x80, 6, 0x0300, 0, 255)
163 self.assertEquals(desc, '\x04\x03\x09\x04')
165 def test_get_string_descriptor(self):
166 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
167 g.AddStringDescriptor(1, 'Hello world!')
168 desc = g.ControlRead(0x80, 6, 0x0301, 0x0409, 255)
169 self.assertEquals(desc, '\x1A\x03H\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d\0!\0')
171 def test_get_missing_string_descriptor(self):
172 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
173 g.AddStringDescriptor(1, 'Hello world!')
174 desc = g.ControlRead(0x80, 6, 0x0302, 0x0409, 255)
175 self.assertEquals(desc, None)
177 def test_get_missing_string_language(self):
178 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
179 g.AddStringDescriptor(1, 'Hello world!')
180 desc = g.ControlRead(0x80, 6, 0x0301, 0x040C, 255)
181 self.assertEquals(desc, None)
183 def test_class_and_vendor_transfers(self):
184 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
185 self.assertIsNone(g.ControlRead(0xA0, 0, 0, 0, 0))
186 self.assertIsNone(g.ControlRead(0xC0, 0, 0, 0, 0))
187 self.assertIsNone(g.ControlWrite(0x20, 0, 0, 0, ''))
188 self.assertIsNone(g.ControlWrite(0x40, 0, 0, 0, ''))
190 def test_set_configuration(self):
191 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
192 chip = mock.Mock()
193 g.Connected(chip, usb_constants.Speed.HIGH)
194 g.ControlWrite(0, 9, 1, 0, 0)
195 chip.StartEndpoint.assert_has_calls([
196 mock.call(hs_bulk_in_endpoint_desc),
197 mock.call(hs_bulk_out_endpoint_desc)
200 def test_set_configuration_zero(self):
201 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
202 chip = mock.Mock()
203 g.Connected(chip, usb_constants.Speed.HIGH)
204 g.ControlWrite(0, 9, 1, 0, 0)
205 chip.StartEndpoint.reset_mock()
206 g.ControlWrite(0, 9, 0, 0, 0)
207 chip.StopEndpoint.assert_has_calls([
208 mock.call(0x01),
209 mock.call(0x81)
212 def test_set_bad_configuration(self):
213 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
214 g.Connected(mock.Mock(), usb_constants.Speed.HIGH)
215 self.assertIsNone(g.ControlWrite(0, 9, 2, 0, 0))
217 def test_set_interface(self):
218 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
219 chip = mock.Mock()
220 g.Connected(chip, usb_constants.Speed.HIGH)
221 self.assertTrue(g.ControlWrite(0, 9, 1, 0, 0))
222 chip.reset_mock()
223 self.assertTrue(g.ControlWrite(1, 11, 1, 0, 0))
224 chip.StopEndpoint.assert_has_calls([
225 mock.call(0x01),
226 mock.call(0x81)
228 chip.StartEndpoint.assert_has_calls([
229 mock.call(hs_interrupt_in_endpoint_desc),
230 mock.call(hs_interrupt_out_endpoint_desc)
232 chip.reset_mock()
233 self.assertTrue(g.ControlWrite(1, 11, 0, 0, 0))
234 chip.StopEndpoint.assert_has_calls([
235 mock.call(0x01),
236 mock.call(0x81)
238 chip.StartEndpoint.assert_has_calls([
239 mock.call(hs_bulk_in_endpoint_desc),
240 mock.call(hs_bulk_out_endpoint_desc)
243 def test_set_bad_interface(self):
244 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
245 g.Connected(mock.Mock(), usb_constants.Speed.HIGH)
246 self.assertTrue(g.ControlWrite(0, 9, 1, 0, 0))
247 self.assertIsNone(g.ControlWrite(1, 11, 0, 1, 0))
249 def test_send_packet(self):
250 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
251 chip = mock.Mock()
252 g.Connected(chip, usb_constants.Speed.HIGH)
253 g.SendPacket(0x81, 'Hello world!')
254 chip.SendPacket.assert_called_once_with(0x81, 'Hello world!')
256 def test_send_packet_disconnected(self):
257 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
258 with self.assertRaisesRegexp(RuntimeError, 'not connected'):
259 g.SendPacket(0x81, 'Hello world!')
260 g.Connected(mock.Mock(), usb_constants.Speed.HIGH)
261 g.SendPacket(0x81, 'Hello world!')
262 g.Disconnected()
263 with self.assertRaisesRegexp(RuntimeError, 'not connected'):
264 g.SendPacket(0x81, 'Hello world!')
266 def test_send_invalid_endpoint(self):
267 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
268 chip = mock.Mock()
269 g.Connected(chip, usb_constants.Speed.HIGH)
270 with self.assertRaisesRegexp(ValueError, 'non-input endpoint'):
271 g.SendPacket(0x01, 'Hello world!')
273 def test_receive_packet(self):
274 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
275 self.assertIsNone(g.ReceivePacket(0x01, 'Hello world!'))
277 def test_halt_endpoint(self):
278 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
279 chip = mock.Mock()
280 g.Connected(chip, usb_constants.Speed.HIGH)
281 g.HaltEndpoint(0x01)
282 chip.HaltEndpoint.assert_called_once_with(0x01)
284 def test_get_microsoft_os_string_descriptor(self):
285 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
286 g.EnableMicrosoftOSDescriptorsV1(vendor_code=0x42)
287 os_string_descriptor = g.ControlRead(0x80,
288 usb_constants.Request.GET_DESCRIPTOR,
289 0x03EE,
290 0x0000,
291 0x12)
292 self.assertEqual(os_string_descriptor,
293 "\x12\x03M\x00S\x00F\x00T\x001\x000\x000\x00\x42\x00")
295 def test_get_microsoft_os_compat_id_descriptor(self):
296 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
297 g.EnableMicrosoftOSDescriptorsV1(vendor_code=0x42)
298 g.SetMicrosoftCompatId(0, 'WINUSB')
299 chip = mock.Mock()
300 g.Connected(chip, usb_constants.Speed.HIGH)
302 expected_compatid_header = \
303 "\x28\x00\x00\x00\x00\x01\x04\x00\x01\0\0\0\0\0\0\0"
304 compatid_header = g.ControlRead(0xC0, 0x42, 0x0000, 0x0004, 0x0010)
305 self.assertEqual(compatid_header, expected_compatid_header)
307 compatid_descriptor = g.ControlRead(0xC0, 0x42, 0x0000, 0x0004, 0x0028)
308 self.assertEqual(compatid_descriptor,
309 expected_compatid_header +
310 "\x00\x01WINUSB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
312 def test_get_bos_descriptor(self):
313 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
314 self.assertIsNone(g.ControlRead(0x80, 0x06, 0x0F00, 0x0000, 5))
316 container_id = uuid.uuid4()
317 g.AddDeviceCapabilityDescriptor(usb_descriptors.ContainerIdDescriptor(
318 ContainerID=container_id.bytes_le))
319 bos_descriptor_header = g.ControlRead(0x80, 0x06, 0x0F00, 0x0000, 5)
320 self.assertEquals('\x05\x0F\x19\x00\x01', bos_descriptor_header)
322 bos_descriptor = g.ControlRead(0x80, 0x06, 0x0F00, 0x0000, 25)
323 self.assertEquals(
324 '\x05\x0F\x19\x00\x01\x14\x10\x04\x00' + container_id.bytes_le,
325 bos_descriptor)
327 def test_get_microsoft_os_20_descriptor_set(self):
328 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc)
329 g.EnableMicrosoftOSDescriptorsV2(vendor_code=0x42)
330 g.SetMicrosoftCompatId(0, 'WINUSB')
331 chip = mock.Mock()
332 g.Connected(chip, usb_constants.Speed.HIGH)
334 bos_descriptor = g.ControlRead(0x80, 0x06, 0x0F00, 0x0000, 33)
335 self.assertEquals(
336 '\x05\x0F\x21\x00\x01' +
337 '\x1C\x10\x05\x00' +
338 uuid.UUID('{D8DD60DF-4589-4CC7-9CD2-659D9E648A9F}').bytes_le +
339 '\x00\x00\x03\x06\x2E\x00\x42\x00',
340 bos_descriptor)
342 descriptor_set = g.ControlRead(0xC0, 0x42, 0x0000, 0x0007, 48)
343 self.assertEquals(
344 '\x0A\x00\x00\x00\x00\x00\x03\x06\x2E\x00' +
345 '\x08\x00\x01\x00\x00\x00\x24\x00' +
346 '\x08\x00\x02\x00\x00\x00\x1C\x00' +
347 '\x14\x00\x03\x00WINUSB\0\0\0\0\0\0\0\0\0\0',
348 descriptor_set)
351 if __name__ == '__main__':
352 unittest.main()