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. 5 6 import unittest 7 8 import mock 9 10 import gadget 11 import usb_constants 12 import usb_descriptors 13 14 15 device_desc = usb_descriptors.DeviceDescriptor( 16 idVendor=0x18D1, # Google Inc. 17 idProduct=0xFF00, 18 bcdUSB=0x0200, 19 iManufacturer=1, 20 iProduct=2, 21 iSerialNumber=3, 22 bNumConfigurations=1, 23 bcdDevice=0x0100) 24 25 fs_config_desc = usb_descriptors.ConfigurationDescriptor( 26 bmAttributes=0xC0, 27 MaxPower=50) 28 29 fs_interface_desc = usb_descriptors.InterfaceDescriptor( 30 bInterfaceNumber=0 31 ) 32 fs_config_desc.AddInterface(fs_interface_desc) 33 34 fs_bulk_in_endpoint_desc = usb_descriptors.EndpointDescriptor( 35 bEndpointAddress=0x01, 36 bmAttributes=usb_constants.TransferType.BULK, 37 wMaxPacketSize=64, 38 bInterval=0 39 ) 40 fs_interface_desc.AddEndpoint(fs_bulk_in_endpoint_desc) 41 42 fs_bulk_out_endpoint_desc = usb_descriptors.EndpointDescriptor( 43 bEndpointAddress=0x81, 44 bmAttributes=usb_constants.TransferType.BULK, 45 wMaxPacketSize=64, 46 bInterval=0 47 ) 48 fs_interface_desc.AddEndpoint(fs_bulk_out_endpoint_desc) 49 50 fs_alt_interface_desc = usb_descriptors.InterfaceDescriptor( 51 bInterfaceNumber=0, 52 bAlternateSetting=1 53 ) 54 fs_config_desc.AddInterface(fs_alt_interface_desc) 55 56 fs_interrupt_in_endpoint_desc = usb_descriptors.EndpointDescriptor( 57 bEndpointAddress=0x01, 58 bmAttributes=usb_constants.TransferType.INTERRUPT, 59 wMaxPacketSize=64, 60 bInterval=1 61 ) 62 fs_alt_interface_desc.AddEndpoint(fs_interrupt_in_endpoint_desc) 63 64 fs_interrupt_out_endpoint_desc = usb_descriptors.EndpointDescriptor( 65 bEndpointAddress=0x81, 66 bmAttributes=usb_constants.TransferType.INTERRUPT, 67 wMaxPacketSize=64, 68 bInterval=1 69 ) 70 fs_alt_interface_desc.AddEndpoint(fs_interrupt_out_endpoint_desc) 71 72 hs_config_desc = usb_descriptors.ConfigurationDescriptor( 73 bmAttributes=0xC0, 74 MaxPower=50) 75 76 hs_interface_desc = usb_descriptors.InterfaceDescriptor( 77 bInterfaceNumber=0 78 ) 79 hs_config_desc.AddInterface(hs_interface_desc) 80 81 hs_bulk_in_endpoint_desc = usb_descriptors.EndpointDescriptor( 82 bEndpointAddress=0x01, 83 bmAttributes=usb_constants.TransferType.BULK, 84 wMaxPacketSize=512, 85 bInterval=0 86 ) 87 hs_interface_desc.AddEndpoint(hs_bulk_in_endpoint_desc) 88 89 hs_bulk_out_endpoint_desc = usb_descriptors.EndpointDescriptor( 90 bEndpointAddress=0x81, 91 bmAttributes=usb_constants.TransferType.BULK, 92 wMaxPacketSize=512, 93 bInterval=0 94 ) 95 hs_interface_desc.AddEndpoint(hs_bulk_out_endpoint_desc) 96 97 hs_alt_interface_desc = usb_descriptors.InterfaceDescriptor( 98 bInterfaceNumber=0, 99 bAlternateSetting=1 100 ) 101 hs_config_desc.AddInterface(hs_alt_interface_desc) 102 103 hs_interrupt_in_endpoint_desc = usb_descriptors.EndpointDescriptor( 104 bEndpointAddress=0x01, 105 bmAttributes=usb_constants.TransferType.INTERRUPT, 106 wMaxPacketSize=256, 107 bInterval=1 108 ) 109 hs_alt_interface_desc.AddEndpoint(hs_interrupt_in_endpoint_desc) 110 111 hs_interrupt_out_endpoint_desc = usb_descriptors.EndpointDescriptor( 112 bEndpointAddress=0x81, 113 bmAttributes=usb_constants.TransferType.INTERRUPT, 114 wMaxPacketSize=256, 115 bInterval=1 116 ) 117 hs_alt_interface_desc.AddEndpoint(hs_interrupt_out_endpoint_desc) 118 119 120 class GadgetTest(unittest.TestCase): 121 122 def test_get_descriptors(self): 123 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 124 self.assertEquals(g.GetDeviceDescriptor(), device_desc) 125 self.assertEquals(g.GetFullSpeedConfigurationDescriptor(), fs_config_desc) 126 self.assertEquals(g.GetHighSpeedConfigurationDescriptor(), hs_config_desc) 127 with self.assertRaisesRegexp(RuntimeError, 'not connected'): 128 g.GetConfigurationDescriptor() 129 130 def test_connect_full_speed(self): 131 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 132 g.Connected(mock.Mock(), usb_constants.Speed.FULL) 133 self.assertTrue(g.IsConnected()) 134 self.assertEquals(g.GetSpeed(), usb_constants.Speed.FULL) 135 self.assertEquals(g.GetConfigurationDescriptor(), fs_config_desc) 136 g.Disconnected() 137 self.assertFalse(g.IsConnected()) 138 139 def test_connect_high_speed(self): 140 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 141 g.Connected(mock.Mock(), usb_constants.Speed.HIGH) 142 self.assertTrue(g.IsConnected()) 143 self.assertEquals(g.GetSpeed(), usb_constants.Speed.HIGH) 144 self.assertEquals(g.GetConfigurationDescriptor(), hs_config_desc) 145 g.Disconnected() 146 self.assertFalse(g.IsConnected()) 147 148 def test_string_index_out_of_range(self): 149 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 150 with self.assertRaisesRegexp(ValueError, 'index out of range'): 151 g.AddStringDescriptor(0, 'Hello world!') 152 153 def test_language_id_out_of_range(self): 154 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 155 with self.assertRaisesRegexp(ValueError, 'language code out of range'): 156 g.AddStringDescriptor(1, 'Hello world!', lang=-1) 157 158 def test_get_languages(self): 159 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 160 g.AddStringDescriptor(1, 'Hello world!') 161 desc = g.ControlRead(0x80, 6, 0x0300, 0, 255) 162 self.assertEquals(desc, '\x04\x03\x09\x04') 163 164 def test_get_string_descriptor(self): 165 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 166 g.AddStringDescriptor(1, 'Hello world!') 167 desc = g.ControlRead(0x80, 6, 0x0301, 0x0409, 255) 168 self.assertEquals(desc, '\x1A\x03H\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d\0!\0') 169 170 def test_get_missing_string_descriptor(self): 171 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 172 g.AddStringDescriptor(1, 'Hello world!') 173 desc = g.ControlRead(0x80, 6, 0x0302, 0x0409, 255) 174 self.assertEquals(desc, None) 175 176 def test_get_missing_string_language(self): 177 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 178 g.AddStringDescriptor(1, 'Hello world!') 179 desc = g.ControlRead(0x80, 6, 0x0301, 0x040C, 255) 180 self.assertEquals(desc, None) 181 182 def test_class_and_vendor_transfers(self): 183 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 184 self.assertIsNone(g.ControlRead(0xA0, 0, 0, 0, 0)) 185 self.assertIsNone(g.ControlRead(0xC0, 0, 0, 0, 0)) 186 self.assertIsNone(g.ControlWrite(0x20, 0, 0, 0, '')) 187 self.assertIsNone(g.ControlWrite(0x40, 0, 0, 0, '')) 188 189 def test_set_configuration(self): 190 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 191 chip = mock.Mock() 192 g.Connected(chip, usb_constants.Speed.HIGH) 193 g.ControlWrite(0, 9, 1, 0, 0) 194 chip.StartEndpoint.assert_has_calls([ 195 mock.call(hs_bulk_in_endpoint_desc), 196 mock.call(hs_bulk_out_endpoint_desc) 197 ]) 198 199 def test_set_configuration_zero(self): 200 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 201 chip = mock.Mock() 202 g.Connected(chip, usb_constants.Speed.HIGH) 203 g.ControlWrite(0, 9, 1, 0, 0) 204 chip.StartEndpoint.reset_mock() 205 g.ControlWrite(0, 9, 0, 0, 0) 206 chip.StopEndpoint.assert_has_calls([ 207 mock.call(0x01), 208 mock.call(0x81) 209 ]) 210 211 def test_set_bad_configuration(self): 212 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 213 g.Connected(mock.Mock(), usb_constants.Speed.HIGH) 214 self.assertIsNone(g.ControlWrite(0, 9, 2, 0, 0)) 215 216 def test_set_interface(self): 217 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 218 chip = mock.Mock() 219 g.Connected(chip, usb_constants.Speed.HIGH) 220 self.assertTrue(g.ControlWrite(0, 9, 1, 0, 0)) 221 chip.reset_mock() 222 self.assertTrue(g.ControlWrite(1, 11, 1, 0, 0)) 223 chip.StopEndpoint.assert_has_calls([ 224 mock.call(0x01), 225 mock.call(0x81) 226 ]) 227 chip.StartEndpoint.assert_has_calls([ 228 mock.call(hs_interrupt_in_endpoint_desc), 229 mock.call(hs_interrupt_out_endpoint_desc) 230 ]) 231 chip.reset_mock() 232 self.assertTrue(g.ControlWrite(1, 11, 0, 0, 0)) 233 chip.StopEndpoint.assert_has_calls([ 234 mock.call(0x01), 235 mock.call(0x81) 236 ]) 237 chip.StartEndpoint.assert_has_calls([ 238 mock.call(hs_bulk_in_endpoint_desc), 239 mock.call(hs_bulk_out_endpoint_desc) 240 ]) 241 242 def test_set_bad_interface(self): 243 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 244 g.Connected(mock.Mock(), usb_constants.Speed.HIGH) 245 self.assertTrue(g.ControlWrite(0, 9, 1, 0, 0)) 246 self.assertIsNone(g.ControlWrite(1, 11, 0, 1, 0)) 247 248 def test_send_packet(self): 249 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 250 chip = mock.Mock() 251 g.Connected(chip, usb_constants.Speed.HIGH) 252 g.SendPacket(0x81, 'Hello world!') 253 chip.SendPacket.assert_called_once_with(0x81, 'Hello world!') 254 255 def test_send_packet_disconnected(self): 256 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 257 with self.assertRaisesRegexp(RuntimeError, 'not connected'): 258 g.SendPacket(0x81, 'Hello world!') 259 g.Connected(mock.Mock(), usb_constants.Speed.HIGH) 260 g.SendPacket(0x81, 'Hello world!') 261 g.Disconnected() 262 with self.assertRaisesRegexp(RuntimeError, 'not connected'): 263 g.SendPacket(0x81, 'Hello world!') 264 265 def test_send_invalid_endpoint(self): 266 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 267 chip = mock.Mock() 268 g.Connected(chip, usb_constants.Speed.HIGH) 269 with self.assertRaisesRegexp(ValueError, 'non-input endpoint'): 270 g.SendPacket(0x01, 'Hello world!') 271 272 def test_receive_packet(self): 273 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 274 self.assertIsNone(g.ReceivePacket(0x01, 'Hello world!')) 275 276 def test_halt_endpoint(self): 277 g = gadget.Gadget(device_desc, fs_config_desc, hs_config_desc) 278 chip = mock.Mock() 279 g.Connected(chip, usb_constants.Speed.HIGH) 280 g.HaltEndpoint(0x01) 281 chip.HaltEndpoint.assert_called_once_with(0x01) 282 283 284 if __name__ == '__main__': 285 unittest.main() 286