Merge lp:~adeuring/launchpad/hwdb-class-udev-device-8 into lp:launchpad
- hwdb-class-udev-device-8
- Merge into devel
Proposed by
Abel Deuring
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~adeuring/launchpad/hwdb-class-udev-device-8 |
Merge into: | lp:launchpad |
Diff against target: |
197 lines 2 files modified
lib/canonical/launchpad/scripts/hwdbsubmissions.py (+1/-1) lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py (+53/-24) |
To merge this branch: | bzr merge lp:~adeuring/launchpad/hwdb-class-udev-device-8 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Eleanor Berger (community) | code | Approve | |
Review via email: mp+13554@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote : | # |
Revision history for this message
Eleanor Berger (intellectronica) wrote : | # |
The change looks fine, r=me.
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/canonical/launchpad/scripts/hwdbsubmissions.py' | |||
2 | --- lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-15 13:59:33 +0000 | |||
3 | +++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-19 09:10:30 +0000 | |||
4 | @@ -2665,7 +2665,7 @@ | |||
5 | 2665 | # While SCSI devices from valid submissions should have four | 2665 | # While SCSI devices from valid submissions should have four |
6 | 2666 | # ancestors, we can't be sure for bogus or broken submissions. | 2666 | # ancestors, we can't be sure for bogus or broken submissions. |
7 | 2667 | try: | 2667 | try: |
9 | 2668 | controller = self.parent.parent.parent.parent | 2668 | controller = self.parent.parent.parent |
10 | 2669 | except AttributeError: | 2669 | except AttributeError: |
11 | 2670 | controller = None | 2670 | controller = None |
12 | 2671 | if controller is None: | 2671 | if controller is None: |
13 | 2672 | 2672 | ||
14 | === modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py' | |||
15 | --- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-15 15:28:38 +0000 | |||
16 | +++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-19 09:10:30 +0000 | |||
17 | @@ -2882,8 +2882,10 @@ | |||
18 | 2882 | }, | 2882 | }, |
19 | 2883 | } | 2883 | } |
20 | 2884 | 2884 | ||
21 | 2885 | self.pci_pccard_bridge_path = ( | ||
22 | 2886 | '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0') | ||
23 | 2885 | self.pci_pccard_bridge = { | 2887 | self.pci_pccard_bridge = { |
25 | 2886 | 'P': '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0', | 2888 | 'P': self.pci_pccard_bridge_path, |
26 | 2887 | 'E': { | 2889 | 'E': { |
27 | 2888 | 'DRIVER': 'yenta_cardbus', | 2890 | 'DRIVER': 'yenta_cardbus', |
28 | 2889 | 'PCI_CLASS': '60700', | 2891 | 'PCI_CLASS': '60700', |
29 | @@ -2894,8 +2896,10 @@ | |||
30 | 2894 | } | 2896 | } |
31 | 2895 | } | 2897 | } |
32 | 2896 | 2898 | ||
33 | 2899 | self.pccard_scsi_controller_path = ( | ||
34 | 2900 | '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0') | ||
35 | 2897 | self.pccard_scsi_controller_data = { | 2901 | self.pccard_scsi_controller_data = { |
37 | 2898 | 'P': '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0', | 2902 | 'P': self.pccard_scsi_controller_path, |
38 | 2899 | 'E': { | 2903 | 'E': { |
39 | 2900 | 'DRIVER': 'aic7xxx', | 2904 | 'DRIVER': 'aic7xxx', |
40 | 2901 | 'PCI_CLASS': '10000', | 2905 | 'PCI_CLASS': '10000', |
41 | @@ -2937,9 +2941,11 @@ | |||
42 | 2937 | }, | 2941 | }, |
43 | 2938 | } | 2942 | } |
44 | 2939 | 2943 | ||
45 | 2944 | self.scsi_scanner_device_path = ( | ||
46 | 2945 | '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0/' | ||
47 | 2946 | 'host6/target6:0:1/6:0:1:0') | ||
48 | 2940 | self.scsi_scanner_device_data = { | 2947 | self.scsi_scanner_device_data = { |
51 | 2941 | 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/' | 2948 | 'P': self.scsi_scanner_device_path, |
50 | 2942 | '0000:09:00.0/host6/target6:0:1/6:0:1:0'), | ||
52 | 2943 | 'E': { | 2949 | 'E': { |
53 | 2944 | 'DEVTYPE': 'scsi_device', | 2950 | 'DEVTYPE': 'scsi_device', |
54 | 2945 | 'SUBSYSTEM': 'scsi', | 2951 | 'SUBSYSTEM': 'scsi', |
55 | @@ -2997,9 +3003,10 @@ | |||
56 | 2997 | }, | 3003 | }, |
57 | 2998 | } | 3004 | } |
58 | 2999 | 3005 | ||
59 | 3006 | self.ide_cdrom_device_path = ( | ||
60 | 3007 | '/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0') | ||
61 | 3000 | self.ide_cdrom_device_data = { | 3008 | self.ide_cdrom_device_data = { |
64 | 3001 | 'P': ('/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/' | 3009 | 'P': self.ide_cdrom_device_path, |
63 | 3002 | '4:0:0:0'), | ||
65 | 3003 | 'E': { | 3010 | 'E': { |
66 | 3004 | 'SUBSYSTEM': 'scsi', | 3011 | 'SUBSYSTEM': 'scsi', |
67 | 3005 | 'DEVTYPE': 'scsi_device', | 3012 | 'DEVTYPE': 'scsi_device', |
68 | @@ -3061,9 +3068,11 @@ | |||
69 | 3061 | }, | 3068 | }, |
70 | 3062 | } | 3069 | } |
71 | 3063 | 3070 | ||
72 | 3071 | self.usb_storage_scsi_device_path = ( | ||
73 | 3072 | '/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' | ||
74 | 3073 | 'target7:0:0/7:0:0:0') | ||
75 | 3064 | self.usb_storage_scsi_device = { | 3074 | self.usb_storage_scsi_device = { |
78 | 3065 | 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' | 3075 | 'P': self.usb_storage_scsi_device_path, |
77 | 3066 | 'target7:0:0/7:0:0:0'), | ||
79 | 3067 | 'E': { | 3076 | 'E': { |
80 | 3068 | 'DEVTYPE': 'scsi_device', | 3077 | 'DEVTYPE': 'scsi_device', |
81 | 3069 | 'DRIVER': 'sd', | 3078 | 'DRIVER': 'sd', |
82 | @@ -3423,22 +3432,42 @@ | |||
83 | 3423 | :param parser: A SubmissionParser instance to be passed to | 3432 | :param parser: A SubmissionParser instance to be passed to |
84 | 3424 | the constructor of UdevDevice. | 3433 | the constructor of UdevDevice. |
85 | 3425 | """ | 3434 | """ |
88 | 3426 | parent = None | 3435 | devices = {} |
87 | 3427 | devices = [] | ||
89 | 3428 | for kwargs in device_data: | 3436 | for kwargs in device_data: |
90 | 3429 | device = UdevDevice(parser, **kwargs) | 3437 | device = UdevDevice(parser, **kwargs) |
94 | 3430 | devices.append(device) | 3438 | devices[device.device_id] = device |
92 | 3431 | if parent is not None: | ||
93 | 3432 | parent.addChild(device) | ||
95 | 3433 | parent = device | 3439 | parent = device |
96 | 3440 | |||
97 | 3441 | # Build the parent-child relations so that the parent device | ||
98 | 3442 | # is that device which has the longest path matching the | ||
99 | 3443 | # start of the child's path. | ||
100 | 3444 | # | ||
101 | 3445 | # There is one exception of this rule: The root device has | ||
102 | 3446 | # the path "/devices/LNXSYSTM:00", but the paths of most of | ||
103 | 3447 | # our test deviies start with "/devices/pci". Well patch the | ||
104 | 3448 | # index temporarily in order to find children of the root | ||
105 | 3449 | # device. | ||
106 | 3450 | if '/devices/LNXSYSTM:00' in devices: | ||
107 | 3451 | devices['/devices'] = devices['/devices/LNXSYSTM:00'] | ||
108 | 3452 | del devices['/devices/LNXSYSTM:00'] | ||
109 | 3453 | |||
110 | 3454 | device_paths = sorted(devices, key=len, reverse=True) | ||
111 | 3455 | for path_index, path in enumerate(device_paths): | ||
112 | 3456 | for parent_path in device_paths[path_index+1:]: | ||
113 | 3457 | if path.startswith(parent_path): | ||
114 | 3458 | devices[parent_path].addChild(devices[path]) | ||
115 | 3459 | break | ||
116 | 3460 | if '/devices' in devices: | ||
117 | 3461 | devices['/devices/LNXSYSTM:00'] = devices['/devices'] | ||
118 | 3462 | del devices['/devices'] | ||
119 | 3434 | return devices | 3463 | return devices |
120 | 3435 | 3464 | ||
121 | 3436 | def test_scsi_controller(self): | 3465 | def test_scsi_controller(self): |
122 | 3437 | """Test of UdevDevice.scsi_controller for a PCI controller.""" | 3466 | """Test of UdevDevice.scsi_controller for a PCI controller.""" |
123 | 3438 | devices = self.buildUdevDeviceHierarchy( | 3467 | devices = self.buildUdevDeviceHierarchy( |
124 | 3439 | self.scsi_device_hierarchy_data) | 3468 | self.scsi_device_hierarchy_data) |
127 | 3440 | controller = devices[0] | 3469 | controller = devices[self.pccard_scsi_controller_path] |
128 | 3441 | scsi_device = devices[-1] | 3470 | scsi_device = devices[self.scsi_scanner_device_path] |
129 | 3442 | self.assertEqual(controller, scsi_device.scsi_controller) | 3471 | self.assertEqual(controller, scsi_device.scsi_controller) |
130 | 3443 | 3472 | ||
131 | 3444 | def test_scsi_controller_insufficient_anchestors(self): | 3473 | def test_scsi_controller_insufficient_anchestors(self): |
132 | @@ -3451,7 +3480,7 @@ | |||
133 | 3451 | parser.submission_key = 'UdevDevice.scsi_controller ancestor missing' | 3480 | parser.submission_key = 'UdevDevice.scsi_controller ancestor missing' |
134 | 3452 | devices = self.buildUdevDeviceHierarchy( | 3481 | devices = self.buildUdevDeviceHierarchy( |
135 | 3453 | self.scsi_device_hierarchy_data[1:], parser) | 3482 | self.scsi_device_hierarchy_data[1:], parser) |
137 | 3454 | scsi_device = devices[-1] | 3483 | scsi_device = devices[self.scsi_scanner_device_path] |
138 | 3455 | self.assertEqual(None, scsi_device.scsi_controller) | 3484 | self.assertEqual(None, scsi_device.scsi_controller) |
139 | 3456 | self.assertWarningMessage( | 3485 | self.assertWarningMessage( |
140 | 3457 | parser.submission_key, | 3486 | parser.submission_key, |
141 | @@ -3471,7 +3500,7 @@ | |||
142 | 3471 | """Test of UdevDevice.translateScsiBus() with a real SCSI device.""" | 3500 | """Test of UdevDevice.translateScsiBus() with a real SCSI device.""" |
143 | 3472 | devices = self.buildUdevDeviceHierarchy( | 3501 | devices = self.buildUdevDeviceHierarchy( |
144 | 3473 | self.scsi_device_hierarchy_data) | 3502 | self.scsi_device_hierarchy_data) |
146 | 3474 | scsi_device = devices[-1] | 3503 | scsi_device = devices[self.scsi_scanner_device_path] |
147 | 3475 | self.assertEqual( | 3504 | self.assertEqual( |
148 | 3476 | HWBus.SCSI, scsi_device.translateScsiBus()) | 3505 | HWBus.SCSI, scsi_device.translateScsiBus()) |
149 | 3477 | 3506 | ||
150 | @@ -3479,14 +3508,14 @@ | |||
151 | 3479 | """Test of UdevDevice.translateScsiBus() with an IDE device.""" | 3508 | """Test of UdevDevice.translateScsiBus() with an IDE device.""" |
152 | 3480 | devices = self.buildUdevDeviceHierarchy( | 3509 | devices = self.buildUdevDeviceHierarchy( |
153 | 3481 | self.ide_device_hierarchy_data) | 3510 | self.ide_device_hierarchy_data) |
155 | 3482 | ide_device = devices[-1] | 3511 | ide_device = devices[self.ide_cdrom_device_path] |
156 | 3483 | self.assertEqual(HWBus.IDE, ide_device.translateScsiBus()) | 3512 | self.assertEqual(HWBus.IDE, ide_device.translateScsiBus()) |
157 | 3484 | 3513 | ||
158 | 3485 | def test_translateScsiBus_usb_device(self): | 3514 | def test_translateScsiBus_usb_device(self): |
159 | 3486 | """Test of UdevDevice.translateScsiBus() with a USB device.""" | 3515 | """Test of UdevDevice.translateScsiBus() with a USB device.""" |
160 | 3487 | devices = self.buildUdevDeviceHierarchy( | 3516 | devices = self.buildUdevDeviceHierarchy( |
161 | 3488 | self.usb_storage_hierarchy_data) | 3517 | self.usb_storage_hierarchy_data) |
163 | 3489 | usb_scsi_device = devices[-1] | 3518 | usb_scsi_device = devices[self.usb_storage_scsi_device_path] |
164 | 3490 | self.assertEqual(None, usb_scsi_device.translateScsiBus()) | 3519 | self.assertEqual(None, usb_scsi_device.translateScsiBus()) |
165 | 3491 | 3520 | ||
166 | 3492 | def test_translateScsiBus_non_scsi_device(self): | 3521 | def test_translateScsiBus_non_scsi_device(self): |
167 | @@ -3498,8 +3527,8 @@ | |||
168 | 3498 | """Test of UdevDevice.translatePciBus().""" | 3527 | """Test of UdevDevice.translatePciBus().""" |
169 | 3499 | devices = self.buildUdevDeviceHierarchy( | 3528 | devices = self.buildUdevDeviceHierarchy( |
170 | 3500 | self.pci_bridge_pccard_hierarchy_data) | 3529 | self.pci_bridge_pccard_hierarchy_data) |
173 | 3501 | pci_device = devices[1] | 3530 | pci_device = devices[self.pci_pccard_bridge_path] |
174 | 3502 | pccard_device = devices[2] | 3531 | pccard_device = devices[self.pccard_scsi_controller_path] |
175 | 3503 | self.assertEqual(HWBus.PCI, pci_device.translatePciBus()) | 3532 | self.assertEqual(HWBus.PCI, pci_device.translatePciBus()) |
176 | 3504 | self.assertEqual(HWBus.PCCARD, pccard_device.translatePciBus()) | 3533 | self.assertEqual(HWBus.PCCARD, pccard_device.translatePciBus()) |
177 | 3505 | 3534 | ||
178 | @@ -3525,8 +3554,8 @@ | |||
179 | 3525 | """Test of UdevDevice.real_bus for PCI devices.""" | 3554 | """Test of UdevDevice.real_bus for PCI devices.""" |
180 | 3526 | devices = self.buildUdevDeviceHierarchy( | 3555 | devices = self.buildUdevDeviceHierarchy( |
181 | 3527 | self.pci_bridge_pccard_hierarchy_data) | 3556 | self.pci_bridge_pccard_hierarchy_data) |
184 | 3528 | pci_device = devices[1] | 3557 | pci_device = devices[self.pci_pccard_bridge_path] |
185 | 3529 | pccard_device = devices[2] | 3558 | pccard_device = devices[self.pccard_scsi_controller_path] |
186 | 3530 | self.assertEqual(HWBus.PCI, pci_device.real_bus) | 3559 | self.assertEqual(HWBus.PCI, pci_device.real_bus) |
187 | 3531 | self.assertEqual(HWBus.PCCARD, pccard_device.real_bus) | 3560 | self.assertEqual(HWBus.PCCARD, pccard_device.real_bus) |
188 | 3532 | 3561 | ||
189 | @@ -3534,7 +3563,7 @@ | |||
190 | 3534 | """Test of UdevDevice.real_bus for a SCSI device.""" | 3563 | """Test of UdevDevice.real_bus for a SCSI device.""" |
191 | 3535 | devices = self.buildUdevDeviceHierarchy( | 3564 | devices = self.buildUdevDeviceHierarchy( |
192 | 3536 | self.scsi_device_hierarchy_data) | 3565 | self.scsi_device_hierarchy_data) |
194 | 3537 | scsi_device = devices[-1] | 3566 | scsi_device = devices[self.scsi_scanner_device_path] |
195 | 3538 | self.assertEqual(HWBus.SCSI, scsi_device.real_bus) | 3567 | self.assertEqual(HWBus.SCSI, scsi_device.real_bus) |
196 | 3539 | 3568 | ||
197 | 3540 | def test_real_bus_system(self): | 3569 | def test_real_bus_system(self): |
This branch fixes a stupid mistake I made in the property UdevDevice. scsi_controller . This property is supposed to return the node of the controller of a SCSI device.
(Background: We get data about hardware mostly from udev; a udev device is represented in the HWDB submission processing script by class UdevDevice. udev devices have parent-child relationships, where device A is an ancestor of device B, if the pathname of device B extends the pathname of device A.)
This mistake happened for two reasons:
1. I copy&pasted the sample data used in tests from "udevadm info --export-db" to the test data as defined in l/c/l/scripts/ tests/test_ hwdb_submission _processing. py, without looking at the data suffciently carefully. So, when reading and copying a relevant part of this data, like:
P: /devices/ pci0000: 00/0000: 00:1f.1/ host4
E: DEVTYPE=scsi_host
E: SUBSYSTEM=scsi
P: /devices/ pci0000: 00/0000: 00:1f.1/ host4/scsi_ host/host4
E: SUBSYSTEM=scsi_host
P: /devices/ pci0000: 00/0000: 00:1f.1/ host4/target4: 0:0
E: DEVTYPE=scsi_target
E: SUBSYSTEM=scsi
P: /devices/ pci0000: 00/0000: 00:1f.1/ host4/target4: 0:0/4:0: 0:0 scsi:t- 0x05
E: DEVTYPE=scsi_device
E: DRIVER=sr
E: MODALIAS=
E: SUBSYSTEM=scsi
I managed to ignore the fact that the path names /devices/ pci0000: 00/0000: 00:1f.1/ host4/scsi_ host/host4 and /devices/ pci0000: 00/0000: 00:1f.1/ host4/target4: 0:0 say that these nodes are siblings, but simply assumed that the former is the parent of the latter.
2. The method UdevDevice.setUo() defines lots of test data. A single udev device is represented by a dictionary like self.pci_ device_ data; a set of devices needed for some tests was represented by a sequence like self.scsi_ device_ hierarchy_ data. The method UdevDevice. buildUdevDevice Hierarchy( ) takes such a list and simply assumed that device N of the sequence is the parent of device N+1.
This way, my wrong assumption about the parent-child relation in the example above is simply mapped into the test data.
So I changed UdevDevice. buildUdevDevice Hierarchy( ) to build the parent-child relations by looking at the path names of the devices (property device_id). Since the test data is copy&pasted from real-world data, we can be quite sure that the relations defined by this method are now correct.
The method now also returns a dictionary instead of a sequence, allowing to identify "interesting" devices by their path names, instead of a somewhat obscure index.
test: ./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: /launchpad/ scripts/ hwdbsubmissions .py /launchpad/ scripts/ tests/test_ hwdb_submission _processing. py
lib/canonical
lib/canonical
== Pyflakes notices ==
lib/canonical/ launchpad/ scripts/ hwdbsubmissions .py
22: redefinition of unused 'etree' from line 20
== Pylint notices ==
lib/canonical/ launchpad/ scripts/ hwdbsubmissions .py cElementTree' (No module named etree)
20: [F0401] Unable to import 'xml.etree.
The complaint about etree is not related to my changes.