Merge lp:~le-chi-thu/lava-test/add-tutorial-1 into lp:lava-test/0.0

Proposed by Le Chi Thu
Status: Rejected
Rejected by: Neil Williams
Proposed branch: lp:~le-chi-thu/lava-test/add-tutorial-1
Merge into: lp:lava-test/0.0
Diff against target: 189 lines (+112/-25)
4 files modified
doc/usage.rst (+93/-15)
examples/stream.json (+5/-3)
lava_test/core/runners.py (+4/-0)
lava_test/test_definitions/stream.py (+10/-7)
To merge this branch: bzr merge lp:~le-chi-thu/lava-test/add-tutorial-1
Reviewer Review Type Date Requested Status
Zygmunt Krynicki (community) Needs Fixing
Review via email: mp+94131@code.launchpad.net

Description of the change

Added tutorial how to create new test and how to implement own test result parser.

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

Hi ChiThu.

42 + run = TestRunner(RUNSTEPS,default_options=DEFAULT_OPTIONS)

not PEP-8 clean

86 +artifacts.stdout_pathname is the file stored the output of the test execution. By parsing this file and append the test
87 +result to the self.results['test_result'] list. The :meth:`~lava_test.core.parsers.TestParser.analyze_test_result` help
88 +method will do the sanity check and also perform the fixup of the result.

IMHO this is not easy to understand. The "fixup" is vague, what is it about, why is it necessary? (I know, but think about the readers)

115 + $ lava-test register http://abc.com/my-custom-test.json

Use example.{com,org,net} per RFC 2606

66 + class LTPParser(TestParser):
67 + def parse(self, artifacts):

Again PEP-8

72 + with open(filename, 'r') as fd:

This is a logical bug, open does not return a file descriptor. It returns a file-like object. That object happens to have (on some platforms) a fileno() method that returns a descriptor number. Call it 'stream' instead; this is just confusing the reader.

121 +To see how the json file look like, let see the examples/stream.json. This file shows how to write the stream test in
122 +json format. Same test is written in python format: lava_test/test_definitions/stream.py.

This is also confusing. We should explain what the JSON representation does. It tells lava-test how to construct a test object out of the available test classes. While learning by example is fine without explanation it _will_ lead to confusion.

63 +To show how to implement the new parser, let have a closer look at one of existing test - lava_test/test_definitions/ltp.py

(snip)
66 + class LTPParser(TestParser):
67 + def parse(self, artifacts):
68 + filename = artifacts.stdout_pathname
69 + print "filename=%s" %filename
70 + # PATTERN = "^(?P<test_case_id>\S+) (?P<subid>\d+) (?P<result>\w+) : (?P<message>.+)"

None of this code makes any sense to the reader. What you should have started with is a discussion on what the test parser is for. Start by showing what the test program output looks like. Highlighting the parts that we want to capture in LAVA and then constructing simple code that does that. Only then show how to wrap that code in a Parser class.

review: Needs Fixing
Revision history for this message
Paul Larson (pwlars) wrote :

bump - ChiThu are you planning to update this soon?

Unmerged revisions

119. By Le Chi Thu <email address hidden> <email address hidden>

Added tutorial how to add new test and some minor documentation update.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/usage.rst'
2--- doc/usage.rst 2011-09-12 09:19:10 +0000
3+++ doc/usage.rst 2012-02-22 11:47:17 +0000
4@@ -141,6 +141,89 @@
5 nice to have a tutorial that walks the user through wrapping a
6 simple pass/fail test.
7
8+Tutorial how to add a new test to LAVA
9+======================================
10+
11+Below are the steps needed to add a new test.
12+
13+* add a new python file in lava_test/test_definitions folder.
14+* add the document of new test in lava_test/doc-test/doc/tests.rst
15+* add the new test to the BuiltInProvider static list in lava_test/core/providers.py
16+* implement the new test
17+
18+To show how to implement the new test, let have a closer look at one of existing test - lava_test/test_definitions/stream.py
19+
20+First import the classes needed ::
21+
22+ from lava_test.core.installers import TestInstaller
23+ from lava_test.core.parsers import TestParser
24+ from lava_test.core.runners import TestRunner
25+ from lava_test.core.tests import Test
26+
27+Create the :class:`~lava_test.core.installers.TestInstaller` object. We tell the installer to download the stream.c.
28+Install the gcc and build-essential Ubuntu packages before compile the stream.c ::
29+
30+ URL="http://www.cs.virginia.edu/stream/FTP/Code/stream.c"
31+ INSTALLSTEPS = ['cc stream.c -O2 -fopenmp -o stream']
32+ DEPS = ['gcc', 'build-essential']
33+
34+ install = TestInstaller(INSTALLSTEPS, deps=DEPS, url=URL)
35+
36+Create the :class:`~lava_test.core.runners.TestRunner` object. We tell the runner to execute the stream command with
37+empty default options ::
38+
39+ DEFAULT_OPTIONS = ""
40+ RUNSTEPS = ['./stream $(OPTIONS)']
41+
42+ run = TestRunner(RUNSTEPS,default_options=DEFAULT_OPTIONS)
43+
44+Create the :class:`~lava_test.core.parsers.TestParser` object. We tell the parser to match each line with regular
45+expression. When the output of the test is parse, the parser will have a list of results. Each result is a dictionary
46+and we ask parser to append the 'units':'MB/s' and 'result':'pass' to the result dictionary. ::
47+
48+ PATTERN = "^(?P<test_case_id>\w+):\W+(?P<measurement>\d+\.\d+)"
49+
50+ parse = TestParser(PATTERN, appendall={'units':'MB/s', 'result':'pass'})
51+
52+Create the :class:`~lava_test.core.tests.Test` object and name it as testobj which is expected by the test loader.
53+::
54+
55+ testobj = Test(test_id="stream", installer=install,runner=run, parser=parse)
56+
57+Tutorial how to create own result parser
58+========================================
59+
60+If the :class:`~lava_test.core.parsers.TestParser` not fulfill the need to parse the test result, you can derive
61+the :class:`~lava_test.core.parsers.TestParser` and overwrite the method :meth:`~lava_test.api.core.ITest.parse`.
62+
63+To show how to implement the new parser, let have a closer look at one of existing test - lava_test/test_definitions/ltp.py
64+::
65+
66+ class LTPParser(TestParser):
67+ def parse(self, artifacts):
68+ filename = artifacts.stdout_pathname
69+ print "filename=%s" %filename
70+ # PATTERN = "^(?P<test_case_id>\S+) (?P<subid>\d+) (?P<result>\w+) : (?P<message>.+)"
71+ pat = re.compile(self.pattern)
72+ with open(filename, 'r') as fd:
73+ for line in fd.readlines():
74+ match = pat.search(line)
75+ if match:
76+ results = match.groupdict()
77+ subid = results.pop('subid')
78+ #The .0 results in ltp are all TINFO, filtering them
79+ #should help eliminate meaningless, duplicate results
80+ if subid == '0':
81+ continue
82+ results['test_case_id'] += "." + subid
83+ self.results['test_results'].append(
84+ self.analyze_test_result(results))
85+
86+artifacts.stdout_pathname is the file stored the output of the test execution. By parsing this file and append the test
87+result to the self.results['test_result'] list. The :meth:`~lava_test.core.parsers.TestParser.analyze_test_result` help
88+method will do the sanity check and also perform the fixup of the result.
89+
90+
91 Maintaining out-of-tree tests
92 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
93
94@@ -178,18 +261,13 @@
95 Maintaining simple declarative tests
96 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
97
98-By registering pure declarative tests at runtime.
99-
100-.. todo::
101-
102- Describe how to use declarative tests. It would be a nice
103- extension of the tutorial once the user feels comfortable with
104- the initial python-based version.
105-
106-Writing new tests from scratch
107-==============================
108-
109-.. todo::
110-
111- Describe considerations for test writers. Using native test
112- format with human-readable output adapters.
113+A declarative test is a json access able by lava-test. The following commands are used in a test scenario. ::
114+
115+ $ lava-test register http://abc.com/my-custom-test.json
116+ $ lava-test install my-custom-test
117+ $ lava-test run my-custom-test
118+ $ lava-test uninstall my-custom-test
119+ $ lava-test unregister http://abc.com/my-custom-test.json
120+
121+To see how the json file look like, let see the examples/stream.json. This file shows how to write the stream test in
122+json format. Same test is written in python format: lava_test/test_definitions/stream.py.
123
124=== modified file 'examples/stream.json'
125--- examples/stream.json 2011-09-12 09:19:10 +0000
126+++ examples/stream.json 2012-02-22 11:47:17 +0000
127@@ -2,11 +2,13 @@
128 "format": "LAVA-Test Test Definition Format",
129 "test_id": "stream-json",
130 "install": {
131- "url": "http://www.cs.virginia.edu/stream/FTP/Code/stream.c",
132- "steps": ["cc stream.c -O2 -fopenmp -o stream"]
133+ "steps": ["cc stream.c -O2 -fopenmp -o stream"],
134+ "deps": ['gcc', 'build-essential'],
135+ "url": "http://www.cs.virginia.edu/stream/FTP/Code/stream.c"
136 },
137 "run": {
138- "steps": ["./stream"]
139+ "steps": ["./stream"],
140+ "default_options": ""
141 },
142 "parse": {
143 "pattern": "^(?P<test_case_id>\\w+):\\W+(?P<measurement>\\d+\\.\\d+)",
144
145=== modified file 'lava_test/core/runners.py'
146--- lava_test/core/runners.py 2011-10-20 17:53:31 +0000
147+++ lava_test/core/runners.py 2012-02-22 11:47:17 +0000
148@@ -31,6 +31,10 @@
149
150 :ivar steps:
151 list of shell commands to execute
152+
153+ :ivar default_options:
154+ The macro $(OPTIONS) in the run steps will be replaced by the command line argument -t
155+ set $(OPTIONS) to this default options if the user not overwritten with the command line option -t
156 """
157 def __init__(self, steps=None, default_options=None):
158 self.steps = steps or []
159
160=== modified file 'lava_test/test_definitions/stream.py'
161--- lava_test/test_definitions/stream.py 2011-10-20 12:12:15 +0000
162+++ lava_test/test_definitions/stream.py 2012-02-22 11:47:17 +0000
163@@ -18,18 +18,21 @@
164 from lava_test.core.runners import TestRunner
165 from lava_test.core.tests import Test
166
167-URL="http://www.cs.virginia.edu/stream/FTP/Code/stream.c"
168 INSTALLSTEPS = ['cc stream.c -O2 -fopenmp -o stream']
169 DEPS = ['gcc', 'build-essential']
170+URL="http://www.cs.virginia.edu/stream/FTP/Code/stream.c"
171+
172+install = TestInstaller(INSTALLSTEPS, deps=DEPS, url=URL)
173+
174 DEFAULT_OPTIONS = ""
175 RUNSTEPS = ['./stream $(OPTIONS)']
176+
177+run = TestRunner(RUNSTEPS,default_options=DEFAULT_OPTIONS)
178+
179 PATTERN = "^(?P<test_case_id>\w+):\W+(?P<measurement>\d+\.\d+)"
180
181-streaminst = TestInstaller(INSTALLSTEPS, deps=DEPS, url=URL)
182-streamrun = TestRunner(RUNSTEPS,default_options=DEFAULT_OPTIONS)
183-streamparser = TestParser(PATTERN,
184- appendall={'units':'MB/s', 'result':'pass'})
185-testobj = Test(test_id="stream", installer=streaminst,
186- runner=streamrun, parser=streamparser)
187+parse = TestParser(PATTERN, appendall={'units':'MB/s', 'result':'pass'})
188+
189+testobj = Test(test_id="stream", installer=install, runner=run, parser=parse)
190
191

Subscribers

People subscribed via source and target branches