Merge lp:~adeuring/launchpad/bug-458029-kernel-package-name-for-udev-submissions into lp:launchpad
- bug-458029-kernel-package-name-for-udev-submissions
- Merge into devel
Proposed by
Abel Deuring
Status: | Merged |
---|---|
Approved by: | Muharem Hrnjadovic |
Approved revision: | no longer in the source branch. |
Merged at revision: | not available |
Proposed branch: | lp:~adeuring/launchpad/bug-458029-kernel-package-name-for-udev-submissions |
Merge into: | lp:launchpad |
Diff against target: |
429 lines 3 files modified
lib/canonical/launchpad/scripts/hwdbsubmissions.py (+22/-10) lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py (+3/-0) lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py (+194/-36) |
To merge this branch: | bzr merge lp:~adeuring/launchpad/bug-458029-kernel-package-name-for-udev-submissions |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Muharem Hrnjadovic (community) | Approve | ||
Review via email: mp+13781@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
Muharem Hrnjadovic (al-maisan) wrote : | # |
Hello Abel!
This looks good. Thanks!
review:
Approve
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-21 10:06:31 +0000 |
3 | +++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-22 11:50:26 +0000 |
4 | @@ -33,6 +33,7 @@ |
5 | |
6 | from canonical.lazr.xml import RelaxNGValidator |
7 | |
8 | +from canonical.cachedproperty import cachedproperty |
9 | from canonical.config import config |
10 | from canonical.librarian.interfaces import LibrarianServerError |
11 | from canonical.launchpad.interfaces.hwdb import ( |
12 | @@ -503,6 +504,7 @@ |
13 | devices = [] |
14 | device = None |
15 | line_number = 0 |
16 | + device_id = 0 |
17 | |
18 | for line_number, line in enumerate(udev_data): |
19 | if len(line) == 0: |
20 | @@ -518,9 +520,11 @@ |
21 | |
22 | key, value = record |
23 | if device is None: |
24 | + device_id += 1 |
25 | device = { |
26 | 'E': {}, |
27 | 'S': [], |
28 | + 'id': device_id, |
29 | } |
30 | devices.append(device) |
31 | # Some attribute lines have a space character after the |
32 | @@ -1467,15 +1471,20 @@ |
33 | del self.devices['/devices'] |
34 | return True |
35 | |
36 | - def getKernelPackageName(self): |
37 | - """Return the kernel package name of the submission,""" |
38 | - root_hal_device = self.devices[ROOT_UDI] |
39 | - kernel_version = root_hal_device.getProperty('system.kernel.version') |
40 | + @cachedproperty |
41 | + def kernel_package_name(self): |
42 | + """The kernel package name for the submission.""" |
43 | + if ROOT_UDI in self.devices: |
44 | + root_hal_device = self.devices[ROOT_UDI] |
45 | + kernel_version = root_hal_device.getProperty( |
46 | + 'system.kernel.version') |
47 | + else: |
48 | + kernel_version = self.parsed_data['summary'].get('kernel-release') |
49 | if kernel_version is None: |
50 | self._logWarning( |
51 | 'Submission does not provide property system.kernel.version ' |
52 | - 'for /org/freedesktop/Hal/devices/computer.', |
53 | - WARNING_NO_HAL_KERNEL_VERSION) |
54 | + 'for /org/freedesktop/Hal/devices/computer or a summary ' |
55 | + 'sub-node <kernel-release>.') |
56 | return None |
57 | kernel_package_name = 'linux-image-' + kernel_version |
58 | packages = self.parsed_data['software']['packages'] |
59 | @@ -1487,8 +1496,7 @@ |
60 | 'Inconsistent kernel version data: According to HAL the ' |
61 | 'kernel is %s, but the submission does not know about a ' |
62 | 'kernel package %s' |
63 | - % (kernel_version, kernel_package_name), |
64 | - WARNING_NO_HAL_KERNEL_VERSION) |
65 | + % (kernel_version, kernel_package_name)) |
66 | return None |
67 | return kernel_package_name |
68 | |
69 | @@ -2182,10 +2190,9 @@ |
70 | # drivers, so there is currently no need to search for |
71 | # for user space printer drivers, for example. |
72 | if self.driver_name is not None: |
73 | - kernel_package_name = self.parser.getKernelPackageName() |
74 | db_driver_set = getUtility(IHWDriverSet) |
75 | return db_driver_set.getOrCreate( |
76 | - kernel_package_name, self.driver_name) |
77 | + self.parser.kernel_package_name, self.driver_name) |
78 | else: |
79 | return None |
80 | |
81 | @@ -2776,6 +2783,11 @@ |
82 | return None |
83 | return controller |
84 | |
85 | + @property |
86 | + def id(self): |
87 | + return self.udev['id'] |
88 | + |
89 | + |
90 | class ProcessingLoop(object): |
91 | """An `ITunableLoop` for processing HWDB submissions.""" |
92 | |
93 | |
94 | === modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py' |
95 | --- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py 2009-10-12 14:50:22 +0000 |
96 | +++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py 2009-10-22 11:50:26 +0000 |
97 | @@ -635,6 +635,7 @@ |
98 | 'MODALIAS': 'acpi:LNXSYSTM:', |
99 | }, |
100 | 'S': [], |
101 | + 'id': 1, |
102 | }, |
103 | { |
104 | 'P': '/devices/pci0000:00/0000:00:1a.0', |
105 | @@ -643,6 +644,7 @@ |
106 | 'DEVPATH': '/devices/pci0000:00/0000:00:1a.0', |
107 | }, |
108 | 'S': ['char/189:256'], |
109 | + 'id': 2, |
110 | }, |
111 | ], |
112 | result, |
113 | @@ -704,6 +706,7 @@ |
114 | 'E': {}, |
115 | 'S': [], |
116 | 'W': '2', |
117 | + 'id': 1, |
118 | }, |
119 | ], |
120 | result, |
121 | |
122 | === modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py' |
123 | --- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-21 10:06:31 +0000 |
124 | +++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-22 11:50:26 +0000 |
125 | @@ -360,8 +360,8 @@ |
126 | self.assertErrorMessage( |
127 | parser.submission_key, "No udev root device defined") |
128 | |
129 | - def testKernelPackageName(self): |
130 | - """Test of SubmissionParser.getKernelPackageName. |
131 | + def test_kernel_package_name_hal_data(self): |
132 | + """Test of SubmissionParser.kernel_package_name. |
133 | |
134 | Regular case. |
135 | """ |
136 | @@ -388,17 +388,19 @@ |
137 | }, |
138 | } |
139 | parser.buildDeviceList(parser.parsed_data) |
140 | - kernel_package = parser.getKernelPackageName() |
141 | - self.assertEqual(kernel_package, self.KERNEL_PACKAGE, |
142 | - 'Unexpected result of SubmissionParser.getKernelPackageName. ' |
143 | + kernel_package = parser.kernel_package_name |
144 | + self.assertEqual( |
145 | + self.KERNEL_PACKAGE, kernel_package, |
146 | + 'Unexpected value of SubmissionParser.kernel_package_name. ' |
147 | 'Expected linux-image-2.6.24-19-generic, got %r' % kernel_package) |
148 | |
149 | - self.assertEqual(len(self.handler.records), 0, |
150 | + self.assertEqual( |
151 | + 0, len(self.handler.records), |
152 | 'One or more warning messages were logged by ' |
153 | - 'getKernelPackageName, where zero was expected.') |
154 | + 'SubmissionParser.kernel_package_name, where zero was expected.') |
155 | |
156 | - def testKernelPackageNameInconsistent(self): |
157 | - """Test of SubmissionParser.getKernelPackageName. |
158 | + def test_kernel_package_hal_data_name_inconsistent(self): |
159 | + """Test of SubmissionParser.kernel_package_name. |
160 | |
161 | Test a name inconsistency. |
162 | """ |
163 | @@ -426,24 +428,24 @@ |
164 | } |
165 | parser.submission_key = 'Test of inconsistent kernel package name' |
166 | parser.buildDeviceList(parser.parsed_data) |
167 | - kernel_package = parser.getKernelPackageName() |
168 | - self.assertEqual(kernel_package, None, |
169 | - 'Unexpected result of SubmissionParser.getKernelPackageName. ' |
170 | - 'Expected None, got %r' % kernel_package) |
171 | - self.assertWarningMessage(parser.submission_key, |
172 | + kernel_package = parser.kernel_package_name |
173 | + self.assertIs(None, kernel_package) |
174 | + self.assertWarningMessage( |
175 | + parser.submission_key, |
176 | 'Inconsistent kernel version data: According to HAL the ' |
177 | 'kernel is 2.6.24-19-generic, but the submission does not ' |
178 | 'know about a kernel package linux-image-2.6.24-19-generic') |
179 | # The warning appears only once per submission, even if the |
180 | - # SubmissionParser.getKernelPackageName is called more than once. |
181 | + # property kernel_package_name is accessed more than once. |
182 | num_warnings = len(self.handler.records) |
183 | - parser.getKernelPackageName() |
184 | - self.assertEqual(num_warnings, len(self.handler.records), |
185 | + test = parser.kernel_package_name |
186 | + self.assertEqual( |
187 | + num_warnings, len(self.handler.records), |
188 | 'Warning for missing HAL property system.kernel.version ' |
189 | 'repeated.') |
190 | |
191 | - def testKernelPackageNameNoHALData(self): |
192 | - """Test of SubmissionParser.getKernelPackageName. |
193 | + def test_kernel_package_name_hal_data_no_kernel_version_in_hal_data(self): |
194 | + """Test of SubmissionParser.kernel_package_name. |
195 | |
196 | Test without HAL property system.kernel.version. |
197 | """ |
198 | @@ -469,26 +471,28 @@ |
199 | } |
200 | parser.submission_key = 'Test: missing property system.kernel.version' |
201 | parser.buildDeviceList(parser.parsed_data) |
202 | - kernel_package = parser.getKernelPackageName() |
203 | - self.assertEqual(kernel_package, None, |
204 | - 'Unexpected result of SubmissionParser.getKernelPackageName. ' |
205 | - 'Expected None, got %r' % kernel_package) |
206 | - self.assertWarningMessage(parser.submission_key, |
207 | + self.assertIs(None, parser.kernel_package_name) |
208 | + self.assertWarningMessage( |
209 | + parser.submission_key, |
210 | 'Submission does not provide property system.kernel.version ' |
211 | - 'for /org/freedesktop/Hal/devices/computer.') |
212 | + 'for /org/freedesktop/Hal/devices/computer or a summary ' |
213 | + 'sub-node <kernel-release>.') |
214 | # The warning appears only once per submission, even if the |
215 | - # SubmissionParser.getKernelPackageName is called more than once. |
216 | + # property kernel_package_name is accessed more than once. |
217 | num_warnings = len(self.handler.records) |
218 | - parser.getKernelPackageName() |
219 | - self.assertEqual(num_warnings, len(self.handler.records), |
220 | + test = parser.kernel_package_name |
221 | + self.assertEqual( |
222 | + num_warnings, len(self.handler.records), |
223 | 'Warning for missing HAL property system.kernel.version ' |
224 | 'repeated.') |
225 | |
226 | - def testKernelPackageNameNoPackageData(self): |
227 | - """Test of SubmissionParser.getKernelPackageName. |
228 | + def test_kernel_package_name_hal_data_no_package_data(self): |
229 | + """Test of SubmissionParser.kernel_package_name. |
230 | |
231 | - Test without any package data. getKernelPackageName returns |
232 | - the property system.kernel.version without any further checking. |
233 | + Test without any package data. In this case, |
234 | + SubmissionParser.kernel_package_name is the value of the property |
235 | + system.kernel.version if the root HAL device. No further checks |
236 | + are done. |
237 | """ |
238 | parser = SubmissionParser(self.log) |
239 | devices = [ |
240 | @@ -512,8 +516,156 @@ |
241 | } |
242 | parser.submission_key = 'Test: missing property system.kernel.version' |
243 | parser.buildDeviceList(parser.parsed_data) |
244 | - kernel_package = parser.getKernelPackageName() |
245 | - self.assertEqual(kernel_package, self.KERNEL_PACKAGE, |
246 | + kernel_package = parser.kernel_package_name |
247 | + self.assertEqual( |
248 | + self.KERNEL_PACKAGE, kernel_package, |
249 | + 'Unexpected result of SubmissionParser.getKernelPackageName, ' |
250 | + 'test without any package data. Expected None, got %r' |
251 | + % kernel_package) |
252 | + |
253 | + def test_kernel_package_name_udev_data(self): |
254 | + """Test of SubmissionParser.kernel_package_name for udev data. |
255 | + |
256 | + Variant for udev data, regular case. |
257 | + """ |
258 | + parser = SubmissionParser(self.log) |
259 | + parser.parsed_data = { |
260 | + 'hardware': { |
261 | + 'udev': [ |
262 | + {'P': '/devices/LNXSYSTM:00'} |
263 | + ], |
264 | + 'sysfs-attributes': {}, |
265 | + 'dmi': {}, |
266 | + }, |
267 | + 'software': { |
268 | + 'packages': { |
269 | + self.KERNEL_PACKAGE: {}, |
270 | + }, |
271 | + }, |
272 | + 'summary': { |
273 | + 'kernel-release': self.KERNEL_VERSION, |
274 | + }, |
275 | + } |
276 | + parser.buildDeviceList(parser.parsed_data) |
277 | + kernel_package = parser.kernel_package_name |
278 | + self.assertEqual( |
279 | + self.KERNEL_PACKAGE, kernel_package, |
280 | + 'Unexpected value of SubmissionParser.kernel_package_name. ' |
281 | + 'Expected linux-image-2.6.24-19-generic, got %r' % kernel_package) |
282 | + |
283 | + self.assertEqual( |
284 | + 0, len(self.handler.records), |
285 | + 'One or more warning messages were logged by ' |
286 | + 'SubmissionParser.kernel_package_name, where zero was expected.') |
287 | + |
288 | + def test_kernel_package_udev_data_name_inconsistent(self): |
289 | + """Test of SubmissionParser.kernel_package_name. |
290 | + |
291 | + Variant for udev data, name inconsistency. |
292 | + """ |
293 | + parser = SubmissionParser(self.log) |
294 | + parser.parsed_data = { |
295 | + 'hardware': { |
296 | + 'udev': [ |
297 | + {'P': '/devices/LNXSYSTM:00'} |
298 | + ], |
299 | + 'sysfs-attributes': {}, |
300 | + 'dmi': {}, |
301 | + }, |
302 | + 'software': { |
303 | + 'packages': { |
304 | + 'linux-image-from-obscure-external-source': {}, |
305 | + }, |
306 | + }, |
307 | + 'summary': { |
308 | + 'kernel-release': self.KERNEL_VERSION, |
309 | + }, |
310 | + } |
311 | + parser.submission_key = 'Test of inconsistent kernel package name' |
312 | + parser.buildDeviceList(parser.parsed_data) |
313 | + kernel_package = parser.kernel_package_name |
314 | + self.assertIs(None, kernel_package) |
315 | + self.assertWarningMessage( |
316 | + parser.submission_key, |
317 | + 'Inconsistent kernel version data: According to HAL the ' |
318 | + 'kernel is 2.6.24-19-generic, but the submission does not ' |
319 | + 'know about a kernel package linux-image-2.6.24-19-generic') |
320 | + # The warning appears only once per submission, even if the |
321 | + # property kernel_package_name is accessed more than once. |
322 | + num_warnings = len(self.handler.records) |
323 | + test = parser.kernel_package_name |
324 | + self.assertEqual( |
325 | + num_warnings, len(self.handler.records), |
326 | + 'Warning for missing HAL property system.kernel.version ' |
327 | + 'repeated.') |
328 | + |
329 | + def test_kernel_package_name_udev_data_no_kernel_version_in_summary(self): |
330 | + """Test of SubmissionParser.kernel_package_name. |
331 | + |
332 | + Test without the summary sub-node <kernel-release>. |
333 | + """ |
334 | + parser = SubmissionParser(self.log) |
335 | + parser.parsed_data = { |
336 | + 'hardware': { |
337 | + 'udev': [ |
338 | + {'P': '/devices/LNXSYSTM:00'} |
339 | + ], |
340 | + 'sysfs-attributes': {}, |
341 | + 'dmi': {}, |
342 | + }, |
343 | + 'software': { |
344 | + 'packages': { |
345 | + self.KERNEL_PACKAGE: {}, |
346 | + }, |
347 | + }, |
348 | + 'summary': {}, |
349 | + } |
350 | + parser.submission_key = 'Test: missing property system.kernel.version' |
351 | + parser.buildDeviceList(parser.parsed_data) |
352 | + self.assertIs(None, parser.kernel_package_name) |
353 | + self.assertWarningMessage( |
354 | + parser.submission_key, |
355 | + 'Submission does not provide property system.kernel.version ' |
356 | + 'for /org/freedesktop/Hal/devices/computer or a summary ' |
357 | + 'sub-node <kernel-release>.') |
358 | + # The warning appears only once per submission, even if the |
359 | + # property kernel_package_name is accessed more than once. |
360 | + num_warnings = len(self.handler.records) |
361 | + test = parser.kernel_package_name |
362 | + self.assertEqual( |
363 | + num_warnings, len(self.handler.records), |
364 | + 'Warning for missing HAL property system.kernel.version ' |
365 | + 'repeated.') |
366 | + |
367 | + def test_kernel_package_name_udev_data_no_package_data(self): |
368 | + """Test of SubmissionParser.kernel_package_name. |
369 | + |
370 | + Variant for udev data, test without any package data. In this case, |
371 | + SubmissionParser.kernel_package_name is the value of the property |
372 | + system.kernel.version if the root HAL device. No further checks |
373 | + are done. |
374 | + """ |
375 | + parser = SubmissionParser(self.log) |
376 | + parser.parsed_data = { |
377 | + 'hardware': { |
378 | + 'udev': [ |
379 | + {'P': '/devices/LNXSYSTM:00'}, |
380 | + ], |
381 | + 'sysfs-attributes': {}, |
382 | + 'dmi': {}, |
383 | + }, |
384 | + 'software': { |
385 | + 'packages': {}, |
386 | + }, |
387 | + 'summary': { |
388 | + 'kernel-release': self.KERNEL_VERSION, |
389 | + }, |
390 | + } |
391 | + parser.submission_key = 'Test: missing property system.kernel.version' |
392 | + parser.buildDeviceList(parser.parsed_data) |
393 | + kernel_package = parser.kernel_package_name |
394 | + self.assertEqual( |
395 | + self.KERNEL_PACKAGE, kernel_package, |
396 | 'Unexpected result of SubmissionParser.getKernelPackageName, ' |
397 | 'test without any package data. Expected None, got %r' |
398 | % kernel_package) |
399 | @@ -3036,7 +3188,8 @@ |
400 | 'DEVPATH': '/devices/LNXSYSTM:00', |
401 | 'MODALIAS': 'acpi:LNXSYSTM:', |
402 | 'SUBSYSTEM': 'acpi', |
403 | - } |
404 | + }, |
405 | + 'id': 1, |
406 | } |
407 | |
408 | self.root_device_dmi_data = { |
409 | @@ -3520,7 +3673,7 @@ |
410 | }, |
411 | } |
412 | |
413 | - def test_device_id(self): |
414 | + def test_device_device_id(self): |
415 | """Test of UdevDevice.device_id.""" |
416 | device = UdevDevice(None, self.pci_sata_controller) |
417 | self.assertEqual( |
418 | @@ -4185,6 +4338,11 @@ |
419 | 'provide bus, vendor ID, product ID or product name: None None ' |
420 | 'None None /devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0') |
421 | |
422 | + def test_device_id(self): |
423 | + """Each UdevDevice has a property 'id'.""" |
424 | + device = UdevDevice(None, self.root_device) |
425 | + self.assertEqual(1, device.id) |
426 | + |
427 | |
428 | class TestHWDBSubmissionTablePopulation(TestCaseHWDB): |
429 | """Tests of the HWDB popoluation with submitted data.""" |
This branch changes the method SubmissionParse r.getKernelPack ageName( ) into a property and makes it "aware" of submissions containig udev data instaed of HAL data.
One detail of the data about a device we store in the HWDB is a driver used to control a given device and the deb package of this driver. For kernel drivers, the package name is 'linux- image'+ <kernel- version> .
Most submissions have two sources for the kernel version and the package name:
- The submitted data may contain the set of installed packages kernel. version' ; submissions with udev data have an XML node <summary> <kernel- release>
- Submissions with HAL data, the root HAL device has a property 'system.
Two source for this data mean that sone inconcistencies are possible; the method/proerty has some checks for these inconsistencies.
A problem with early versions of the processing was that getKernelPackag eName is called for nearly each device of a submission (typically more 50), which led to a log file cluttered with 50 or more identical warnings, if there was a name inconsistency.
In a later version of the script, I introduced the optional parameter warning_id, which allow to suppress the repeated logging of warning with the same ID. The tests of getKernelPackag eName/kernel_ package_ name ensure that a warning appears only once, even if the method/property is used more than once.
We have the nice feature of cached properties, so I declared the property as cachable, allowing to omit the warning_id parameter from the _logWarning call, and having the additional benefit of being a bit faster.
This branch is based on the reviewed but not yet merged branch lp:~adeuring/launchpad/bug-457475-udev-device-id; a diff of the changes in this branch is below.
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.
These complaints are not related to my changes.
=== modified file 'lib/canonical/ launchpad/ scripts/ hwdbsubmissions .py' launchpad/ scripts/ hwdbsubmissions .py 2009-10-21 16:49:03 +0000 launchpad/ scripts/ hwdbsubmissions .py 2009-10-22 11:04:03 +0000
--- lib/canonical/
+++ lib/canonical/
@@ -33,6 +33,7 @@
from canonical.lazr.xml import RelaxNGValidator
+from canonical. cachedproperty import cachedproperty librarian. interfaces import LibrarianServer Error launchpad. interfaces. hwdb import ( '/devices' ]
from canonical.config import config
from canonical.
from canonical.
@@ -1470,15 +1471,20 @@
del self.devices[
return True
- def getKernelPackag eName(self) : ROOT_UDI]
- """Return the kernel package name of the submission,"""
- root_hal_device = self.devices[
- kern...