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

Proposed by Abel Deuring
Status: Merged
Merged at revision: not available
Proposed branch: lp:~adeuring/launchpad/hwdb-class-udev-device-9
Merge into: lp:launchpad
Diff against target: 829 lines
2 files modified
lib/canonical/launchpad/scripts/hwdbsubmissions.py (+43/-7)
lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py (+391/-52)
To merge this branch: bzr merge lp:~adeuring/launchpad/hwdb-class-udev-device-9
Reviewer Review Type Date Requested Status
Eleanor Berger (community) code Approve
Review via email: mp+13562@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote :
Download full text (4.3 KiB)

This branch "adjusts" BaseDevice.is_real_device for udev data.

The HWDB submission processing script creates instances of class UdevDevice (derived from class BaseDevice) for each udev node found in the submitted data. (run "udevadm info --export-db" to see how this data looks in real like. But note that the output differs in many small details between the udev versions in Jaunty and Karmic.) In many cases udev has more than one node for a given physical device. SCSI devices, for example, have a "main" node, one sub-node for the the "disk aspect" of the device, another sub-node for the generic SCSI driver (allowing you to control the device with "raw" SCSI commands from a user-space program) etc.

We do not want to store these fine details in the HWDB -- we want to store data about a physical device just once. The decision if a given UdevDevice node represents a physical device is made by the property BaseDevice.is_real_device.

The code of this property accessed the property HALDevice.udi which is not available for class UdevDevice; this is replaced by is_root_device.

The core idea of is_real_device is to base the decision on the value of the property raw_bus. This does not work very well for the root device, where raw_bus is None or "Unknown" for submissions with HAL data, and "acpi" for udev submissions. So I moved the case for the root device to the top of the method, to keep the remaining code a bit more clean.

There are some differences in the values of raw_bus between HAL and udev submissions: For udev data, we can have raw_bus set to "partition", "scsi_disk", "scsi_target", "spi_transport". Such nodes desribe "aspects" of SCSI devices, but not real devices, so I added these values to "if bus in (None..."

These values do not appear in submissions with HAL data, so there is no bad side effect of this change.

The raw_bus is "scsi_device" for the udev node describing the "physical" device, while it is "scsi" for submissions with HAL data, so I had to adjust "elif bus == 'scsi':" too. Again, "scsi_device" is not used in submissions with HAL data, so no bad side effect.

Finally, I had to adjust UdevDevice.raw_bus (diff @@ -2564,7 +2590,17 @@). The core idea if the property is to access the HAL property "info.bus" or "info.subsystem" (depending on the HAL version), and to access "something correspondent" for udev devices, where we use the udev properties SUBSYSTEM and DEVTYPE. The name is intended to show a "contrast" to another property real_bus, which may differ for PCI devices (where real_bus may be "PC Card") and for SCSI devices, which may in fact be IDE, ATA or USB devices.

The idea to use DEVTYPE, if this udev property is available, or SUBSYSTEM otherwsie, works mostly fine, except for a certain sub-node of a real SCSI device, where SUBSYSTEM is "scsi_device" and DEVTYPE is None. This leads to conflicts with the main node of a SCSI device, where SUBSYSTEM is "scsi", and DEVTYPE is "scsi_device". The former node should not be treated as a real device, while the latter should be... So I introduced the "if subsystem != 'scsi_device':" clause. This makes the property raw_bus, let's say, "less raw", but I could not come up with a ...

Read more...

Revision history for this message
Abel Deuring (adeuring) wrote :
Download full text (24.8 KiB)

This branch is based on lp:~adeuring/launchpad/hwdb-class-udev-device-9, which is reviewd, but has not yet landed. Here is the diff against that branch:

=== modified file 'lib/canonical/launchpad/scripts/hwdbsubmissions.py'
--- lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-18 17:44:12 +0000
+++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-19 10:41:31 +0000
@@ -1835,6 +1835,9 @@
             Since these components are not the most important ones
             for the HWDB, we'll ignore them for now. Bug 237038.

+ - 'disk' is used udev submissions for a node related to the
+ sd or sr driver of (real or fake) SCSI block devices.
+
           - info.bus == 'drm' is used by the HAL for the direct
             rendering interface of a graphics card.

@@ -1847,6 +1850,12 @@
           - info.bus == 'net' is used by the HAL version in
             Intrepid for the "output aspects" of network devices.

+ - 'partition' is used in udev submissions for a node
+ related to disk partition
+
+ - 'scsi_disk' is used in udev submissions for a sub-node of
+ the real device node.
+
             info.bus == 'scsi_generic' is used by the HAL version in
             Intrepid for a HAL node representing the generic
             interface of a SCSI device.
@@ -1858,6 +1867,12 @@
             "SCSI aspect" of another HAL node which represents the
             real device.

+ 'scsi_target' is used in udev data for SCSI target nodes,
+ the parent of a SCSI device (or LUN) node.
+
+ 'spi_transport' (SCSI Parallel Transport) is used in
+ udev data for a sub-node of real SCSI devices.
+
             info.bus == 'sound' is used by the HAL version in
             Intrepid for "aspects" of sound devices.

@@ -1873,20 +1888,31 @@
             info.bus == 'usb' is used for end points of USB devices;
             the root node of a USB device has info.bus == 'usb_device'.

+ 'usb_interface' is used in udv submissions for interface
+ nodes of USB devices.
+
             info.bus == 'video4linux' is used for the "input aspect"
             of video devices.
         """
+ # The root node is always a real device, but its raw_bus
+ # property can have different values: None or 'Unknown' in
+ # submissions with HAL data, 'acpi' for submissions with udev
+ # data.
+ if self.is_root_device:
+ return True
+
         bus = self.raw_bus
         # This set of buses is only used once; it's easier to have it
         # here than to put it elsewhere and have to document its
         # location and purpose.
- if bus in (None, 'drm', 'dvb', 'memstick_host', 'net',
- 'scsi_generic', 'scsi_host', 'sound', 'ssb', 'tty',
- 'usb', 'video4linux', ):
+ if bus in (None, 'disk', 'drm', 'dvb', 'memstick_host', 'net',
+ 'partition', 'scsi_disk', 'scsi_generic', 'scsi_host',
+ 'scsi_target', 'sound', 'spi_transport', 'ssb', 'tty',
+ 'usb', 'usb_interface', 'video4linux', ):
             #
          ...

Revision history for this message
Abel Deuring (adeuring) wrote :
Revision history for this message
Eleanor Berger (intellectronica) :
review: Approve (code)

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-15 13:59:33 +0000
+++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-19 11:30:32 +0000
@@ -1835,6 +1835,9 @@
1835 Since these components are not the most important ones1835 Since these components are not the most important ones
1836 for the HWDB, we'll ignore them for now. Bug 237038.1836 for the HWDB, we'll ignore them for now. Bug 237038.
18371837
1838 - 'disk' is used udev submissions for a node related to the
1839 sd or sr driver of (real or fake) SCSI block devices.
1840
1838 - info.bus == 'drm' is used by the HAL for the direct1841 - info.bus == 'drm' is used by the HAL for the direct
1839 rendering interface of a graphics card.1842 rendering interface of a graphics card.
18401843
@@ -1847,6 +1850,12 @@
1847 - info.bus == 'net' is used by the HAL version in1850 - info.bus == 'net' is used by the HAL version in
1848 Intrepid for the "output aspects" of network devices.1851 Intrepid for the "output aspects" of network devices.
18491852
1853 - 'partition' is used in udev submissions for a node
1854 related to disk partition
1855
1856 - 'scsi_disk' is used in udev submissions for a sub-node of
1857 the real device node.
1858
1850 info.bus == 'scsi_generic' is used by the HAL version in1859 info.bus == 'scsi_generic' is used by the HAL version in
1851 Intrepid for a HAL node representing the generic1860 Intrepid for a HAL node representing the generic
1852 interface of a SCSI device.1861 interface of a SCSI device.
@@ -1858,6 +1867,12 @@
1858 "SCSI aspect" of another HAL node which represents the1867 "SCSI aspect" of another HAL node which represents the
1859 real device.1868 real device.
18601869
1870 'scsi_target' is used in udev data for SCSI target nodes,
1871 the parent of a SCSI device (or LUN) node.
1872
1873 'spi_transport' (SCSI Parallel Transport) is used in
1874 udev data for a sub-node of real SCSI devices.
1875
1861 info.bus == 'sound' is used by the HAL version in1876 info.bus == 'sound' is used by the HAL version in
1862 Intrepid for "aspects" of sound devices.1877 Intrepid for "aspects" of sound devices.
18631878
@@ -1873,20 +1888,31 @@
1873 info.bus == 'usb' is used for end points of USB devices;1888 info.bus == 'usb' is used for end points of USB devices;
1874 the root node of a USB device has info.bus == 'usb_device'.1889 the root node of a USB device has info.bus == 'usb_device'.
18751890
1891 'usb_interface' is used in udv submissions for interface
1892 nodes of USB devices.
1893
1876 info.bus == 'video4linux' is used for the "input aspect"1894 info.bus == 'video4linux' is used for the "input aspect"
1877 of video devices.1895 of video devices.
1878 """1896 """
1897 # The root node is always a real device, but its raw_bus
1898 # property can have different values: None or 'Unknown' in
1899 # submissions with HAL data, 'acpi' for submissions with udev
1900 # data.
1901 if self.is_root_device:
1902 return True
1903
1879 bus = self.raw_bus1904 bus = self.raw_bus
1880 # This set of buses is only used once; it's easier to have it1905 # This set of buses is only used once; it's easier to have it
1881 # here than to put it elsewhere and have to document its1906 # here than to put it elsewhere and have to document its
1882 # location and purpose.1907 # location and purpose.
1883 if bus in (None, 'drm', 'dvb', 'memstick_host', 'net',1908 if bus in (None, 'disk', 'drm', 'dvb', 'memstick_host', 'net',
1884 'scsi_generic', 'scsi_host', 'sound', 'ssb', 'tty',1909 'partition', 'scsi_disk', 'scsi_generic', 'scsi_host',
1885 'usb', 'video4linux', ):1910 'scsi_target', 'sound', 'spi_transport', 'ssb', 'tty',
1911 'usb', 'usb_interface', 'video4linux', ):
1886 #1912 #
1887 # The computer itself is the only HAL device without the1913 # The computer itself is the only HAL device without the
1888 # info.bus property that we treat as a real device.1914 # info.bus property that we treat as a real device.
1889 return self.udi == ROOT_UDI1915 return False
1890 elif bus == 'usb_device':1916 elif bus == 'usb_device':
1891 vendor_id = self.usb_vendor_id1917 vendor_id = self.usb_vendor_id
1892 product_id = self.usb_product_id1918 product_id = self.usb_product_id
@@ -1910,7 +1936,7 @@
1910 'host controller: %s' % self.udi)1936 'host controller: %s' % self.udi)
1911 return False1937 return False
1912 return True1938 return True
1913 elif bus == 'scsi':1939 elif bus in ('scsi', 'scsi_device'):
1914 # Ensure consistency with HALDevice.real_bus1940 # Ensure consistency with HALDevice.real_bus
1915 return self.real_bus is not None1941 return self.real_bus is not None
1916 else:1942 else:
@@ -2564,7 +2590,17 @@
2564 devtype = properties.get('DEVTYPE')2590 devtype = properties.get('DEVTYPE')
2565 if devtype is not None:2591 if devtype is not None:
2566 return devtype2592 return devtype
2567 return properties.get('SUBSYSTEM')2593 subsystem = properties.get('SUBSYSTEM')
2594 # A real mess: The main node of a SCSI device has
2595 # SUBSYSTEM = 'scsi' and DEVTYPE = 'scsi_device', while
2596 # a sub-node has SUBSYSTEM='scsi_device'. We don't want
2597 # the two to be confused. The latter node is not of any
2598 # interest for us, so we return None. This ensures that
2599 # is_real_device returns False for the sub-node.
2600 if subsystem != 'scsi_device':
2601 return subsystem
2602 else:
2603 return None
25682604
2569 @property2605 @property
2570 def is_root_device(self):2606 def is_root_device(self):
@@ -2665,7 +2701,7 @@
2665 # While SCSI devices from valid submissions should have four2701 # While SCSI devices from valid submissions should have four
2666 # ancestors, we can't be sure for bogus or broken submissions.2702 # ancestors, we can't be sure for bogus or broken submissions.
2667 try:2703 try:
2668 controller = self.parent.parent.parent.parent2704 controller = self.parent.parent.parent
2669 except AttributeError:2705 except AttributeError:
2670 controller = None2706 controller = None
2671 if controller is None:2707 if controller is None:
26722708
=== modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py'
--- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-15 15:28:38 +0000
+++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-19 11:30:32 +0000
@@ -2859,18 +2859,6 @@
2859 '/sys/class/dmi/id/product_name': 'LIFEBOOK E8210',2859 '/sys/class/dmi/id/product_name': 'LIFEBOOK E8210',
2860 }2860 }
28612861
2862 self.pci_device_data = {
2863 'P': '/devices/pci0000:00/0000:00:1f.2',
2864 'E': {
2865 'PCI_CLASS': '10602',
2866 'PCI_ID': '8086:27C5',
2867 'PCI_SUBSYS_ID': '10CF:1387',
2868 'PCI_SLOT_NAME': '0000:00:1f.2',
2869 'SUBSYSTEM': 'pci',
2870 'DRIVER': 'ahci',
2871 }
2872 }
2873
2874 self.usb_device_data = {2862 self.usb_device_data = {
2875 'P': '/devices/pci0000:00/0000:00:1d.1/usb3/3-2',2863 'P': '/devices/pci0000:00/0000:00:1d.1/usb3/3-2',
2876 'E': {2864 'E': {
@@ -2882,8 +2870,10 @@
2882 },2870 },
2883 }2871 }
28842872
2873 self.pci_pccard_bridge_path = (
2874 '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0')
2885 self.pci_pccard_bridge = {2875 self.pci_pccard_bridge = {
2886 'P': '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0',2876 'P': self.pci_pccard_bridge_path,
2887 'E': {2877 'E': {
2888 'DRIVER': 'yenta_cardbus',2878 'DRIVER': 'yenta_cardbus',
2889 'PCI_CLASS': '60700',2879 'PCI_CLASS': '60700',
@@ -2894,8 +2884,10 @@
2894 }2884 }
2895 }2885 }
28962886
2887 self.pccard_scsi_controller_path = (
2888 '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0')
2897 self.pccard_scsi_controller_data = {2889 self.pccard_scsi_controller_data = {
2898 'P': '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0',2890 'P': self.pccard_scsi_controller_path,
2899 'E': {2891 'E': {
2900 'DRIVER': 'aic7xxx',2892 'DRIVER': 'aic7xxx',
2901 'PCI_CLASS': '10000',2893 'PCI_CLASS': '10000',
@@ -2937,9 +2929,11 @@
2937 },2929 },
2938 }2930 }
29392931
2932 self.scsi_scanner_device_path = (
2933 '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0/'
2934 'host6/target6:0:1/6:0:1:0')
2940 self.scsi_scanner_device_data = {2935 self.scsi_scanner_device_data = {
2941 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/'2936 'P': self.scsi_scanner_device_path,
2942 '0000:09:00.0/host6/target6:0:1/6:0:1:0'),
2943 'E': {2937 'E': {
2944 'DEVTYPE': 'scsi_device',2938 'DEVTYPE': 'scsi_device',
2945 'SUBSYSTEM': 'scsi',2939 'SUBSYSTEM': 'scsi',
@@ -2952,6 +2946,31 @@
2952 'type': '6',2946 'type': '6',
2953 }2947 }
29542948
2949 self.scsi_scanner_device_data_2 = {
2950 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/'
2951 '0000:09:00.0/host6/target6:0:1/6:0:1:0/scsi_device/'
2952 '6:0:1:0'),
2953 'E': {
2954 'SUBSYSTEM': 'scsi_device',
2955 },
2956 }
2957
2958 self.scsi_scanner_scsi_generic = {
2959 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/'
2960 '0000:09:00.0/host6/target6:0:1/6:0:1:0/scsi_generic/sg2'),
2961 'E': {
2962 'SUBSYSTEM': 'scsi_generic',
2963 },
2964 }
2965
2966 self.scsi_scanner_spi = {
2967 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/'
2968 '0000:09:00.0/host6/target6:0:1/spi_transport/target6:0:1'),
2969 'E': {
2970 'SUBSYSTEM': 'spi_transport',
2971 },
2972 }
2973
2955 self.scsi_device_hierarchy_data = [2974 self.scsi_device_hierarchy_data = [
2956 {'udev_data': self.pccard_scsi_controller_data},2975 {'udev_data': self.pccard_scsi_controller_data},
2957 {'udev_data': self.pci_scsi_controller_scsi_side_1},2976 {'udev_data': self.pci_scsi_controller_scsi_side_1},
@@ -2961,10 +2980,14 @@
2961 'udev_data': self.scsi_scanner_device_data,2980 'udev_data': self.scsi_scanner_device_data,
2962 'sysfs_data': self.scsi_scanner_device_sysfs_data,2981 'sysfs_data': self.scsi_scanner_device_sysfs_data,
2963 },2982 },
2983 {'udev_data': self.scsi_scanner_device_data_2},
2984 {'udev_data': self.scsi_scanner_scsi_generic},
2985 {'udev_data': self.scsi_scanner_spi},
2964 ]2986 ]
29652987
2988 self.pci_ide_controller_path = '/devices/pci0000:00/0000:00:1f.1'
2966 self.pci_ide_controller = {2989 self.pci_ide_controller = {
2967 'P': '/devices/pci0000:00/0000:00:1f.1',2990 'P': self.pci_ide_controller_path,
2968 'E': {2991 'E': {
2969 'DRIVER': 'ata_piix',2992 'DRIVER': 'ata_piix',
2970 'PCI_CLASS': '1018A',2993 'PCI_CLASS': '1018A',
@@ -2997,9 +3020,10 @@
2997 },3020 },
2998 }3021 }
29993022
3023 self.ide_cdrom_device_path = (
3024 '/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0')
3000 self.ide_cdrom_device_data = {3025 self.ide_cdrom_device_data = {
3001 'P': ('/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/'3026 'P': self.ide_cdrom_device_path,
3002 '4:0:0:0'),
3003 'E': {3027 'E': {
3004 'SUBSYSTEM': 'scsi',3028 'SUBSYSTEM': 'scsi',
3005 'DEVTYPE': 'scsi_device',3029 'DEVTYPE': 'scsi_device',
@@ -3013,6 +3037,31 @@
3013 'type': '5',3037 'type': '5',
3014 }3038 }
30153039
3040 self.ide_cdrom_sr_data = {
3041 'P': ('/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/'
3042 '4:0:0:0/block/sr0'),
3043 'E': {
3044 'DEVTYPE': 'disk',
3045 'SUBSYSTEM': 'block',
3046 },
3047 }
3048
3049 self.ide_cdrom_device_data_2 = {
3050 'P': ('/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/'
3051 '4:0:0:0/scsi_device/4:0:0:0'),
3052 'E': {
3053 'SUBSYSTEM': 'scsi_device',
3054 },
3055 }
3056
3057 self.ide_cdrom_scsi_generic_data = {
3058 'P': ('/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/'
3059 '4:0:0:0/scsi_generic/sg1'),
3060 'E': {
3061 'SUBSYSTEM': 'scsi_generic',
3062 },
3063 }
3064
3016 self.ide_device_hierarchy_data = [3065 self.ide_device_hierarchy_data = [
3017 {'udev_data': self.pci_ide_controller},3066 {'udev_data': self.pci_ide_controller},
3018 {'udev_data': self.pci_ide_controller_scsi_side_1},3067 {'udev_data': self.pci_ide_controller_scsi_side_1},
@@ -3022,8 +3071,136 @@
3022 'udev_data': self.ide_cdrom_device_data,3071 'udev_data': self.ide_cdrom_device_data,
3023 'sysfs_data': self.ide_cdrom_device_sysfs_data,3072 'sysfs_data': self.ide_cdrom_device_sysfs_data,
3024 },3073 },
3074 {'udev_data': self.ide_cdrom_sr_data},
3075 {'udev_data': self.ide_cdrom_device_data_2},
3076 {'udev_data': self.ide_cdrom_scsi_generic_data},
3025 ]3077 ]
30263078
3079 self.pci_sata_controller_path = '/devices/pci0000:00/0000:00:1f.2'
3080 self.pci_sata_controller = {
3081 'P': self.pci_sata_controller_path,
3082 'E': {
3083 'PCI_CLASS': '10602',
3084 'PCI_ID': '8086:27C5',
3085 'PCI_SUBSYS_ID': '10CF:1387',
3086 'PCI_SLOT_NAME': '0000:00:1f.2',
3087 'SUBSYSTEM': 'pci',
3088 'DRIVER': 'ahci',
3089 }
3090 }
3091
3092 self.pci_sata_controller_scsi_side_1 = {
3093 'P': '/devices/pci0000:00/0000:00:1f.2/host0',
3094 'E': {
3095 'DEVTYPE': 'scsi_host',
3096 'SUBSYSTEM': 'scsi',
3097 },
3098 }
3099
3100 self.pci_sata_controller_scsi_side_2 = {
3101 'P': '/devices/pci0000:00/0000:00:1f.2/host0/scsi_host/host0',
3102 'E': {
3103 'SUBSYSTEM': 'scsi_host',
3104 },
3105 }
3106
3107 self.sata_disk_target_data = {
3108 'P': '/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0',
3109 'E': {
3110 'DEVTYPE': 'scsi_target',
3111 'SUBSYSTEM': 'scsi',
3112 },
3113 }
3114
3115 self.sata_disk_device_path = (
3116 '/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0')
3117 self.sata_disk_device_data = {
3118 'P': self.sata_disk_device_path,
3119 'E': {
3120 'DEVTYPE': 'scsi_device',
3121 'DRIVER': 'sd',
3122 'SUBSYSTEM': 'scsi',
3123 },
3124 }
3125
3126 self.sata_disk_device_sysfs_data = {
3127 'vendor': 'ATA',
3128 'model': 'Hitachi HTS54251',
3129 'type': '0',
3130 }
3131
3132 self.sata_disk_device_data_2 = {
3133 'P': ('/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/'
3134 '0:0:0:0/scsi_device/0:0:0:0'),
3135 'E': {
3136 'SUBSYSTEM': 'scsi_device',
3137 },
3138 }
3139
3140 self.sata_disk_device_scsi_disk_data = {
3141 'P': ('/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/'
3142 '0:0:0:0/scsi_disk/0:0:0:0'),
3143 'E': {
3144 'SUBSYSTEM': 'scsi_disk',
3145 },
3146 }
3147
3148 self.sata_disk_device_scsi_generic_data = {
3149 'P': ('/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/'
3150 '0:0:0:0/scsi_generic/sg0'),
3151 'E': {
3152 'SUBSYSTEM': 'scsi_generic'
3153 },
3154 }
3155
3156 self.sata_disk_block_data = {
3157 'P': ('/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/'
3158 '0:0:0:0/block/sda'),
3159 'E': {
3160 'DEVTYPE': 'disk',
3161 'SUBSYSTEM': 'block',
3162 },
3163 }
3164
3165 self.sata_disk_partition_data = {
3166 'P': ('/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/'
3167 '0:0:0:0/block/sda/sda1'),
3168 'E': {
3169 'DEVTYPE': 'partition',
3170 'SUBSYSTEM': 'block',
3171 },
3172 }
3173
3174 self.sata_device_hierarchy_data = [
3175 {'udev_data': self.pci_sata_controller},
3176 {'udev_data': self.pci_sata_controller_scsi_side_1},
3177 {'udev_data': self.pci_sata_controller_scsi_side_2},
3178 {'udev_data': self.sata_disk_target_data},
3179 {'udev_data': self.sata_disk_device_data},
3180 {
3181 'udev_data': self.sata_disk_device_data,
3182 'sysfs_data': self.sata_disk_device_sysfs_data,
3183 },
3184 {'udev_data': self.sata_disk_device_data_2},
3185 {'udev_data': self.sata_disk_device_scsi_disk_data},
3186 {'udev_data': self.sata_disk_device_scsi_generic_data},
3187 {'udev_data': self.sata_disk_block_data},
3188 {'udev_data': self.sata_disk_partition_data},
3189 ]
3190
3191 self.usb_storage_usb_device_path = (
3192 '/devices/pci0000:00/0000:00:1d.7/usb1/1-1')
3193 self.usb_storage_usb_device_data = {
3194 'P': self.usb_storage_usb_device_path,
3195 'E': {
3196 'DEVTYPE': 'usb_device',
3197 'DRIVER': 'usb',
3198 'PRODUCT': '1307/163/100',
3199 'TYPE': '0/0/0',
3200 'SUBSYSTEM': 'usb',
3201 },
3202 }
3203
3027 self.usb_storage_usb_interface = {3204 self.usb_storage_usb_interface = {
3028 'P': '/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0',3205 'P': '/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0',
3029 'E': {3206 'E': {
@@ -3061,9 +3238,11 @@
3061 },3238 },
3062 }3239 }
30633240
3241 self.usb_storage_scsi_device_path = (
3242 '/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/'
3243 'target7:0:0/7:0:0:0')
3064 self.usb_storage_scsi_device = {3244 self.usb_storage_scsi_device = {
3065 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/'3245 'P': self.usb_storage_scsi_device_path,
3066 'target7:0:0/7:0:0:0'),
3067 'E': {3246 'E': {
3068 'DEVTYPE': 'scsi_device',3247 'DEVTYPE': 'scsi_device',
3069 'DRIVER': 'sd',3248 'DRIVER': 'sd',
@@ -3077,7 +3256,50 @@
3077 'type': '0',3256 'type': '0',
3078 }3257 }
30793258
3259 self.usb_storage_scsi_device_2 = {
3260 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/'
3261 'target7:0:0/7:0:0:0/scsi_device/7:0:0:0'),
3262 'E': {
3263 'SUBSYSTEM': 'scsi_device',
3264 },
3265 }
3266
3267 self.usb_storage_scsi_disk = {
3268 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/'
3269 'target7:0:0/7:0:0:0/scsi_disk/7:0:0:0'),
3270 'E': {
3271 'SUBSYSTEM': 'scsi_disk',
3272 },
3273 }
3274
3275 self.usb_storage_scsi_generic = {
3276 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/'
3277 'target7:0:0/7:0:0:0/scsi_generic/sg3'),
3278 'E': {
3279 'SUBSYSTEM': 'scsi_generic',
3280 },
3281 }
3282
3283 self.usb_storage_block_device_data = {
3284 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/'
3285 'target7:0:0/7:0:0:0/block/sdb'),
3286 'E': {
3287 'DEVTYPE': 'disk',
3288 'SUBSYSTEM': 'block',
3289 },
3290 }
3291
3292 self.usb_storage_block_partition_data = {
3293 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/'
3294 'target7:0:0/7:0:0:0/block/sdb/sdb1'),
3295 'E': {
3296 'DEVTYPE': 'partition',
3297 'SUBSYSTEM': 'block',
3298 },
3299 }
3300
3080 self.usb_storage_hierarchy_data = [3301 self.usb_storage_hierarchy_data = [
3302 {'udev_data': self.usb_storage_usb_device_data},
3081 {'udev_data': self.usb_storage_usb_interface},3303 {'udev_data': self.usb_storage_usb_interface},
3082 {'udev_data': self.usb_storage_scsi_host_1},3304 {'udev_data': self.usb_storage_scsi_host_1},
3083 {'udev_data': self.usb_storage_scsi_host_2},3305 {'udev_data': self.usb_storage_scsi_host_2},
@@ -3086,6 +3308,11 @@
3086 'udev_data': self.usb_storage_scsi_device,3308 'udev_data': self.usb_storage_scsi_device,
3087 'sysfs_data': self.usb_storage_scsi_device_sysfs,3309 'sysfs_data': self.usb_storage_scsi_device_sysfs,
3088 },3310 },
3311 {'udev_data': self.usb_storage_scsi_device_2},
3312 {'udev_data': self.usb_storage_scsi_disk},
3313 {'udev_data': self.usb_storage_scsi_generic},
3314 {'udev_data': self.usb_storage_block_device_data},
3315 {'udev_data': self.usb_storage_block_partition_data},
3089 ]3316 ]
30903317
3091 self.no_subsystem_device_data = {3318 self.no_subsystem_device_data = {
@@ -3095,7 +3322,7 @@
30953322
3096 def test_device_id(self):3323 def test_device_id(self):
3097 """Test of UdevDevice.device_id."""3324 """Test of UdevDevice.device_id."""
3098 device = UdevDevice(None, self.pci_device_data)3325 device = UdevDevice(None, self.pci_sata_controller)
3099 self.assertEqual(3326 self.assertEqual(
3100 '/devices/pci0000:00/0000:00:1f.2', device.device_id,3327 '/devices/pci0000:00/0000:00:1f.2', device.device_id,
3101 'Unexpected value of UdevDevice.device_id.')3328 'Unexpected value of UdevDevice.device_id.')
@@ -3121,7 +3348,7 @@
31213348
3122 def test_is_pci(self):3349 def test_is_pci(self):
3123 """Test of UdevDevice.is_pci."""3350 """Test of UdevDevice.is_pci."""
3124 device = UdevDevice(None, self.pci_device_data)3351 device = UdevDevice(None, self.pci_sata_controller)
3125 self.assertTrue(device.is_pci)3352 self.assertTrue(device.is_pci)
31263353
3127 device = UdevDevice(None, self.root_device)3354 device = UdevDevice(None, self.root_device)
@@ -3129,7 +3356,7 @@
31293356
3130 def test_pci_class_info(self):3357 def test_pci_class_info(self):
3131 """Test of UdevDevice.pci_class_info"""3358 """Test of UdevDevice.pci_class_info"""
3132 device = UdevDevice(None, self.pci_device_data)3359 device = UdevDevice(None, self.pci_sata_controller)
3133 self.assertEqual(3360 self.assertEqual(
3134 (1, 6, 2), device.pci_class_info,3361 (1, 6, 2), device.pci_class_info,
3135 'Invalid value of UdevDevice.pci_class_info for PCI device.')3362 'Invalid value of UdevDevice.pci_class_info for PCI device.')
@@ -3141,7 +3368,7 @@
31413368
3142 def test_pci_class(self):3369 def test_pci_class(self):
3143 """Test of UdevDevice.pci_class"""3370 """Test of UdevDevice.pci_class"""
3144 device = UdevDevice(None, self.pci_device_data)3371 device = UdevDevice(None, self.pci_sata_controller)
3145 self.assertEqual(3372 self.assertEqual(
3146 1, device.pci_class,3373 1, device.pci_class,
3147 'Invalid value of UdevDevice.pci_class for PCI device.')3374 'Invalid value of UdevDevice.pci_class for PCI device.')
@@ -3153,7 +3380,7 @@
31533380
3154 def test_pci_subclass(self):3381 def test_pci_subclass(self):
3155 """Test of UdevDevice.pci_subclass"""3382 """Test of UdevDevice.pci_subclass"""
3156 device = UdevDevice(None, self.pci_device_data)3383 device = UdevDevice(None, self.pci_sata_controller)
3157 self.assertEqual(3384 self.assertEqual(
3158 6, device.pci_subclass,3385 6, device.pci_subclass,
3159 'Invalid value of UdevDevice.pci_class for PCI device.')3386 'Invalid value of UdevDevice.pci_class for PCI device.')
@@ -3165,7 +3392,7 @@
31653392
3166 def test_pci_ids(self):3393 def test_pci_ids(self):
3167 """Test of UdevDevice.pci_ids"""3394 """Test of UdevDevice.pci_ids"""
3168 device = UdevDevice(None, self.pci_device_data)3395 device = UdevDevice(None, self.pci_sata_controller)
3169 self.assertEqual(3396 self.assertEqual(
3170 {'vendor': 0x8086,3397 {'vendor': 0x8086,
3171 'product': 0x27C5,3398 'product': 0x27C5,
@@ -3186,7 +3413,7 @@
3186 device = UdevDevice(None, self.usb_device_data)3413 device = UdevDevice(None, self.usb_device_data)
3187 self.assertTrue(device.is_usb)3414 self.assertTrue(device.is_usb)
31883415
3189 device = UdevDevice(None, self.pci_device_data)3416 device = UdevDevice(None, self.pci_sata_controller)
3190 self.assertFalse(device.is_usb)3417 self.assertFalse(device.is_usb)
31913418
3192 def test_usb_ids(self):3419 def test_usb_ids(self):
@@ -3269,7 +3496,7 @@
3269 device = UdevDevice(None, self.root_device)3496 device = UdevDevice(None, self.root_device)
3270 self.assertEqual(None, device.raw_bus)3497 self.assertEqual(None, device.raw_bus)
32713498
3272 device = UdevDevice(None, self.pci_device_data)3499 device = UdevDevice(None, self.pci_sata_controller)
3273 self.assertEqual('pci', device.raw_bus)3500 self.assertEqual('pci', device.raw_bus)
32743501
3275 device = UdevDevice(None, self.usb_device_data)3502 device = UdevDevice(None, self.usb_device_data)
@@ -3283,7 +3510,7 @@
3283 device = UdevDevice(None, self.root_device)3510 device = UdevDevice(None, self.root_device)
3284 self.assertTrue(device.is_root_device)3511 self.assertTrue(device.is_root_device)
32853512
3286 device = UdevDevice(None, self.pci_device_data)3513 device = UdevDevice(None, self.pci_sata_controller)
3287 self.assertFalse(device.is_root_device)3514 self.assertFalse(device.is_root_device)
32883515
3289 def test_getVendorOrProduct(self):3516 def test_getVendorOrProduct(self):
@@ -3297,7 +3524,7 @@
3297 self.assertRaises(3524 self.assertRaises(
3298 AssertionError, device.getVendorOrProduct, 'nonsense')3525 AssertionError, device.getVendorOrProduct, 'nonsense')
32993526
3300 device = UdevDevice(None, self.pci_device_data)3527 device = UdevDevice(None, self.pci_sata_controller)
3301 self.assertEqual('Unknown', device.getVendorOrProduct('vendor'))3528 self.assertEqual('Unknown', device.getVendorOrProduct('vendor'))
3302 self.assertEqual('Unknown', device.getVendorOrProduct('product'))3529 self.assertEqual('Unknown', device.getVendorOrProduct('product'))
33033530
@@ -3338,7 +3565,7 @@
3338 self.assertRaises(3565 self.assertRaises(
3339 AssertionError, device.getVendorOrProductID, 'nonsense')3566 AssertionError, device.getVendorOrProductID, 'nonsense')
33403567
3341 device = UdevDevice(None, self.pci_device_data)3568 device = UdevDevice(None, self.pci_sata_controller)
3342 self.assertEqual(0x8086, device.getVendorOrProductID('vendor'))3569 self.assertEqual(0x8086, device.getVendorOrProductID('vendor'))
3343 self.assertEqual(0x27C5, device.getVendorOrProductID('product'))3570 self.assertEqual(0x27C5, device.getVendorOrProductID('product'))
33443571
@@ -3375,7 +3602,7 @@
3375 None, self.root_device, None, self.root_device_dmi_data)3602 None, self.root_device, None, self.root_device_dmi_data)
3376 self.assertEqual('FUJITSU SIEMENS', device.vendor_id_for_db)3603 self.assertEqual('FUJITSU SIEMENS', device.vendor_id_for_db)
33773604
3378 device = UdevDevice(None, self.pci_device_data)3605 device = UdevDevice(None, self.pci_sata_controller)
3379 self.assertEqual('0x8086', device.vendor_id_for_db)3606 self.assertEqual('0x8086', device.vendor_id_for_db)
33803607
3381 device = UdevDevice(None, self.usb_device_data)3608 device = UdevDevice(None, self.usb_device_data)
@@ -3392,7 +3619,7 @@
3392 None, self.root_device, None, self.root_device_dmi_data)3619 None, self.root_device, None, self.root_device_dmi_data)
3393 self.assertEqual('LIFEBOOK E8210', device.product_id_for_db)3620 self.assertEqual('LIFEBOOK E8210', device.product_id_for_db)
33943621
3395 device = UdevDevice(None, self.pci_device_data)3622 device = UdevDevice(None, self.pci_sata_controller)
3396 self.assertEqual('0x27c5', device.product_id_for_db)3623 self.assertEqual('0x27c5', device.product_id_for_db)
33973624
3398 device = UdevDevice(None, self.usb_device_data)3625 device = UdevDevice(None, self.usb_device_data)
@@ -3405,7 +3632,7 @@
34053632
3406 def test_driver_name(self):3633 def test_driver_name(self):
3407 """Test of UdevDevice.driver_name."""3634 """Test of UdevDevice.driver_name."""
3408 device = UdevDevice(None, self.pci_device_data)3635 device = UdevDevice(None, self.pci_sata_controller)
3409 self.assertEqual('ahci', device.driver_name)3636 self.assertEqual('ahci', device.driver_name)
34103637
3411 device = UdevDevice(3638 device = UdevDevice(
@@ -3423,22 +3650,42 @@
3423 :param parser: A SubmissionParser instance to be passed to3650 :param parser: A SubmissionParser instance to be passed to
3424 the constructor of UdevDevice.3651 the constructor of UdevDevice.
3425 """3652 """
3426 parent = None3653 devices = {}
3427 devices = []
3428 for kwargs in device_data:3654 for kwargs in device_data:
3429 device = UdevDevice(parser, **kwargs)3655 device = UdevDevice(parser, **kwargs)
3430 devices.append(device)3656 devices[device.device_id] = device
3431 if parent is not None:
3432 parent.addChild(device)
3433 parent = device3657 parent = device
3658
3659 # Build the parent-child relations so that the parent device
3660 # is that device which has the longest path matching the
3661 # start of the child's path.
3662 #
3663 # There is one exception of this rule: The root device has
3664 # the path "/devices/LNXSYSTM:00", but the paths of most of
3665 # our test deviies start with "/devices/pci". Well patch the
3666 # index temporarily in order to find children of the root
3667 # device.
3668 if '/devices/LNXSYSTM:00' in devices:
3669 devices['/devices'] = devices['/devices/LNXSYSTM:00']
3670 del devices['/devices/LNXSYSTM:00']
3671
3672 device_paths = sorted(devices, key=len, reverse=True)
3673 for path_index, path in enumerate(device_paths):
3674 for parent_path in device_paths[path_index+1:]:
3675 if path.startswith(parent_path):
3676 devices[parent_path].addChild(devices[path])
3677 break
3678 if '/devices' in devices:
3679 devices['/devices/LNXSYSTM:00'] = devices['/devices']
3680 del devices['/devices']
3434 return devices3681 return devices
34353682
3436 def test_scsi_controller(self):3683 def test_scsi_controller(self):
3437 """Test of UdevDevice.scsi_controller for a PCI controller."""3684 """Test of UdevDevice.scsi_controller for a PCI controller."""
3438 devices = self.buildUdevDeviceHierarchy(3685 devices = self.buildUdevDeviceHierarchy(
3439 self.scsi_device_hierarchy_data)3686 self.scsi_device_hierarchy_data)
3440 controller = devices[0]3687 controller = devices[self.pccard_scsi_controller_path]
3441 scsi_device = devices[-1]3688 scsi_device = devices[self.scsi_scanner_device_path]
3442 self.assertEqual(controller, scsi_device.scsi_controller)3689 self.assertEqual(controller, scsi_device.scsi_controller)
34433690
3444 def test_scsi_controller_insufficient_anchestors(self):3691 def test_scsi_controller_insufficient_anchestors(self):
@@ -3451,7 +3698,7 @@
3451 parser.submission_key = 'UdevDevice.scsi_controller ancestor missing'3698 parser.submission_key = 'UdevDevice.scsi_controller ancestor missing'
3452 devices = self.buildUdevDeviceHierarchy(3699 devices = self.buildUdevDeviceHierarchy(
3453 self.scsi_device_hierarchy_data[1:], parser)3700 self.scsi_device_hierarchy_data[1:], parser)
3454 scsi_device = devices[-1]3701 scsi_device = devices[self.scsi_scanner_device_path]
3455 self.assertEqual(None, scsi_device.scsi_controller)3702 self.assertEqual(None, scsi_device.scsi_controller)
3456 self.assertWarningMessage(3703 self.assertWarningMessage(
3457 parser.submission_key,3704 parser.submission_key,
@@ -3464,14 +3711,14 @@
34643711
3465 For non-SCSI devices, this property is None.3712 For non-SCSI devices, this property is None.
3466 """3713 """
3467 device = UdevDevice(None, self.pci_device_data)3714 device = UdevDevice(None, self.pci_sata_controller)
3468 self.assertEqual(None, device.scsi_controller)3715 self.assertEqual(None, device.scsi_controller)
34693716
3470 def test_translateScsiBus_real_scsi_device(self):3717 def test_translateScsiBus_real_scsi_device(self):
3471 """Test of UdevDevice.translateScsiBus() with a real SCSI device."""3718 """Test of UdevDevice.translateScsiBus() with a real SCSI device."""
3472 devices = self.buildUdevDeviceHierarchy(3719 devices = self.buildUdevDeviceHierarchy(
3473 self.scsi_device_hierarchy_data)3720 self.scsi_device_hierarchy_data)
3474 scsi_device = devices[-1]3721 scsi_device = devices[self.scsi_scanner_device_path]
3475 self.assertEqual(3722 self.assertEqual(
3476 HWBus.SCSI, scsi_device.translateScsiBus())3723 HWBus.SCSI, scsi_device.translateScsiBus())
34773724
@@ -3479,14 +3726,14 @@
3479 """Test of UdevDevice.translateScsiBus() with an IDE device."""3726 """Test of UdevDevice.translateScsiBus() with an IDE device."""
3480 devices = self.buildUdevDeviceHierarchy(3727 devices = self.buildUdevDeviceHierarchy(
3481 self.ide_device_hierarchy_data)3728 self.ide_device_hierarchy_data)
3482 ide_device = devices[-1]3729 ide_device = devices[self.ide_cdrom_device_path]
3483 self.assertEqual(HWBus.IDE, ide_device.translateScsiBus())3730 self.assertEqual(HWBus.IDE, ide_device.translateScsiBus())
34843731
3485 def test_translateScsiBus_usb_device(self):3732 def test_translateScsiBus_usb_device(self):
3486 """Test of UdevDevice.translateScsiBus() with a USB device."""3733 """Test of UdevDevice.translateScsiBus() with a USB device."""
3487 devices = self.buildUdevDeviceHierarchy(3734 devices = self.buildUdevDeviceHierarchy(
3488 self.usb_storage_hierarchy_data)3735 self.usb_storage_hierarchy_data)
3489 usb_scsi_device = devices[-1]3736 usb_scsi_device = devices[self.usb_storage_scsi_device_path]
3490 self.assertEqual(None, usb_scsi_device.translateScsiBus())3737 self.assertEqual(None, usb_scsi_device.translateScsiBus())
34913738
3492 def test_translateScsiBus_non_scsi_device(self):3739 def test_translateScsiBus_non_scsi_device(self):
@@ -3498,8 +3745,8 @@
3498 """Test of UdevDevice.translatePciBus()."""3745 """Test of UdevDevice.translatePciBus()."""
3499 devices = self.buildUdevDeviceHierarchy(3746 devices = self.buildUdevDeviceHierarchy(
3500 self.pci_bridge_pccard_hierarchy_data)3747 self.pci_bridge_pccard_hierarchy_data)
3501 pci_device = devices[1]3748 pci_device = devices[self.pci_pccard_bridge_path]
3502 pccard_device = devices[2]3749 pccard_device = devices[self.pccard_scsi_controller_path]
3503 self.assertEqual(HWBus.PCI, pci_device.translatePciBus())3750 self.assertEqual(HWBus.PCI, pci_device.translatePciBus())
3504 self.assertEqual(HWBus.PCCARD, pccard_device.translatePciBus())3751 self.assertEqual(HWBus.PCCARD, pccard_device.translatePciBus())
35053752
@@ -3525,8 +3772,8 @@
3525 """Test of UdevDevice.real_bus for PCI devices."""3772 """Test of UdevDevice.real_bus for PCI devices."""
3526 devices = self.buildUdevDeviceHierarchy(3773 devices = self.buildUdevDeviceHierarchy(
3527 self.pci_bridge_pccard_hierarchy_data)3774 self.pci_bridge_pccard_hierarchy_data)
3528 pci_device = devices[1]3775 pci_device = devices[self.pci_pccard_bridge_path]
3529 pccard_device = devices[2]3776 pccard_device = devices[self.pccard_scsi_controller_path]
3530 self.assertEqual(HWBus.PCI, pci_device.real_bus)3777 self.assertEqual(HWBus.PCI, pci_device.real_bus)
3531 self.assertEqual(HWBus.PCCARD, pccard_device.real_bus)3778 self.assertEqual(HWBus.PCCARD, pccard_device.real_bus)
35323779
@@ -3534,7 +3781,7 @@
3534 """Test of UdevDevice.real_bus for a SCSI device."""3781 """Test of UdevDevice.real_bus for a SCSI device."""
3535 devices = self.buildUdevDeviceHierarchy(3782 devices = self.buildUdevDeviceHierarchy(
3536 self.scsi_device_hierarchy_data)3783 self.scsi_device_hierarchy_data)
3537 scsi_device = devices[-1]3784 scsi_device = devices[self.scsi_scanner_device_path]
3538 self.assertEqual(HWBus.SCSI, scsi_device.real_bus)3785 self.assertEqual(HWBus.SCSI, scsi_device.real_bus)
35393786
3540 def test_real_bus_system(self):3787 def test_real_bus_system(self):
@@ -3542,6 +3789,98 @@
3542 root_device = UdevDevice(None, self.root_device)3789 root_device = UdevDevice(None, self.root_device)
3543 self.assertEqual(HWBus.SYSTEM, root_device.real_bus)3790 self.assertEqual(HWBus.SYSTEM, root_device.real_bus)
35443791
3792 def test_is_real_device_root_device(self):
3793 """Test of UdevDevice._is_real_device for the root device."""
3794 root_device = UdevDevice(None, self.root_device)
3795 self.assertTrue(root_device.is_real_device)
3796
3797 def test_is_real_device_pci_device(self):
3798 """Test of UdevDevice._is_real_device for a PCI device."""
3799 pci_device = UdevDevice(None, self.pci_sata_controller)
3800 self.assertTrue(pci_device.is_real_device)
3801
3802 def test_is_real_device_scsi_device_related_nodes(self):
3803 """Test of UdevDevice._is_real_device for SCSI related nodes.
3804
3805 A SCSI device and its controller are represented by several
3806 nodes which describe different aspects. Only the controller
3807 itself and the node representing the SCSI device are
3808 considered to be real devices.
3809 """
3810 devices = self.buildUdevDeviceHierarchy(
3811 self.scsi_device_hierarchy_data)
3812 real_devices = (
3813 self.pccard_scsi_controller_path, self.scsi_scanner_device_path
3814 )
3815 for device in devices.values():
3816 self.assertEqual(
3817 device.device_id in real_devices, device.is_real_device,
3818 'Invalid result of UdevDevice.is_real_device for %s '
3819 'Expected %s, got %s'
3820 % (device.device_id, device.device_id in real_devices,
3821 device.is_real_device))
3822
3823 def test_is_real_device_ide_device_related_nodes(self):
3824 """Test of UdevDevice._is_real_device for IDE related nodes.
3825
3826 An IDE device and its controller are represented by several
3827 nodes which describe different aspects. Only the controller
3828 itself and the node representing the IDE device are
3829 considered to be real devices.
3830 """
3831 devices = self.buildUdevDeviceHierarchy(
3832 self.ide_device_hierarchy_data)
3833 real_devices = (
3834 self.pci_ide_controller_path, self.ide_cdrom_device_path,
3835 )
3836 for device in devices.values():
3837 self.assertEqual(
3838 device.device_id in real_devices, device.is_real_device,
3839 'Invalid result of UdevDevice.is_real_device for %s '
3840 'Expected %s, got %s'
3841 % (device.device_id, device.device_id in real_devices,
3842 device.is_real_device))
3843
3844 def test_is_real_device_ata_device_related_nodes(self):
3845 """Test of UdevDevice._is_real_device for IDE related nodes.
3846
3847 An IDE device and its controller are represented by several
3848 nodes which describe different aspects. Only the controller
3849 itself and the node representing the IDE device are
3850 considered to be real devices.
3851 """
3852 devices = self.buildUdevDeviceHierarchy(
3853 self.sata_device_hierarchy_data)
3854 real_devices = (
3855 self.pci_sata_controller_path, self.sata_disk_device_path,
3856 )
3857 for device in devices.values():
3858 self.assertEqual(
3859 device.device_id in real_devices, device.is_real_device,
3860 'Invalid result of UdevDevice.is_real_device for %s '
3861 'Expected %s, got %s'
3862 % (device.device_id, device.device_id in real_devices,
3863 device.is_real_device))
3864
3865 def test_is_real_device_usb_storage_device_related_nodes(self):
3866 """Test of UdevDevice._is_real_device for USB storage related nodes.
3867
3868 A USB storage device is represented by several nodes which
3869 describe different aspects. Only the main USB device is
3870 considered to be real devices.
3871 """
3872 devices = self.buildUdevDeviceHierarchy(
3873 self.usb_storage_hierarchy_data)
3874 for device in devices.values():
3875 self.assertEqual(
3876 device.device_id == self.usb_storage_usb_device_path,
3877 device.is_real_device,
3878 'Invalid result of UdevDevice.is_real_device for %s '
3879 'Expected %s, got %s'
3880 % (device.device_id,
3881 device.device_id == self.usb_storage_usb_device_path,
3882 device.is_real_device))
3883
35453884
3546class TestHWDBSubmissionTablePopulation(TestCaseHWDB):3885class TestHWDBSubmissionTablePopulation(TestCaseHWDB):
3547 """Tests of the HWDB popoluation with submitted data."""3886 """Tests of the HWDB popoluation with submitted data."""