Merge lp:~adeuring/launchpad/hwdb-class-udev-device-2 into lp:launchpad

Proposed by Abel Deuring
Status: Merged
Approved by: Barry Warsaw
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~adeuring/launchpad/hwdb-class-udev-device-2
Merge into: lp:launchpad
Diff against target: 456 lines
3 files modified
lib/canonical/launchpad/scripts/hwdbsubmissions.py (+109/-4)
lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py (+150/-7)
lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py (+54/-0)
To merge this branch: bzr merge lp:~adeuring/launchpad/hwdb-class-udev-device-2
Reviewer Review Type Date Requested Status
Barry Warsaw (community) Approve
Review via email: mp+13118@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote :

This branch adds a few USB-related properties to class UdevDevice, which will be used in the script hwdbsubmisison.py to process HWDB submission coming from the client in Karmic.

The branch also adds some sanity checks for USB-related data, to ensure that required properties exist and that their values have the correct format.

tests:

./bin/test --test=test_hwdb_submission_parser/bin/test --test=test_hwdb_submission_processing

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/canonical/launchpad/scripts/hwdbsubmissions.py
  lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py
  lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py

== Pyflakes notices ==

lib/canonical/launchpad/scripts/hwdbsubmissions.py
    22: redefinition of unused 'etree' from line 20

lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py
    10: redefinition of unused 'etree' from line 8

== Pylint notices ==

lib/canonical/launchpad/scripts/hwdbsubmissions.py
    20: [F0401] Unable to import 'xml.etree.cElementTree' (No module named etree)

lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py
    8: [F0401] Unable to import 'xml.etree.cElementTree' (No module named etree)

These complaints are not not related to my cheanges; the come from a branch which prepares LP for Python 2.5

Revision history for this message
Barry Warsaw (barry) wrote :
Download full text (19.7 KiB)

Hi Abel,

A rather terse review from me today, since I'm also the CHR. I have some
comments that should be easy to address. r=me, merge-conditional with their
consideration.

 review approve
 status approve

-Barry

=== modified file 'lib/canonical/launchpad/scripts/hwdbsubmissions.py'
--- lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-08 13:41:32 +0000
+++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-09 12:10:24 +0000
> @@ -1212,11 +1212,83 @@
> return False
> return True
>
> + USB_DEVICE_PROPERTIES = set(('DEVTYPE', 'PRODUCT', 'TYPE'))
> + usb_product_re = re.compile(
> + '^[0-9a-f]{1,4}/[0-9a-f]{1,4}/[0-9a-f]{1,4}$', re.I)
> + usb_type_re = re.compile('^[0-9]{1,3}/[0-9]{1,3}/[0-9]{1,3}$')

Is there a reason these are class attributes? They probably make more sense
being module globals, with all-caps names.

> +
> + def checkUdevUsbProperties(self, udev_data):
> + """Validation of udev USB devices.
> +
> + USB devices must have the properties DEVTYPE (value
> + 'usb_device' or 'usb_interface'), PRODUCT and TYPE. PRODUCT
> + must be a tuple of three integers in hexadecimal
> + representation, separates by '/'. TYPE must be a a tuple of
> + three integers in decimal representation, separated by '/'.
> + usb_interface nodes must additionally have a property
> + INTERFACE, containing three integers in the same format as
> + TYPE.
> + """
> + for device in udev_data:
> + subsystem = device['E'].get('SUBSYSTEM')
> + if subsystem != 'usb':
> + continue
> + properties = device['E']
> + property_names = set(properties.keys())

Since 'properties' is a dictionary, this is more efficient:

            property_names = set(properties)

> + existing_usb_properties = property_names.intersection(
> + self.USB_DEVICE_PROPERTIES)
> + if existing_usb_properties != self.USB_DEVICE_PROPERTIES:
> + self._logError(
> + 'USB udev device found without required properties: %r %r'
> + % (self.USB_DEVICE_PROPERTIES.difference(
> + existing_usb_properties),
> + device['P']),

This is somewhat unreadable. You should move the .difference() calculation to
above the self._logError() call and stash it in a local variable, then use the
local variable in the interpolation.

> + self.submission_key)
> + return False
> + if self.usb_product_re.search(properties['PRODUCT']) is None:
> + self._logError(
> + 'USB udev device found with invalid product ID: %r %r'
> + % (properties['PRODUCT'], device['P']),
> + self.submission_key)
> + return False
> + if self.usb_type_re.search(properties['TYPE']) is None:
> + self._logError(
> + 'USB udev device found with invalid type data: %r %r'
> + % (properties['TYPE'], device['P']),
> + ...

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/launchpad/scripts/hwdbsubmissions.py'
--- lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-08 13:41:32 +0000
+++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-09 15:45:23 +0000
@@ -94,6 +94,11 @@
94 'scsi': '%-16s',94 'scsi': '%-16s',
95 }95 }
9696
97UDEV_USB_DEVICE_PROPERTIES = set(('DEVTYPE', 'PRODUCT', 'TYPE'))
98UDEV_USB_PRODUCT_RE = re.compile(
99 '^[0-9a-f]{1,4}/[0-9a-f]{1,4}/[0-9a-f]{1,4}$', re.I)
100UDEV_USB_TYPE_RE = re.compile('^[0-9]{1,3}/[0-9]{1,3}/[0-9]{1,3}$')
101
97class SubmissionParser(object):102class SubmissionParser(object):
98 """A Parser for the submissions to the hardware database."""103 """A Parser for the submissions to the hardware database."""
99104
@@ -1165,7 +1170,7 @@
1165 """1170 """
1166 for device in udev_data:1171 for device in udev_data:
1167 properties = device['E']1172 properties = device['E']
1168 property_names = set(properties.keys())1173 property_names = set(properties)
1169 existing_pci_properties = property_names.intersection(1174 existing_pci_properties = property_names.intersection(
1170 self.PCI_PROPERTIES)1175 self.PCI_PROPERTIES)
1171 subsystem = device['E'].get('SUBSYSTEM')1176 subsystem = device['E'].get('SUBSYSTEM')
@@ -1212,11 +1217,78 @@
1212 return False1217 return False
1213 return True1218 return True
12141219
1220 def checkUdevUsbProperties(self, udev_data):
1221 """Validation of udev USB devices.
1222
1223 USB devices must have the properties DEVTYPE (value
1224 'usb_device' or 'usb_interface'), PRODUCT and TYPE. PRODUCT
1225 must be a tuple of three integers in hexadecimal
1226 representation, separates by '/'. TYPE must be a a tuple of
1227 three integers in decimal representation, separated by '/'.
1228 usb_interface nodes must additionally have a property
1229 INTERFACE, containing three integers in the same format as
1230 TYPE.
1231 """
1232 for device in udev_data:
1233 subsystem = device['E'].get('SUBSYSTEM')
1234 if subsystem != 'usb':
1235 continue
1236 properties = device['E']
1237 property_names = set(properties)
1238 existing_usb_properties = property_names.intersection(
1239 UDEV_USB_DEVICE_PROPERTIES)
1240 if existing_usb_properties != UDEV_USB_DEVICE_PROPERTIES:
1241 missing_properties = UDEV_USB_DEVICE_PROPERTIES.difference(
1242 existing_usb_properties)
1243 self._logError(
1244 'USB udev device found without required properties: %r %r'
1245 % (missing_properties, device['P']),
1246 self.submission_key)
1247 return False
1248 if UDEV_USB_PRODUCT_RE.search(properties['PRODUCT']) is None:
1249 self._logError(
1250 'USB udev device found with invalid product ID: %r %r'
1251 % (properties['PRODUCT'], device['P']),
1252 self.submission_key)
1253 return False
1254 if UDEV_USB_TYPE_RE.search(properties['TYPE']) is None:
1255 self._logError(
1256 'USB udev device found with invalid type data: %r %r'
1257 % (properties['TYPE'], device['P']),
1258 self.submission_key)
1259 return False
1260
1261 device_type = properties['DEVTYPE']
1262 if device_type not in ('usb_device', 'usb_interface'):
1263 self._logError(
1264 'USB udev device found with invalid udev type data: %r %r'
1265 % (device_type, device['P']),
1266 self.submission_key)
1267 return False
1268 if device_type == 'usb_interface':
1269 interface_type = properties.get('INTERFACE')
1270 if interface_type is None:
1271 self._logError(
1272 'USB interface udev device found without INTERFACE '
1273 'property: %r'
1274 % device['P'],
1275 self.submission_key)
1276 return False
1277 if UDEV_USB_TYPE_RE.search(interface_type) is None:
1278 self._logError(
1279 'USB Interface udev device found with invalid '
1280 'INTERFACE property: %r %r'
1281 % (interface_type, device['P']),
1282 self.submission_key)
1283 return False
1284 return True
1285
1215 def checkConsistentUdevDeviceData(self, udev_data):1286 def checkConsistentUdevDeviceData(self, udev_data):
1216 """Consistency checks for udev data."""1287 """Consistency checks for udev data."""
1217 if not self.checkUdevDictsHavePathKey(udev_data):1288 return (
1218 return False1289 self.checkUdevDictsHavePathKey(udev_data) and
1219 return self.checkUdevPciProperties(udev_data)1290 self.checkUdevPciProperties(udev_data) and
1291 self.checkUdevUsbProperties(udev_data))
12201292
1221 def checkConsistency(self, parsed_data):1293 def checkConsistency(self, parsed_data):
1222 """Run consistency checks on the submitted data.1294 """Run consistency checks on the submitted data.
@@ -2278,6 +2350,39 @@
2278 """See `BaseDevice`."""2350 """See `BaseDevice`."""
2279 return self.pci_class_info[1]2351 return self.pci_class_info[1]
22802352
2353 @property
2354 def is_usb(self):
2355 """True, if this is a USB device, else False."""
2356 return self.udev['E'].get('SUBSYSTEM') == 'usb'
2357
2358 @property
2359 def usb_ids(self):
2360 """The vendor ID, product ID, product version for USB devices.
2361
2362 :return: [vendor_id, product_id, version] for USB devices
2363 or [None, None, None] for other devices.
2364 """
2365 if self.is_usb:
2366 # udev represents USB device IDs as strings
2367 # vendor_id/prodct_id/version, where each part is
2368 # as a hexdecimal number.
2369 # SubmissionParser.checkUdevUsbProperties() ensures that
2370 # the string PRODUCT is in the format required below.
2371 product_info = self.udev['E']['PRODUCT'].split('/')
2372 return [int(part, 16) for part in product_info]
2373 else:
2374 return [None, None, None]
2375
2376 @property
2377 def usb_vendor_id(self):
2378 """See `BaseDevice`."""
2379 return self.usb_ids[0]
2380
2381 @property
2382 def usb_product_id(self):
2383 """See `BaseDevice`."""
2384 return self.usb_ids[1]
2385
22812386
2282class ProcessingLoop(object):2387class ProcessingLoop(object):
2283 """An `ITunableLoop` for processing HWDB submissions."""2388 """An `ITunableLoop` for processing HWDB submissions."""
22842389
=== modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py'
--- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py 2009-10-08 13:41:32 +0000
+++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py 2009-10-09 15:45:23 +0000
@@ -112,6 +112,25 @@
112 'PCI_SLOT_NAME': '0000:00:1f.2',112 'PCI_SLOT_NAME': '0000:00:1f.2',
113 }113 }
114 }114 }
115 self.udev_usb_device = {
116 'P': '/devices/pci0000:00/0000:00:1d.1/usb3/3-2',
117 'E': {
118 'SUBSYSTEM': 'usb',
119 'DEVTYPE': 'usb_device',
120 'PRODUCT': '46d/a01/1013',
121 'TYPE': '0/0/0',
122 },
123 }
124 self.udev_usb_interface = {
125 'P': '/devices/pci0000:00/0000:00:1d.1/usb3/3-2/3-2:1.1',
126 'E': {
127 'SUBSYSTEM': 'usb',
128 'DEVTYPE': 'usb_interface',
129 'PRODUCT': '46d/a01/1013',
130 'TYPE': '0/0/0',
131 'INTERFACE': '1/2/0',
132 },
133 }
115134
116 def getTimestampETreeNode(self, time_string):135 def getTimestampETreeNode(self, time_string):
117 """Return an Elementtree node for an XML tag with a timestamp."""136 """Return an Elementtree node for an XML tag with a timestamp."""
@@ -1788,7 +1807,7 @@
1788 parser.submission_key, 'udev node found without a "P" key')1807 parser.submission_key, 'udev node found without a "P" key')
17891808
1790 def testCheckUdevPciProperties(self):1809 def testCheckUdevPciProperties(self):
1791 """Test of SubmmissionParser.checkUdevPciProperties()."""1810 """Test of SubmissionParser.checkUdevPciProperties()."""
1792 # udev PCI devices must have the properties PCI_CLASS, PCI_ID,1811 # udev PCI devices must have the properties PCI_CLASS, PCI_ID,
1793 # PCI_SUBSYS_ID, PCI_SLOT_NAME; other devices must not have1812 # PCI_SUBSYS_ID, PCI_SLOT_NAME; other devices must not have
1794 # these properties.1813 # these properties.
@@ -1797,7 +1816,7 @@
1797 [self.udev_root_device, self.udev_pci_device]))1816 [self.udev_root_device, self.udev_pci_device]))
17981817
1799 def testCheckUdevPciPropertiesNonPciDeviceWithPciProperties(self):1818 def testCheckUdevPciPropertiesNonPciDeviceWithPciProperties(self):
1800 """Test of SubmmissionParser.checkUdevPciProperties().1819 """Test of SubmissionParser.checkUdevPciProperties().
18011820
1802 A non-PCI device having PCI properties makes a submission invalid.1821 A non-PCI device having PCI properties makes a submission invalid.
1803 """1822 """
@@ -1812,7 +1831,7 @@
1812 "'/devices/LNXSYSTM:00'")1831 "'/devices/LNXSYSTM:00'")
18131832
1814 def testCheckUdevPciPropertiesPciDeviceWithoutRequiredProperties(self):1833 def testCheckUdevPciPropertiesPciDeviceWithoutRequiredProperties(self):
1815 """Test of SubmmissionParser.checkUdevPciProperties().1834 """Test of SubmissionParser.checkUdevPciProperties().
18161835
1817 A PCI device not having a required PCI property makes a submission1836 A PCI device not having a required PCI property makes a submission
1818 invalid.1837 invalid.
@@ -1828,7 +1847,7 @@
1828 "set(['PCI_CLASS']) '/devices/pci0000:00/0000:00:1f.2'")1847 "set(['PCI_CLASS']) '/devices/pci0000:00/0000:00:1f.2'")
18291848
1830 def testCheckUdevPciPropertiesPciDeviceWithNonIntegerPciClass(self):1849 def testCheckUdevPciPropertiesPciDeviceWithNonIntegerPciClass(self):
1831 """Test of SubmmissionParser.checkUdevPciProperties().1850 """Test of SubmissionParser.checkUdevPciProperties().
18321851
1833 A PCI device with a non-integer class value makes a submission1852 A PCI device with a non-integer class value makes a submission
1834 invalid.1853 invalid.
@@ -1844,7 +1863,7 @@
1844 "'/devices/pci0000:00/0000:00:1f.2'")1863 "'/devices/pci0000:00/0000:00:1f.2'")
18451864
1846 def testCheckUdevPciPropertiesPciDeviceWithInvalidPciClassValue(self):1865 def testCheckUdevPciPropertiesPciDeviceWithInvalidPciClassValue(self):
1847 """Test of SubmmissionParser.checkUdevPciProperties().1866 """Test of SubmissionParser.checkUdevPciProperties().
18481867
1849 A PCI device with invalid class data makes a submission1868 A PCI device with invalid class data makes a submission
1850 invalid.1869 invalid.
@@ -1860,7 +1879,7 @@
1860 "'/devices/pci0000:00/0000:00:1f.2'")1879 "'/devices/pci0000:00/0000:00:1f.2'")
18611880
1862 def testCheckUdevPciPropertiesPciDeviceWithInvalidDeviceID(self):1881 def testCheckUdevPciPropertiesPciDeviceWithInvalidDeviceID(self):
1863 """Test of SubmmissionParser.checkUdevPciProperties().1882 """Test of SubmissionParser.checkUdevPciProperties().
18641883
1865 A PCI device with an invalid device ID makes a submission1884 A PCI device with an invalid device ID makes a submission
1866 invalid.1885 invalid.
@@ -1876,7 +1895,7 @@
1876 "'/devices/pci0000:00/0000:00:1f.2'")1895 "'/devices/pci0000:00/0000:00:1f.2'")
18771896
1878 def testCheckUdevPciPropertiesPciDeviceWithInvalidSubsystemID(self):1897 def testCheckUdevPciPropertiesPciDeviceWithInvalidSubsystemID(self):
1879 """Test of SubmmissionParser.checkUdevPciProperties().1898 """Test of SubmissionParser.checkUdevPciProperties().
18801899
1881 A PCI device with an invalid subsystem ID makes a submission1900 A PCI device with an invalid subsystem ID makes a submission
1882 invalid.1901 invalid.
@@ -1891,6 +1910,110 @@
1891 "Invalid udev PCI device ID: 'not-a-subsystem-id' "1910 "Invalid udev PCI device ID: 'not-a-subsystem-id' "
1892 "'/devices/pci0000:00/0000:00:1f.2'")1911 "'/devices/pci0000:00/0000:00:1f.2'")
18931912
1913 def testCheckUdevUsbProperties(self):
1914 """Test of SubmissionParser.checkUdevUsbProperties()."""
1915 parser = SubmissionParser()
1916 self.assertTrue(parser.checkUdevUsbProperties(
1917 [self.udev_root_device, self.udev_usb_device,
1918 self.udev_usb_interface]))
1919
1920 def testCheckUdevUsbProperties_missing_required_property(self):
1921 """Test of SubmissionParser.checkUdevUsbProperties().
1922
1923 A USB device that does not have a required property makes a
1924 submission invalid.
1925 """
1926 del self.udev_usb_device['E']['DEVTYPE']
1927 parser = SubmissionParser(self.log)
1928 parser.submission_key = 'USB device without DEVTYPE property'
1929 self.assertFalse(parser.checkUdevUsbProperties(
1930 [self.udev_root_device, self.udev_usb_device]))
1931 self.assertErrorMessage(
1932 parser.submission_key,
1933 "USB udev device found without required properties: "
1934 "set(['DEVTYPE']) '/devices/pci0000:00/0000:00:1d.1/usb3/3-2'")
1935
1936 def testCheckUdevUsbProperties_with_invalid_product_id(self):
1937 """Test of SubmissionParser.checkUdevUsbProperties().
1938
1939 A USB device with an invalid product ID makes a submission
1940 invalid.
1941 """
1942 self.udev_usb_device['E']['PRODUCT'] = 'not-a-valid-usb-product-id'
1943 parser = SubmissionParser(self.log)
1944 parser.submission_key = 'USB device with invalid product ID'
1945 self.assertFalse(parser.checkUdevUsbProperties(
1946 [self.udev_root_device, self.udev_usb_device]))
1947 self.assertErrorMessage(
1948 parser.submission_key,
1949 "USB udev device found with invalid product ID: "
1950 "'not-a-valid-usb-product-id' "
1951 "'/devices/pci0000:00/0000:00:1d.1/usb3/3-2'")
1952
1953 def testCheckUdevUsbProperties_with_invalid_type_data(self):
1954 """Test of SubmmissionParser.checkUdevUsbProperties().
1955
1956 A USB device with invalid type data makes a submission invalid.
1957 """
1958 self.udev_usb_device['E']['TYPE'] = 'no-type'
1959 parser = SubmissionParser(self.log)
1960 parser.submission_key = 'USB device with invalid type data'
1961 self.assertFalse(parser.checkUdevUsbProperties(
1962 [self.udev_root_device, self.udev_usb_device]))
1963 self.assertErrorMessage(
1964 parser.submission_key,
1965 "USB udev device found with invalid type data: 'no-type' "
1966 "'/devices/pci0000:00/0000:00:1d.1/usb3/3-2'")
1967
1968 def testCheckUdevUsbProperties_with_invalid_devtype(self):
1969 """Test of SubmmissionParser.checkUdevUsbProperties().
1970
1971 A udev USB device must have DEVTYPE set to 'usb_device' or
1972 'usb_interface'.
1973 """
1974 self.udev_usb_device['E']['DEVTYPE'] = 'nonsense'
1975 parser = SubmissionParser(self.log)
1976 parser.submission_key = 'USB device with invalid DEVTYPE'
1977 self.assertFalse(parser.checkUdevUsbProperties(
1978 [self.udev_root_device, self.udev_usb_device]))
1979 self.assertErrorMessage(
1980 parser.submission_key,
1981 "USB udev device found with invalid udev type data: 'nonsense' "
1982 "'/devices/pci0000:00/0000:00:1d.1/usb3/3-2'")
1983
1984 def testCheckUdevUsbProperties_interface_without_interface_property(self):
1985 """Test of SubmmissionParser.checkUdevUsbProperties().
1986
1987 A udev USB device for a USB interface have the property INTERFACE.
1988 """
1989 del self.udev_usb_interface['E']['INTERFACE']
1990 parser = SubmissionParser(self.log)
1991 parser.submission_key = 'USB interface without INTERFACE property'
1992 self.assertFalse(parser.checkUdevUsbProperties(
1993 [self.udev_root_device, self.udev_usb_interface]))
1994 self.assertErrorMessage(
1995 parser.submission_key,
1996 "USB interface udev device found without INTERFACE property: "
1997 "'/devices/pci0000:00/0000:00:1d.1/usb3/3-2/3-2:1.1'")
1998
1999 def testCheckUdevUsbProperties_interface_invalid_interface_property(self):
2000 """Test of SubmmissionParser.checkUdevUsbProperties().
2001
2002 The INTERFACE proeprty of A udev USB device for a USB interface
2003 must have value in the format main_class/sub_class/version
2004 """
2005 self.udev_usb_interface['E']['INTERFACE'] = 'nonsense'
2006 parser = SubmissionParser(self.log)
2007 parser.submission_key = 'USB interface with invalid INTERFACE data'
2008 self.assertFalse(parser.checkUdevUsbProperties(
2009 [self.udev_root_device, self.udev_usb_interface]))
2010 self.assertErrorMessage(
2011 parser.submission_key,
2012 "USB Interface udev device found with invalid INTERFACE "
2013 "property: 'nonsense' "
2014 "'/devices/pci0000:00/0000:00:1d.1/usb3/3-2/3-2:1.1'")
2015
2016
1894 class UdevTestSubmissionParser(SubmissionParser):2017 class UdevTestSubmissionParser(SubmissionParser):
1895 """A variant of SubmissionParser that shortcuts udev related tests.2018 """A variant of SubmissionParser that shortcuts udev related tests.
18962019
@@ -1904,6 +2027,10 @@
1904 """See `SubmissionParser`."""2027 """See `SubmissionParser`."""
1905 return True2028 return True
19062029
2030 def checkUdevUsbProperties(self, udev_data):
2031 """See `SubmissionParser`."""
2032 return True
2033
1907 def testCheckConsistentUdevDeviceData(self):2034 def testCheckConsistentUdevDeviceData(self):
1908 """Test of SubmissionParser.checkConsistentUdevDeviceData(),"""2035 """Test of SubmissionParser.checkConsistentUdevDeviceData(),"""
1909 parser = self.UdevTestSubmissionParser()2036 parser = self.UdevTestSubmissionParser()
@@ -1941,6 +2068,22 @@
1941 parser = SubmissionParserUdevPciCheckFails()2068 parser = SubmissionParserUdevPciCheckFails()
1942 self.assertFalse(parser.checkConsistentUdevDeviceData(None))2069 self.assertFalse(parser.checkConsistentUdevDeviceData(None))
19432070
2071 def testCheckConsistentUdevDeviceData_invalid_usb_data(self):
2072 """Test of SubmissionParser.checkConsistentUdevDeviceData(),
2073
2074 Detection of invalid PCI data lets the check fail.
2075 """
2076 class SubmissionParserUdevUsbCheckFails(
2077 self.UdevTestSubmissionParser):
2078 """A SubmissionPaser where checkUdevPciProperties() fails."""
2079
2080 def checkUdevUsbProperties(self, udev_data):
2081 """See `SubmissionParser`."""
2082 return False
2083
2084 parser = SubmissionParserUdevUsbCheckFails()
2085 self.assertFalse(parser.checkConsistentUdevDeviceData(None))
2086
1944 def _setupConsistencyCheckParser(self):2087 def _setupConsistencyCheckParser(self):
1945 """Prepare and return a SubmissionParser instance.2088 """Prepare and return a SubmissionParser instance.
19462089
19472090
=== modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py'
--- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-08 13:41:32 +0000
+++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-09 15:45:23 +0000
@@ -2617,6 +2617,16 @@
2617 }2617 }
2618 }2618 }
26192619
2620 usb_device_data = {
2621 'P': '/devices/pci0000:00/0000:00:1d.1/usb3/3-2',
2622 'E': {
2623 'SUBSYSTEM': 'usb',
2624 'DEVTYPE': 'usb_device',
2625 'PRODUCT': '46d/a01/1013',
2626 'TYPE': '0/0/0',
2627 },
2628 }
2629
2620 def test_device_id(self):2630 def test_device_id(self):
2621 """Test of UdevDevice.device_id."""2631 """Test of UdevDevice.device_id."""
2622 device = UdevDevice(self.pci_device_data, None, None)2632 device = UdevDevice(self.pci_device_data, None, None)
@@ -2668,6 +2678,50 @@
2668 None, device.pci_class,2678 None, device.pci_class,
2669 'Invalid value of UdevDevice.pci_class for Non-PCI device.')2679 'Invalid value of UdevDevice.pci_class for Non-PCI device.')
26702680
2681 def test_is_usb(self):
2682 """Test of UdevDevice.is_usb"""
2683 device = UdevDevice(self.usb_device_data, None, None)
2684 self.assertTrue(device.is_usb)
2685
2686 device = UdevDevice(self.pci_device_data, None, None)
2687 self.assertFalse(device.is_usb)
2688
2689 def test_usb_ids(self):
2690 """Test of UdevDevice.usb_ids"""
2691 device = UdevDevice(self.usb_device_data, None, None)
2692 self.assertEqual(
2693 [0x46d, 0xa01, 0x1013], device.usb_ids,
2694 'Invalid value of UdevDevice.usb_ids for USB device.')
2695
2696 device = UdevDevice(self.root_device, None, None)
2697 self.assertEqual(
2698 [None, None, None], device.usb_ids,
2699 'Invalid value of UdevDevice.usb_ids for Non-USB device.')
2700
2701 def test_usb_vendor_id(self):
2702 """Test of UdevDevice.usb_vendor_id"""
2703 device = UdevDevice(self.usb_device_data, None, None)
2704 self.assertEqual(
2705 0x46d, device.usb_vendor_id,
2706 'Invalid value of UdevDevice.usb_vendor_id for USB device.')
2707
2708 device = UdevDevice(self.root_device, None, None)
2709 self.assertEqual(
2710 None, device.usb_vendor_id,
2711 'Invalid value of UdevDevice.usb_vendor_id for Non-USB device.')
2712
2713 def test_usb_product_id(self):
2714 """Test of UdevDevice.usb_product_id"""
2715 device = UdevDevice(self.usb_device_data, None, None)
2716 self.assertEqual(
2717 0xa01, device.usb_product_id,
2718 'Invalid value of UdevDevice.usb_product_id for USB device.')
2719
2720 device = UdevDevice(self.root_device, None, None)
2721 self.assertEqual(
2722 None, device.usb_product_id,
2723 'Invalid value of UdevDevice.usb_product_id for Non-USB device.')
2724
26712725
2672class TestHWDBSubmissionTablePopulation(TestCaseHWDB):2726class TestHWDBSubmissionTablePopulation(TestCaseHWDB):
2673 """Tests of the HWDB popoluation with submitted data."""2727 """Tests of the HWDB popoluation with submitted data."""