Merge lp:~adeuring/launchpad/hwdb-test-natty-mess into lp:launchpad

Proposed by Abel Deuring
Status: Merged
Approved by: Abel Deuring
Approved revision: no longer in the source branch.
Merged at revision: 13870
Proposed branch: lp:~adeuring/launchpad/hwdb-test-natty-mess
Merge into: lp:launchpad
Diff against target: 560 lines (+529/-1)
3 files modified
lib/canonical/launchpad/scripts/tests/hardwaretest-natty.xml (+473/-0)
lib/lp/hardwaredb/scripts/hwdbsubmissions.py (+37/-1)
lib/lp/hardwaredb/tests/test_hwdb_submission_validation.py (+19/-0)
To merge this branch: bzr merge lp:~adeuring/launchpad/hwdb-test-natty-mess
Reviewer Review Type Date Requested Status
Francis J. Lacoste (community) Approve
Review via email: mp+73722@code.launchpad.net

Commit message

[r=flacoste][bug=839102] allow processing of HWDB submissions from Natty

Description of the change

This branch fixes the problem that HWDB submissions from Natty can not be processed.

The reason for the failure is simple: The submission processing script expects an XML file with a structure as defined in lib/canonical/launchpad/scripts/hardware-1_0.rng

One part of the required XML data looks like

  <hardware>
    <udev>(lots of text data)
    </udev>
    <dmi>(more text data)
    </dmi>
    (other tags)
  </hardware>

The reports from Natty do not contain the tags <udev> and <dmi>; their content is instead stored in

  <context>
    <info command="udevadm info --export-db">(text data)
    </info>
    <info command="grep -r . /sys/class/dmi/id/ 2&gt;/dev/null">(test data)
    </info>
  </context>

The fix is quite simple: Two regular expressions check if the tags <udev> and <dmi> exist within <hardware>; if not, these tags are inserted, provided that the corresponding <info> nodes can be found.

This is a bit of a "brute force" fix. I tried at first to modify the etree structure, but then flacoste gave me the hint that the RelaxNG validation is _not_ on the etree representaion of the data, but on the "text string". Creating the etree, modifying it, writing its contents into a StringIO buffer, and finally passing the buffer's content to the RNG validator should have worked too, but would be much slower.

A note about the diff: The first 480 lines are the content of a new file with test data. Its content is a variant of the already existing file lib/canonical/launchpad/scripts/tests/hardwaretest-udev.xml and hence probably easier to understand by running

  diff -u hardwaretest-udev.xml hardwaretest-natty.xml

in lib/canonical/launchpad/scripts/tests

test: ./bin/test hardwaredb -vvt test_hwdb_submission_validation

To post a comment you must log in.
Revision history for this message
Francis J. Lacoste (flacoste) wrote :

I find the test a bit weak as it just checks that result isn't None. But I guess that's fine since the result from runValidator is a parsed etree that we know match the expected structure.

Thanks for fixing this Abel!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'lib/canonical/launchpad/scripts/tests/hardwaretest-natty.xml'
2--- lib/canonical/launchpad/scripts/tests/hardwaretest-natty.xml 1970-01-01 00:00:00 +0000
3+++ lib/canonical/launchpad/scripts/tests/hardwaretest-natty.xml 2011-09-02 07:16:32 +0000
4@@ -0,0 +1,473 @@
5+<?xml version="1.0" ?>
6+<system version="1.0">
7+
8+ <!-- Reports coming from the checkbox version in Natty do not
9+ have the tags <udev> and <dmi> inside <hardware>. Instead,
10+ they store the data expected in these tags in the tags
11+
12+ <info command="udevadm info - -export-db"> and
13+ <info command="grep -r . /sys/class/dmi/id/ 2&gt;/dev/null">
14+
15+ inside <
16+ -->
17+ <!-- summary: generic information about the submission -->
18+ <summary>
19+
20+ <!-- live_cd: Was this submission made on a system running an Ubuntu Live
21+ CD or on a regular Ubuntu/Linux installation?
22+ -->
23+ <live_cd value="False"/>
24+
25+ <!-- system_id: A hash of the "system identifier". This value is intended
26+ to identify the tested computer model; the value should
27+ be derived from the properties
28+ system.product, system.vendor of the HAL UDI
29+ /org/freedesktop/Hal/devices/computer.
30+ -->
31+ <system_id value="f982bb1ab536469cebfd6eaadcea0ffc"/>
32+
33+ <!-- distribution, distroseries: These values are retrieved from
34+ /etc/lsb-release, parameters DISTRIB_ID and DISTRIB_RELEASE.
35+ -->
36+ <distribution value="Ubuntu"/>
37+ <distroseries value="7.04"/>
38+
39+ <!-- architecture: The processor architecture of the operating system.
40+ -->
41+ <architecture value="amd64"/>
42+
43+ <!-- private: If False, this submission is publicly accessible from
44+ Launchpad, else it is only accesible by the submitter, by
45+ Launchpad administrators and by scripts running with
46+ administrator rights. Submissions marked "private" should
47+ only be used to gather statistical data.
48+ -->
49+ <private value="False"/>
50+
51+ <!-- contactable: If True, the owner agrees to be contacted by other
52+ persons about devices which appear in his submission.
53+ Example of a use case: Developers can ask device owners
54+ to perform tests.
55+ -->
56+ <contactable value="False"/>
57+
58+ <!-- date_created: Date and time (UTC) of the submission.
59+ -->
60+ <date_created value="2007-09-28T16:09:20.126842"/>
61+
62+ <!-- client: The name and version of the program that created the
63+ submission data.
64+ -->
65+ <client name="hwtest" version="0.9">
66+
67+ <!-- plugin: name and version of a plugin used by the client.
68+ This tag may appear more than once.
69+ -->
70+ <plugin name="architecture_info" version="1.1"/>
71+ <plugin name="find_network_controllers" version="2.34"/>
72+ <plugin name="internet_ping" version="1.1"/>
73+ <plugin name="harddisk_speed" version="0.7"/>
74+ </client>
75+
76+ <!-- The kernel name and version, as shown by "uname -r"
77+ -->
78+ <kernel-release value="2.6.28-14-generic"/>
79+ </summary>
80+
81+ <!-- hardware: data about the hardware the submission was made on.
82+ -->
83+ <hardware>
84+
85+ <!-- udev: The output of running "udevadm info - -export-db" -->
86+
87+
88+ <!-- Additional data for SCSI devices: vendor, model, type
89+
90+ For each udev node which has DEVTYPE=scsi_device, we need
91+ the content of the sysfs files vendor, model, type. The data
92+ is stored in the same format as the DMI data:
93+ /path/to/file:filecontent
94+ -->
95+ <sysfs-attributes>
96+P: /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
97+A: modalias=input:b0019v0000p0001e0000-e0,1,k74,ramlsfw
98+A: uniq=
99+A: phys=LNXPWRBN/button/input0
100+A: name=Power Button
101+
102+P: /devices/LNXSYSTM:00/device:00/PNP0A08:00/device:03/input/input8
103+A: modalias=input:b0019v0000p0006e0000-e0,1,kE0,E1,E3,F0,F1,F2,F3,F4,F5,ramlsfw
104+A: uniq=
105+A: phys=/video/input0
106+A: name=Video Bus
107+</sysfs-attributes>
108+
109+ <!-- processors: Data about processors installed in a system.
110+ The data is retrieved from /proc/cpuinfo.
111+ -->
112+ <processors>
113+
114+ <!-- processor: Data from /proc/cpuinfo about a single processor.
115+ -->
116+ <processor id="123" name="0">
117+
118+ <!-- property: The data of one line of /proc/cpuinfo.
119+ attribute name: The name of the property
120+ (the text left of the ':' in a line of /proc/cpuinfo)
121+ attribute type: A Python type appropriate for the value.
122+ -->
123+ <property name="wp" type="bool">
124+ True
125+ </property>
126+ <property name="flags" type="list">
127+ <value type="str">
128+ fpu
129+ </value>
130+ <value type="str">
131+ vme
132+ </value>
133+ <value type="str">
134+ de
135+ </value>
136+ </property>
137+ <property name="cpu_mhz" type="float">
138+ 1000.0
139+ </property>
140+ </processor>
141+ </processors>
142+
143+ <!-- aliases: optional data provided by the user:
144+ The name of a peripheral, PCI card etc as shown by a label on
145+ the device. OEM devices are often sold under different names
146+ by different vendors; having a set of alias names for a device
147+ allows users of the HWDB to search for information by these
148+ "marketing names".
149+ -->
150+ <aliases>
151+ <!-- alias: The "label name" of a device or system.
152+ attribute target: The sysfs path of a device as given
153+ in <udev>.
154+ -->
155+ <alias target="/devices/pci0000:00/0000:00:1f.1/host3/target3:0:0/3:0:0:0">
156+
157+ <!-- vendor: The vendor name shown on the device label.
158+ -->
159+ <vendor>Medion</vendor>
160+
161+ <!-- model: The model name of shown on the label.
162+ -->
163+ <model>QuickPrint 9876</model>
164+ </alias>
165+ </aliases>
166+ </hardware>
167+
168+ <!-- software: Data about the software installed on the system.
169+ -->
170+ <software>
171+
172+ <!-- lsbrelease: The data from /etc/lsb-release.
173+ -->
174+ <lsbrelease>
175+
176+ <!-- property: the data from one line of /etc/lsb-release.
177+ attribute type: A Python type appropriate for this
178+ property (str).
179+ -->
180+ <property name="release" type="str">
181+ 7.04
182+ </property>
183+ <property name="codename" type="str">
184+ feisty
185+ </property>
186+ <property name="distributor-id" type="str">
187+ Ubuntu
188+ </property>
189+ <property name="description" type="str">
190+ Ubuntu 7.04
191+ </property>
192+ <property name="dict_example" type="dict">
193+ <value name="a" type="str">value for key a</value>
194+ <value name="b" type="int">1234</value>
195+ </property>
196+ </lsbrelease>
197+
198+ <!-- packages: Data about the installed software packages.
199+ -->
200+ <packages>
201+
202+ <!-- package: Data about a single package.
203+ The <property> sub-tags contain the DEB properties
204+ "name", "priority", "section", "source", "version",
205+ "installed_size", "size", "summary".
206+
207+ XXX Abel Deuring 2007-12-12: What about submissions
208+ from RPM-based Linux versions? (And "exotic" variants
209+ like Gentoo?)
210+ -->
211+ <package name="metacity" id="200">
212+ <property name="installed_size" type="int">
213+ 868352
214+ </property>
215+ <property name="section" type="str">
216+ x11
217+ </property>
218+ <property name="summary" type="str">
219+ A lightweight GTK2 based Window Manager
220+ </property>
221+ <property name="priority" type="str">
222+ optional
223+ </property>
224+ <property name="source" type="str">
225+ metacity
226+ </property>
227+ <property name="version" type="str">
228+ 1:2.18.2-0ubuntu1.1
229+ </property>
230+ <property name="size" type="int">
231+ 429128
232+ </property>
233+ </package>
234+ </packages>
235+ <!-- Information extracted from Xorg.0.log.
236+ HAL does not provide any information about Xorg drivers, so
237+ we retrieve that from the xserver's log file.
238+ -->
239+ <xorg version="1.3.0">
240+ <!-- driver: Data about a driver.
241+ (optional)
242+ attribute name: The name of the driver.
243+ attribute version: The version of the driver.
244+ attribute class: The module class of the driver
245+ attribute device: The ID of a device driven by this driver.
246+ -->
247+ <driver name="fglrx" version="1.23" class="X.Org Video Driver"
248+ device="12"/>
249+ </xorg>
250+ </software>
251+
252+ <!-- questions: User's answers to questions asked by the client.
253+ -->
254+ <questions>
255+
256+ <!-- question: Data of a question.
257+ attribute name: The unique name of the question.
258+ attribute plugin: The name of the plugin which asked
259+ the question.
260+ attribute version: The version of the question.
261+ attribute type: Allowed values are "manual" and "automatic".
262+ A "manual" question requires user input for the answer;
263+ an "automatic" question gets the answer automatically.
264+ -->
265+ <question name="detected_network_controllers"
266+ plugin="find_network_controllers">
267+
268+ <!-- target: Information about a device or software package the
269+ question is about. The attribute "id" is the sysfs path of
270+ a device as given in <udev>, or the ID of a software package
271+ node.
272+ This node may appear multiple times.
273+ -->
274+ <target id="/devices/pci0000:00/0000:00:1a.0/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81">
275+ <!-- driver: The driver which controls the target device. This tag
276+ may appear more than once.
277+
278+ While we are working on a project called "Hardware Database",
279+ we are not that much interested in the question, if a device
280+ works "as such", but if their Linux driver(s) work.
281+
282+ It is not in every case possible to identify the used driver
283+ from HAL data, so we need another way to add this information.
284+ (example: HAL does not know, which driver is used for the
285+ graphics card.)
286+
287+ Example for multiple drivers: Some scanners have a SCSI _and_
288+ a USB interface; if such a scanner is tested, we not only want
289+ to know, which Sane backend is used, but also, which interface
290+ is used.
291+
292+ Also, it might be interesting to know for many USB 2.0 devices,
293+ if a USB 1 (uhci_hcd or ohci_hcd driver) or the USB 2 driver
294+ (ehci_hcd) was used. A USB 1 driver might for example explain
295+ latency problems.
296+ -->
297+ <driver>ipw3945</driver>
298+ </target>
299+
300+ <!-- ID of the 88E8055 PCI-E Gigabit Ethernet Controller -->
301+ <target id="/devices/pci0000:00/0000:00:1f.1"/>
302+
303+ <!-- command: The command line of an external command required to
304+ ask this question.
305+ -->
306+ <command/>
307+
308+ <!-- answer: The answer to the question. Two types of answers are
309+ defined, "multiple_choice" and "measurement". (See below
310+ for an example of the latter.)
311+ attribute type: Must be "multiple_choice" or "measurement".
312+ -->
313+ <answer type="multiple_choice">pass</answer>
314+
315+ <!-- answer_choices: The list of possible choices.
316+ The data should only be used for consistency
317+ checks and to detect variants of the question.
318+ -->
319+ <answer_choices>
320+ <value type="str">fail</value>
321+ <value type="str">pass</value>
322+ <value type="str">skip</value>
323+ </answer_choices>
324+
325+ <!-- A user comment about the device or about the test.
326+ -->
327+ <comment>
328+ The WLAN adapter drops the connection very frequently.
329+ </comment>
330+ </question>
331+
332+ <question name="internet_ping"
333+ plugin="internet_ping">
334+ <target id="/devices/pci0000:00/0000:00:1f.1"/>
335+ <command/>
336+ <answer type="multiple_choice">pass</answer>
337+ <answer_choices>
338+ <value type="str">fail</value>
339+ <value type="str">pass</value>
340+ <value type="str">skip</value>
341+ </answer_choices>
342+ </question>
343+
344+ <!-- example for a "measurement question"
345+ -->
346+ <question name="harddisk_speed"
347+ plugin="harddisk_speed">
348+ <target id="/devices/pci0000:00/0000:00:1f.1/host3/target3:0:0/3:0:0:0"/>
349+ <command>hdparm -t /dev/sda</command>
350+ <!-- answer: The answer to a "measurement question".
351+ attribute type: See above.
352+ attribute unit: The unit of the result of the measurement.
353+ XXX Abel Deuring 2007-12-12 bug=175978 We should
354+ enumerate a list of allowed units, in order to avoid
355+ multiple units for the same dimension. e.g., B/sec,
356+ MB/sec or inch, cm, foot.
357+
358+ For dimensionless values, the attribute unit is omitted.
359+
360+ "Percentage" and similar "convenience pseudo-units" like
361+ ppm are _not_ allowed; instead a dimensionless
362+ value must be used, where 0 is equivalent 0% and 1.0 is
363+ equivalent to 100%.
364+ -->
365+ <answer type="measurement" unit="MB/sec">38.4</answer>
366+ </question>
367+ </questions>
368+ <!-- miscellaneous additional text data.
369+ -->
370+ <context>
371+ <info command="udevadm info --export-db">P: /devices/LNXSYSTM:00
372+E: UDEV_LOG=3
373+E: DEVPATH=/devices/LNXSYSTM:00
374+E: MODALIAS=acpi:LNXSYSTM:
375+
376+P: /devices/pci0000:00/0000:00:1a.0
377+E: UDEV_LOG=3
378+E: DEVPATH=/devices/pci0000:00/0000:00:1a.0
379+E: DRIVER=uhci_hcd
380+E: PCI_CLASS=C0300
381+E: PCI_ID=8086:2834
382+E: PCI_SUBSYS_ID=17AA:20AA
383+E: PCI_SLOT_NAME=0000:00:1a.0
384+E: MODALIAS=pci:v00008086d00002834sv000017AAsd000020AAbc0Csc03i00
385+
386+P: /devices/pci0000:00/0000:00:1a.0/usb3
387+N: bus/usb/003/001
388+S: char/189:256
389+E: UDEV_LOG=3
390+E: DEVPATH=/devices/pci0000:00/0000:00:1a.0/usb3
391+E: MAJOR=189
392+E: MINOR=256
393+E: DEVTYPE=usb_device
394+E: DRIVER=usb
395+E: DEVICE=/proc/bus/usb/003/001
396+E: PRODUCT=1d6b/1/206
397+E: TYPE=9/0/0
398+E: BUSNUM=003
399+E: DEVNUM=001
400+E: DEVNAME=/dev/bus/usb/003/001
401+E: DEVLINKS=/dev/char/189:256
402+
403+P: /devices/pci0000:00/0000:00:1a.0/usb3/3-0:1.0
404+E: UDEV_LOG=3
405+E: DEVPATH=/devices/pci0000:00/0000:00:1a.0/usb3/3-0:1.0
406+E: DEVTYPE=usb_interface
407+E: DRIVER=hub
408+E: DEVICE=/proc/bus/usb/003/001
409+E: PRODUCT=1d6b/1/206
410+E: TYPE=9/0/0
411+E: INTERFACE=9/0/0
412+E: MODALIAS=usb:v1D6Bp0001d0206dc09dsc00dp00ic09isc00ip00
413+
414+P: /devices/pci0000:00/0000:00:1a.0/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81
415+N: usbdev3.1_ep81
416+S: char/252:4
417+E: UDEV_LOG=3
418+E: DEVPATH=/devices/pci0000:00/0000:00:1a.0/usb3/3-0:1.0/usb_endpoint/usbdev3.1_ep81
419+E: MAJOR=252
420+E: MINOR=4
421+E: DEVNAME=/dev/usbdev3.1_ep81
422+E: DEVLINKS=/dev/char/252:4
423+
424+P: /devices/pci0000:00/0000:00:1f.1
425+E: UDEV_LOG=3
426+E: DEVPATH=/devices/pci0000:00/0000:00:1f.1
427+E: DRIVER=ata_piix
428+E: PCI_CLASS=1018A
429+E: PCI_ID=8086:2850
430+E: PCI_SUBSYS_ID=17AA:20A6
431+E: PCI_SLOT_NAME=0000:00:1f.1
432+E: MODALIAS=pci:v00008086d00002850sv000017AAsd000020A6bc01sc01i8a
433+
434+P: /devices/pci0000:00/0000:00:1f.1/host3
435+E: UDEV_LOG=3
436+E: DEVPATH=/devices/pci0000:00/0000:00:1f.1/host3
437+E: DEVTYPE=scsi_host
438+
439+P: /devices/pci0000:00/0000:00:1f.1/host3/scsi_host/host3
440+E: UDEV_LOG=3
441+E: DEVPATH=/devices/pci0000:00/0000:00:1f.1/host3/scsi_host/host3
442+
443+P: /devices/pci0000:00/0000:00:1f.1/host3/target3:0:0
444+E: UDEV_LOG=3
445+E: DEVPATH=/devices/pci0000:00/0000:00:1f.1/host3/target3:0:0
446+E: DEVTYPE=scsi_target
447+
448+P: /devices/pci0000:00/0000:00:1f.1/host3/target3:0:0/3:0:0:0
449+E: UDEV_LOG=3
450+E: DEVPATH=/devices/pci0000:00/0000:00:1f.1/host3/target3:0:0/3:0:0:0
451+E: DEVTYPE=scsi_device
452+E: DRIVER=sr
453+E: MODALIAS=scsi:t-0x05
454+</info>
455+
456+ <!-- The content of publicly accessible files in /sys/class/dmi/id/
457+ format: filename:content
458+ as for example generated by "grep -r . /sys/class/dmi/id/"
459+ -->
460+
461+ <info command="grep -r . /sys/class/dmi/id/ 2&gt;/dev/null">/sys/class/dmi/id/bios_vendor:LENOVO
462+/sys/class/dmi/id/bios_version:7LETB9WW (2.19 )
463+/sys/class/dmi/id/bios_date:06/06/2008
464+/sys/class/dmi/id/sys_vendor:LENOVO
465+/sys/class/dmi/id/product_name:6457BAG
466+/sys/class/dmi/id/product_version:ThinkPad T61
467+/sys/class/dmi/id/board_vendor:LENOVO
468+/sys/class/dmi/id/board_name:6457BAG
469+/sys/class/dmi/id/board_version:Not Available
470+/sys/class/dmi/id/chassis_vendor:LENOVO
471+/sys/class/dmi/id/chassis_type:10
472+/sys/class/dmi/id/chassis_version:Not Available
473+/sys/class/dmi/id/chassis_asset_tag:No Asset Information
474+/sys/class/dmi/id/modalias:dmi:bvnLENOVO:bvr7LETB9WW(2.19)
475+</info>
476+ </context>
477+</system>
478
479=== modified file 'lib/lp/hardwaredb/scripts/hwdbsubmissions.py'
480--- lib/lp/hardwaredb/scripts/hwdbsubmissions.py 2011-08-31 16:38:48 +0000
481+++ lib/lp/hardwaredb/scripts/hwdbsubmissions.py 2011-09-02 07:16:32 +0000
482@@ -72,6 +72,13 @@
483 re.VERBOSE)
484
485 _broken_comment_nodes_re = re.compile('(<comment>.*?</comment>)', re.DOTALL)
486+_missing_udev_node_data = re.compile(
487+ '<info command="udevadm info --export-db">(.*?)</info>', re.DOTALL)
488+_missing_dmi_node_data = re.compile(
489+ r'<info command="grep -r \. /sys/class/dmi/id/ 2&gt;/dev/null">(.*?)'
490+ '</info>', re.DOTALL)
491+_udev_node_exists = re.compile('<hardware>.*?<udev>.*?</hardware>', re.DOTALL)
492+_dmi_node_exists = re.compile('<hardware>.*?<dmi>.*?</hardware>', re.DOTALL)
493
494 ROOT_UDI = '/org/freedesktop/Hal/devices/computer'
495 UDEV_ROOT_PATH = '/devices/LNXSYSTM:00'
496@@ -166,7 +173,36 @@
497 # A considerable number of reports for Lucid has ESC characters
498 # in comment nodes. We don't need the comment nodes at all, so
499 # we can simply empty them.
500- return _broken_comment_nodes_re.sub('<comment/>', submission)
501+ submission = _broken_comment_nodes_re.sub('<comment/>', submission)
502+
503+ # Submissions from Natty don't have the nodes <dmi> and <udev>
504+ # as children of the <hardware> node. Fortunately, they provide
505+ # this data in
506+ #
507+ # <context>
508+ # <info command="grep -r . /sys/class/dmi/id/ 2&gt;/dev/null">
509+ # ...
510+ # </info>
511+ # <info command="udevadm info --export-db">
512+ # ...
513+ # </info>
514+ # </context>
515+ #
516+ # We can try to find the two relevant <info> nodes inside <context>
517+ # and move their content into the proper subnodes of <hardware>.
518+ if _udev_node_exists.search(submission) is None:
519+ mo = _missing_udev_node_data.search(submission)
520+ if mo is not None:
521+ missing_data = mo.group(1)
522+ missing_data = '<udev>%s</udev>\n</hardware>' % missing_data
523+ submission = submission.replace('</hardware>', missing_data)
524+ if _dmi_node_exists.search(submission) is None:
525+ mo = _missing_dmi_node_data.search(submission)
526+ if mo is not None:
527+ missing_data = mo.group(1)
528+ missing_data = '<dmi>%s</dmi>\n</hardware>' % missing_data
529+ submission = submission.replace('</hardware>', missing_data)
530+ return submission
531
532 def _getValidatedEtree(self, submission, submission_key):
533 """Create an etree doc from the XML string submission and validate it.
534
535=== modified file 'lib/lp/hardwaredb/tests/test_hwdb_submission_validation.py'
536--- lib/lp/hardwaredb/tests/test_hwdb_submission_validation.py 2011-08-31 16:38:48 +0000
537+++ lib/lp/hardwaredb/tests/test_hwdb_submission_validation.py 2011-09-02 07:16:32 +0000
538@@ -2823,3 +2823,22 @@
539 submission_id, result,
540 'Extra element context in interleave',
541 'detection of an invalid sub.node of <info> failed')
542+
543+ def test_natty_reports_validate(self):
544+ # HWDB submissions from Natty can be processed.
545+ # the raw data from these reports would be passed directly
546+ # to the RelaxNG validator, they would fail, because they
547+ # do not have the sub-nodes <dmi> and <udev> inside <hardware>.
548+ # The data is stored instead in the nodes
549+ # <info command="grep -r . /sys/class/dmi/id/ 2&gt;/dev/null">
550+ # and <info command="udevadm info --export-db">
551+ #
552+ # The method SubmissionParser.fixFrequentErrors() (called by
553+ # _getValidatedEtree()) creates the missing nodes, so that
554+ # _getValidatedEtree() succeeds.
555+ sample_data_path = os.path.join(
556+ config.root, 'lib', 'canonical', 'launchpad', 'scripts',
557+ 'tests', 'hardwaretest-natty.xml')
558+ sample_data = open(sample_data_path).read()
559+ result, submission_id = self.runValidator(sample_data)
560+ self.assertTrue(result is None)