Merge lp:~roadmr/checkbox/cmdline-subparser into lp:checkbox

Proposed by Daniel Manrique
Status: Merged
Approved by: Zygmunt Krynicki
Approved revision: 3775
Merged at revision: 3774
Proposed branch: lp:~roadmr/checkbox/cmdline-subparser
Merge into: lp:checkbox
Diff against target: 216 lines (+129/-0)
4 files modified
checkbox-support/checkbox_support/parsers/kernel_cmdline.py (+37/-0)
checkbox-support/checkbox_support/parsers/submission.py (+72/-0)
checkbox-support/checkbox_support/parsers/tests/fixtures/submission_info_kernel_cmdline.xml (+10/-0)
checkbox-support/checkbox_support/parsers/tests/test_submission.py (+10/-0)
To merge this branch: bzr merge lp:~roadmr/checkbox/cmdline-subparser
Reviewer Review Type Date Requested Status
Zygmunt Krynicki (community) Approve
Review via email: mp+258666@code.launchpad.net

Commit message

checkbox-support:parsers:submission: Add parsing of kernel_cmdline_attachment.

This includes the kernel commandline parser as well as the changes to SubmissionParser and the TestRun class to actually invoke the subparser when needed and gather the data, data files and tests.

Description of the change

checkbox-support:parsers:submission: Add parsing of kernel_cmdline_attachment.

This includes the kernel commandline parser as well as the changes to SubmissionParser and the TestRun class to actually invoke the subparser when needed and gather the data, data files and tests.

The parser is purposefully trivial since I was mostly trying to understand how to add and connect a new subparser in the SubmissionParser.

To post a comment you must log in.
Revision history for this message
Zygmunt Krynicki (zyga) wrote :

Just minor nitpicks below. I'd put commits in different order though:
 - docstring for test run
 - new parser _with_ tests

Revision history for this message
Daniel Manrique (roadmr) wrote :

Applied the fixes as suggested and changed the commits too.

Exceptions:

- I didn't change the TestRun name as that is also used in Hexr and I want to be consistent, this is scary enough as it is :)
- I didn't change the camelcase for the setKernelCmdline method for the same reason. Let me know if you feel strongly about this and I can change it.
- I still haven't figured out the DeferredParser thing, once I got this parser working I'm investigating *why* it works so I'll be able to answer this later, hopefully...

Revision history for this message
Zygmunt Krynicki (zyga) wrote :

I'm fine with the first two as it's more of a long-term change. The
last thing is okay if you feel that this is the way things work. I was
more curious than anything and I assumed you know why you've used it
:-)

+1

On Fri, May 8, 2015 at 9:56 PM, Daniel Manrique
<email address hidden> wrote:
> Applied the fixes as suggested and changed the commits too.
>
> Exceptions:
>
> - I didn't change the TestRun name as that is also used in Hexr and I want to be consistent, this is scary enough as it is :)
> - I didn't change the camelcase for the setKernelCmdline method for the same reason. Let me know if you feel strongly about this and I can change it.
> - I still haven't figured out the DeferredParser thing, once I got this parser working I'm investigating *why* it works so I'll be able to answer this later, hopefully...
> --
> https://code.launchpad.net/~roadmr/checkbox/cmdline-subparser/+merge/258666
> You are subscribed to branch lp:checkbox.

Revision history for this message
Zygmunt Krynicki (zyga) wrote :

Thanks, let's merge it, +1

review: Approve
Revision history for this message
Daniel Manrique (roadmr) wrote :

Attempt to merge into lp:checkbox failed due to conflicts:

text conflict in checkbox-support/checkbox_support/parsers/submission.py
text conflict in checkbox-support/checkbox_support/parsers/tests/test_submission.py

Revision history for this message
Daniel Manrique (roadmr) wrote :

I knew that was going to happen :) Fixed the merge conflicts, ready again.

3774. By Daniel Manrique

checkbox-support:parsers:submission: Add parsing of kernel_cmdline_attachment.

This includes the kernel commandline parser (trivial since we don't actually
parse the commandline, we just extract it verbatim from the raw attachment data)
as well as the changes to SubmissionParser and the TestRun class to actually invoke
the subparser when needed and gather the data.

Testing changes add the xml chunk data file for the test, the test
method itself, and augment the SubmissionRun data-holding class with a
setKernelCmdline method which we'd expect the submission parser to call
when it finds and parses a kernel_cmdline_attachment.

3775. By Daniel Manrique

checkbox-support:parsers:submission: Document the TestRun class and SubmissionParser.run method

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'checkbox-support/checkbox_support/parsers/kernel_cmdline.py'
--- checkbox-support/checkbox_support/parsers/kernel_cmdline.py 1970-01-01 00:00:00 +0000
+++ checkbox-support/checkbox_support/parsers/kernel_cmdline.py 2015-05-13 13:30:33 +0000
@@ -0,0 +1,37 @@
1# This file is part of Checkbox.
2#
3# Copyright 2015 Canonical Ltd.
4#
5# Checkbox is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 3,
7# as published by the Free Software Foundation.
8#
9# Checkbox is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
16
17from __future__ import absolute_import
18from __future__ import division
19from __future__ import print_function
20from __future__ import unicode_literals
21
22
23class KernelCmdlineParser(object):
24
25 """Parser for kernel cmdline information."""
26
27 def __init__(self, stream):
28 self.stream = stream
29
30 def run(self, result):
31 """
32 The kernel cmdline is usually a single line of text so this parser is
33 quite simple. It will just call the result's setKernelCmdline method
34 with the first line
35 """
36 line = self.stream.readline().strip()
37 result.setKernelCmdline(line)
038
=== modified file 'checkbox-support/checkbox_support/parsers/submission.py'
--- checkbox-support/checkbox_support/parsers/submission.py 2015-05-12 18:08:20 +0000
+++ checkbox-support/checkbox_support/parsers/submission.py 2015-05-13 13:30:33 +0000
@@ -44,6 +44,7 @@
44from checkbox_support.parsers.meminfo import MeminfoParser44from checkbox_support.parsers.meminfo import MeminfoParser
45from checkbox_support.parsers.udevadm import UdevadmParser45from checkbox_support.parsers.udevadm import UdevadmParser
46from checkbox_support.parsers.modprobe import ModprobeParser46from checkbox_support.parsers.modprobe import ModprobeParser
47from checkbox_support.parsers.kernel_cmdline import KernelCmdlineParser
4748
4849
49logger = logging.getLogger("checkbox_support.parsers.submission")50logger = logging.getLogger("checkbox_support.parsers.submission")
@@ -65,6 +66,47 @@
65# from apps/uploads/checkbox_parser.py licensed internally by Canonical under66# from apps/uploads/checkbox_parser.py licensed internally by Canonical under
66# the license of the Chcekbox project.67# the license of the Chcekbox project.
67class TestRun(object):68class TestRun(object):
69 """
70 The TestRun class is responsible for acting upon information from a
71 submission. It decouples the storage and processing of that information
72 from the parsing process. A TestRun class is passed to the SubmissionParser
73 at run time::
74
75 # stream is the file or submission data
76 parser = SubmissionParser(stream)
77 parser.run(TestRun, <other arguments>)
78
79 The parser will create a TestRun instance and, as it finds elements
80 in the submission, will call methods in the TestRun instance passing them
81 the chunks it has parsed. The TestRun instance can do things like print
82 the data, save it into a list or dict for later use, dump it
83 directly to a database, or anything else.
84
85 The interface that TestRun-compliant classes must implement is not really
86 formalized anywhere; perhaps *this* class is the most authoritative
87 reference of which methods/events may be called.
88
89 This particular TestRun implementation uses "messages" as its storage
90 convention, for historical reasons: it's initialized with an empty
91 list and it will populate it with the data stored in dictionaries of
92 the form::
93
94 { type: "set-$something",
95 "foo": "data-1",
96 "baz": "data-2"}
97
98 The only required key is "type": the rest are dependent on which data
99 item is processed.
100
101 There are a few conventions in naming the "callback" methods:
102
103 - Methods that will be called only once to set a single item are
104 named set\* (example setArchitecture).
105 - Methods that can be called many times due to processing of several
106 similar items (packages, devices) are named add\*
107 (example addDeviceState). Look at the existing methods to see how they
108 append to an existing element of the messages list.
109 """
68110
69 project = "certification"111 project = "certification"
70112
@@ -96,6 +138,12 @@
96 "module": module,138 "module": module,
97 "options": options})139 "options": options})
98140
141 def setKernelCmdline(self, kernel_cmdline):
142 self.messages.append({
143 "type": "set-kernel-cmdline",
144 "kernel_cmdline": kernel_cmdline})
145 logger.debug("Setting Kernel Commandline: %s", kernel_cmdline)
146
99 def setDistribution(self, **distribution):147 def setDistribution(self, **distribution):
100 self.messages.append({148 self.messages.append({
101 "type": "set-distribution",149 "type": "set-distribution",
@@ -499,6 +547,9 @@
499 ("cpuinfo", "machine", "cpuinfo_result",),547 ("cpuinfo", "machine", "cpuinfo_result",),
500 self.setCpuinfo, count=1)548 self.setCpuinfo, count=1)
501 register(549 register(
550 ("test_run", "kernel_cmdline",),
551 self.setKernelCmdline, count=1)
552 register(
502 ("meminfo", "meminfo_result",),553 ("meminfo", "meminfo_result",),
503 self.setMeminfo, count=1)554 self.setMeminfo, count=1)
504 register(555 register(
@@ -542,6 +593,7 @@
542 r"udevadm": self.parseUdevadm,593 r"udevadm": self.parseUdevadm,
543 r"efi(?!rtvariable)": EfiParser,594 r"efi(?!rtvariable)": EfiParser,
544 r"modprobe_attachment": self.parseModprobe,595 r"modprobe_attachment": self.parseModprobe,
596 r"kernel_cmdline": self.parseKernelCmdline,
545 }597 }
546 for context, parser in context_parsers.items():598 for context, parser in context_parsers.items():
547 if re.search(context, command):599 if re.search(context, command):
@@ -656,6 +708,10 @@
656 elif name == "kernel-release":708 elif name == "kernel-release":
657 self.dispatcher.publishEvent("kernel", value)709 self.dispatcher.publishEvent("kernel", value)
658710
711 def parseKernelCmdline(self, cmdline):
712 self.dispatcher.publishEvent("kernel_cmdline", cmdline)
713 return DeferredParser(self.dispatcher, "kernel_cmdline_result")
714
659 def parseCpuinfo(self, cpuinfo):715 def parseCpuinfo(self, cpuinfo):
660 self.dispatcher.publishEvent("cpuinfo", cpuinfo)716 self.dispatcher.publishEvent("cpuinfo", cpuinfo)
661 return DeferredParser(self.dispatcher, "cpuinfo_result")717 return DeferredParser(self.dispatcher, "cpuinfo_result")
@@ -680,6 +736,10 @@
680 def setKernelState(self, test_run, kernel):736 def setKernelState(self, test_run, kernel):
681 test_run.setKernelState(kernel)737 test_run.setKernelState(kernel)
682738
739 def setKernelCmdline(self, test_run, kernel_cmdline):
740 parser = KernelCmdlineParser(kernel_cmdline)
741 parser.run(test_run)
742
683 def setCpuinfo(self, cpuinfo, machine, cpuinfo_result):743 def setCpuinfo(self, cpuinfo, machine, cpuinfo_result):
684 parser = CpuinfoParser(cpuinfo, machine)744 parser = CpuinfoParser(cpuinfo, machine)
685 parser.run(cpuinfo_result)745 parser.run(cpuinfo_result)
@@ -1002,6 +1062,18 @@
1002 "Unsupported tag <%s> in <system>" % child.tag)1062 "Unsupported tag <%s> in <system>" % child.tag)
10031063
1004 def run(self, test_run_factory, **kwargs):1064 def run(self, test_run_factory, **kwargs):
1065 """
1066 Entry point to start parsing the stream with which the parser
1067 was initialized.
1068
1069 :param test_run_factory: A class from which to instantiate a
1070 "test_run" object whose add\*/set\* methods will be called as elements
1071 are found in the stream
1072
1073 :returns: a SubmissionResult instance. This is not really used
1074 and seems redundant, as the data will be processed and stored by
1075 the TestRun instance (which is, however, also not returned anywhere).
1076 """
1005 parser = etree.XMLParser()1077 parser = etree.XMLParser()
10061078
1007 tree = etree.parse(self.file, parser=parser)1079 tree = etree.parse(self.file, parser=parser)
10081080
=== added file 'checkbox-support/checkbox_support/parsers/tests/fixtures/submission_info_kernel_cmdline.xml'
--- checkbox-support/checkbox_support/parsers/tests/fixtures/submission_info_kernel_cmdline.xml 1970-01-01 00:00:00 +0000
+++ checkbox-support/checkbox_support/parsers/tests/fixtures/submission_info_kernel_cmdline.xml 2015-05-13 13:30:33 +0000
@@ -0,0 +1,10 @@
1<?xml version="1.0" ?>
2<system version="1.0">
3 <context>
4 <info command="kernel_cmdline_attachment">BOOT_IMAGE=/boot/vmlinuz-3.13.0-48-generic root=UUID=645553f3-c6b8-49c4-adf5-68ac8134d9e5 ro quiet splash video.use_native_backlight=1 radeon.modeset=0 nouveau.modeset=0
5 </info>
6 </context>
7 <summary>
8 <architecture value="amd64"/>
9 </summary>
10</system>
011
=== modified file 'checkbox-support/checkbox_support/parsers/tests/test_submission.py'
--- checkbox-support/checkbox_support/parsers/tests/test_submission.py 2015-05-12 18:08:20 +0000
+++ checkbox-support/checkbox_support/parsers/tests/test_submission.py 2015-05-13 13:30:33 +0000
@@ -54,6 +54,9 @@
54 self.result.setdefault('module_options', {})54 self.result.setdefault('module_options', {})
55 self.result['module_options'][module] = options55 self.result['module_options'][module] = options
5656
57 def setKernelCmdline(self, kernel_cmdline):
58 self.result['kernel_cmdline'] = kernel_cmdline
59
57 def addAttachment(self, **attachment):60 def addAttachment(self, **attachment):
58 self.result.setdefault("attachments", [])61 self.result.setdefault("attachments", [])
59 self.result["attachments"].append(attachment)62 self.result["attachments"].append(attachment)
@@ -187,6 +190,13 @@
187 self.assertIn("single_cmd=1",190 self.assertIn("single_cmd=1",
188 result['module_options']['snd-hda-intel'])191 result['module_options']['snd-hda-intel'])
189192
193 def test_kernel_cmdline(self):
194 """a kernel commandline can be in a kernel_cmdline info element."""
195 result = self.getResult("submission_info_kernel_cmdline.xml")
196 self.assertTrue("kernel_cmdline" in result)
197 self.assertIn("ro quiet splash video.use_native_backlight=1",
198 result["kernel_cmdline"])
199
190 def test_device_dmidecode(self):200 def test_device_dmidecode(self):
191 """Device states can be in a dmidecode info element."""201 """Device states can be in a dmidecode info element."""
192 result = self.getResult("submission_info_dmidecode.xml")202 result = self.getResult("submission_info_dmidecode.xml")

Subscribers

People subscribed via source and target branches