Merge lp:~adeuring/launchpad/hwdb-class-udev-device-7 into lp:launchpad
- hwdb-class-udev-device-7
- Merge into devel
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~adeuring/launchpad/hwdb-class-udev-device-7 |
Merge into: | lp:launchpad |
Diff against target: |
1070 lines 2 files modified
lib/canonical/launchpad/scripts/hwdbsubmissions.py (+83/-26) lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py (+702/-70) |
To merge this branch: | bzr merge lp:~adeuring/launchpad/hwdb-class-udev-device-7 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Nelson (community) | code | Approve | |
Review via email: mp+13413@code.launchpad.net |
Commit message
Description of the change
Abel Deuring (adeuring) wrote : | # |
Michael Nelson (michael.nelson) wrote : | # |
Great! The addition of the is_root_device property makes the code much
more readable.
As usual, just one or two comments below, in particular, one change for which I couldn't see the cause...
Thanks!
> === modified file 'lib/canonical/
> --- lib/canonical/
> +++ lib/canonical/
> @@ -1644,7 +1644,7 @@
> return None
> pci_subclass = scsi_controller
> return self.pci_
> - elif scsi_controller_bus == 'usb':
> + elif scsi_controller_bus in ('usb', 'usb_interface'):
> # USB storage devices have the following HAL device hierarchy:
> # - HAL node for the USB device. info.bus == 'usb_device',
> # device class == 0, device subclass == 0
> @@ -1703,6 +1703,12 @@
> return HWBus.PCI
>
> @property
> + def is_root_
> + """Return True is this is the root node of all devicese, else False.
> + """
> + raise NotImplementedError
> +
> + @property
> def raw_bus(self):
> """Return the device bus as specified by HAL or udev."""
> raise NotImplementedError
> @@ -1719,11 +1725,11 @@
> if result is not None:
> return result
>
> - if device_bus == 'scsi':
> + if device_bus in ('scsi', 'scsi_device'):
> return self.translateS
> elif device_bus == 'pci':
> return self.translateP
> - elif self.udi == ROOT_UDI:
> + elif self.is_
> # The computer itself. In Hardy, HAL provides no info.bus
> # for the machine itself; older versions set info.bus to
> # 'unknown', hence it is better to use the machine's
> @@ -1731,7 +1737,7 @@
> return HWBus.SYSTEM
> else:
> self.parser.
> - 'Unknown bus %r for device %s' % (device_bus, self.udi))
> + 'Unknown bus %r for device %s' % (device_bus, self.device_id))
> return None
>
> @property
> @@ -2275,6 +2281,11 @@
> return result
> return self.getPropert
>
> + @property
> + def is_root_
> + """See `BaseDevice`."""
> + return self.udi == ROOT_UDI
> +
> def getVendorOrProd
> """Return the vendor or product of this device.
>
> @@ -2547,7 +2558,7 @@
> # DEVTYPE. DEVTYPE is preferable.
> # The root device has the subsystem/bus value "acpi", which
> # is a bit nonsensical.
> - if self.device_id == UDEV_ROOT_PATH:
> + if self.is_
> return None
> properties = self.udev['E']
> devtype = properties.
> @@ -2555,6 +2566,11 @@
> return devtype
> return properties.
>
> + @property
> + def is_root_
> + """See `BaseDevice`."""
> + return self.udev[...
Abel Deuring (adeuring) wrote : | # |
Hi Michael,
thanks for your review!
> Great! The addition of the is_root_device property makes the code much
> more readable.
>
> As usual, just one or two comments below, in particular, one change for which
> I couldn't see the cause...
>
> Thanks!
>
> > === modified file 'lib/canonical/
> > --- lib/canonical/
> 13:22:14 +0000
> > +++ lib/canonical/
> 13:59:33 +0000
> > @@ -1644,7 +1644,7 @@
> > return None
> > pci_subclass = scsi_controller
> > return self.pci_
> > - elif scsi_controller_bus == 'usb':
> > + elif scsi_controller_bus in ('usb', 'usb_interface'):
> > # USB storage devices have the following HAL device hierarchy:
> > # - HAL node for the USB device. info.bus == 'usb_device',
> > # device class == 0, device subclass == 0
> > @@ -1703,6 +1703,12 @@
> > return HWBus.PCI
> >
> > @property
> > + def is_root_
> > + """Return True is this is the root node of all devicese, else
> False.
> > + """
> > + raise NotImplementedError
> > +
> > + @property
> > def raw_bus(self):
> > """Return the device bus as specified by HAL or udev."""
> > raise NotImplementedError
> > @@ -1719,11 +1725,11 @@
> > if result is not None:
> > return result
> >
> > - if device_bus == 'scsi':
> > + if device_bus in ('scsi', 'scsi_device'):
> > return self.translateS
> > elif device_bus == 'pci':
> > return self.translateP
> > - elif self.udi == ROOT_UDI:
> > + elif self.is_
> > # The computer itself. In Hardy, HAL provides no info.bus
> > # for the machine itself; older versions set info.bus to
> > # 'unknown', hence it is better to use the machine's
> > @@ -1731,7 +1737,7 @@
> > return HWBus.SYSTEM
> > else:
> > self.parser.
> > - 'Unknown bus %r for device %s' % (device_bus, self.udi))
> > + 'Unknown bus %r for device %s' % (device_bus,
> self.device_id))
> > return None
> >
> > @property
> > @@ -2275,6 +2281,11 @@
> > return result
> > return self.getPropert
> >
> > + @property
> > + def is_root_
> > + """See `BaseDevice`."""
> > + return self.udi == ROOT_UDI
> > +
> > def getVendorOrProd
> > """Return the vendor or product of this device.
> >
> > @@ -2547,7 +2558,7 @@
> > # DEVTYPE. DEVTYPE is preferable.
> > # The root device has the subsystem/bus value "acpi", which
> > # is a bit nonsensical.
> > - if self.device_id == UDEV_ROOT_PATH:
> > + if self.is_
> > return None
> > properties = self.udev['E']
> > devtype = properties.
> > @@ -2555,6...
Preview Diff
1 | === modified file 'lib/canonical/launchpad/scripts/hwdbsubmissions.py' |
2 | --- lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-13 21:03:31 +0000 |
3 | +++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-15 17:00:35 +0000 |
4 | @@ -87,12 +87,14 @@ |
5 | 'pci': '0x%04x', |
6 | 'usb_device': '0x%04x', |
7 | 'scsi': '%-8s', |
8 | + 'scsi_device': '%-8s', |
9 | } |
10 | |
11 | DB_FORMAT_FOR_PRODUCT_ID = { |
12 | 'pci': '0x%04x', |
13 | 'usb_device': '0x%04x', |
14 | 'scsi': '%-16s', |
15 | + 'scsi_device': '%-16s', |
16 | } |
17 | |
18 | UDEV_USB_DEVICE_PROPERTIES = set(('DEVTYPE', 'PRODUCT', 'TYPE')) |
19 | @@ -1609,6 +1611,11 @@ |
20 | """The name of the driver contolling this device. May be None.""" |
21 | raise NotImplementedError |
22 | |
23 | + @property |
24 | + def scsi_controller(self): |
25 | + """Return the SCSI host controller for this device.""" |
26 | + raise NotImplementedError |
27 | + |
28 | def translateScsiBus(self): |
29 | """Return the real bus of a device where raw_bus=='scsi'. |
30 | |
31 | @@ -1617,37 +1624,27 @@ |
32 | for more details. This method determines the real bus |
33 | of a device accessed via the kernel's SCSI subsystem. |
34 | """ |
35 | - # While SCSI devices from valid submissions should have a |
36 | - # parent and a grandparent, we can't be sure for bogus or |
37 | - # broken submissions. |
38 | - parent = self.parent |
39 | - if parent is None: |
40 | - self.parser._logWarning( |
41 | - 'Found SCSI device without a parent: %s.' % self.device_id) |
42 | - return None |
43 | - grandparent = parent.parent |
44 | - if grandparent is None: |
45 | - self.parser._logWarning( |
46 | - 'Found SCSI device without a grandparent: %s.' |
47 | - % self.device_id) |
48 | + scsi_controller = self.scsi_controller |
49 | + if scsi_controller is None: |
50 | return None |
51 | |
52 | - grandparent_bus = grandparent.raw_bus |
53 | - if grandparent_bus == 'pci': |
54 | - if (grandparent.pci_class != PCI_CLASS_STORAGE): |
55 | + scsi_controller_bus = scsi_controller.raw_bus |
56 | + if scsi_controller_bus == 'pci': |
57 | + if (scsi_controller.pci_class != PCI_CLASS_STORAGE): |
58 | # This is not a storage class PCI device? This |
59 | # indicates a bug somewhere in HAL or in the hwdb |
60 | # client, or a fake submission. |
61 | - device_class = grandparent.pci_class |
62 | + device_class = scsi_controller.pci_class |
63 | self.parser._logWarning( |
64 | 'A (possibly fake) SCSI device %s is connected to ' |
65 | 'PCI device %s that has the PCI device class %s; ' |
66 | 'expected class 1 (storage).' |
67 | - % (self.device_id, grandparent.device_id, device_class)) |
68 | + % (self.device_id, scsi_controller.device_id, |
69 | + device_class)) |
70 | return None |
71 | - pci_subclass = grandparent.pci_subclass |
72 | + pci_subclass = scsi_controller.pci_subclass |
73 | return self.pci_storage_subclass_hwbus.get(pci_subclass) |
74 | - elif grandparent_bus == 'usb': |
75 | + elif scsi_controller_bus in ('usb', 'usb_interface'): |
76 | # USB storage devices have the following HAL device hierarchy: |
77 | # - HAL node for the USB device. info.bus == 'usb_device', |
78 | # device class == 0, device subclass == 0 |
79 | @@ -1706,6 +1703,12 @@ |
80 | return HWBus.PCI |
81 | |
82 | @property |
83 | + def is_root_device(self): |
84 | + """Return True is this is the root node of all devicese, else False. |
85 | + """ |
86 | + raise NotImplementedError |
87 | + |
88 | + @property |
89 | def raw_bus(self): |
90 | """Return the device bus as specified by HAL or udev.""" |
91 | raise NotImplementedError |
92 | @@ -1722,11 +1725,11 @@ |
93 | if result is not None: |
94 | return result |
95 | |
96 | - if device_bus == 'scsi': |
97 | + if device_bus in ('scsi', 'scsi_device'): |
98 | return self.translateScsiBus() |
99 | elif device_bus == 'pci': |
100 | return self.translatePciBus() |
101 | - elif self.udi == ROOT_UDI: |
102 | + elif self.is_root_device: |
103 | # The computer itself. In Hardy, HAL provides no info.bus |
104 | # for the machine itself; older versions set info.bus to |
105 | # 'unknown', hence it is better to use the machine's |
106 | @@ -1734,7 +1737,7 @@ |
107 | return HWBus.SYSTEM |
108 | else: |
109 | self.parser._logWarning( |
110 | - 'Unknown bus %r for device %s' % (device_bus, self.udi)) |
111 | + 'Unknown bus %r for device %s' % (device_bus, self.device_id)) |
112 | return None |
113 | |
114 | @property |
115 | @@ -2278,6 +2281,11 @@ |
116 | return result |
117 | return self.getProperty('info.subsystem') |
118 | |
119 | + @property |
120 | + def is_root_device(self): |
121 | + """See `BaseDevice`.""" |
122 | + return self.udi == ROOT_UDI |
123 | + |
124 | def getVendorOrProduct(self, type_): |
125 | """Return the vendor or product of this device. |
126 | |
127 | @@ -2357,6 +2365,27 @@ |
128 | """See `BaseDevice`.""" |
129 | return self.getVendorOrProductID('product') |
130 | |
131 | + @property |
132 | + def scsi_controller(self): |
133 | + """See `BaseDevice`.""" |
134 | + # While SCSI devices from valid submissions should have a |
135 | + # parent and a grandparent, we can't be sure for bogus or |
136 | + # broken submissions. |
137 | + if self.raw_bus != 'scsi': |
138 | + return None |
139 | + parent = self.parent |
140 | + if parent is None: |
141 | + self.parser._logWarning( |
142 | + 'Found SCSI device without a parent: %s.' % self.device_id) |
143 | + return None |
144 | + grandparent = parent.parent |
145 | + if grandparent is None: |
146 | + self.parser._logWarning( |
147 | + 'Found SCSI device without a grandparent: %s.' |
148 | + % self.device_id) |
149 | + return None |
150 | + return grandparent |
151 | + |
152 | |
153 | class UdevDevice(BaseDevice): |
154 | """The representation of a udev device node.""" |
155 | @@ -2529,7 +2558,7 @@ |
156 | # DEVTYPE. DEVTYPE is preferable. |
157 | # The root device has the subsystem/bus value "acpi", which |
158 | # is a bit nonsensical. |
159 | - if self.device_id == UDEV_ROOT_PATH: |
160 | + if self.is_root_device: |
161 | return None |
162 | properties = self.udev['E'] |
163 | devtype = properties.get('DEVTYPE') |
164 | @@ -2537,6 +2566,11 @@ |
165 | return devtype |
166 | return properties.get('SUBSYSTEM') |
167 | |
168 | + @property |
169 | + def is_root_device(self): |
170 | + """See `BaseDevice`.""" |
171 | + return self.udev['P'] == UDEV_ROOT_PATH |
172 | + |
173 | def getVendorOrProduct(self, type_): |
174 | """Return the vendor or product of this device. |
175 | |
176 | @@ -2547,7 +2581,7 @@ |
177 | 'Unexpected value of type_: %r' % type_) |
178 | |
179 | bus = self.raw_bus |
180 | - if self.device_id == UDEV_ROOT_PATH: |
181 | + if self.is_root_device: |
182 | # udev does not known about any product information for |
183 | # the root device. We use DMI data instead. |
184 | return self.root_device_ids[type_] |
185 | @@ -2587,7 +2621,7 @@ |
186 | 'Unexpected value of type_: %r' % type_) |
187 | |
188 | bus = self.raw_bus |
189 | - if self.device_id == UDEV_ROOT_PATH: |
190 | + if self.is_root_device: |
191 | # udev does not known about any product information for |
192 | # the root device. We use DMI data instead. |
193 | if type_ == 'vendor': |
194 | @@ -2617,6 +2651,29 @@ |
195 | """See `BaseDevice`.""" |
196 | return self.getVendorOrProductID('product') |
197 | |
198 | + @property |
199 | + def driver_name(self): |
200 | + """See `BaseDevice`.""" |
201 | + return self.udev['E'].get('DRIVER') |
202 | + |
203 | + @property |
204 | + def scsi_controller(self): |
205 | + """See `BaseDevice`.""" |
206 | + if self.raw_bus != 'scsi_device': |
207 | + return None |
208 | + |
209 | + # While SCSI devices from valid submissions should have four |
210 | + # ancestors, we can't be sure for bogus or broken submissions. |
211 | + try: |
212 | + controller = self.parent.parent.parent.parent |
213 | + except AttributeError: |
214 | + controller = None |
215 | + if controller is None: |
216 | + self.parser._logWarning( |
217 | + 'Found a SCSI device without a sufficient number of ' |
218 | + 'ancestors: %s' % self.device_id) |
219 | + return None |
220 | + return controller |
221 | |
222 | class ProcessingLoop(object): |
223 | """An `ITunableLoop` for processing HWDB submissions.""" |
224 | |
225 | === modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py' |
226 | --- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-13 21:02:35 +0000 |
227 | +++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-15 17:00:35 +0000 |
228 | @@ -539,6 +539,214 @@ |
229 | 'HAL property info.bus.') |
230 | |
231 | |
232 | + def test_HALDevice_scsi_controller_usb_storage_device(self): |
233 | + """test of HALDevice.scsi_controller. |
234 | + |
235 | + The physical device is a USB storage device. |
236 | + """ |
237 | + devices = [ |
238 | + # The main node of the USB storage device. |
239 | + { |
240 | + 'id': 1, |
241 | + 'udi': self.UDI_USB_STORAGE, |
242 | + 'properties': { |
243 | + 'info.bus': ('usb_device', 'str'), |
244 | + }, |
245 | + }, |
246 | + # The storage interface of the USB device. |
247 | + { |
248 | + 'id': 2, |
249 | + 'udi': self.UDI_USB_STORAGE_IF0, |
250 | + 'properties': { |
251 | + 'info.bus': ('usb', 'str'), |
252 | + 'info.parent': (self.UDI_USB_STORAGE, 'str'), |
253 | + }, |
254 | + }, |
255 | + # The fake SCSI host of the storage device. Note that HAL does |
256 | + # _not_ provide the info.bus property. |
257 | + { |
258 | + 'id': 3, |
259 | + 'udi': self.UDI_USB_STORAGE_SCSI_HOST, |
260 | + 'properties': { |
261 | + 'info.parent': (self.UDI_USB_STORAGE_IF0, 'str'), |
262 | + }, |
263 | + }, |
264 | + # The fake SCSI disk. |
265 | + { |
266 | + 'id': 3, |
267 | + 'udi': self.UDI_USB_STORAGE_SCSI_DEVICE, |
268 | + 'properties': { |
269 | + 'info.bus': ('scsi', 'str'), |
270 | + 'info.parent': (self.UDI_USB_STORAGE_SCSI_HOST, 'str'), |
271 | + }, |
272 | + }, |
273 | + ] |
274 | + parsed_data = { |
275 | + 'hardware': { |
276 | + 'hal': { |
277 | + 'devices': devices, |
278 | + }, |
279 | + }, |
280 | + } |
281 | + |
282 | + parser = SubmissionParser() |
283 | + parser.buildDeviceList(parsed_data) |
284 | + |
285 | + usb_fake_scsi_disk = parser.hal_devices[ |
286 | + self.UDI_USB_STORAGE_SCSI_DEVICE] |
287 | + usb_main_device = parser.hal_devices[self.UDI_USB_STORAGE_IF0] |
288 | + self.assertEqual(usb_main_device, usb_fake_scsi_disk.scsi_controller) |
289 | + |
290 | + def test_HALDevice_scsi_controller_pci_controller(self): |
291 | + """test of HALDevice.scsi_controller. |
292 | + |
293 | + Variant for a SCSI device connected to a PCI controller. |
294 | + """ |
295 | + devices = [ |
296 | + # The PCI host controller. |
297 | + { |
298 | + 'id': 1, |
299 | + 'udi': self.UDI_SATA_CONTROLLER, |
300 | + 'properties': { |
301 | + 'info.bus': ('pci', 'str'), |
302 | + 'pci.device_class': (PCI_CLASS_STORAGE, 'int'), |
303 | + 'pci.device_subclass': (PCI_SUBCLASS_STORAGE_SATA, |
304 | + 'int'), |
305 | + }, |
306 | + }, |
307 | + # The (fake or real) SCSI host of the storage device. |
308 | + { |
309 | + 'id': 2, |
310 | + 'udi': self.UDI_SATA_CONTROLLER_SCSI, |
311 | + 'properties': { |
312 | + 'info.parent': (self.UDI_SATA_CONTROLLER, 'str'), |
313 | + }, |
314 | + }, |
315 | + # The (possibly fake) SCSI disk. |
316 | + { |
317 | + 'id': 3, |
318 | + 'udi': self.UDI_SATA_DISK, |
319 | + 'properties': { |
320 | + 'info.bus': ('scsi', 'str'), |
321 | + 'info.parent': (self.UDI_SATA_CONTROLLER_SCSI, 'str'), |
322 | + }, |
323 | + }, |
324 | + ] |
325 | + parsed_data = { |
326 | + 'hardware': { |
327 | + 'hal': { |
328 | + 'devices': devices, |
329 | + }, |
330 | + }, |
331 | + } |
332 | + |
333 | + parser = SubmissionParser() |
334 | + parser.buildDeviceList(parsed_data) |
335 | + |
336 | + scsi_device = parser.hal_devices[self.UDI_SATA_DISK] |
337 | + controller = parser.hal_devices[self.UDI_SATA_CONTROLLER] |
338 | + self.assertEqual(controller, scsi_device.scsi_controller) |
339 | + |
340 | + def test_HALDevice_scsi_controller_non_scsi_device(self): |
341 | + """test of HALDevice.scsi_controller. |
342 | + |
343 | + Variant for non-SCSI devices. |
344 | + """ |
345 | + devices = [ |
346 | + { |
347 | + 'id': 1, |
348 | + 'udi': self.UDI_COMPUTER, |
349 | + 'properties': {}, |
350 | + }, |
351 | + ] |
352 | + parsed_data = { |
353 | + 'hardware': { |
354 | + 'hal': { |
355 | + 'devices': devices, |
356 | + }, |
357 | + }, |
358 | + } |
359 | + |
360 | + parser = SubmissionParser() |
361 | + parser.buildDeviceList(parsed_data) |
362 | + |
363 | + device = parser.hal_devices[self.UDI_COMPUTER] |
364 | + self.assertEqual(None, device.scsi_controller) |
365 | + |
366 | + def test_HALDevice_scsi_controller_no_grandparent(self): |
367 | + """test of HALDevice.scsi_controller. |
368 | + |
369 | + Variant for a SCSI device without a grandparent device. |
370 | + """ |
371 | + devices = [ |
372 | + # The (fake or real) SCSI host of the storage device. |
373 | + { |
374 | + 'id': 1, |
375 | + 'udi': self.UDI_SATA_CONTROLLER_SCSI, |
376 | + 'properties': {}, |
377 | + }, |
378 | + # The (possibly fake) SCSI disk. |
379 | + { |
380 | + 'id': 2, |
381 | + 'udi': self.UDI_SATA_DISK, |
382 | + 'properties': { |
383 | + 'info.bus': ('scsi', 'str'), |
384 | + 'info.parent': (self.UDI_SATA_CONTROLLER_SCSI, 'str'), |
385 | + }, |
386 | + }, |
387 | + ] |
388 | + parsed_data = { |
389 | + 'hardware': { |
390 | + 'hal': { |
391 | + 'devices': devices, |
392 | + }, |
393 | + }, |
394 | + } |
395 | + |
396 | + parser = SubmissionParser(self.log) |
397 | + parser.submission_key = 'SCSI device without grandparent device' |
398 | + parser.buildDeviceList(parsed_data) |
399 | + |
400 | + scsi_device = parser.hal_devices[self.UDI_SATA_DISK] |
401 | + self.assertEqual(None, scsi_device.scsi_controller) |
402 | + self.assertWarningMessage( |
403 | + parser.submission_key, |
404 | + "Found SCSI device without a grandparent: %s." |
405 | + % self.UDI_SATA_DISK) |
406 | + |
407 | + def test_HALDevice_scsi_controller_no_parent(self): |
408 | + """test of HALDevice.scsi_controller. |
409 | + |
410 | + Variant for a SCSI device without a parent device. |
411 | + """ |
412 | + devices = [ |
413 | + # The (possibly fake) SCSI disk. |
414 | + { |
415 | + 'id': 1, |
416 | + 'udi': self.UDI_SATA_DISK, |
417 | + 'properties': { |
418 | + 'info.bus': ('scsi', 'str'), |
419 | + }, |
420 | + }, |
421 | + ] |
422 | + parsed_data = { |
423 | + 'hardware': { |
424 | + 'hal': { |
425 | + 'devices': devices, |
426 | + }, |
427 | + }, |
428 | + } |
429 | + |
430 | + parser = SubmissionParser(self.log) |
431 | + parser.submission_key = 'SCSI device without parent device' |
432 | + parser.buildDeviceList(parsed_data) |
433 | + |
434 | + scsi_device = parser.hal_devices[self.UDI_SATA_DISK] |
435 | + self.assertEqual(None, scsi_device.scsi_controller) |
436 | + self.assertWarningMessage( |
437 | + parser.submission_key, |
438 | + "Found SCSI device without a parent: %s." % self.UDI_SATA_DISK) |
439 | + |
440 | def testHALDeviceGetRealBus(self): |
441 | """Test of HALDevice.real_bus, generic case. |
442 | |
443 | @@ -965,6 +1173,51 @@ |
444 | parser.submission_key, |
445 | "Unknown bus 'nonsense' for device " + self.UDI_PCCARD_DEVICE) |
446 | |
447 | + def test_HALDevice_is_root_device_for_root_device(self): |
448 | + """Test of HALDevice.is_root_device for the root device.""" |
449 | + devices = [ |
450 | + { |
451 | + 'id': 1, |
452 | + 'udi': self.UDI_COMPUTER, |
453 | + 'properties': {}, |
454 | + }, |
455 | + ] |
456 | + parsed_data = { |
457 | + 'hardware': { |
458 | + 'hal': { |
459 | + 'devices': devices, |
460 | + }, |
461 | + }, |
462 | + } |
463 | + |
464 | + parser = SubmissionParser() |
465 | + parser.submission_key = 'Test of HALDevice.is_root_device' |
466 | + parser.buildDeviceList(parsed_data) |
467 | + self.assertTrue(parser.hal_devices[self.UDI_COMPUTER].is_root_device) |
468 | + |
469 | + def test_HALDevice_is_root_device_for_non_root_device(self): |
470 | + """Test of HALDevice.is_root_device for a non-root device.""" |
471 | + devices = [ |
472 | + { |
473 | + 'id': 1, |
474 | + 'udi': self.UDI_PCCARD_DEVICE, |
475 | + 'properties': {}, |
476 | + }, |
477 | + ] |
478 | + parsed_data = { |
479 | + 'hardware': { |
480 | + 'hal': { |
481 | + 'devices': devices, |
482 | + }, |
483 | + }, |
484 | + } |
485 | + |
486 | + parser = SubmissionParser() |
487 | + parser.submission_key = 'Test of HALDevice.is_root_device' |
488 | + parser.buildDeviceList(parsed_data) |
489 | + self.assertFalse( |
490 | + parser.hal_devices[self.UDI_PCCARD_DEVICE].is_root_device) |
491 | + |
492 | def renameInfoBusToInfoSubsystem(self, devices): |
493 | """Rename the property info.bus in a device list to info.subsystem. |
494 | |
495 | @@ -2585,65 +2838,260 @@ |
496 | 'property not treated as a real device.') |
497 | |
498 | |
499 | -class TestUdevDevice(TestCase): |
500 | +class TestUdevDevice(TestCaseHWDB): |
501 | """Tests of class UdevDevice.""" |
502 | |
503 | - layer = BaseLayer |
504 | - |
505 | - root_device = { |
506 | - 'P': '/devices/LNXSYSTM:00', |
507 | - 'E': { |
508 | - 'UDEV_LOG': '3', |
509 | - 'DEVPATH': '/devices/LNXSYSTM:00', |
510 | - 'MODALIAS': 'acpi:LNXSYSTM:', |
511 | - 'SUBSYSTEM': 'acpi', |
512 | - } |
513 | - } |
514 | - |
515 | - root_device_dmi_data = { |
516 | - '/sys/class/dmi/id/sys_vendor': 'FUJITSU SIEMENS', |
517 | - '/sys/class/dmi/id/product_name': 'LIFEBOOK E8210', |
518 | - } |
519 | - |
520 | - pci_device_data = { |
521 | - 'P': '/devices/pci0000:00/0000:00:1f.2', |
522 | - 'E': { |
523 | - 'PCI_CLASS': '10602', |
524 | - 'PCI_ID': '8086:27C5', |
525 | - 'PCI_SUBSYS_ID': '10CF:1387', |
526 | - 'PCI_SLOT_NAME': '0000:00:1f.2', |
527 | - 'SUBSYSTEM': 'pci', |
528 | - } |
529 | - } |
530 | - |
531 | - usb_device_data = { |
532 | - 'P': '/devices/pci0000:00/0000:00:1d.1/usb3/3-2', |
533 | - 'E': { |
534 | - 'SUBSYSTEM': 'usb', |
535 | - 'DEVTYPE': 'usb_device', |
536 | - 'PRODUCT': '46d/a01/1013', |
537 | - 'TYPE': '0/0/0', |
538 | - }, |
539 | - } |
540 | - |
541 | - scsi_device_data = { |
542 | - 'P': '/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/4:0:0:0', |
543 | - 'E': { |
544 | - 'SUBSYSTEM': 'scsi', |
545 | - 'DEVTYPE': 'scsi_device', |
546 | - }, |
547 | - } |
548 | - |
549 | - scsi_device_sysfs_data = { |
550 | - 'vendor': 'MATSHITA', |
551 | - 'model': 'DVD-RAM UJ-841S', |
552 | - 'type': '5', |
553 | - } |
554 | - |
555 | - no_subsystem_device_data = { |
556 | - 'P': '/devices/pnp0/00:00', |
557 | - 'E': {} |
558 | - } |
559 | + def setUp(self): |
560 | + """Setup the test environment.""" |
561 | + super(TestUdevDevice, self).setUp() |
562 | + self.root_device = { |
563 | + 'P': '/devices/LNXSYSTM:00', |
564 | + 'E': { |
565 | + 'UDEV_LOG': '3', |
566 | + 'DEVPATH': '/devices/LNXSYSTM:00', |
567 | + 'MODALIAS': 'acpi:LNXSYSTM:', |
568 | + 'SUBSYSTEM': 'acpi', |
569 | + } |
570 | + } |
571 | + |
572 | + self.root_device_dmi_data = { |
573 | + '/sys/class/dmi/id/sys_vendor': 'FUJITSU SIEMENS', |
574 | + '/sys/class/dmi/id/product_name': 'LIFEBOOK E8210', |
575 | + } |
576 | + |
577 | + self.pci_device_data = { |
578 | + 'P': '/devices/pci0000:00/0000:00:1f.2', |
579 | + 'E': { |
580 | + 'PCI_CLASS': '10602', |
581 | + 'PCI_ID': '8086:27C5', |
582 | + 'PCI_SUBSYS_ID': '10CF:1387', |
583 | + 'PCI_SLOT_NAME': '0000:00:1f.2', |
584 | + 'SUBSYSTEM': 'pci', |
585 | + 'DRIVER': 'ahci', |
586 | + } |
587 | + } |
588 | + |
589 | + self.usb_device_data = { |
590 | + 'P': '/devices/pci0000:00/0000:00:1d.1/usb3/3-2', |
591 | + 'E': { |
592 | + 'SUBSYSTEM': 'usb', |
593 | + 'DEVTYPE': 'usb_device', |
594 | + 'PRODUCT': '46d/a01/1013', |
595 | + 'TYPE': '0/0/0', |
596 | + 'DRIVER': 'usb', |
597 | + }, |
598 | + } |
599 | + |
600 | + self.pci_pccard_bridge = { |
601 | + 'P': '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0', |
602 | + 'E': { |
603 | + 'DRIVER': 'yenta_cardbus', |
604 | + 'PCI_CLASS': '60700', |
605 | + 'PCI_ID': '1217:7134', |
606 | + 'PCI_SUBSYS_ID': '10CF:131E', |
607 | + 'PCI_SLOT_NAME': '0000:08:03.0', |
608 | + 'SUBSYSTEM': 'pci', |
609 | + } |
610 | + } |
611 | + |
612 | + self.pccard_scsi_controller_data = { |
613 | + 'P': '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0', |
614 | + 'E': { |
615 | + 'DRIVER': 'aic7xxx', |
616 | + 'PCI_CLASS': '10000', |
617 | + 'PCI_ID': '9004:6075', |
618 | + 'PCI_SUBSYS_ID': '9004:7560', |
619 | + 'SUBSYSTEM': 'pci', |
620 | + }, |
621 | + } |
622 | + |
623 | + self.pci_scsi_controller_scsi_side_1 = { |
624 | + 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/' |
625 | + '0000:09:00.0/host6'), |
626 | + 'E': { |
627 | + 'DEVTYPE': 'scsi_host', |
628 | + 'SUBSYSTEM': 'scsi', |
629 | + }, |
630 | + } |
631 | + |
632 | + self.pci_bridge_pccard_hierarchy_data = [ |
633 | + {'udev_data': self.root_device}, |
634 | + {'udev_data': self.pci_pccard_bridge}, |
635 | + {'udev_data': self.pccard_scsi_controller_data}, |
636 | + ] |
637 | + |
638 | + self.pci_scsi_controller_scsi_side_2 = { |
639 | + 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/' |
640 | + '0000:09:00.0/host6/scsi_host/host6'), |
641 | + 'E': { |
642 | + 'SUBSYSTEM': 'scsi_host', |
643 | + }, |
644 | + } |
645 | + |
646 | + self.scsi_scanner_target_data = { |
647 | + 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/' |
648 | + '0000:09:00.0/host6/target6:0:1'), |
649 | + 'E': { |
650 | + 'DEVTYPE': 'scsi_target', |
651 | + 'SUBSYSTEM': 'scsi' |
652 | + }, |
653 | + } |
654 | + |
655 | + self.scsi_scanner_device_data = { |
656 | + 'P': ('/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/' |
657 | + '0000:09:00.0/host6/target6:0:1/6:0:1:0'), |
658 | + 'E': { |
659 | + 'DEVTYPE': 'scsi_device', |
660 | + 'SUBSYSTEM': 'scsi', |
661 | + }, |
662 | + } |
663 | + |
664 | + self.scsi_scanner_device_sysfs_data = { |
665 | + 'vendor': 'FUJITSU', |
666 | + 'model': 'fi-5120Cdj', |
667 | + 'type': '6', |
668 | + } |
669 | + |
670 | + self.scsi_device_hierarchy_data = [ |
671 | + {'udev_data': self.pccard_scsi_controller_data}, |
672 | + {'udev_data': self.pci_scsi_controller_scsi_side_1}, |
673 | + {'udev_data': self.pci_scsi_controller_scsi_side_2}, |
674 | + {'udev_data': self.scsi_scanner_target_data}, |
675 | + { |
676 | + 'udev_data': self.scsi_scanner_device_data, |
677 | + 'sysfs_data': self.scsi_scanner_device_sysfs_data, |
678 | + }, |
679 | + ] |
680 | + |
681 | + self.pci_ide_controller = { |
682 | + 'P': '/devices/pci0000:00/0000:00:1f.1', |
683 | + 'E': { |
684 | + 'DRIVER': 'ata_piix', |
685 | + 'PCI_CLASS': '1018A', |
686 | + 'PCI_ID': '8086:27DF', |
687 | + 'PCI_SUBSYS_ID': '10CF:1385', |
688 | + 'SUBSYSTEM': 'pci', |
689 | + }, |
690 | + } |
691 | + |
692 | + self.pci_ide_controller_scsi_side_1 = { |
693 | + 'P': '/devices/pci0000:00/0000:00:1f.1/host4', |
694 | + 'E': { |
695 | + 'DEVTYPE': 'scsi_host', |
696 | + 'SUBSYSTEM': 'scsi', |
697 | + }, |
698 | + } |
699 | + |
700 | + self.pci_ide_controller_scsi_side_2 = { |
701 | + 'P': '/devices/pci0000:00/0000:00:1f.1/host4/scsi_host/host4', |
702 | + 'E': { |
703 | + 'SUBSYSTEM': 'scsi_host', |
704 | + }, |
705 | + } |
706 | + |
707 | + self.ide_device_target_data = { |
708 | + 'P': '/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0', |
709 | + 'E': { |
710 | + 'DEVTYPE': 'scsi_target', |
711 | + 'SUBSYSTEM': 'scsi', |
712 | + }, |
713 | + } |
714 | + |
715 | + self.ide_cdrom_device_data = { |
716 | + 'P': ('/devices/pci0000:00/0000:00:1f.1/host4/target4:0:0/' |
717 | + '4:0:0:0'), |
718 | + 'E': { |
719 | + 'SUBSYSTEM': 'scsi', |
720 | + 'DEVTYPE': 'scsi_device', |
721 | + 'DRIVER': 'sr', |
722 | + }, |
723 | + } |
724 | + |
725 | + self.ide_cdrom_device_sysfs_data = { |
726 | + 'vendor': 'MATSHITA', |
727 | + 'model': 'DVD-RAM UJ-841S', |
728 | + 'type': '5', |
729 | + } |
730 | + |
731 | + self.ide_device_hierarchy_data = [ |
732 | + {'udev_data': self.pci_ide_controller}, |
733 | + {'udev_data': self.pci_ide_controller_scsi_side_1}, |
734 | + {'udev_data': self.pci_ide_controller_scsi_side_2}, |
735 | + {'udev_data': self.ide_device_target_data}, |
736 | + { |
737 | + 'udev_data': self.ide_cdrom_device_data, |
738 | + 'sysfs_data': self.ide_cdrom_device_sysfs_data, |
739 | + }, |
740 | + ] |
741 | + |
742 | + self.usb_storage_usb_interface = { |
743 | + 'P': '/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0', |
744 | + 'E': { |
745 | + 'DRIVER': 'usb-storage', |
746 | + 'PRODUCT': '1307/163/100', |
747 | + 'TYPE': '0/0/0', |
748 | + 'INTERFACE': '8/6/80', |
749 | + 'DEVTYPE': 'usb_interface', |
750 | + 'SUBSYSTEM': 'usb', |
751 | + }, |
752 | + } |
753 | + |
754 | + self.usb_storage_scsi_host_1 = { |
755 | + 'P': '/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7', |
756 | + 'E': { |
757 | + 'DEVTYPE': 'scsi_host', |
758 | + 'SUBSYSTEM': 'scsi', |
759 | + }, |
760 | + } |
761 | + |
762 | + self.usb_storage_scsi_host_2 = { |
763 | + 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' |
764 | + 'scsi_host/host7'), |
765 | + 'E': { |
766 | + 'SUBSYSTEM': 'scsi_host', |
767 | + }, |
768 | + } |
769 | + |
770 | + self.usb_storage_scsi_target = { |
771 | + 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' |
772 | + 'target7:0:0'), |
773 | + 'E': { |
774 | + 'DEVTYPE': 'scsi_target', |
775 | + 'SUBSYSTEM': 'scsi', |
776 | + }, |
777 | + } |
778 | + |
779 | + self.usb_storage_scsi_device = { |
780 | + 'P': ('/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host7/' |
781 | + 'target7:0:0/7:0:0:0'), |
782 | + 'E': { |
783 | + 'DEVTYPE': 'scsi_device', |
784 | + 'DRIVER': 'sd', |
785 | + 'SUBSYSTEM': 'scsi', |
786 | + }, |
787 | + } |
788 | + |
789 | + self.usb_storage_scsi_device_sysfs = { |
790 | + 'vendor': 'Ut163', |
791 | + 'model': 'USB2FlashStorage', |
792 | + 'type': '0', |
793 | + } |
794 | + |
795 | + self.usb_storage_hierarchy_data = [ |
796 | + {'udev_data': self.usb_storage_usb_interface}, |
797 | + {'udev_data': self.usb_storage_scsi_host_1}, |
798 | + {'udev_data': self.usb_storage_scsi_host_2}, |
799 | + {'udev_data': self.usb_storage_scsi_target}, |
800 | + { |
801 | + 'udev_data': self.usb_storage_scsi_device, |
802 | + 'sysfs_data': self.usb_storage_scsi_device_sysfs, |
803 | + }, |
804 | + ] |
805 | + |
806 | + self.no_subsystem_device_data = { |
807 | + 'P': '/devices/pnp0/00:00', |
808 | + 'E': {} |
809 | + } |
810 | |
811 | def test_device_id(self): |
812 | """Test of UdevDevice.device_id.""" |
813 | @@ -2790,7 +3238,8 @@ |
814 | def test_is_scsi_device(self): |
815 | """Test of UdevDevice.is_scsi_device.""" |
816 | device = UdevDevice( |
817 | - None, self.scsi_device_data, self.scsi_device_sysfs_data) |
818 | + None, self.scsi_scanner_device_data, |
819 | + self.scsi_scanner_device_sysfs_data) |
820 | self.assertTrue(device.is_scsi_device) |
821 | |
822 | device = UdevDevice(None, self.root_device) |
823 | @@ -2799,16 +3248,18 @@ |
824 | def test_scsi_vendor(self): |
825 | """Test of UdevDevice.scsi_vendor.""" |
826 | device = UdevDevice( |
827 | - None, self.scsi_device_data, self.scsi_device_sysfs_data, None) |
828 | - self.assertEqual('MATSHITA', device.scsi_vendor) |
829 | + None, self.scsi_scanner_device_data, |
830 | + self.scsi_scanner_device_sysfs_data) |
831 | + self.assertEqual('FUJITSU', device.scsi_vendor) |
832 | device = UdevDevice(None, self.root_device) |
833 | self.assertEqual(None, device.scsi_vendor) |
834 | |
835 | def test_scsi_model(self): |
836 | """Test of UdevDevice.scsi_model.""" |
837 | device = UdevDevice( |
838 | - None, self.scsi_device_data, self.scsi_device_sysfs_data) |
839 | - self.assertEqual('DVD-RAM UJ-841S', device.scsi_model) |
840 | + None, self.scsi_scanner_device_data, |
841 | + self.scsi_scanner_device_sysfs_data) |
842 | + self.assertEqual('fi-5120Cdj', device.scsi_model) |
843 | |
844 | device = UdevDevice(None, self.root_device) |
845 | self.assertEqual(None, device.scsi_model) |
846 | @@ -2827,6 +3278,14 @@ |
847 | device = UdevDevice(None, self.no_subsystem_device_data) |
848 | self.assertEqual(None, device.raw_bus) |
849 | |
850 | + def test_is_root_device(self): |
851 | + """Test of UdevDevice.is_root_device.""" |
852 | + device = UdevDevice(None, self.root_device) |
853 | + self.assertTrue(device.is_root_device) |
854 | + |
855 | + device = UdevDevice(None, self.pci_device_data) |
856 | + self.assertFalse(device.is_root_device) |
857 | + |
858 | def test_getVendorOrProduct(self): |
859 | """Test of UdevDevice.getVendorOrProduct().""" |
860 | device = UdevDevice( |
861 | @@ -2847,10 +3306,10 @@ |
862 | self.assertEqual('Unknown', device.getVendorOrProduct('product')) |
863 | |
864 | device = UdevDevice( |
865 | - None, self.scsi_device_data, self.scsi_device_sysfs_data) |
866 | - self.assertEqual('MATSHITA', device.getVendorOrProduct('vendor')) |
867 | - self.assertEqual( |
868 | - 'DVD-RAM UJ-841S', device.getVendorOrProduct('product')) |
869 | + None, self.scsi_scanner_device_data, |
870 | + self.scsi_scanner_device_sysfs_data) |
871 | + self.assertEqual('FUJITSU', device.getVendorOrProduct('vendor')) |
872 | + self.assertEqual('fi-5120Cdj', device.getVendorOrProduct('product')) |
873 | |
874 | device = UdevDevice(None, self.no_subsystem_device_data) |
875 | self.assertEqual(None, device.getVendorOrProduct('vendor')) |
876 | @@ -2888,10 +3347,10 @@ |
877 | self.assertEqual(0xa01, device.getVendorOrProductID('product')) |
878 | |
879 | device = UdevDevice( |
880 | - None, self.scsi_device_data, self.scsi_device_sysfs_data) |
881 | - self.assertEqual('MATSHITA', device.getVendorOrProductID('vendor')) |
882 | - self.assertEqual( |
883 | - 'DVD-RAM UJ-841S', device.getVendorOrProductID('product')) |
884 | + None, self.scsi_scanner_device_data, |
885 | + self.scsi_scanner_device_sysfs_data) |
886 | + self.assertEqual('FUJITSU', device.getVendorOrProductID('vendor')) |
887 | + self.assertEqual('fi-5120Cdj', device.getVendorOrProductID('product')) |
888 | |
889 | device = UdevDevice( |
890 | None, self.no_subsystem_device_data) |
891 | @@ -2910,6 +3369,179 @@ |
892 | None, self.root_device, None, self.root_device_dmi_data) |
893 | self.assertEqual('LIFEBOOK E8210', device.product_id) |
894 | |
895 | + def test_vendor_id_for_db(self): |
896 | + """Test of UdevDevice.vendor_id_for_db.""" |
897 | + device = UdevDevice( |
898 | + None, self.root_device, None, self.root_device_dmi_data) |
899 | + self.assertEqual('FUJITSU SIEMENS', device.vendor_id_for_db) |
900 | + |
901 | + device = UdevDevice(None, self.pci_device_data) |
902 | + self.assertEqual('0x8086', device.vendor_id_for_db) |
903 | + |
904 | + device = UdevDevice(None, self.usb_device_data) |
905 | + self.assertEqual('0x046d', device.vendor_id_for_db) |
906 | + |
907 | + device = UdevDevice( |
908 | + None, self.scsi_scanner_device_data, |
909 | + self.scsi_scanner_device_sysfs_data) |
910 | + self.assertEqual('FUJITSU ', device.vendor_id_for_db) |
911 | + |
912 | + def test_product_id_for_db(self): |
913 | + """Test of UdevDevice.product_id_for_db.""" |
914 | + device = UdevDevice( |
915 | + None, self.root_device, None, self.root_device_dmi_data) |
916 | + self.assertEqual('LIFEBOOK E8210', device.product_id_for_db) |
917 | + |
918 | + device = UdevDevice(None, self.pci_device_data) |
919 | + self.assertEqual('0x27c5', device.product_id_for_db) |
920 | + |
921 | + device = UdevDevice(None, self.usb_device_data) |
922 | + self.assertEqual('0x0a01', device.product_id_for_db) |
923 | + |
924 | + device = UdevDevice( |
925 | + None, self.scsi_scanner_device_data, |
926 | + self.scsi_scanner_device_sysfs_data) |
927 | + self.assertEqual('fi-5120Cdj ', device.product_id_for_db) |
928 | + |
929 | + def test_driver_name(self): |
930 | + """Test of UdevDevice.driver_name.""" |
931 | + device = UdevDevice(None, self.pci_device_data) |
932 | + self.assertEqual('ahci', device.driver_name) |
933 | + |
934 | + device = UdevDevice( |
935 | + None, self.root_device, None, self.root_device_dmi_data) |
936 | + self.assertEqual(None, device.driver_name) |
937 | + |
938 | + def buildUdevDeviceHierarchy(self, device_data, parser=None): |
939 | + """Build a UdevDevice hierarchy from device_data. |
940 | + |
941 | + :param device_data: A sequence of arguments that are passed |
942 | + to the UdevDevice constructor. Each element must be a |
943 | + dictionary that can be used as a **kwargs argument. |
944 | + |
945 | + Element N of the sequence is the parent of element N+1. |
946 | + :param parser: A SubmissionParser instance to be passed to |
947 | + the constructor of UdevDevice. |
948 | + """ |
949 | + parent = None |
950 | + devices = [] |
951 | + for kwargs in device_data: |
952 | + device = UdevDevice(parser, **kwargs) |
953 | + devices.append(device) |
954 | + if parent is not None: |
955 | + parent.addChild(device) |
956 | + parent = device |
957 | + return devices |
958 | + |
959 | + def test_scsi_controller(self): |
960 | + """Test of UdevDevice.scsi_controller for a PCI controller.""" |
961 | + devices = self.buildUdevDeviceHierarchy( |
962 | + self.scsi_device_hierarchy_data) |
963 | + controller = devices[0] |
964 | + scsi_device = devices[-1] |
965 | + self.assertEqual(controller, scsi_device.scsi_controller) |
966 | + |
967 | + def test_scsi_controller_insufficient_anchestors(self): |
968 | + """Test of UdevDevice.scsi_controller for a PCI controller. |
969 | + |
970 | + If a SCSI device does not have a sufficient number of ancestors, |
971 | + UdevDevice.scsi_controller returns None. |
972 | + """ |
973 | + parser = SubmissionParser(self.log) |
974 | + parser.submission_key = 'UdevDevice.scsi_controller ancestor missing' |
975 | + devices = self.buildUdevDeviceHierarchy( |
976 | + self.scsi_device_hierarchy_data[1:], parser) |
977 | + scsi_device = devices[-1] |
978 | + self.assertEqual(None, scsi_device.scsi_controller) |
979 | + self.assertWarningMessage( |
980 | + parser.submission_key, |
981 | + 'Found a SCSI device without a sufficient number of ancestors: ' |
982 | + '/devices/pci0000:00/0000:00:1e.0/0000:08:03.0/0000:09:00.0/' |
983 | + 'host6/target6:0:1/6:0:1:0') |
984 | + |
985 | + def test_scsi_controller_no_scsi_device(self): |
986 | + """Test of UdevDevice.scsi_controller for a PCI controller. |
987 | + |
988 | + For non-SCSI devices, this property is None. |
989 | + """ |
990 | + device = UdevDevice(None, self.pci_device_data) |
991 | + self.assertEqual(None, device.scsi_controller) |
992 | + |
993 | + def test_translateScsiBus_real_scsi_device(self): |
994 | + """Test of UdevDevice.translateScsiBus() with a real SCSI device.""" |
995 | + devices = self.buildUdevDeviceHierarchy( |
996 | + self.scsi_device_hierarchy_data) |
997 | + scsi_device = devices[-1] |
998 | + self.assertEqual( |
999 | + HWBus.SCSI, scsi_device.translateScsiBus()) |
1000 | + |
1001 | + def test_translateScsiBus_ide_device(self): |
1002 | + """Test of UdevDevice.translateScsiBus() with an IDE device.""" |
1003 | + devices = self.buildUdevDeviceHierarchy( |
1004 | + self.ide_device_hierarchy_data) |
1005 | + ide_device = devices[-1] |
1006 | + self.assertEqual(HWBus.IDE, ide_device.translateScsiBus()) |
1007 | + |
1008 | + def test_translateScsiBus_usb_device(self): |
1009 | + """Test of UdevDevice.translateScsiBus() with a USB device.""" |
1010 | + devices = self.buildUdevDeviceHierarchy( |
1011 | + self.usb_storage_hierarchy_data) |
1012 | + usb_scsi_device = devices[-1] |
1013 | + self.assertEqual(None, usb_scsi_device.translateScsiBus()) |
1014 | + |
1015 | + def test_translateScsiBus_non_scsi_device(self): |
1016 | + """Test of UdevDevice.translateScsiBus() for a non-SCSI device.""" |
1017 | + device = UdevDevice(None, self.root_device) |
1018 | + self.assertEqual(None, device.translateScsiBus()) |
1019 | + |
1020 | + def test_translatePciBus(self): |
1021 | + """Test of UdevDevice.translatePciBus().""" |
1022 | + devices = self.buildUdevDeviceHierarchy( |
1023 | + self.pci_bridge_pccard_hierarchy_data) |
1024 | + pci_device = devices[1] |
1025 | + pccard_device = devices[2] |
1026 | + self.assertEqual(HWBus.PCI, pci_device.translatePciBus()) |
1027 | + self.assertEqual(HWBus.PCCARD, pccard_device.translatePciBus()) |
1028 | + |
1029 | + def test_real_bus_usb_device(self): |
1030 | + """Test of UdevDevice.real_bus for a USB device.""" |
1031 | + usb_device = UdevDevice(None, self.usb_device_data) |
1032 | + self.assertEqual(HWBus.USB, usb_device.real_bus) |
1033 | + |
1034 | + def test_real_bus_usb_interface(self): |
1035 | + """Test of UdevDevice.real_bus for a USB interface.""" |
1036 | + parser = SubmissionParser(self.log) |
1037 | + parser.submission_key = 'UdevDevice.real_bus for a not-real device' |
1038 | + usb_interface = UdevDevice(parser, self.usb_storage_usb_interface) |
1039 | + self.assertEqual(None, usb_interface.real_bus) |
1040 | + # UdevDevice.real_bus should only be accessed for real devices, |
1041 | + # which a USB is not. Hence we get a warning. |
1042 | + self.assertWarningMessage( |
1043 | + parser.submission_key, |
1044 | + "Unknown bus 'usb_interface' for device " |
1045 | + "/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0") |
1046 | + |
1047 | + def test_real_bus_pci(self): |
1048 | + """Test of UdevDevice.real_bus for PCI devices.""" |
1049 | + devices = self.buildUdevDeviceHierarchy( |
1050 | + self.pci_bridge_pccard_hierarchy_data) |
1051 | + pci_device = devices[1] |
1052 | + pccard_device = devices[2] |
1053 | + self.assertEqual(HWBus.PCI, pci_device.real_bus) |
1054 | + self.assertEqual(HWBus.PCCARD, pccard_device.real_bus) |
1055 | + |
1056 | + def test_real_bus_scsi(self): |
1057 | + """Test of UdevDevice.real_bus for a SCSI device.""" |
1058 | + devices = self.buildUdevDeviceHierarchy( |
1059 | + self.scsi_device_hierarchy_data) |
1060 | + scsi_device = devices[-1] |
1061 | + self.assertEqual(HWBus.SCSI, scsi_device.real_bus) |
1062 | + |
1063 | + def test_real_bus_system(self): |
1064 | + """Test of UdevDevice.real_bus for a system.""" |
1065 | + root_device = UdevDevice(None, self.root_device) |
1066 | + self.assertEqual(HWBus.SYSTEM, root_device.real_bus) |
1067 | + |
1068 | |
1069 | class TestHWDBSubmissionTablePopulation(TestCaseHWDB): |
1070 | """Tests of the HWDB popoluation with submitted data.""" |
This branch has several small improvements for the HWDB submission
processing script for submissions with udev data:
- it fixes a bug in the udev test data for USB storage devices: The udev
property DEVTYPE was missing.
This uncovered a (now fixed) bug in BaseDevice. translateScsiBu s()
Up to now, the detection of a USB storage device pretending to be a
SCSI device was based on the value "usb" of the property raw_bus of an
ancestor node of the fake SCSI device, but the real value of
ancestor.raw_bus for udev submissions is "usb_interface". Since this
value is not used in submissions with HAL data, there are no bad
side-effects.
- it defines a new property BaseDevice. is_root_ device, implemented in
the derived classes HALDevice and UdevDevice. There are a few places
in the code, were the root device needs to be treated specially. Up to
now, the decision "is this device the root device" was based on a
comparison of the HAL-specific property "udi".
- it modifies the property BaseDevice.real_bus to properly deal with
udev submissions. If we have a SCSI device, is now detected by
comparing the value self.raw_bus with 'scsi' and 'scsi_device'. Again,
HAL does not use the new value 'scsi_device', so there are no bad side
effects.
- it adds tests for UdevDevice.real_bus and UdevDevice. translatePciBus ()
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
20: [F0401] Unable to import 'xml.etree.
named etree)
The complaint is not related to my changes.