Merge lp:~adeuring/launchpad/hwdb-refactor-haldevice-2 into lp:launchpad

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
Reviewer Review Type Date Requested Status
Michael Nelson (community) code Approve
Review via email: mp+12713@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote :
Download full text (11.1 KiB)

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:
  lib/canonical/launchpad/scripts/hwdbsubmissions.py
  lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py

== Pyflakes notices ==

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

== Pylint notices ==

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

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'
--- lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-01 09:06:59 +0000
+++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-01 11:13:38 +0000
@@ -1294,6 +1294,16 @@
         """
         raise NotImplementedError()

+ @property
+ def usb_vendor_id(self):
+ """The USB vendor ID of the device or None for Non-USB devices."""
+ raise NotImplementedError()
+
+ @property
+ def usb_product_id(self):
+ """The USB product ID of the device or None for Non-USB devices."""
+ raise NotImplementedError()
+
     def translateScsiBus(self):
         """Return the real bus of a device where raw_bus=='scsi'.

@@ -1395,78 +1405,6 @@
         """Return the device bus as specified by HAL or udev."""
         raise NotImplementedError()

-
-class HALDevice(BaseDevice):
- """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).__init__(parser)
- 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[property_name]
- return name
-
- @p...

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 = {