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