Home | History | Annotate | Download | only in mbim_compliance
      1 # Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import logging
      6 import unittest
      7 from array import array
      8 
      9 import common
     10 from autotest_lib.client.cros.cellular.mbim_compliance.usb_descriptors \
     11     import *
     12 
     13 
     14 class TestDescriptor(Descriptor):
     15     """ Descriptor for unit testing. """
     16     DESCRIPTOR_TYPE = 0xAA
     17     DESCRIPTOR_SUBTYPE = 0xBB
     18     _FIELDS = (('B', 'bLength'),
     19                ('B', 'bDescriptorType'),
     20                ('B', 'bDescriptorSubtype'))
     21 
     22 
     23 class DescriptorTestCase(unittest.TestCase):
     24     """ Test cases for verifying Descriptor classes and DescriptorParser. """
     25 
     26 
     27     def test_fields_not_defined(self):
     28         """
     29         Verifies that an excepion is raised when constructing a Descriptor
     30         subclass that does not define a _FIELDS attribute.
     31         """
     32         with self.assertRaisesRegexp(
     33                 mbim_errors.MBIMComplianceFrameworkError,
     34                 'DescriptorFieldsNotDefined must define a _FIELDS attribute$'):
     35             class DescriptorFieldsNotDefined(Descriptor):
     36                 """ Descriptor without _FIELDS attribute. """
     37                 pass
     38 
     39 
     40     def test_descriptor_type_not_defined(self):
     41         """
     42         Verifies that it is OK to construct a Descriptor subclass that does not
     43         define a DESCRIPTOR_TYPE attribute.
     44         """
     45         class DescriptorTypeNotDefined(Descriptor):
     46             """ Descriptor without DESCRIPTOR_TYPE attribute. """
     47             _FIELDS = (('B', 'bLength'), ('B', 'bDescriptorType'))
     48 
     49         descriptor_data = array('B', [0x02, 0xAA])
     50         descriptor = DescriptorTypeNotDefined(descriptor_data)
     51         self.assertEqual(2, descriptor.bLength)
     52         self.assertEqual(0xAA, descriptor.bDescriptorType)
     53         self.assertEqual(descriptor_data, descriptor.data)
     54 
     55 
     56     def test_descriptor_type_mismatch(self):
     57         """
     58         Verifies that an exception is raised when constructing a Descriptor
     59         subclass from raw descriptor data with a descriptor type that differs
     60         from the value specified by the DESCRIPTOR_TYPE attribute of the
     61         subclass.
     62         """
     63         with self.assertRaisesRegexp(
     64                 mbim_errors.MBIMComplianceFrameworkError,
     65                 '^Expected descriptor type 0xAA, got 0xBB$'):
     66             descriptor = TestDescriptor(array('B', [0x03, 0xBB, 0xBB]))
     67 
     68 
     69     def test_descriptor_subtype_mismatch(self):
     70         """
     71         Verifies that an exception is raised when constructing a Descriptor
     72         subclass from raw descriptor data with a descriptor subtype that differs
     73         from the value specified by the DESCRIPTOR_SUBTYPE attribute of the
     74         subclass.
     75         """
     76         with self.assertRaisesRegexp(
     77                 mbim_errors.MBIMComplianceFrameworkError,
     78                 '^Expected descriptor subtype 0xBB, got 0xCC$'):
     79             descriptor = TestDescriptor(array('B', [0x03, 0xAA, 0xCC]))
     80 
     81 
     82     def test_descriptor_length_mismatch(self):
     83         """
     84         Verifies that an exception is raised when constructing a Descriptor
     85         subclass from raw descriptor data with a descriptor length that differs
     86         from the length of the descriptor data.
     87         """
     88         with self.assertRaisesRegexp(
     89                 mbim_errors.MBIMComplianceFrameworkError,
     90                 '^Expected descriptor length 3, got 1$'):
     91             descriptor = TestDescriptor(array('B', [0x01, 0xAA, 0xBB]))
     92 
     93         with self.assertRaisesRegexp(
     94                 mbim_errors.MBIMComplianceFrameworkError,
     95                 '^Expected descriptor length 3, got 4$'):
     96             descriptor = TestDescriptor(array('B', [0x04, 0xAA, 0xBB]))
     97 
     98 
     99     def test_descriptor_data_less_than_total_size_of_fields(self):
    100         """
    101         Verifies that an exception is raised when constructing a Descriptor
    102         subclass from raw descriptor data of length less than the total size of
    103         fields specified by the _FIELDS attribute.
    104         """
    105         with self.assertRaisesRegexp(
    106                 mbim_errors.MBIMComplianceFrameworkError,
    107                 '^Expected 3 or more bytes of descriptor data, got 1$'):
    108             descriptor = TestDescriptor(array('B', [0x03]))
    109 
    110 
    111     def test_descriptor_data_more_than_total_size_of_fields(self):
    112         """
    113         Verifies that it is OK to construct a Descriptor subclass from raw
    114         descriptor data of length more than the total size of fields specified
    115         by the _FIELDS attribute.
    116         """
    117         descriptor_data = array('B', [0x03, 0xAA, 0xBB])
    118         descriptor = TestDescriptor(descriptor_data)
    119         self.assertEqual(3, descriptor.bLength)
    120         self.assertEqual(0xAA, descriptor.bDescriptorType)
    121         self.assertEqual(descriptor_data, descriptor.data)
    122 
    123 
    124     def test_parsing_unknown_descriptor_type(self):
    125         """
    126         Verifies that DescriptorParser returns an instance of UnknownDescriptor
    127         when the descriptor type is not specified by any Descriptor subclass.
    128         """
    129         descriptor_data = array('B', [0x02, 0xFF])
    130         descriptors = list(DescriptorParser(descriptor_data))
    131         self.assertEqual(1, len(descriptors))
    132         descriptor = descriptors[0]
    133         self.assertIsInstance(descriptor, UnknownDescriptor)
    134         self.assertEqual(2, descriptor.bLength)
    135         self.assertEqual(0xFF, descriptor.bDescriptorType)
    136         self.assertEqual(descriptor_data, descriptor.data)
    137 
    138 
    139     def test_parsing_unsupported_descriptor_subtype(self):
    140         """
    141         Verifies that DescriptorParser returns an instance of
    142         FunctionalDescriptor when the descriptor type is 0x24 but the descriptor
    143         subtype is not supported.
    144         """
    145         descriptor_data = array('B', [0x03, 0x24, 0xFF])
    146         descriptors = list(DescriptorParser(descriptor_data))
    147         self.assertEqual(1, len(descriptors))
    148         descriptor = descriptors[0]
    149         self.assertIsInstance(descriptor, FunctionalDescriptor)
    150         self.assertEqual(3, descriptor.bLength)
    151         self.assertEqual(0x24, descriptor.bDescriptorType)
    152         self.assertEqual(0xFF, descriptor.bDescriptorSubtype)
    153         self.assertEqual(descriptor_data, descriptor.data)
    154 
    155 
    156     def test_parsing_descriptors(self):
    157         """
    158         Verifies that DescriptorParser returns an instance of an appropriate
    159         Descriptor subclass for each descriptor found in the given raw
    160         descriptor data.
    161         """
    162         descriptor_data = array('B', [0x09, 0x02, 0x5f, 0x00, 0x02, 0x01, 0x04,
    163                                       0xa0, 0xfa, 0x08, 0x0b, 0x00, 0x02, 0x02,
    164                                       0x0e, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
    165                                       0x01, 0x02, 0x0e, 0x00, 0x05, 0x05, 0x24,
    166                                       0x00, 0x20, 0x01, 0x0c, 0x24, 0x1b, 0x00,
    167                                       0x01, 0x00, 0x06, 0x20, 0x80, 0x96, 0x05,
    168                                       0x00, 0x08, 0x24, 0x1c, 0x00, 0x01, 0x0f,
    169                                       0x96, 0x05, 0x05, 0x24, 0x06, 0x00, 0x01,
    170                                       0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 0x05,
    171                                       0x09, 0x04, 0x01, 0x00, 0x00, 0x0a, 0x00,
    172                                       0x02, 0x06, 0x09, 0x04, 0x01, 0x01, 0x02,
    173                                       0x0a, 0x00, 0x02, 0x07, 0x07, 0x05, 0x82,
    174                                       0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x01,
    175                                       0x02, 0x00, 0x02, 0x00])
    176         parser = DescriptorParser(descriptor_data)
    177 
    178         descriptor = parser.next()
    179         self.assertIsInstance(descriptor, ConfigurationDescriptor)
    180         self.assertIsInstance(descriptor, Descriptor)
    181         self.assertEquals(9, descriptor.bLength)
    182         self.assertEquals(0x02, descriptor.bDescriptorType)
    183         self.assertEquals(95, descriptor.wTotalLength)
    184         self.assertEquals(2, descriptor.bNumInterfaces)
    185         self.assertEquals(1, descriptor.bConfigurationValue)
    186         self.assertEquals(4, descriptor.iConfiguration)
    187         self.assertEquals(0xA0, descriptor.bmAttributes)
    188         self.assertEquals(250, descriptor.bMaxPower)
    189         self.assertEqual(array('B', [0x09, 0x02, 0x5f, 0x00, 0x02, 0x01, 0x04,
    190                                      0xa0, 0xfa]),
    191                          descriptor.data)
    192 
    193         descriptor = parser.next()
    194         self.assertIsInstance(descriptor, InterfaceAssociationDescriptor)
    195         self.assertIsInstance(descriptor, Descriptor)
    196         self.assertEquals(8, descriptor.bLength)
    197         self.assertEquals(0x0B, descriptor.bDescriptorType)
    198         self.assertEquals(0, descriptor.bFirstInterface)
    199         self.assertEquals(2, descriptor.bInterfaceCount)
    200         self.assertEquals(0x02, descriptor.bFunctionClass)
    201         self.assertEquals(0x0E, descriptor.bFunctionSubClass)
    202         self.assertEquals(0x00, descriptor.bFunctionProtocol)
    203         self.assertEquals(0, descriptor.iFunction)
    204         self.assertEqual(array('B', [0x08, 0x0b, 0x00, 0x02, 0x02, 0x0e, 0x00,
    205                                      0x00]),
    206                          descriptor.data)
    207 
    208         descriptor = parser.next()
    209         self.assertIsInstance(descriptor, InterfaceDescriptor)
    210         self.assertIsInstance(descriptor, Descriptor)
    211         self.assertEquals(9, descriptor.bLength)
    212         self.assertEquals(0x04, descriptor.bDescriptorType)
    213         self.assertEquals(0, descriptor.bInterfaceNumber)
    214         self.assertEquals(0, descriptor.bAlternateSetting)
    215         self.assertEquals(1, descriptor.bNumEndpoints)
    216         self.assertEquals(0x02, descriptor.bInterfaceClass)
    217         self.assertEquals(0x0E, descriptor.bInterfaceSubClass)
    218         self.assertEquals(0x00, descriptor.bInterfaceProtocol)
    219         self.assertEquals(5, descriptor.iInterface)
    220         self.assertEqual(array('B', [0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x0e,
    221                                      0x00, 0x05]),
    222                          descriptor.data)
    223 
    224         descriptor = parser.next()
    225         self.assertIsInstance(descriptor, HeaderFunctionalDescriptor)
    226         self.assertIsInstance(descriptor, FunctionalDescriptor)
    227         self.assertIsInstance(descriptor, Descriptor)
    228         self.assertEquals(5, descriptor.bLength)
    229         self.assertEquals(0x24, descriptor.bDescriptorType)
    230         self.assertEquals(0x00, descriptor.bDescriptorSubtype)
    231         self.assertEquals(0x120, descriptor.bcdCDC)
    232         self.assertEqual(array('B', [0x05, 0x24, 0x00, 0x20, 0x01]),
    233                          descriptor.data)
    234 
    235         descriptor = parser.next()
    236         self.assertIsInstance(descriptor, MBIMFunctionalDescriptor)
    237         self.assertIsInstance(descriptor, FunctionalDescriptor)
    238         self.assertIsInstance(descriptor, Descriptor)
    239         self.assertEquals(12, descriptor.bLength)
    240         self.assertEquals(0x24, descriptor.bDescriptorType)
    241         self.assertEquals(0x1B, descriptor.bDescriptorSubtype)
    242         self.assertEquals(0x100, descriptor.bcdMBIMVersion)
    243         self.assertEquals(1536, descriptor.wMaxControlMessage)
    244         self.assertEquals(32, descriptor.bNumberFilters)
    245         self.assertEquals(128, descriptor.bMaxFilterSize)
    246         self.assertEquals(1430, descriptor.wMaxSegmentSize)
    247         self.assertEquals(0x00, descriptor.bmNetworkCapabilities)
    248         self.assertEqual(array('B', [0x0c, 0x24, 0x1b, 0x00, 0x01, 0x00, 0x06,
    249                                      0x20, 0x80, 0x96, 0x05, 0x00]),
    250                          descriptor.data)
    251 
    252         descriptor = parser.next()
    253         self.assertIsInstance(descriptor, MBIMExtendedFunctionalDescriptor)
    254         self.assertIsInstance(descriptor, FunctionalDescriptor)
    255         self.assertIsInstance(descriptor, Descriptor)
    256         self.assertEquals(8, descriptor.bLength)
    257         self.assertEquals(0x24, descriptor.bDescriptorType)
    258         self.assertEquals(0x1C, descriptor.bDescriptorSubtype)
    259         self.assertEquals(0x100, descriptor.bcdMBIMExtendedVersion)
    260         self.assertEquals(15, descriptor.bMaxOutstandingCommandMessages)
    261         self.assertEquals(1430, descriptor.wMTU)
    262         self.assertEqual(array('B', [0x08, 0x24, 0x1c, 0x00, 0x01, 0x0f, 0x96,
    263                                      0x05]),
    264                          descriptor.data)
    265 
    266         descriptor = parser.next()
    267         self.assertIsInstance(descriptor, UnionFunctionalDescriptor)
    268         self.assertIsInstance(descriptor, FunctionalDescriptor)
    269         self.assertIsInstance(descriptor, Descriptor)
    270         self.assertEquals(5, descriptor.bLength)
    271         self.assertEquals(0x24, descriptor.bDescriptorType)
    272         self.assertEquals(0x06, descriptor.bDescriptorSubtype)
    273         self.assertEquals(0, descriptor.bControlInterface)
    274         self.assertEquals(1, descriptor.bSubordinateInterface0)
    275         self.assertEqual(array('B', [0x05, 0x24, 0x06, 0x00, 0x01]),
    276                          descriptor.data)
    277 
    278         descriptor = parser.next()
    279         self.assertIsInstance(descriptor, EndpointDescriptor)
    280         self.assertIsInstance(descriptor, Descriptor)
    281         self.assertEquals(7, descriptor.bLength)
    282         self.assertEquals(0x05, descriptor.bDescriptorType)
    283         self.assertEquals(0x81, descriptor.bEndpointAddress)
    284         self.assertEquals(0x03, descriptor.bmAttributes)
    285         self.assertEquals(64, descriptor.wMaxPacketSize)
    286         self.assertEquals(5, descriptor.bInterval)
    287         self.assertEqual(array('B', [0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 0x05]),
    288                          descriptor.data)
    289 
    290         descriptor = parser.next()
    291         self.assertIsInstance(descriptor, InterfaceDescriptor)
    292         self.assertIsInstance(descriptor, Descriptor)
    293         self.assertEquals(9, descriptor.bLength)
    294         self.assertEquals(0x04, descriptor.bDescriptorType)
    295         self.assertEquals(1, descriptor.bInterfaceNumber)
    296         self.assertEquals(0, descriptor.bAlternateSetting)
    297         self.assertEquals(0, descriptor.bNumEndpoints)
    298         self.assertEquals(0x0A, descriptor.bInterfaceClass)
    299         self.assertEquals(0x00, descriptor.bInterfaceSubClass)
    300         self.assertEquals(0x02, descriptor.bInterfaceProtocol)
    301         self.assertEquals(6, descriptor.iInterface)
    302         self.assertEqual(array('B', [0x09, 0x04, 0x01, 0x00, 0x00, 0x0a, 0x00,
    303                                      0x02, 0x06]),
    304                          descriptor.data)
    305 
    306         descriptor = parser.next()
    307         self.assertIsInstance(descriptor, InterfaceDescriptor)
    308         self.assertIsInstance(descriptor, Descriptor)
    309         self.assertEquals(9, descriptor.bLength)
    310         self.assertEquals(0x04, descriptor.bDescriptorType)
    311         self.assertEquals(1, descriptor.bInterfaceNumber)
    312         self.assertEquals(1, descriptor.bAlternateSetting)
    313         self.assertEquals(2, descriptor.bNumEndpoints)
    314         self.assertEquals(0x0A, descriptor.bInterfaceClass)
    315         self.assertEquals(0x00, descriptor.bInterfaceSubClass)
    316         self.assertEquals(0x02, descriptor.bInterfaceProtocol)
    317         self.assertEquals(7, descriptor.iInterface)
    318         self.assertEqual(array('B', [0x09, 0x04, 0x01, 0x01, 0x02, 0x0a, 0x00,
    319                                      0x02, 0x07]),
    320                          descriptor.data)
    321 
    322         descriptor = parser.next()
    323         self.assertIsInstance(descriptor, EndpointDescriptor)
    324         self.assertIsInstance(descriptor, Descriptor)
    325         self.assertEquals(7, descriptor.bLength)
    326         self.assertEquals(0x05, descriptor.bDescriptorType)
    327         self.assertEquals(0x82, descriptor.bEndpointAddress)
    328         self.assertEquals(0x02, descriptor.bmAttributes)
    329         self.assertEquals(512, descriptor.wMaxPacketSize)
    330         self.assertEquals(0, descriptor.bInterval)
    331         self.assertEqual(array('B', [0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00]),
    332                          descriptor.data)
    333 
    334         descriptor = parser.next()
    335         self.assertIsInstance(descriptor, EndpointDescriptor)
    336         self.assertIsInstance(descriptor, Descriptor)
    337         self.assertEquals(7, descriptor.bLength)
    338         self.assertEquals(0x05, descriptor.bDescriptorType)
    339         self.assertEquals(0x01, descriptor.bEndpointAddress)
    340         self.assertEquals(0x02, descriptor.bmAttributes)
    341         self.assertEquals(512, descriptor.wMaxPacketSize)
    342         self.assertEquals(0, descriptor.bInterval)
    343         self.assertEqual(array('B', [0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00]),
    344                          descriptor.data)
    345 
    346         with self.assertRaises(StopIteration):
    347             descriptor = parser.next()
    348 
    349 
    350 if __name__ == '__main__':
    351     logging.basicConfig(level=logging.DEBUG)
    352     unittest.main()
    353