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
1=== added file 'checkbox-support/checkbox_support/parsers/kernel_cmdline.py'
2--- checkbox-support/checkbox_support/parsers/kernel_cmdline.py 1970-01-01 00:00:00 +0000
3+++ checkbox-support/checkbox_support/parsers/kernel_cmdline.py 2015-05-13 13:30:33 +0000
4@@ -0,0 +1,37 @@
5+# This file is part of Checkbox.
6+#
7+# Copyright 2015 Canonical Ltd.
8+#
9+# Checkbox is free software: you can redistribute it and/or modify
10+# it under the terms of the GNU General Public License version 3,
11+# as published by the Free Software Foundation.
12+#
13+# Checkbox is distributed in the hope that it will be useful,
14+# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+# GNU General Public License for more details.
17+#
18+# You should have received a copy of the GNU General Public License
19+# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
20+
21+from __future__ import absolute_import
22+from __future__ import division
23+from __future__ import print_function
24+from __future__ import unicode_literals
25+
26+
27+class KernelCmdlineParser(object):
28+
29+ """Parser for kernel cmdline information."""
30+
31+ def __init__(self, stream):
32+ self.stream = stream
33+
34+ def run(self, result):
35+ """
36+ The kernel cmdline is usually a single line of text so this parser is
37+ quite simple. It will just call the result's setKernelCmdline method
38+ with the first line
39+ """
40+ line = self.stream.readline().strip()
41+ result.setKernelCmdline(line)
42
43=== modified file 'checkbox-support/checkbox_support/parsers/submission.py'
44--- checkbox-support/checkbox_support/parsers/submission.py 2015-05-12 18:08:20 +0000
45+++ checkbox-support/checkbox_support/parsers/submission.py 2015-05-13 13:30:33 +0000
46@@ -44,6 +44,7 @@
47 from checkbox_support.parsers.meminfo import MeminfoParser
48 from checkbox_support.parsers.udevadm import UdevadmParser
49 from checkbox_support.parsers.modprobe import ModprobeParser
50+from checkbox_support.parsers.kernel_cmdline import KernelCmdlineParser
51
52
53 logger = logging.getLogger("checkbox_support.parsers.submission")
54@@ -65,6 +66,47 @@
55 # from apps/uploads/checkbox_parser.py licensed internally by Canonical under
56 # the license of the Chcekbox project.
57 class TestRun(object):
58+ """
59+ The TestRun class is responsible for acting upon information from a
60+ submission. It decouples the storage and processing of that information
61+ from the parsing process. A TestRun class is passed to the SubmissionParser
62+ at run time::
63+
64+ # stream is the file or submission data
65+ parser = SubmissionParser(stream)
66+ parser.run(TestRun, <other arguments>)
67+
68+ The parser will create a TestRun instance and, as it finds elements
69+ in the submission, will call methods in the TestRun instance passing them
70+ the chunks it has parsed. The TestRun instance can do things like print
71+ the data, save it into a list or dict for later use, dump it
72+ directly to a database, or anything else.
73+
74+ The interface that TestRun-compliant classes must implement is not really
75+ formalized anywhere; perhaps *this* class is the most authoritative
76+ reference of which methods/events may be called.
77+
78+ This particular TestRun implementation uses "messages" as its storage
79+ convention, for historical reasons: it's initialized with an empty
80+ list and it will populate it with the data stored in dictionaries of
81+ the form::
82+
83+ { type: "set-$something",
84+ "foo": "data-1",
85+ "baz": "data-2"}
86+
87+ The only required key is "type": the rest are dependent on which data
88+ item is processed.
89+
90+ There are a few conventions in naming the "callback" methods:
91+
92+ - Methods that will be called only once to set a single item are
93+ named set\* (example setArchitecture).
94+ - Methods that can be called many times due to processing of several
95+ similar items (packages, devices) are named add\*
96+ (example addDeviceState). Look at the existing methods to see how they
97+ append to an existing element of the messages list.
98+ """
99
100 project = "certification"
101
102@@ -96,6 +138,12 @@
103 "module": module,
104 "options": options})
105
106+ def setKernelCmdline(self, kernel_cmdline):
107+ self.messages.append({
108+ "type": "set-kernel-cmdline",
109+ "kernel_cmdline": kernel_cmdline})
110+ logger.debug("Setting Kernel Commandline: %s", kernel_cmdline)
111+
112 def setDistribution(self, **distribution):
113 self.messages.append({
114 "type": "set-distribution",
115@@ -499,6 +547,9 @@
116 ("cpuinfo", "machine", "cpuinfo_result",),
117 self.setCpuinfo, count=1)
118 register(
119+ ("test_run", "kernel_cmdline",),
120+ self.setKernelCmdline, count=1)
121+ register(
122 ("meminfo", "meminfo_result",),
123 self.setMeminfo, count=1)
124 register(
125@@ -542,6 +593,7 @@
126 r"udevadm": self.parseUdevadm,
127 r"efi(?!rtvariable)": EfiParser,
128 r"modprobe_attachment": self.parseModprobe,
129+ r"kernel_cmdline": self.parseKernelCmdline,
130 }
131 for context, parser in context_parsers.items():
132 if re.search(context, command):
133@@ -656,6 +708,10 @@
134 elif name == "kernel-release":
135 self.dispatcher.publishEvent("kernel", value)
136
137+ def parseKernelCmdline(self, cmdline):
138+ self.dispatcher.publishEvent("kernel_cmdline", cmdline)
139+ return DeferredParser(self.dispatcher, "kernel_cmdline_result")
140+
141 def parseCpuinfo(self, cpuinfo):
142 self.dispatcher.publishEvent("cpuinfo", cpuinfo)
143 return DeferredParser(self.dispatcher, "cpuinfo_result")
144@@ -680,6 +736,10 @@
145 def setKernelState(self, test_run, kernel):
146 test_run.setKernelState(kernel)
147
148+ def setKernelCmdline(self, test_run, kernel_cmdline):
149+ parser = KernelCmdlineParser(kernel_cmdline)
150+ parser.run(test_run)
151+
152 def setCpuinfo(self, cpuinfo, machine, cpuinfo_result):
153 parser = CpuinfoParser(cpuinfo, machine)
154 parser.run(cpuinfo_result)
155@@ -1002,6 +1062,18 @@
156 "Unsupported tag <%s> in <system>" % child.tag)
157
158 def run(self, test_run_factory, **kwargs):
159+ """
160+ Entry point to start parsing the stream with which the parser
161+ was initialized.
162+
163+ :param test_run_factory: A class from which to instantiate a
164+ "test_run" object whose add\*/set\* methods will be called as elements
165+ are found in the stream
166+
167+ :returns: a SubmissionResult instance. This is not really used
168+ and seems redundant, as the data will be processed and stored by
169+ the TestRun instance (which is, however, also not returned anywhere).
170+ """
171 parser = etree.XMLParser()
172
173 tree = etree.parse(self.file, parser=parser)
174
175=== added file 'checkbox-support/checkbox_support/parsers/tests/fixtures/submission_info_kernel_cmdline.xml'
176--- checkbox-support/checkbox_support/parsers/tests/fixtures/submission_info_kernel_cmdline.xml 1970-01-01 00:00:00 +0000
177+++ checkbox-support/checkbox_support/parsers/tests/fixtures/submission_info_kernel_cmdline.xml 2015-05-13 13:30:33 +0000
178@@ -0,0 +1,10 @@
179+<?xml version="1.0" ?>
180+<system version="1.0">
181+ <context>
182+ <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
183+ </info>
184+ </context>
185+ <summary>
186+ <architecture value="amd64"/>
187+ </summary>
188+</system>
189
190=== modified file 'checkbox-support/checkbox_support/parsers/tests/test_submission.py'
191--- checkbox-support/checkbox_support/parsers/tests/test_submission.py 2015-05-12 18:08:20 +0000
192+++ checkbox-support/checkbox_support/parsers/tests/test_submission.py 2015-05-13 13:30:33 +0000
193@@ -54,6 +54,9 @@
194 self.result.setdefault('module_options', {})
195 self.result['module_options'][module] = options
196
197+ def setKernelCmdline(self, kernel_cmdline):
198+ self.result['kernel_cmdline'] = kernel_cmdline
199+
200 def addAttachment(self, **attachment):
201 self.result.setdefault("attachments", [])
202 self.result["attachments"].append(attachment)
203@@ -187,6 +190,13 @@
204 self.assertIn("single_cmd=1",
205 result['module_options']['snd-hda-intel'])
206
207+ def test_kernel_cmdline(self):
208+ """a kernel commandline can be in a kernel_cmdline info element."""
209+ result = self.getResult("submission_info_kernel_cmdline.xml")
210+ self.assertTrue("kernel_cmdline" in result)
211+ self.assertIn("ro quiet splash video.use_native_backlight=1",
212+ result["kernel_cmdline"])
213+
214 def test_device_dmidecode(self):
215 """Device states can be in a dmidecode info element."""
216 result = self.getResult("submission_info_dmidecode.xml")

Subscribers

People subscribed via source and target branches