1# Copyright (C) 2009-2014 Wander Lairson Costa 2# 3# The following terms apply to all files associated 4# with the software unless explicitly disclaimed in individual files. 5# 6# The authors hereby grant permission to use, copy, modify, distribute, 7# and license this software and its documentation for any purpose, provided 8# that existing copyright notices are retained in all copies and that this 9# notice is included verbatim in any distributions. No written agreement, 10# license, or royalty fee is required for any of the authorized uses. 11# Modifications to this software may be copyrighted by their authors 12# and need not follow the licensing terms described here, provided that 13# the new terms are clearly indicated on the first page of each file where 14# they apply. 15# 16# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY 17# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 18# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY 19# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE 20# POSSIBILITY OF SUCH DAMAGE. 21# 22# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, 23# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 24# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE 25# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE 26# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 27# MODIFICATIONS. 28 29# Integration tests 30 31import utils 32import unittest 33import usb.core 34import devinfo 35import usb._interop 36from usb._debug import methodtrace 37import usb.util 38import usb.backend.libusb0 as libusb0 39import usb.backend.libusb1 as libusb1 40import usb.backend.openusb as openusb 41import time 42import sys 43 44def make_data_list(length = 8): 45 return (utils.get_array_data1(length), 46 utils.get_array_data2(length), 47 utils.get_list_data1(length), 48 utils.get_list_data2(length), 49 utils.get_str_data1(length), 50 utils.get_str_data1(length)) 51 52class DeviceTest(unittest.TestCase): 53 @methodtrace(utils.logger) 54 def __init__(self, dev): 55 unittest.TestCase.__init__(self) 56 self.dev = dev 57 58 @methodtrace(utils.logger) 59 def runTest(self): 60 try: 61 self.test_attributes() 62 self.test_timeout() 63 self.test_set_configuration() 64 self.test_set_interface_altsetting() 65 self.test_write_read() 66 self.test_write_array() 67 self.test_ctrl_transfer() 68 self.test_clear_halt() 69 #self.test_reset() 70 finally: 71 usb.util.dispose_resources(self.dev) 72 73 @methodtrace(utils.logger) 74 def test_attributes(self): 75 self.assertEqual(self.dev.bLength, 18) 76 self.assertEqual(self.dev.bDescriptorType, usb.util.DESC_TYPE_DEVICE) 77 self.assertEqual(self.dev.bcdUSB, 0x0200) 78 self.assertEqual(self.dev.idVendor, devinfo.ID_VENDOR) 79 self.assertEqual(self.dev.idProduct, devinfo.ID_PRODUCT) 80 self.assertEqual(self.dev.bcdDevice, 0x0001) 81 self.assertEqual(self.dev.iManufacturer, 0x01) 82 self.assertEqual(self.dev.iProduct, 0x02) 83 self.assertEqual(self.dev.iSerialNumber, 0x03) 84 self.assertEqual(self.dev.bNumConfigurations, 0x01) 85 self.assertEqual(self.dev.bMaxPacketSize0, 8) 86 self.assertEqual(self.dev.bDeviceClass, 0x00) 87 self.assertEqual(self.dev.bDeviceSubClass, 0x00) 88 self.assertEqual(self.dev.bDeviceProtocol, 0x00) 89 90 @methodtrace(utils.logger) 91 def test_timeout(self): 92 def set_invalid_timeout(): 93 self.dev.default_timeout = -1 94 tmo = self.dev.default_timeout 95 self.dev.default_timeout = 1 96 self.assertEqual(self.dev.default_timeout, 1) 97 self.dev.default_timeout = tmo 98 self.assertEqual(self.dev.default_timeout, tmo) 99 self.assertRaises(ValueError, set_invalid_timeout) 100 self.assertEqual(self.dev.default_timeout, tmo) 101 102 @methodtrace(utils.logger) 103 def test_set_configuration(self): 104 cfg = self.dev[0].bConfigurationValue 105 self.dev.set_configuration(cfg) 106 self.dev.set_configuration() 107 self.assertEqual(cfg, self.dev.get_active_configuration().bConfigurationValue) 108 109 @methodtrace(utils.logger) 110 def test_set_interface_altsetting(self): 111 intf = self.dev.get_active_configuration()[(0,0)] 112 self.dev.set_interface_altsetting(intf.bInterfaceNumber, intf.bAlternateSetting) 113 self.dev.set_interface_altsetting() 114 115 @methodtrace(utils.logger) 116 def test_reset(self): 117 self.dev.reset() 118 utils.delay_after_reset() 119 120 @methodtrace(utils.logger) 121 def test_write_read(self): 122 altsettings = [devinfo.INTF_BULK, devinfo.INTF_INTR] 123 eps = [devinfo.EP_BULK, devinfo.EP_INTR] 124 data_len = [8, 8] 125 126 if utils.is_iso_test_allowed(): 127 altsettings.append(devinfo.INTF_ISO) 128 eps.append(devinfo.EP_ISO) 129 data_len.append(64) 130 131 def delay(alt): 132 # Hack to avoid two consecutive isochronous transfers to fail 133 if alt == devinfo.INTF_ISO and utils.is_windows(): 134 time.sleep(0.5) 135 136 for alt, length in zip(altsettings, data_len): 137 self.dev.set_interface_altsetting(0, alt) 138 for data in make_data_list(length): 139 adata = utils.to_array(data) 140 length = utils.data_len(data) 141 buff = usb.util.create_buffer(length) 142 143 try: 144 ret = self.dev.write(eps[alt], data) 145 except NotImplementedError: 146 continue 147 148 self.assertEqual(ret, length) 149 150 self.assertEqual( 151 ret, 152 length, 153 'Failed to write data: ' + \ 154 str(data) + ', in interface = ' + \ 155 str(alt)) 156 157 try: 158 ret = self.dev.read(eps[alt] | usb.util.ENDPOINT_IN, length) 159 except NotImplementedError: 160 continue 161 162 self.assertTrue( 163 utils.array_equals(ret, adata), 164 str(ret) + ' != ' + \ 165 str(adata) + ', in interface = ' + \ 166 str(alt)) 167 168 delay(alt) 169 170 try: 171 ret = self.dev.write(eps[alt], data) 172 except NotImplementedError: 173 continue 174 175 self.assertEqual(ret, length) 176 177 self.assertEqual( 178 ret, 179 length, 180 'Failed to write data: ' + \ 181 str(data) + ', in interface = ' + \ 182 str(alt)) 183 184 try: 185 ret = self.dev.read(eps[alt] | usb.util.ENDPOINT_IN, buff) 186 except NotImplementedError: 187 continue 188 189 self.assertEqual(ret, length) 190 191 self.assertTrue( 192 utils.array_equals(buff, adata), 193 str(buff) + ' != ' + \ 194 str(adata) + ', in interface = ' + \ 195 str(alt)) 196 197 delay(alt) 198 199 @methodtrace(utils.logger) 200 def test_write_array(self): 201 a = usb._interop.as_array('test') 202 self.dev.set_interface_altsetting(0, devinfo.INTF_BULK) 203 204 self.assertEquals(self.dev.write(devinfo.EP_BULK, a), len(a)) 205 206 self.assertTrue(utils.array_equals( 207 self.dev.read(devinfo.EP_BULK | usb.util.ENDPOINT_IN, len(a)), 208 a)) 209 210 @methodtrace(utils.logger) 211 def test_ctrl_transfer(self): 212 for data in make_data_list(): 213 length = utils.data_len(data) 214 adata = utils.to_array(data) 215 216 ret = self.dev.ctrl_transfer( 217 0x40, 218 devinfo.PICFW_SET_VENDOR_BUFFER, 219 0, 220 0, 221 data) 222 223 self.assertEqual(ret, 224 length, 225 'Failed to write data: ' + str(data)) 226 227 ret = utils.to_array(self.dev.ctrl_transfer( 228 0xC0, 229 devinfo.PICFW_GET_VENDOR_BUFFER, 230 0, 231 0, 232 length)) 233 234 self.assertTrue(utils.array_equals(ret, adata), 235 str(ret) + ' != ' + str(adata)) 236 237 buff = usb.util.create_buffer(length) 238 239 ret = self.dev.ctrl_transfer( 240 0x40, 241 devinfo.PICFW_SET_VENDOR_BUFFER, 242 0, 243 0, 244 data) 245 246 self.assertEqual(ret, 247 length, 248 'Failed to write data: ' + str(data)) 249 250 ret = self.dev.ctrl_transfer( 251 0xC0, 252 devinfo.PICFW_GET_VENDOR_BUFFER, 253 0, 254 0, 255 buff) 256 257 self.assertEqual(ret, length) 258 259 self.assertTrue(utils.array_equals(buff, adata), 260 str(buff) + ' != ' + str(adata)) 261 262 @methodtrace(utils.logger) 263 def test_clear_halt(self): 264 self.dev.set_interface_altsetting(0, 0) 265 self.dev.clear_halt(0x01) 266 self.dev.clear_halt(0x81) 267 268class ConfigurationTest(unittest.TestCase): 269 @methodtrace(utils.logger) 270 def __init__(self, dev): 271 unittest.TestCase.__init__(self) 272 self.cfg = dev[0] 273 274 @methodtrace(utils.logger) 275 def runTest(self): 276 try: 277 self.test_attributes() 278 self.test_set() 279 finally: 280 usb.util.dispose_resources(self.cfg.device) 281 282 @methodtrace(utils.logger) 283 def test_attributes(self): 284 self.assertEqual(self.cfg.bLength, 9) 285 self.assertEqual(self.cfg.bDescriptorType, usb.util.DESC_TYPE_CONFIG) 286 self.assertEqual(self.cfg.wTotalLength, 78) 287 self.assertEqual(self.cfg.bNumInterfaces, 0x01) 288 self.assertEqual(self.cfg.bConfigurationValue, 0x01) 289 self.assertEqual(self.cfg.iConfiguration, 0x00) 290 self.assertEqual(self.cfg.bmAttributes, 0xC0) 291 self.assertEqual(self.cfg.bMaxPower, 50) 292 293 @methodtrace(utils.logger) 294 def test_set(self): 295 self.cfg.set() 296 297class InterfaceTest(unittest.TestCase): 298 @methodtrace(utils.logger) 299 def __init__(self, dev): 300 unittest.TestCase.__init__(self) 301 self.dev = dev 302 self.intf = dev[0][(0,0)] 303 304 @methodtrace(utils.logger) 305 def runTest(self): 306 try: 307 self.dev.set_configuration() 308 self.test_attributes() 309 self.test_set_altsetting() 310 finally: 311 usb.util.dispose_resources(self.intf.device) 312 313 @methodtrace(utils.logger) 314 def test_attributes(self): 315 self.assertEqual(self.intf.bLength, 9) 316 self.assertEqual(self.intf.bDescriptorType, usb.util.DESC_TYPE_INTERFACE) 317 self.assertEqual(self.intf.bInterfaceNumber, 0) 318 self.assertEqual(self.intf.bAlternateSetting, 0) 319 self.assertEqual(self.intf.bNumEndpoints, 2) 320 self.assertEqual(self.intf.bInterfaceClass, 0x00) 321 self.assertEqual(self.intf.bInterfaceSubClass, 0x00) 322 self.assertEqual(self.intf.bInterfaceProtocol, 0x00) 323 self.assertEqual(self.intf.iInterface, 0x00) 324 325 @methodtrace(utils.logger) 326 def test_set_altsetting(self): 327 self.intf.set_altsetting() 328 329class EndpointTest(unittest.TestCase): 330 @methodtrace(utils.logger) 331 def __init__(self, dev): 332 unittest.TestCase.__init__(self) 333 self.dev = dev 334 intf = dev[0][(0,0)] 335 self.ep_out = usb.util.find_descriptor(intf, bEndpointAddress=0x01) 336 self.ep_in = usb.util.find_descriptor(intf, bEndpointAddress=0x81) 337 338 @methodtrace(utils.logger) 339 def runTest(self): 340 try: 341 self.dev.set_configuration() 342 self.test_attributes() 343 self.test_write_read() 344 finally: 345 usb.util.dispose_resources(self.dev) 346 347 @methodtrace(utils.logger) 348 def test_attributes(self): 349 self.assertEqual(self.ep_out.bLength, 7) 350 self.assertEqual(self.ep_out.bDescriptorType, usb.util.DESC_TYPE_ENDPOINT) 351 self.assertEqual(self.ep_out.bEndpointAddress, 0x01) 352 self.assertEqual(self.ep_out.bmAttributes, 0x02) 353 self.assertEqual(self.ep_out.wMaxPacketSize, 16) 354 self.assertEqual(self.ep_out.bInterval, 0) 355 356 @methodtrace(utils.logger) 357 def test_write_read(self): 358 self.dev.set_interface_altsetting(0, 0) 359 for data in make_data_list(): 360 adata = utils.to_array(data) 361 length = utils.data_len(data) 362 buff = usb.util.create_buffer(length) 363 364 ret = self.ep_out.write(data) 365 self.assertEqual(ret, length, 'Failed to write data: ' + str(data)) 366 ret = self.ep_in.read(length) 367 self.assertTrue(utils.array_equals(ret, adata), str(ret) + ' != ' + str(adata)) 368 369 ret = self.ep_out.write(data) 370 self.assertEqual(ret, length, 'Failed to write data: ' + str(data)) 371 ret = self.ep_in.read(buff) 372 self.assertEqual(ret, length) 373 self.assertTrue(utils.array_equals(buff, adata), str(buff) + ' != ' + str(adata)) 374 375def get_suite(): 376 suite = unittest.TestSuite() 377 test_cases = (DeviceTest, ConfigurationTest, InterfaceTest, EndpointTest) 378 for m in (libusb1, libusb0, openusb): 379 b = m.get_backend() 380 if b is None: 381 continue 382 dev = utils.find_my_device(b) 383 if dev is None: 384 utils.logger.warning('Test hardware not found for backend %s', m.__name__) 385 continue 386 387 for ObjectTestCase in test_cases: 388 utils.logger.info('Adding %s(%s) to test suite...', ObjectTestCase.__name__, m.__name__) 389 suite.addTest(ObjectTestCase(dev)) 390 391 return suite 392 393if __name__ == '__main__': 394 utils.run_tests(get_suite()) 395