Merge lp:~adeuring/launchpad/hwdb-refactor-haldevice-3 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-refactor-haldevice-3
Merge into: lp:launchpad
Diff against target: 604 lines
2 files modified
lib/canonical/launchpad/scripts/hwdbsubmissions.py (+258/-209)
lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py (+54/-0)
To merge this branch: bzr merge lp:~adeuring/launchpad/hwdb-refactor-haldevice-3
Reviewer Review Type Date Requested Status
Barry Warsaw (community) Approve
Review via email: mp+12733@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote :

This branch is the third and last part to refactor class
l.c.l.scripts.hwdbsubmissions.HALDevice. See
https://code.edge.launchpad.net/~adeuring/launchpad/hwdb-refactor-haldevice/+merge/12669
for the reason of the refactoring.

The branch adds new properties scsi_vendor, scsi_model and driver_name
to BaseDevice and HALDevice (including short tests), and it defines some
"dummy properties" in class BaseDevice that correspond to exsting
properties in class HALDevice.

Finally, it moves methods that can be used both for class HALDevice and
the not-yet-existing class UdevDevice into class BaseDevice.

test: ./bin/test -t 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_processing.py

== Pyflakes notices ==

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

== Pylint notices ==

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

A complaint caused by an unrelated branch that prepares Launchpad for
Python 2.5

Revision history for this message
Barry Warsaw (barry) wrote :

<barry> adeuring: when you raise NotImplementedError in your properties, you
        don't need to instantiate them if they have no arguments. Python will
        DTRT for you here, and it's also somewhat more efficient [11:27]

with that fix, r=me

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-01 11:14:19 +0000
+++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-02 15:43:14 +0000
@@ -1281,28 +1281,94 @@
1281 @property1281 @property
1282 def device_id(self):1282 def device_id(self):
1283 """A unique ID for this device."""1283 """A unique ID for this device."""
1284 raise NotImplementedError()1284 raise NotImplementedError
12851285
1286 @property1286 @property
1287 def pci_class(self):1287 def pci_class(self):
1288 """The PCI device class of the device or None for Non-PCI devices."""1288 """The PCI device class of the device or None for Non-PCI devices."""
1289 raise NotImplementedError()1289 raise NotImplementedError
12901290
1291 @property1291 @property
1292 def pci_subclass(self):1292 def pci_subclass(self):
1293 """The PCI device sub-class of the device or None for Non-PCI devices.1293 """The PCI device sub-class of the device or None for Non-PCI devices.
1294 """1294 """
1295 raise NotImplementedError()1295 raise NotImplementedError
12961296
1297 @property1297 @property
1298 def usb_vendor_id(self):1298 def usb_vendor_id(self):
1299 """The USB vendor ID of the device or None for Non-USB devices."""1299 """The USB vendor ID of the device or None for Non-USB devices."""
1300 raise NotImplementedError()1300 raise NotImplementedError
13011301
1302 @property1302 @property
1303 def usb_product_id(self):1303 def usb_product_id(self):
1304 """The USB product ID of the device or None for Non-USB devices."""1304 """The USB product ID of the device or None for Non-USB devices."""
1305 raise NotImplementedError()1305 raise NotImplementedError
1306
1307 @property
1308 def scsi_vendor(self):
1309 """The SCSI vendor name of the device or None for Non-SCSI devices."""
1310 raise NotImplementedError
1311
1312 @property
1313 def scsi_model(self):
1314 """The SCSI model name of the device or None for Non-SCSI devices."""
1315 raise NotImplementedError
1316
1317 @property
1318 def vendor(self):
1319 """The vendor of this device."""
1320 raise NotImplementedError
1321
1322 @property
1323 def product(self):
1324 """The vendor of this device."""
1325 raise NotImplementedError
1326
1327 @property
1328 def vendor_id(self):
1329 """The vendor ID of this device."""
1330 raise NotImplementedError
1331
1332 @property
1333 def product_id(self):
1334 """The product ID of this device."""
1335 raise NotImplementedError
1336
1337 @property
1338 def vendor_id_for_db(self):
1339 """The vendor ID in the representation needed for the HWDB tables.
1340
1341 USB and PCI IDs are represented in the database in hexadecimal,
1342 while the IDs provided by HAL are integers.
1343
1344 The SCSI vendor name is right-padded with spaces to 8 bytes.
1345 """
1346 bus = self.raw_bus
1347 format = DB_FORMAT_FOR_VENDOR_ID.get(bus)
1348 if format is None:
1349 return self.vendor_id
1350 else:
1351 return format % self.vendor_id
1352
1353 @property
1354 def product_id_for_db(self):
1355 """The product ID in the representation needed for the HWDB tables.
1356
1357 USB and PCI IDs are represented in the database in hexadecimal,
1358 while the IDs provided by HAL are integers.
1359
1360 The SCSI product name is right-padded with spaces to 16 bytes.
1361 """
1362 bus = self.raw_bus
1363 format = DB_FORMAT_FOR_PRODUCT_ID.get(bus)
1364 if format is None:
1365 return self.product_id
1366 else:
1367 return format % self.product_id
1368
1369 @property
1370 def driver_name(self):
1371 """The name of the driver contolling this device. May be None."""
13061372
1307 def translateScsiBus(self):1373 def translateScsiBus(self):
1308 """Return the real bus of a device where raw_bus=='scsi'.1374 """Return the real bus of a device where raw_bus=='scsi'.
@@ -1403,7 +1469,7 @@
1403 @property1469 @property
1404 def raw_bus(self):1470 def raw_bus(self):
1405 """Return the device bus as specified by HAL or udev."""1471 """Return the device bus as specified by HAL or udev."""
1406 raise NotImplementedError()1472 raise NotImplementedError
14071473
1408 @property1474 @property
1409 def real_bus(self):1475 def real_bus(self):
@@ -1734,88 +1800,6 @@
1734 return False1800 return False
1735 return True1801 return True
17361802
1737
1738class HALDevice(BaseDevice):
1739 """The representation of a HAL device node."""
1740
1741 def __init__(self, id, udi, properties, parser):
1742 """HALDevice constructor.
1743
1744 :param id: The ID of the HAL device in the submission data as
1745 specified in <device id=...>.
1746 :type id: int
1747 :param udi: The UDI of the HAL device.
1748 :type udi: string
1749 :param properties: The HAL properties of the device.
1750 :type properties: dict
1751 :param parser: The parser processing a submission.
1752 :type parser: SubmissionParser
1753 """
1754 super(HALDevice, self).__init__(parser)
1755 self.id = id
1756 self.udi = udi
1757 self.properties = properties
1758
1759 def getProperty(self, property_name):
1760 """Return the HAL property property_name.
1761
1762 Note that there is no check of the property type.
1763 """
1764 if property_name not in self.properties:
1765 return None
1766 name, type_ = self.properties[property_name]
1767 return name
1768
1769 @property
1770 def parent_udi(self):
1771 """The UDI of the parent device."""
1772 return self.getProperty('info.parent')
1773
1774 @property
1775 def device_id(self):
1776 """See `BaseDevice`."""
1777 return self.udi
1778
1779 @property
1780 def pci_class(self):
1781 """See `BaseDevice`."""
1782 return self.getProperty('pci.device_class')
1783
1784 @property
1785 def pci_subclass(self):
1786 """The PCI device sub-class of the device or None for Non-PCI devices.
1787 """
1788 return self.getProperty('pci.device_subclass')
1789
1790 @property
1791 def usb_vendor_id(self):
1792 """See `BaseDevice`."""
1793 return self.getProperty('usb_device.vendor_id')
1794
1795 @property
1796 def usb_product_id(self):
1797 """See `BaseDevice`."""
1798 return self.getProperty('usb_device.product_id')
1799
1800 @property
1801 def raw_bus(self):
1802 """See `BaseDevice`."""
1803 # Older versions of HAL stored this value in the property
1804 # info.bus; newer versions store it in info.subsystem.
1805 #
1806 # Note that info.bus is gone for all devices except the
1807 # USB bus. For USB devices, the property info.bus returns more
1808 # detailed data: info.subsystem has the value 'usb' for all
1809 # HAL nodes belonging to USB devices, while info.bus has the
1810 # value 'usb_device' for the root node of a USB device, and the
1811 # value 'usb' for sub-nodes of a USB device. We use these
1812 # different value to to find the root USB device node, hence
1813 # try to read info.bus first.
1814 result = self.getProperty('info.bus')
1815 if result is not None:
1816 return result
1817 return self.getProperty('info.subsystem')
1818
1819 def getScsiVendorAndModelName(self):1803 def getScsiVendorAndModelName(self):
1820 """Separate vendor and model name of SCSI decvices.1804 """Separate vendor and model name of SCSI decvices.
18211805
@@ -1839,132 +1823,17 @@
18391823
1840 In all other cases, vendor and model name are returned unmodified.1824 In all other cases, vendor and model name are returned unmodified.
1841 """1825 """
1842 vendor = self.getProperty('scsi.vendor')1826 vendor = self.scsi_vendor
1843 if vendor == 'ATA':1827 if vendor == 'ATA':
1844 # The assumption below that the vendor name does not1828 # The assumption below that the vendor name does not
1845 # contain any spaces is not necessarily correct, but1829 # contain any spaces is not necessarily correct, but
1846 # it is hard to find a better heuristic to separate1830 # it is hard to find a better heuristic to separate
1847 # the vendor name from the product name.1831 # the vendor name from the product name.
1848 splitted_name = self.getProperty('scsi.model').split(' ', 1)1832 splitted_name = self.scsi_model.split(' ', 1)
1849 if len(splitted_name) < 2:1833 if len(splitted_name) < 2:
1850 return 'ATA', splitted_name[0]1834 return 'ATA', splitted_name[0]
1851 return splitted_name1835 return splitted_name
1852 return (vendor, self.getProperty('scsi.model'))1836 return (vendor, self.scsi_model)
1853
1854 def getVendorOrProduct(self, type_):
1855 """Return the vendor or product of this device.
1856
1857 :return: The vendor or product data for this device.
1858 :param type_: 'vendor' or 'product'
1859 """
1860 # HAL does not store vendor data very consistently. Try to find
1861 # the data in several places.
1862 assert type_ in ('vendor', 'product'), (
1863 'Unexpected value of type_: %r' % type_)
1864
1865 bus = self.raw_bus
1866 if self.udi == ROOT_UDI:
1867 # HAL sets info.product to "Computer", provides no property
1868 # info.vendor and raw_bus is "unknown", hence the logic
1869 # below does not work properly.
1870 return self.getProperty('system.hardware.' + type_)
1871 elif bus == 'scsi':
1872 vendor, product = self.getScsiVendorAndModelName()
1873 if type_ == 'vendor':
1874 return vendor
1875 else:
1876 return product
1877 else:
1878 result = self.getProperty('info.' + type_)
1879 if result is None:
1880 if bus is None:
1881 return None
1882 else:
1883 return self.getProperty('%s.%s' % (bus, type_))
1884 else:
1885 return result
1886
1887 @property
1888 def vendor(self):
1889 """The vendor of this device."""
1890 return self.getVendorOrProduct('vendor')
1891
1892 @property
1893 def product(self):
1894 """The vendor of this device."""
1895 return self.getVendorOrProduct('product')
1896
1897 def getVendorOrProductID(self, type_):
1898 """Return the vendor or product ID for this device.
1899
1900 :return: The vendor or product ID for this device.
1901 :param type_: 'vendor' or 'product'
1902 """
1903 assert type_ in ('vendor', 'product'), (
1904 'Unexpected value of type_: %r' % type_)
1905 bus = self.raw_bus
1906 if self.udi == ROOT_UDI:
1907 # HAL does not provide IDs for a system itself, we use the
1908 # vendor resp. product name instead.
1909 return self.getVendorOrProduct(type_)
1910 elif bus is None:
1911 return None
1912 elif bus == 'scsi' or self.udi == ROOT_UDI:
1913 # The SCSI specification does not distinguish between a
1914 # vendor/model ID and vendor/model name: the SCSI INQUIRY
1915 # command returns an 8 byte string as the vendor name and
1916 # a 16 byte string as the model name. We use these strings
1917 # as the vendor/product name as well as the vendor/product
1918 # ID.
1919 #
1920 # Similary, HAL does not provide a vendor or product ID
1921 # for the host system itself, so we use the vendor resp.
1922 # product name as the vendor/product ID for systems too.
1923 return self.getVendorOrProduct(type_)
1924 else:
1925 return self.getProperty('%s.%s_id' % (bus, type_))
1926
1927 @property
1928 def vendor_id(self):
1929 """The vendor ID of this device."""
1930 return self.getVendorOrProductID('vendor')
1931
1932 @property
1933 def product_id(self):
1934 """The product ID of this device."""
1935 return self.getVendorOrProductID('product')
1936
1937 @property
1938 def vendor_id_for_db(self):
1939 """The vendor ID in the representation needed for the HWDB tables.
1940
1941 USB and PCI IDs are represented in the database in hexadecimal,
1942 while the IDs provided by HAL are integers.
1943
1944 The SCSI vendor name is right-padded with spaces to 8 bytes.
1945 """
1946 bus = self.raw_bus
1947 format = DB_FORMAT_FOR_VENDOR_ID.get(bus)
1948 if format is None:
1949 return self.vendor_id
1950 else:
1951 return format % self.vendor_id
1952
1953 @property
1954 def product_id_for_db(self):
1955 """The product ID in the representation needed for the HWDB tables.
1956
1957 USB and PCI IDs are represented in the database in hexadecimal,
1958 while the IDs provided by HAL are integers.
1959
1960 The SCSI product name is right-padded with spaces to 16 bytes.
1961 """
1962 bus = self.raw_bus
1963 format = DB_FORMAT_FOR_PRODUCT_ID.get(bus)
1964 if format is None:
1965 return self.product_id
1966 else:
1967 return format % self.product_id
19681837
1969 def getDriver(self):1838 def getDriver(self):
1970 """Return the HWDriver instance associated with this device.1839 """Return the HWDriver instance associated with this device.
@@ -1974,11 +1843,11 @@
1974 # HAL and the HWDB client know at present only about kernel1843 # HAL and the HWDB client know at present only about kernel
1975 # drivers, so there is currently no need to search for1844 # drivers, so there is currently no need to search for
1976 # for user space printer drivers, for example.1845 # for user space printer drivers, for example.
1977 driver_name = self.getProperty('info.linux.driver')1846 if self.driver_name is not None:
1978 if driver_name is not None:
1979 kernel_package_name = self.parser.getKernelPackageName()1847 kernel_package_name = self.parser.getKernelPackageName()
1980 db_driver_set = getUtility(IHWDriverSet)1848 db_driver_set = getUtility(IHWDriverSet)
1981 return db_driver_set.getOrCreate(kernel_package_name, driver_name)1849 return db_driver_set.getOrCreate(
1850 kernel_package_name, self.driver_name)
1982 else:1851 else:
1983 return None1852 return None
19841853
@@ -2069,6 +1938,186 @@
2069 submission_device)1938 submission_device)
20701939
20711940
1941class HALDevice(BaseDevice):
1942 """The representation of a HAL device node."""
1943
1944 def __init__(self, id, udi, properties, parser):
1945 """HALDevice constructor.
1946
1947 :param id: The ID of the HAL device in the submission data as
1948 specified in <device id=...>.
1949 :type id: int
1950 :param udi: The UDI of the HAL device.
1951 :type udi: string
1952 :param properties: The HAL properties of the device.
1953 :type properties: dict
1954 :param parser: The parser processing a submission.
1955 :type parser: SubmissionParser
1956 """
1957 super(HALDevice, self).__init__(parser)
1958 self.id = id
1959 self.udi = udi
1960 self.properties = properties
1961
1962 def getProperty(self, property_name):
1963 """Return the HAL property property_name.
1964
1965 Note that there is no check of the property type.
1966 """
1967 if property_name not in self.properties:
1968 return None
1969 name, type_ = self.properties[property_name]
1970 return name
1971
1972 @property
1973 def parent_udi(self):
1974 """The UDI of the parent device."""
1975 return self.getProperty('info.parent')
1976
1977 @property
1978 def device_id(self):
1979 """See `BaseDevice`."""
1980 return self.udi
1981
1982 @property
1983 def pci_class(self):
1984 """See `BaseDevice`."""
1985 return self.getProperty('pci.device_class')
1986
1987 @property
1988 def pci_subclass(self):
1989 """The PCI device sub-class of the device or None for Non-PCI devices.
1990 """
1991 return self.getProperty('pci.device_subclass')
1992
1993 @property
1994 def usb_vendor_id(self):
1995 """See `BaseDevice`."""
1996 return self.getProperty('usb_device.vendor_id')
1997
1998 @property
1999 def usb_product_id(self):
2000 """See `BaseDevice`."""
2001 return self.getProperty('usb_device.product_id')
2002
2003 @property
2004 def scsi_vendor(self):
2005 """See `BaseDevice`."""
2006 return self.getProperty('scsi.vendor')
2007
2008 @property
2009 def scsi_model(self):
2010 """See `BaseDevice`."""
2011 return self.getProperty('scsi.model')
2012
2013 @property
2014 def driver_name(self):
2015 """See `BaseDevice`."""
2016 return self.getProperty('info.linux.driver')
2017
2018 @property
2019 def raw_bus(self):
2020 """See `BaseDevice`."""
2021 # Older versions of HAL stored this value in the property
2022 # info.bus; newer versions store it in info.subsystem.
2023 #
2024 # Note that info.bus is gone for all devices except the
2025 # USB bus. For USB devices, the property info.bus returns more
2026 # detailed data: info.subsystem has the value 'usb' for all
2027 # HAL nodes belonging to USB devices, while info.bus has the
2028 # value 'usb_device' for the root node of a USB device, and the
2029 # value 'usb' for sub-nodes of a USB device. We use these
2030 # different value to to find the root USB device node, hence
2031 # try to read info.bus first.
2032 result = self.getProperty('info.bus')
2033 if result is not None:
2034 return result
2035 return self.getProperty('info.subsystem')
2036
2037 def getVendorOrProduct(self, type_):
2038 """Return the vendor or product of this device.
2039
2040 :return: The vendor or product data for this device.
2041 :param type_: 'vendor' or 'product'
2042 """
2043 # HAL does not store vendor data very consistently. Try to find
2044 # the data in several places.
2045 assert type_ in ('vendor', 'product'), (
2046 'Unexpected value of type_: %r' % type_)
2047
2048 bus = self.raw_bus
2049 if self.udi == ROOT_UDI:
2050 # HAL sets info.product to "Computer", provides no property
2051 # info.vendor and raw_bus is "unknown", hence the logic
2052 # below does not work properly.
2053 return self.getProperty('system.hardware.' + type_)
2054 elif bus == 'scsi':
2055 vendor, product = self.getScsiVendorAndModelName()
2056 if type_ == 'vendor':
2057 return vendor
2058 else:
2059 return product
2060 else:
2061 result = self.getProperty('info.' + type_)
2062 if result is None:
2063 if bus is None:
2064 return None
2065 else:
2066 return self.getProperty('%s.%s' % (bus, type_))
2067 else:
2068 return result
2069
2070 @property
2071 def vendor(self):
2072 """See `BaseDevice`."""
2073 return self.getVendorOrProduct('vendor')
2074
2075 @property
2076 def product(self):
2077 """See `BaseDevice`."""
2078 return self.getVendorOrProduct('product')
2079
2080 def getVendorOrProductID(self, type_):
2081 """Return the vendor or product ID for this device.
2082
2083 :return: The vendor or product ID for this device.
2084 :param type_: 'vendor' or 'product'
2085 """
2086 assert type_ in ('vendor', 'product'), (
2087 'Unexpected value of type_: %r' % type_)
2088 bus = self.raw_bus
2089 if self.udi == ROOT_UDI:
2090 # HAL does not provide IDs for a system itself, we use the
2091 # vendor resp. product name instead.
2092 return self.getVendorOrProduct(type_)
2093 elif bus is None:
2094 return None
2095 elif bus == 'scsi' or self.udi == ROOT_UDI:
2096 # The SCSI specification does not distinguish between a
2097 # vendor/model ID and vendor/model name: the SCSI INQUIRY
2098 # command returns an 8 byte string as the vendor name and
2099 # a 16 byte string as the model name. We use these strings
2100 # as the vendor/product name as well as the vendor/product
2101 # ID.
2102 #
2103 # Similary, HAL does not provide a vendor or product ID
2104 # for the host system itself, so we use the vendor resp.
2105 # product name as the vendor/product ID for systems too.
2106 return self.getVendorOrProduct(type_)
2107 else:
2108 return self.getProperty('%s.%s_id' % (bus, type_))
2109
2110 @property
2111 def vendor_id(self):
2112 """See `BaseDevice`."""
2113 return self.getVendorOrProductID('vendor')
2114
2115 @property
2116 def product_id(self):
2117 """See `BaseDevice`."""
2118 return self.getVendorOrProductID('product')
2119
2120
2072class ProcessingLoop(object):2121class ProcessingLoop(object):
2073 """An `ITunableLoop` for processing HWDB submissions."""2122 """An `ITunableLoop` for processing HWDB submissions."""
20742123
20752124
=== modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py'
--- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-01 11:14:19 +0000
+++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-02 15:43:14 +0000
@@ -462,6 +462,60 @@
462 'Unexpected value of HALDevice.usb_product_id for Non-USB '462 'Unexpected value of HALDevice.usb_product_id for Non-USB '
463 'device.')463 'device.')
464464
465 def testHALDeviceScsiVendor(self):
466 """Test of HALDevice.scsi_vendor."""
467 properties = {
468 'scsi.vendor': ('SEAGATE', 'string'),
469 }
470 parser = SubmissionParser(self.log)
471 device = HALDevice(1, '/some/udi/path', properties, parser)
472 self.assertEqual(
473 'SEAGATE', device.scsi_vendor,
474 'Unexpected value of HALDevice.scsi_vendor.')
475
476 properties = {}
477 parser = SubmissionParser(self.log)
478 device = HALDevice(1, '/some/udi/path', properties, parser)
479 self.assertEqual(
480 None, device.scsi_vendor,
481 'Unexpected value of HALDevice.scsi_vendor for Non-SCSI device.')
482
483 def testHALDeviceScsiModel(self):
484 """Test of HALDevice.scsi_model."""
485 properties = {
486 'scsi.model': ('ST1234567', 'string'),
487 }
488 parser = SubmissionParser(self.log)
489 device = HALDevice(1, '/some/udi/path', properties, parser)
490 self.assertEqual(
491 'ST1234567', device.scsi_model,
492 'Unexpected value of HALDevice.scsi_model.')
493
494 properties = {}
495 parser = SubmissionParser(self.log)
496 device = HALDevice(1, '/some/udi/path', properties, parser)
497 self.assertEqual(
498 None, device.scsi_model,
499 'Unexpected value of HALDevice.scsi_model for Non-SCSI device.')
500
501 def testHALDeviceDriverName(self):
502 """Test of HALDevice.driver_name."""
503 properties = {
504 'info.linux.driver': ('ahci', 'string'),
505 }
506 parser = SubmissionParser(self.log)
507 device = HALDevice(1, '/some/udi/path', properties, parser)
508 self.assertEqual(
509 'ahci', device.driver_name,
510 'Unexpected value of HALDevice.driver_name.')
511
512 properties = {}
513 parser = SubmissionParser(self.log)
514 device = HALDevice(1, '/some/udi/path', properties, parser)
515 self.assertEqual(
516 None, device.driver_name,
517 'Unexpected value of HALDevice.driver_name for Non-SCSI device.')
518
465 def testHalDeviceRawBus(self):519 def testHalDeviceRawBus(self):
466 """test of HALDevice.raw_bus."""520 """test of HALDevice.raw_bus."""
467 properties = {521 properties = {