Merge lp:~adeuring/launchpad/hwdb-refactor-haldevice-2 into lp:launchpad
- hwdb-refactor-haldevice-2
- Merge into devel
Proposed by
Abel Deuring
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~adeuring/launchpad/hwdb-refactor-haldevice-2 |
Merge into: | lp:launchpad |
Diff against target: |
435 lines 2 files modified
lib/canonical/launchpad/scripts/hwdbsubmissions.py (+140/-83) lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py (+82/-0) |
To merge this branch: | bzr merge lp:~adeuring/launchpad/hwdb-refactor-haldevice-2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Nelson (community) | code | Approve | |
Review via email: mp+12713@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
Michael Nelson (michael.nelson) wrote : | # |
<noodles775> adeuring: gee, that's an unfortunate diff...
<adeuring> noodles775: why?
<noodles775> adeuring: Nothing wrong with your code, I jut meant the huge segment of HALDevice that diff has assumed has been deleted and added.
<adeuring> noodles775: Ah, OK.
<noodles775> adeuring: r=me
<adeuring> noodles775: thanks!
<noodles775> adeuring: did you try using the revision spec '-r x..y' with bzr send so that the colour-coded diff on the mp is just the revisions you want? If not, might be good for the third installment :)
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-09-29 15:05:09 +0000 |
3 | +++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-01 11:20:32 +0000 |
4 | @@ -7,7 +7,7 @@ |
5 | data and for the community test submissions. |
6 | """ |
7 | |
8 | - |
9 | +__metaclass__ = type |
10 | __all__ = [ |
11 | 'SubmissionParser', |
12 | 'process_pending_submissions', |
13 | @@ -1235,59 +1235,30 @@ |
14 | root_device.createDBData(submission, None) |
15 | return True |
16 | |
17 | -class HALDevice: |
18 | - """The representation of a HAL device node.""" |
19 | - |
20 | - def __init__(self, id, udi, properties, parser): |
21 | - """HALDevice constructor. |
22 | - |
23 | - :param id: The ID of the HAL device in the submission data as |
24 | - specified in <device id=...>. |
25 | - :type id: int |
26 | - :param udi: The UDI of the HAL device. |
27 | - :type udi: string |
28 | - :param properties: The HAL properties of the device. |
29 | - :type properties: dict |
30 | - :param parser: The parser processing a submission. |
31 | - :type parser: SubmissionParser |
32 | - """ |
33 | - self.id = id |
34 | - self.udi = udi |
35 | - self.properties = properties |
36 | + |
37 | +class BaseDevice: |
38 | + """A base class to represent device data from HAL and udev.""" |
39 | + |
40 | + def __init__(self, parser): |
41 | self.children = [] |
42 | self.parser = parser |
43 | self.parent = None |
44 | |
45 | + # Translation of the HAL info.bus/info.subsystem property and the |
46 | + # udev property SUBSYSTEM to HWBus enumerated buses. |
47 | + subsystem_hwbus = { |
48 | + 'pcmcia': HWBus.PCMCIA, |
49 | + 'usb_device': HWBus.USB, |
50 | + 'ide': HWBus.IDE, |
51 | + 'serio': HWBus.SERIAL, |
52 | + } |
53 | + |
54 | def addChild(self, child): |
55 | """Add a child device and set the child's parent.""" |
56 | assert type(child) == type(self) |
57 | self.children.append(child) |
58 | child.parent = self |
59 | |
60 | - def getProperty(self, property_name): |
61 | - """Return the property property_name. |
62 | - |
63 | - Note that there is no check of the property type. |
64 | - """ |
65 | - if property_name not in self.properties: |
66 | - return None |
67 | - name, type_ = self.properties[property_name] |
68 | - return name |
69 | - |
70 | - @property |
71 | - def parent_udi(self): |
72 | - """The UDI of the parent device.""" |
73 | - return self.getProperty('info.parent') |
74 | - |
75 | - # Translation of the HAL info.bus/info.subsystem property to HWBus |
76 | - # enumerated buses. |
77 | - hal_bus_hwbus = { |
78 | - 'pcmcia': HWBus.PCMCIA, |
79 | - 'usb_device': HWBus.USB, |
80 | - 'ide': HWBus.IDE, |
81 | - 'serio': HWBus.SERIAL, |
82 | - } |
83 | - |
84 | # Translation of subclasses of the PCI class storage to HWBus |
85 | # enumerated buses. The Linux kernel accesses IDE and SATA disks |
86 | # and CDROM drives via the SCSI system; we want to know the real bus |
87 | @@ -1307,6 +1278,32 @@ |
88 | 7: HWBus.SAS, |
89 | } |
90 | |
91 | + @property |
92 | + def device_id(self): |
93 | + """A unique ID for this device.""" |
94 | + raise NotImplementedError() |
95 | + |
96 | + @property |
97 | + def pci_class(self): |
98 | + """The PCI device class of the device or None for Non-PCI devices.""" |
99 | + raise NotImplementedError() |
100 | + |
101 | + @property |
102 | + def pci_subclass(self): |
103 | + """The PCI device sub-class of the device or None for Non-PCI devices. |
104 | + """ |
105 | + raise NotImplementedError() |
106 | + |
107 | + @property |
108 | + def usb_vendor_id(self): |
109 | + """The USB vendor ID of the device or None for Non-USB devices.""" |
110 | + raise NotImplementedError() |
111 | + |
112 | + @property |
113 | + def usb_product_id(self): |
114 | + """The USB product ID of the device or None for Non-USB devices.""" |
115 | + raise NotImplementedError() |
116 | + |
117 | def translateScsiBus(self): |
118 | """Return the real bus of a device where raw_bus=='scsi'. |
119 | |
120 | @@ -1321,29 +1318,29 @@ |
121 | parent = self.parent |
122 | if parent is None: |
123 | self.parser._logWarning( |
124 | - 'Found SCSI device without a parent: %s.' % self.udi) |
125 | + 'Found SCSI device without a parent: %s.' % self.device_id) |
126 | return None |
127 | grandparent = parent.parent |
128 | if grandparent is None: |
129 | self.parser._logWarning( |
130 | - 'Found SCSI device without a grandparent: %s.' % self.udi) |
131 | + 'Found SCSI device without a grandparent: %s.' |
132 | + % self.device_id) |
133 | return None |
134 | |
135 | grandparent_bus = grandparent.raw_bus |
136 | if grandparent_bus == 'pci': |
137 | - if (grandparent.getProperty('pci.device_class') |
138 | - != PCI_CLASS_STORAGE): |
139 | + if (grandparent.pci_class != PCI_CLASS_STORAGE): |
140 | # This is not a storage class PCI device? This |
141 | # indicates a bug somewhere in HAL or in the hwdb |
142 | # client, or a fake submission. |
143 | - device_class = grandparent.getProperty('pci.device_class') |
144 | + device_class = grandparent.pci_class |
145 | self.parser._logWarning( |
146 | 'A (possibly fake) SCSI device %s is connected to ' |
147 | 'PCI device %s that has the PCI device class %s; ' |
148 | 'expected class 1 (storage).' |
149 | - % (self.udi, grandparent.udi, device_class)) |
150 | + % (self.device_id, grandparent.device_id, device_class)) |
151 | return None |
152 | - pci_subclass = grandparent.getProperty('pci.device_subclass') |
153 | + pci_subclass = grandparent.pci_subclass |
154 | return self.pci_storage_subclass_hwbus.get(pci_subclass) |
155 | elif grandparent_bus == 'usb': |
156 | # USB storage devices have the following HAL device hierarchy: |
157 | @@ -1395,38 +1392,18 @@ |
158 | # subclass 7). |
159 | # XXX Abel Deuring 2005-05-14 How can we detect ExpressCards? |
160 | # I do not have any such card at present... |
161 | - parent_class = self.parent.getProperty('pci.device_class') |
162 | - parent_subclass = self.parent.getProperty('pci.device_subclass') |
163 | + parent_class = self.parent.pci_class |
164 | + parent_subclass = self.parent.pci_subclass |
165 | if (parent_class == PCI_CLASS_BRIDGE |
166 | and parent_subclass == PCI_SUBCLASS_BRIDGE_CARDBUS): |
167 | return HWBus.PCCARD |
168 | else: |
169 | return HWBus.PCI |
170 | |
171 | - translate_bus_name = { |
172 | - 'pci': translatePciBus, |
173 | - 'scsi': translateScsiBus, |
174 | - } |
175 | - |
176 | @property |
177 | def raw_bus(self): |
178 | - """Return the device bus as specified by HAL. |
179 | - |
180 | - Older versions of HAL stored this value in the property |
181 | - info.bus; newer versions store it in info.subsystem. |
182 | - """ |
183 | - # Note that info.bus is gone for all devices except the |
184 | - # USB bus. For USB devices, the property info.bus returns more |
185 | - # detailed data: info.subsystem has the value 'usb' for all |
186 | - # HAL nodes belonging to USB devices, while info.bus has the |
187 | - # value 'usb_device' for the root node of a USB device, and the |
188 | - # value 'usb' for sub-nodes of a USB device. We use these |
189 | - # different value to to find the root USB device node, hence |
190 | - # try to read info.bus first. |
191 | - result = self.getProperty('info.bus') |
192 | - if result is not None: |
193 | - return result |
194 | - return self.getProperty('info.subsystem') |
195 | + """Return the device bus as specified by HAL or udev.""" |
196 | + raise NotImplementedError() |
197 | |
198 | @property |
199 | def real_bus(self): |
200 | @@ -1436,7 +1413,7 @@ |
201 | cannot be determined. |
202 | """ |
203 | device_bus = self.raw_bus |
204 | - result = self.hal_bus_hwbus.get(device_bus) |
205 | + result = self.subsystem_hwbus.get(device_bus) |
206 | if result is not None: |
207 | return result |
208 | |
209 | @@ -1588,7 +1565,7 @@ |
210 | info.bus == 'usb' is used for end points of USB devices; |
211 | the root node of a USB device has info.bus == 'usb_device'. |
212 | |
213 | - info.bus == 'viedo4linux' is used for the "input aspect" |
214 | + info.bus == 'video4linux' is used for the "input aspect" |
215 | of video devices. |
216 | """ |
217 | bus = self.raw_bus |
218 | @@ -1603,8 +1580,8 @@ |
219 | # info.bus property that we treat as a real device. |
220 | return self.udi == ROOT_UDI |
221 | elif bus == 'usb_device': |
222 | - vendor_id = self.getProperty('usb_device.vendor_id') |
223 | - product_id = self.getProperty('usb_device.product_id') |
224 | + vendor_id = self.usb_vendor_id |
225 | + product_id = self.usb_product_id |
226 | if vendor_id == 0 and product_id == 0: |
227 | # double-check: The parent device should be a PCI host |
228 | # controller, identifiable by its device class and subclass. |
229 | @@ -1612,8 +1589,8 @@ |
230 | # possible bridges, like ISA->USB.. |
231 | parent = self.parent |
232 | parent_bus = parent.raw_bus |
233 | - parent_class = parent.getProperty('pci.device_class') |
234 | - parent_subclass = parent.getProperty('pci.device_subclass') |
235 | + parent_class = parent.pci_class |
236 | + parent_subclass = parent.pci_subclass |
237 | if (parent_bus == 'pci' |
238 | and parent_class == PCI_CLASS_SERIALBUS_CONTROLLER |
239 | and parent_subclass == PCI_SUBCLASS_SERIALBUS_USB): |
240 | @@ -1757,6 +1734,88 @@ |
241 | return False |
242 | return True |
243 | |
244 | + |
245 | +class HALDevice(BaseDevice): |
246 | + """The representation of a HAL device node.""" |
247 | + |
248 | + def __init__(self, id, udi, properties, parser): |
249 | + """HALDevice constructor. |
250 | + |
251 | + :param id: The ID of the HAL device in the submission data as |
252 | + specified in <device id=...>. |
253 | + :type id: int |
254 | + :param udi: The UDI of the HAL device. |
255 | + :type udi: string |
256 | + :param properties: The HAL properties of the device. |
257 | + :type properties: dict |
258 | + :param parser: The parser processing a submission. |
259 | + :type parser: SubmissionParser |
260 | + """ |
261 | + super(HALDevice, self).__init__(parser) |
262 | + self.id = id |
263 | + self.udi = udi |
264 | + self.properties = properties |
265 | + |
266 | + def getProperty(self, property_name): |
267 | + """Return the HAL property property_name. |
268 | + |
269 | + Note that there is no check of the property type. |
270 | + """ |
271 | + if property_name not in self.properties: |
272 | + return None |
273 | + name, type_ = self.properties[property_name] |
274 | + return name |
275 | + |
276 | + @property |
277 | + def parent_udi(self): |
278 | + """The UDI of the parent device.""" |
279 | + return self.getProperty('info.parent') |
280 | + |
281 | + @property |
282 | + def device_id(self): |
283 | + """See `BaseDevice`.""" |
284 | + return self.udi |
285 | + |
286 | + @property |
287 | + def pci_class(self): |
288 | + """See `BaseDevice`.""" |
289 | + return self.getProperty('pci.device_class') |
290 | + |
291 | + @property |
292 | + def pci_subclass(self): |
293 | + """The PCI device sub-class of the device or None for Non-PCI devices. |
294 | + """ |
295 | + return self.getProperty('pci.device_subclass') |
296 | + |
297 | + @property |
298 | + def usb_vendor_id(self): |
299 | + """See `BaseDevice`.""" |
300 | + return self.getProperty('usb_device.vendor_id') |
301 | + |
302 | + @property |
303 | + def usb_product_id(self): |
304 | + """See `BaseDevice`.""" |
305 | + return self.getProperty('usb_device.product_id') |
306 | + |
307 | + @property |
308 | + def raw_bus(self): |
309 | + """See `BaseDevice`.""" |
310 | + # Older versions of HAL stored this value in the property |
311 | + # info.bus; newer versions store it in info.subsystem. |
312 | + # |
313 | + # Note that info.bus is gone for all devices except the |
314 | + # USB bus. For USB devices, the property info.bus returns more |
315 | + # detailed data: info.subsystem has the value 'usb' for all |
316 | + # HAL nodes belonging to USB devices, while info.bus has the |
317 | + # value 'usb_device' for the root node of a USB device, and the |
318 | + # value 'usb' for sub-nodes of a USB device. We use these |
319 | + # different value to to find the root USB device node, hence |
320 | + # try to read info.bus first. |
321 | + result = self.getProperty('info.bus') |
322 | + if result is not None: |
323 | + return result |
324 | + return self.getProperty('info.subsystem') |
325 | + |
326 | def getScsiVendorAndModelName(self): |
327 | """Separate vendor and model name of SCSI decvices. |
328 | |
329 | @@ -1830,13 +1889,11 @@ |
330 | """The vendor of this device.""" |
331 | return self.getVendorOrProduct('vendor') |
332 | |
333 | - |
334 | @property |
335 | def product(self): |
336 | """The vendor of this device.""" |
337 | return self.getVendorOrProduct('product') |
338 | |
339 | - |
340 | def getVendorOrProductID(self, type_): |
341 | """Return the vendor or product ID for this device. |
342 | |
343 | |
344 | === modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py' |
345 | --- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-06-25 05:30:52 +0000 |
346 | +++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-01 11:20:32 +0000 |
347 | @@ -380,6 +380,88 @@ |
348 | 'Unexpected value of HALDevice.parent_udi, ' |
349 | 'when no parent information available.') |
350 | |
351 | + def testHALDeviceDeviceId(self): |
352 | + """Test of HALDevice.device_id.""" |
353 | + properties = {} |
354 | + parser = SubmissionParser(self.log) |
355 | + device = HALDevice(1, '/some/udi/path', properties, parser) |
356 | + self.assertEqual( |
357 | + '/some/udi/path', device.device_id, |
358 | + 'Unexpected value of HALDevice.device_id') |
359 | + |
360 | + def testHALDevicePciClass(self): |
361 | + """Test of HALDevice.pci_class.""" |
362 | + properties = { |
363 | + 'pci.device_class': (1, 'int'), |
364 | + } |
365 | + parser = SubmissionParser(self.log) |
366 | + device = HALDevice(1, '/some/udi/path', properties, parser) |
367 | + self.assertEqual( |
368 | + 1, device.pci_class, |
369 | + 'Unexpected value of HALDevice.pci_class.') |
370 | + |
371 | + properties = {} |
372 | + parser = SubmissionParser(self.log) |
373 | + device = HALDevice(1, '/some/udi/path', properties, parser) |
374 | + self.assertEqual( |
375 | + None, device.pci_class, |
376 | + 'Unexpected value of HALDevice.pci_class for Non-PCI device.') |
377 | + |
378 | + def testHALDevicePciSubClass(self): |
379 | + """Test of HALDevice.pci_subclass.""" |
380 | + properties = { |
381 | + 'pci.device_subclass': (1, 'int'), |
382 | + } |
383 | + parser = SubmissionParser(self.log) |
384 | + device = HALDevice(1, '/some/udi/path', properties, parser) |
385 | + self.assertEqual( |
386 | + 1, device.pci_subclass, |
387 | + 'Unexpected value of HALDevice.pci_subclass.') |
388 | + |
389 | + properties = {} |
390 | + parser = SubmissionParser(self.log) |
391 | + device = HALDevice(1, '/some/udi/path', properties, parser) |
392 | + self.assertEqual( |
393 | + None, device.pci_subclass, |
394 | + 'Unexpected value of HALDevice.pci_sub_class for Non-PCI device.') |
395 | + |
396 | + def testHALDeviceUsbVendorId(self): |
397 | + """Test of HALDevice.usb_vendor_id.""" |
398 | + properties = { |
399 | + 'usb_device.vendor_id': (1, 'int'), |
400 | + } |
401 | + parser = SubmissionParser(self.log) |
402 | + device = HALDevice(1, '/some/udi/path', properties, parser) |
403 | + self.assertEqual( |
404 | + 1, device.usb_vendor_id, |
405 | + 'Unexpected value of HALDevice.usb_vendor_id.') |
406 | + |
407 | + properties = {} |
408 | + parser = SubmissionParser(self.log) |
409 | + device = HALDevice(1, '/some/udi/path', properties, parser) |
410 | + self.assertEqual( |
411 | + None, device.usb_vendor_id, |
412 | + 'Unexpected value of HALDevice.usb_vendor_id for Non-USB device.') |
413 | + |
414 | + def testHALDeviceUsbProductId(self): |
415 | + """Test of HALDevice.usb_product_id.""" |
416 | + properties = { |
417 | + 'usb_device.product_id': (1, 'int'), |
418 | + } |
419 | + parser = SubmissionParser(self.log) |
420 | + device = HALDevice(1, '/some/udi/path', properties, parser) |
421 | + self.assertEqual( |
422 | + 1, device.usb_product_id, |
423 | + 'Unexpected value of HALDevice.usb_product_id.') |
424 | + |
425 | + properties = {} |
426 | + parser = SubmissionParser(self.log) |
427 | + device = HALDevice(1, '/some/udi/path', properties, parser) |
428 | + self.assertEqual( |
429 | + None, device.usb_product_id, |
430 | + 'Unexpected value of HALDevice.usb_product_id for Non-USB ' |
431 | + 'device.') |
432 | + |
433 | def testHalDeviceRawBus(self): |
434 | """test of HALDevice.raw_bus.""" |
435 | properties = { |
This branch continues the refactoring of class HALDevice in l/c/l/scrpits/ hwdbsubmissons. py
(see https:/ /code.edge. launchpad. net/~adeuring/ launchpad/ hwdb-refactor- haldevice/ +merge/ 12669)
It moves the properties real_bus and is_real_device into the new base class BaseDevice. The latter property needs access to the USB vendor/product IDs, which were retrieved by the HAL-specific mmethod getProperty(). These calls are replaced by the new properties usb_vendor_id and usb_product_id.
test: ./bin/test -t test_hwdb_ submission_ processing
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: /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.
These complaints are caused by another, unrelated, branch that prepares the transition to Python 2.5
diff against the base branch (still in ec2test):
=== modified file 'lib/canonical/ launchpad/ scripts/ hwdbsubmissions .py' launchpad/ scripts/ hwdbsubmissions .py 2009-10-01 09:06:59 +0000 launchpad/ scripts/ hwdbsubmissions .py 2009-10-01 11:13:38 +0000 rror()
--- lib/canonical/
+++ lib/canonical/
@@ -1294,6 +1294,16 @@
"""
raise NotImplementedE
+ @property id(self) : rror() id(self) : rror() s(self) :
+ def usb_vendor_
+ """The USB vendor ID of the device or None for Non-USB devices."""
+ raise NotImplementedE
+
+ @property
+ def usb_product_
+ """The USB product ID of the device or None for Non-USB devices."""
+ raise NotImplementedE
+
def translateScsiBu
"""Return the real bus of a device where raw_bus=='scsi'.
@@ -1395,78 +1405,6 @@ rror()
"""Return the device bus as specified by HAL or udev."""
raise NotImplementedE
- BaseDevice) : _init__ (parser) [property_ name]
-class HALDevice(
- """The representation of a HAL device node."""
-
- def __init__(self, id, udi, properties, parser):
- """HALDevice constructor.
-
- :param id: The ID of the HAL device in the submission data as
- specified in <device id=...>.
- :type id: int
- :param udi: The UDI of the HAL device.
- :type udi: string
- :param properties: The HAL properties of the device.
- :type properties: dict
- :param parser: The parser processing a submission.
- :type parser: SubmissionParser
- """
- super(HALDevice, self)._
- self.id = id
- self.udi = udi
- self.properties = properties
-
- def getProperty(self, property_name):
- """Return the HAL property property_name.
-
- Note that there is no check of the property type.
- """
- if property_name not in self.properties:
- return None
- name, type_ = self.properties
- return name
-
- @p...