Merge lp:~adeuring/launchpad/bug-438169-parse-sysfs-attr into lp:launchpad/db-devel

Proposed by Abel Deuring
Status: Merged
Approved by: Graham Binns
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~adeuring/launchpad/bug-438169-parse-sysfs-attr
Merge into: lp:launchpad/db-devel
Diff against target: 569 lines
8 files modified
lib/canonical/launchpad/database/__init__.py (+0/-2)
lib/canonical/launchpad/doc/hwdb-device-tables.txt (+1/-1)
lib/canonical/launchpad/scripts/hwdbsubmissions.py (+77/-0)
lib/canonical/launchpad/scripts/tests/hardwaretest-udev.xml (+13/-4)
lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py (+164/-0)
lib/canonical/launchpad/zcml/hwdb.zcml (+23/-23)
lib/canonical/launchpad/zcml/launchpadstatistic.zcml (+3/-3)
lib/lp/code/model/tests/test_branchjob.py (+19/-0)
To merge this branch: bzr merge lp:~adeuring/launchpad/bug-438169-parse-sysfs-attr
Reviewer Review Type Date Requested Status
Graham Binns (community) Approve
Review via email: mp+12581@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote :

This branch adds a method _parseSysfsAttributes to the class SubmisisonParser.

The HWDB client in Karmic will no longer submit data from HAL; instead the data will come from udev, the content from some sysfs files etc. The new method parses the content from the new XML node <sysfs-attributes>.

Additonially I changed the content of the sample submission file l/c/l/scripts/tests/hardwaretest-udev.xml to reflect the real content sent by the HWDB client.

test: ./bin/test -t test_hwdb_submission_parser

= 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/hardwaretest-udev.xml
  lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py

== Pyflakes notices ==

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

lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py
    10: redefinition of unused 'etree' from line 8

== Pylint notices ==

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

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

These messages are not related to the new methods.

Revision history for this message
Graham Binns (gmb) wrote :

I'm happy for this to land with the following changes:

 - Use dedent() in the tests to prevent ugly alignment issues.
 - Clean up the leading braces of the dicts in the assertEqual() call as discussed on IRC.

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/database/__init__.py'
2--- lib/canonical/launchpad/database/__init__.py 2009-08-27 07:05:16 +0000
3+++ lib/canonical/launchpad/database/__init__.py 2009-09-29 11:33:15 +0000
4@@ -58,7 +58,6 @@
5 from canonical.launchpad.database.personnotification import *
6 from canonical.launchpad.database.packaging import *
7 from canonical.launchpad.database.librarian import *
8-from canonical.launchpad.database.launchpadstatistic import *
9 from canonical.launchpad.database.binaryandsourcepackagename import *
10 from canonical.launchpad.database.message import *
11 from canonical.launchpad.database.structuralsubscription import *
12@@ -66,4 +65,3 @@
13 from canonical.launchpad.database.temporaryblobstorage import *
14 from canonical.launchpad.database.emailaddress import *
15 from canonical.launchpad.database.oauth import *
16-from canonical.launchpad.database.hwdb import *
17
18=== modified file 'lib/canonical/launchpad/doc/hwdb-device-tables.txt'
19--- lib/canonical/launchpad/doc/hwdb-device-tables.txt 2009-08-14 13:03:36 +0000
20+++ lib/canonical/launchpad/doc/hwdb-device-tables.txt 2009-09-29 11:33:15 +0000
21@@ -1486,7 +1486,7 @@
22 names. Note that the package name value None (used in older submissions)
23 is not included.
24
25- >>> from canonical.launchpad.database import HWDriver
26+ >>> from canonical.launchpad.database.hwdb import HWDriver
27 >>> store.add(HWDriver(name='foo', package_name=None))
28 <HWDriver at...
29 >>> for package_name in driver_set.all_package_names():
30
31=== modified file 'lib/canonical/launchpad/scripts/hwdbsubmissions.py'
32--- lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-09-28 11:33:57 +0000
33+++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-09-29 11:33:15 +0000
34@@ -556,6 +556,82 @@
35 dmi_data[record[0]] = record[1]
36 return dmi_data
37
38+ def _parseSysfsAttributes(self, sysfs_node):
39+ """Parse the <sysfs-attributes> node.
40+
41+ :return: A dictionary {path: attrs, ...} where path is the
42+ path is the path of a sysfs directory, and where attrs
43+ is a dictionary containing attribute names and values.
44+
45+ A sample of the input data:
46+
47+ P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
48+ A: modalias=input:b0019v0000p0001e0000-e0,1,k74,ramlsfw
49+ A: uniq=
50+ A: phys=LNXPWRBN/button/input0
51+ A: name=Power Button
52+
53+ P: /devices/LNXSYSTM:00/device:00/PNP0A08:00/device:03/input/input8
54+ A: modalias=input:b0019v0000p0006e0000-e0,1,kE0,E1,E3,F0,F1
55+ A: uniq=
56+ A: phys=/video/input0
57+ A: name=Video Bus
58+
59+ Data for different devices is separated by empty lines. The data
60+ for each device starts with a line 'P: /devices/LNXSYSTM...',
61+ specifying the sysfs path of a device, followed by zero or more
62+ lines of the form 'A: key=value'
63+ """
64+ sysfs_lines = sysfs_node.text.split('\n')
65+ sysfs_data = {}
66+ attributes = None
67+
68+ for line_number, line in enumerate(sysfs_lines):
69+ if len(line) == 0:
70+ attributes = None
71+ continue
72+ record = line.split(': ', 1)
73+ if len(record) != 2:
74+ self._logError(
75+ 'Line %i in <sysfs-attributes>: No valid key:value data: '
76+ '%r' % (line_number, line),
77+ self.submission_key)
78+ return None
79+
80+ key, value = record
81+ if key == 'P':
82+ if attributes is not None:
83+ self._logError(
84+ "Line %i in <sysfs-attributes>: duplicate 'P' line "
85+ "found: %r" % (line_number, line),
86+ self.submission_key)
87+ return None
88+ attributes = {}
89+ sysfs_data[value] = attributes
90+ elif key == 'A':
91+ if attributes is None:
92+ self._logError(
93+ "Line %i in <sysfs-attributes>: Block for a device "
94+ "does not start with 'P:': %r" % (line_number, line),
95+ self.submission_key)
96+ return None
97+ attribute_data = value.split('=', 1)
98+ if len(attribute_data) != 2:
99+ self._logError(
100+ 'Line %i in <sysfs-attributes>: Attribute line does '
101+ 'not contain key=value data: %r'
102+ % (line_number, line),
103+ self.submission_key)
104+ return None
105+ attributes[attribute_data[0]] = attribute_data[1]
106+ else:
107+ self._logError(
108+ 'Line %i in <sysfs-attributes>: Unexpected key: %r'
109+ % (line_number, line),
110+ self.submission_key)
111+ return None
112+ return sysfs_data
113+
114 def _setHardwareSectionParsers(self):
115 self._parse_hardware_section = {
116 'hal': self._parseHAL,
117@@ -563,6 +639,7 @@
118 'aliases': self._parseAliases,
119 'udev': self._parseUdev,
120 'dmi': self._parseDmi,
121+ 'sysfs-attributes': self._parseSysfsAttributes,
122 }
123
124 def _parseHardware(self, hardware_node):
125
126=== modified file 'lib/canonical/launchpad/scripts/tests/hardwaretest-udev.xml'
127--- lib/canonical/launchpad/scripts/tests/hardwaretest-udev.xml 2009-09-14 09:16:45 +0000
128+++ lib/canonical/launchpad/scripts/tests/hardwaretest-udev.xml 2009-09-29 11:33:15 +0000
129@@ -184,10 +184,19 @@
130 is stored in the same format as the DMI data:
131 /path/to/file:filecontent
132 -->
133- <sysfs-attributes>/sys/devices/pci0000:00/0000:00:1f.1/host3/target3:0:0/3:0:0:0/vendor:HL-DT-ST
134-/sys/devices/pci0000:00/0000:00:1f.1/host3/target3:0:0/3:0:0:0/model:DVDRAM GSA-4083N
135-/sys/devices/pci0000:00/0000:00:1f.1/host3/target3:0:0/3:0:0:0/type:5
136- </sysfs-attributes>
137+ <sysfs-attributes>
138+P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
139+A: modalias=input:b0019v0000p0001e0000-e0,1,k74,ramlsfw
140+A: uniq=
141+A: phys=LNXPWRBN/button/input0
142+A: name=Power Button
143+
144+P: /devices/LNXSYSTM:00/device:00/PNP0A08:00/device:03/input/input8
145+A: modalias=input:b0019v0000p0006e0000-e0,1,kE0,E1,E3,F0,F1,F2,F3,F4,F5,ramlsfw
146+A: uniq=
147+A: phys=/video/input0
148+A: name=Video Bus
149+</sysfs-attributes>
150
151 <!-- processors: Data about processors installed in a system.
152 The data is retrieved from /proc/cpuinfo.
153
154=== modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py'
155--- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py 2009-09-28 12:35:40 +0000
156+++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py 2009-09-29 11:33:15 +0000
157@@ -11,6 +11,7 @@
158 from datetime import datetime
159 import logging
160 import os
161+from textwrap import dedent
162 from unittest import TestCase, TestLoader
163
164 import pytz
165@@ -649,6 +650,169 @@
166 parser.submission_key,
167 "Line 1 in <dmi>: No valid key:value data: 'invalid line'")
168
169+ def testSysfsAttributes(self):
170+ """Test of SubmissionParser._parseSysfsAttributes().
171+
172+ The content of the <sys-attributes> node is converted into
173+ a dictionary.
174+ """
175+ parser = SubmissionParser(self.log)
176+ node = etree.fromstring(dedent("""
177+ <sysfs-attributes>
178+ P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
179+ A: modalias=input:b0019v0000p0001e0000-e0,1,k74
180+ A: uniq=
181+ A: phys=LNXPWRBN/button/input0
182+ A: name=Power Button
183+
184+ P: /devices/LNXSYSTM:00/device:00/PNP0A08:00/device:03
185+ A: uniq=
186+ A: phys=/video/input0
187+ A: name=Video Bus
188+ </sysfs-attributes>
189+ """))
190+ result = parser._parseSysfsAttributes(node)
191+ self.assertEqual(
192+ {
193+ '/devices/LNXSYSTM:00/LNXPWRBN:00/input/input0': {
194+ 'modalias': 'input:b0019v0000p0001e0000-e0,1,k74',
195+ 'uniq': '',
196+ 'phys': 'LNXPWRBN/button/input0',
197+ 'name': 'Power Button',
198+ },
199+ '/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:03': {
200+ 'uniq': '',
201+ 'phys': '/video/input0',
202+ 'name': 'Video Bus',
203+ },
204+
205+ },
206+ result,
207+ 'Invalid parsing result of <sysfs-attributes> node.')
208+
209+ def testSysfsAttributesLineWithoutKeyValueData(self):
210+ """Test of SubmissionParser._parseSysfsAttributes().
211+
212+ Lines not in key: value format are rejected.
213+ """
214+ parser = SubmissionParser(self.log)
215+ parser.submission_key = (
216+ 'Detect <sysfs-attributes> lines not in key:value format')
217+ node = etree.fromstring(dedent("""
218+ <sysfs-attributes>
219+ P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
220+ A: modalias=input:b0019v0000p0001e0000-e0,1,k74
221+ invalid line
222+ </sysfs-attributes>
223+ """))
224+ result = parser._parseSysfsAttributes(node)
225+ self.assertEqual(
226+ None, result,
227+ 'Invalid parsing result of a <sysfs-attributes> node containing '
228+ 'a line not in key:value format.')
229+ self.assertErrorMessage(
230+ parser.submission_key,
231+ "Line 3 in <sysfs-attributes>: No valid key:value data: "
232+ "'invalid line'")
233+
234+ def testSysfsAttributesDuplicatePLine(self):
235+ """Test of SubmissionParser._parseSysfsAttributes().
236+
237+ A line starting with "P:" must be the first line of a device block.
238+ """
239+ parser = SubmissionParser(self.log)
240+ parser.submission_key = (
241+ 'Detect <sysfs-attributes> node with duplicate P: line')
242+ node = etree.fromstring(dedent("""
243+ <sysfs-attributes>
244+ P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
245+ A: modalias=input:b0019v0000p0001e0000-e0,1,k74
246+ P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
247+ </sysfs-attributes>
248+ """))
249+ result = parser._parseSysfsAttributes(node)
250+ self.assertEqual(
251+ None, result,
252+ 'Invalid parsing result of a <sysfs-attributes> node containing '
253+ 'a duplicate P: line.')
254+ self.assertErrorMessage(
255+ parser.submission_key,
256+ "Line 3 in <sysfs-attributes>: duplicate 'P' line found: "
257+ "'P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0'")
258+
259+ def testSysfsAttributesNoPLineAtDeviceStart(self):
260+ """Test of SubmissionParser._parseSysfsAttributes().
261+
262+ The data for a device must start with a "P:" line.
263+ """
264+ parser = SubmissionParser(self.log)
265+ parser.submission_key = (
266+ 'Detect <sysfs-attributes> node without leading P: line')
267+ node = etree.fromstring(dedent("""
268+ <sysfs-attributes>
269+ A: modalias=input:b0019v0000p0001e0000-e0,1,k74
270+ </sysfs-attributes>
271+ """))
272+ result = parser._parseSysfsAttributes(node)
273+ self.assertEqual(
274+ None, result,
275+ 'Invalid parsing result of a <sysfs-attributes> node where a '
276+ 'device block does not start with a "P": line.')
277+ self.assertErrorMessage(
278+ parser.submission_key,
279+ "Line 1 in <sysfs-attributes>: Block for a device does not "
280+ "start with 'P:': "
281+ "'A: modalias=input:b0019v0000p0001e0000-e0,1,k74'")
282+
283+ def testSysfsAttributesNoAttributeKeyValue(self):
284+ """Test of SubmissionParser._parseSysfsAttributes().
285+
286+ A line starting with "A:" must be in key=value format.
287+ """
288+ parser = SubmissionParser(self.log)
289+ parser.submission_key = (
290+ 'Detect <sysfs-attributes> node with A: line not in key=value '
291+ 'format')
292+ node = etree.fromstring(dedent("""
293+ <sysfs-attributes>
294+ P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
295+ A: equal sign is missing
296+ </sysfs-attributes>
297+ """))
298+ result = parser._parseSysfsAttributes(node)
299+ self.assertEqual(
300+ None, result,
301+ 'Invalid parsing result of a <sysfs-attributes> node with A: '
302+ 'line not in key=value format.')
303+ self.assertErrorMessage(
304+ parser.submission_key,
305+ "Line 2 in <sysfs-attributes>: Attribute line does not contain "
306+ "key=value data: 'A: equal sign is missing'")
307+
308+ def testSysfsAttributesInvalidMainKey(self):
309+ """Test of SubmissionParser._parseSysfsAttributes().
310+
311+ All lines must start with "P:" or "A:".
312+ """
313+ parser = SubmissionParser(self.log)
314+ parser.submission_key = (
315+ 'Detect <sysfs-attributes> node with invalid main key.')
316+ node = etree.fromstring(dedent("""
317+ <sysfs-attributes>
318+ P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
319+ X: an invalid line
320+ </sysfs-attributes>
321+ """))
322+ result = parser._parseSysfsAttributes(node)
323+ self.assertEqual(
324+ None, result,
325+ 'Invalid parsing result of a <sysfs-attributes> node containg '
326+ 'a line that does not start with "A:" or "P:".')
327+ self.assertErrorMessage(
328+ parser.submission_key,
329+ "Line 2 in <sysfs-attributes>: Unexpected key: "
330+ "'X: an invalid line'")
331+
332 def testHardware(self):
333 """The <hardware> tag is converted into a dictionary."""
334 test = self
335
336=== modified file 'lib/canonical/launchpad/zcml/hwdb.zcml'
337--- lib/canonical/launchpad/zcml/hwdb.zcml 2009-08-14 13:03:36 +0000
338+++ lib/canonical/launchpad/zcml/hwdb.zcml 2009-09-29 11:33:15 +0000
339@@ -44,7 +44,7 @@
340 template="../templates/hwdb-submit-hardware-data.pt"
341 />
342
343- <class class="canonical.launchpad.database.HWSubmission">
344+ <class class="canonical.launchpad.database.hwdb.HWSubmission">
345 <require
346 permission="launchpad.View"
347 interface="canonical.launchpad.interfaces.IHWSubmission"
348@@ -78,18 +78,18 @@
349 />
350
351 <securedutility
352- class="canonical.launchpad.database.HWSubmissionSet"
353+ class="canonical.launchpad.database.hwdb.HWSubmissionSet"
354 provides="canonical.launchpad.interfaces.IHWSubmissionSet">
355 <allow interface="canonical.launchpad.interfaces.IHWSubmissionSet" />
356 </securedutility>
357
358- <class class="canonical.launchpad.database.HWSystemFingerprint">
359+ <class class="canonical.launchpad.database.hwdb.HWSystemFingerprint">
360 <allow
361 interface="canonical.launchpad.interfaces.IHWSystemFingerprint" />
362 </class>
363
364 <securedutility
365- class="canonical.launchpad.database.HWSystemFingerprintSet"
366+ class="canonical.launchpad.database.hwdb.HWSystemFingerprintSet"
367 provides="canonical.launchpad.interfaces.IHWSystemFingerprintSet">
368 <allow
369 interface="canonical.launchpad.interfaces.IHWSystemFingerprintSet" />
370@@ -109,18 +109,18 @@
371 <allow attributes="__call__" />
372 </class>
373
374- <class class="canonical.launchpad.database.HWVendorName">
375+ <class class="canonical.launchpad.database.hwdb.HWVendorName">
376 <allow interface="canonical.launchpad.interfaces.IHWVendorName" />
377 <allow attributes="id" />
378 </class>
379
380 <securedutility
381- class="canonical.launchpad.database.HWVendorNameSet"
382+ class="canonical.launchpad.database.hwdb.HWVendorNameSet"
383 provides="canonical.launchpad.interfaces.IHWVendorNameSet">
384 <allow interface="canonical.launchpad.interfaces.IHWVendorNameSet" />
385 </securedutility>
386
387- <class class="canonical.launchpad.database.HWVendorID">
388+ <class class="canonical.launchpad.database.hwdb.HWVendorID">
389 <require
390 permission="launchpad.View"
391 interface="canonical.launchpad.interfaces.IHWVendorID" />
392@@ -133,12 +133,12 @@
393 />
394
395 <securedutility
396- class="canonical.launchpad.database.HWVendorIDSet"
397+ class="canonical.launchpad.database.hwdb.HWVendorIDSet"
398 provides="canonical.launchpad.interfaces.IHWVendorIDSet">
399 <allow interface="canonical.launchpad.interfaces.IHWVendorIDSet" />
400 </securedutility>
401
402- <class class="canonical.launchpad.database.HWDevice">
403+ <class class="canonical.launchpad.database.hwdb.HWDevice">
404 <require
405 permission="launchpad.View"
406 interface="canonical.launchpad.interfaces.IHWDevice" />
407@@ -151,24 +151,24 @@
408 />
409
410 <securedutility
411- class="canonical.launchpad.database.HWDeviceSet"
412+ class="canonical.launchpad.database.hwdb.HWDeviceSet"
413 provides="canonical.launchpad.interfaces.IHWDeviceSet">
414 <allow interface="canonical.launchpad.interfaces.IHWDeviceSet" />
415 </securedutility>
416
417- <class class="canonical.launchpad.database.HWDeviceNameVariant">
418+ <class class="canonical.launchpad.database.hwdb.HWDeviceNameVariant">
419 <allow interface=
420 "canonical.launchpad.interfaces.IHWDeviceNameVariant" />
421 </class>
422
423 <securedutility
424- class="canonical.launchpad.database.HWDeviceNameVariantSet"
425+ class="canonical.launchpad.database.hwdb.HWDeviceNameVariantSet"
426 provides="canonical.launchpad.interfaces.IHWDeviceNameVariantSet">
427 <allow interface=
428 "canonical.launchpad.interfaces.IHWDeviceNameVariantSet" />
429 </securedutility>
430
431- <class class="canonical.launchpad.database.HWDriver">
432+ <class class="canonical.launchpad.database.hwdb.HWDriver">
433 <require
434 permission="launchpad.View"
435 interface="canonical.launchpad.interfaces.IHWDriver" />
436@@ -181,13 +181,13 @@
437 />
438
439 <securedutility
440- class="canonical.launchpad.database.HWDriverSet"
441+ class="canonical.launchpad.database.hwdb.HWDriverSet"
442 provides="canonical.launchpad.interfaces.IHWDriverSet">
443 <allow
444 interface="canonical.launchpad.interfaces.IHWDriverSet" />
445 </securedutility>
446
447- <class class="canonical.launchpad.database.HWDriverName">
448+ <class class="canonical.launchpad.database.hwdb.HWDriverName">
449 <require
450 permission="launchpad.View"
451 interface="canonical.launchpad.interfaces.IHWDriverName" />
452@@ -199,7 +199,7 @@
453 parent_utility="canonical.launchpad.interfaces.IHWDBApplication"
454 />
455
456- <class class="canonical.launchpad.database.HWDriverPackageName">
457+ <class class="canonical.launchpad.database.hwdb.HWDriverPackageName">
458 <require
459 permission="launchpad.View"
460 interface="canonical.launchpad.interfaces.IHWDriverPackageName" />
461@@ -211,20 +211,20 @@
462 parent_utility="canonical.launchpad.interfaces.IHWDBApplication"
463 />
464
465- <class class="canonical.launchpad.database.HWDeviceDriverLink">
466+ <class class="canonical.launchpad.database.hwdb.HWDeviceDriverLink">
467 <allow
468 interface="canonical.launchpad.interfaces.IHWDeviceDriverLink" />
469 <allow attributes="id" />
470 </class>
471
472 <securedutility
473- class="canonical.launchpad.database.HWDeviceDriverLinkSet"
474+ class="canonical.launchpad.database.hwdb.HWDeviceDriverLinkSet"
475 provides="canonical.launchpad.interfaces.IHWDeviceDriverLinkSet">
476 <allow
477 interface="canonical.launchpad.interfaces.IHWDeviceDriverLinkSet" />
478 </securedutility>
479
480- <class class="canonical.launchpad.database.HWDeviceClass">
481+ <class class="canonical.launchpad.database.hwdb.HWDeviceClass">
482 <require permission="launchpad.View"
483 interface="canonical.launchpad.interfaces.IHWDeviceClass" />
484 </class>
485@@ -242,7 +242,7 @@
486 interface="canonical.launchpad.interfaces.IHWDeviceClassSet" />
487 </securedutility>
488
489- <class class="canonical.launchpad.database.HWSubmissionDevice">
490+ <class class="canonical.launchpad.database.hwdb.HWSubmissionDevice">
491 <require
492 permission="launchpad.View"
493 interface="canonical.launchpad.interfaces.IHWSubmissionDevice" />
494@@ -255,20 +255,20 @@
495 />
496
497 <securedutility
498- class="canonical.launchpad.database.HWSubmissionDeviceSet"
499+ class="canonical.launchpad.database.hwdb.HWSubmissionDeviceSet"
500 provides="canonical.launchpad.interfaces.IHWSubmissionDeviceSet">
501 <allow
502 interface="canonical.launchpad.interfaces.IHWSubmissionDeviceSet" />
503 </securedutility>
504
505- <class class="canonical.launchpad.database.HWSubmissionBug">
506+ <class class="canonical.launchpad.database.hwdb.HWSubmissionBug">
507 <allow
508 interface="canonical.launchpad.interfaces.IHWSubmissionBug" />
509 <allow attributes="id" />
510 </class>
511
512 <securedutility
513- class="canonical.launchpad.database.HWSubmissionBugSet"
514+ class="canonical.launchpad.database.hwdb.HWSubmissionBugSet"
515 provides="canonical.launchpad.interfaces.IHWSubmissionBugSet">
516 <allow
517 interface="canonical.launchpad.interfaces.IHWSubmissionBugSet" />
518
519=== modified file 'lib/canonical/launchpad/zcml/launchpadstatistic.zcml'
520--- lib/canonical/launchpad/zcml/launchpadstatistic.zcml 2009-09-18 13:24:29 +0000
521+++ lib/canonical/launchpad/zcml/launchpadstatistic.zcml 2009-09-29 11:33:15 +0000
522@@ -9,14 +9,14 @@
523 i18n_domain="launchpad">
524
525 <!-- LaunchpadStatistic -->
526- <class class="canonical.launchpad.database.LaunchpadStatistic">
527- <allow interface="canonical.launchpad.interfaces.ILaunchpadStatistic" />
528+ <class class="canonical.launchpad.database.launchpadstatistic.LaunchpadStatistic">
529+ <allow interface="canonical.launchpad.interfaces.launchpadstatistic.ILaunchpadStatistic" />
530 </class>
531
532
533 <!-- LaunchpadStatisticSet -->
534 <securedutility
535- class="canonical.launchpad.database.LaunchpadStatisticSet"
536+ class="canonical.launchpad.database.launchpadstatistic.LaunchpadStatisticSet"
537 provides="canonical.launchpad.interfaces.ILaunchpadStatisticSet">
538 <allow interface="canonical.launchpad.interfaces.ILaunchpadStatisticSet" />
539 </securedutility>
540
541=== modified file 'lib/lp/code/model/tests/test_branchjob.py'
542--- lib/lp/code/model/tests/test_branchjob.py 2009-08-13 07:00:48 +0000
543+++ lib/lp/code/model/tests/test_branchjob.py 2009-09-29 11:33:15 +0000
544@@ -957,6 +957,25 @@
545 entry = entries[0]
546 self.assertEqual(pot_path, entry.path)
547
548+ def test_init_translation_file_lists_skip_dirs(self):
549+ # The method _init_translation_file_lists extracts all translation
550+ # files from the branch but does not add changed directories to the
551+ # template_files_changed and translation_files_changed lists .
552+ pot_path = u"subdir/foo.pot"
553+ pot_content = self.factory.getUniqueString()
554+ po_path = u"subdir/foo.po"
555+ po_content = self.factory.getUniqueString()
556+ self._makeBranchWithTreeAndFiles(((pot_path, pot_content),
557+ (po_path, po_content)))
558+ self._makeProductSeries(TranslationsBranchImportMode.NO_IMPORT)
559+ job = RosettaUploadJob.create(self.branch, NULL_REVISION, True)
560+ job._init_translation_file_lists()
561+
562+ self.assertEqual([(pot_path, pot_content)],
563+ job.template_files_changed)
564+ self.assertEqual([(po_path, po_content)],
565+ job.translation_files_changed)
566+
567 def test_upload_xpi_template(self):
568 # XPI templates are indentified by a special name. They are imported
569 # like POT files.

Subscribers

People subscribed via source and target branches

to status/vote changes: