Merge lp:~pwlars/lava-test/betteroutput into lp:lava-test/0.0

Proposed by Paul Larson
Status: Merged
Merged at revision: 34
Proposed branch: lp:~pwlars/lava-test/betteroutput
Merge into: lp:lava-test/0.0
Diff against target: 227 lines (+93/-22)
4 files modified
abrek/builtins.py (+3/-1)
abrek/testdef.py (+8/-9)
abrek/utils.py (+32/-1)
tests/test_abrektestrunner.py (+50/-11)
To merge this branch: bzr merge lp:~pwlars/lava-test/betteroutput
Reviewer Review Type Date Requested Status
Linaro Infrastructure Pending
Review via email: mp+36233@code.launchpad.net

Description of the change

This adds a -q/--quiet option for running tests, and changes default
behavior to be verbose. Some long running tests would leave the user
without feedback during the run. To do this, two util functions were
added as well. One to run commands and poll for output, and another to
mimic tee functionality so that output can optionally be sent to stdout,
and to a logfile.

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

124 + proc = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
125 + while proc.poll() is None:
126 + output, err = proc.communicate()
127 + if output is not None:
128 + fd.write(output)
129 + return proc.returncode

I'm not sure what poll() does exactly but I remember writing similar code without it. Just call proc.communicate() - it blocks until the subprocess finishes. Am I missing anything?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'abrek/builtins.py'
2--- abrek/builtins.py 2010-08-26 20:05:06 +0000
3+++ abrek/builtins.py 2010-09-21 22:42:49 +0000
4@@ -79,6 +79,8 @@
5 Run tests
6 """
7 arglist = ['*testname']
8+ options = [make_option('-q', '--quiet', action='store_true',
9+ default=False, dest='quiet')]
10
11 def run(self):
12 if len(self.args) != 1:
13@@ -86,7 +88,7 @@
14 sys.exit(1)
15 test = abrek.testdef.testloader(self.args[0])
16 try:
17- test.run()
18+ test.run(quiet=self.opts.quiet)
19 except Exception as strerror:
20 print "Test execution error: %s" % strerror
21 sys.exit(1)
22
23=== modified file 'abrek/testdef.py'
24--- abrek/testdef.py 2010-09-21 02:07:11 +0000
25+++ abrek/testdef.py 2010-09-21 22:42:49 +0000
26@@ -25,7 +25,7 @@
27 from uuid import uuid1
28
29 from abrek.config import get_config
30-from abrek.utils import geturl, write_file
31+from abrek.utils import Tee, geturl, run_and_log, write_file
32 from abrek import hwprofile
33 from abrek import swprofile
34
35@@ -105,7 +105,7 @@
36 testdata['sw_context'] = sw
37 write_file(json.dumps(testdata), filename)
38
39- def run(self):
40+ def run(self, quiet=False):
41 if not self.runner:
42 raise RuntimeError("no test runner defined for '%s'" %
43 self.testname)
44@@ -114,7 +114,7 @@
45 self.resultsdir = os.path.join(self.config.resultsdir, resultname)
46 os.makedirs(self.resultsdir)
47 os.chdir(self.installdir)
48- self.runner.run(self.resultsdir)
49+ self.runner.run(self.resultsdir, quiet=quiet)
50 self._savetestdata()
51
52 def parse(self, resultname):
53@@ -200,16 +200,15 @@
54 self.steps = steps
55 self.testoutput = []
56
57- def _runsteps(self, resultsdir):
58+ def _runsteps(self, resultsdir, quiet=False):
59 outputlog = os.path.join(resultsdir, 'testoutput.log')
60- with open(outputlog, 'a') as fd:
61+ with Tee(outputlog, 'a', quiet=quiet) as fd:
62 for cmd in self.steps:
63- rc, output = getstatusoutput(cmd)
64- fd.write(output)
65+ run_and_log(cmd, fd)
66
67- def run(self, resultsdir):
68+ def run(self, resultsdir, quiet=False):
69 self.starttime = datetime.utcnow()
70- self._runsteps(resultsdir)
71+ self._runsteps(resultsdir, quiet=quiet)
72 self.endtime = datetime.utcnow()
73
74
75
76=== modified file 'abrek/utils.py'
77--- abrek/utils.py 2010-09-18 04:21:56 +0000
78+++ abrek/utils.py 2010-09-21 22:42:49 +0000
79@@ -13,14 +13,34 @@
80 # You should have received a copy of the GNU General Public License
81 # along with this program. If not, see <http://www.gnu.org/licenses/>.
82
83+import os
84 import shutil
85-import os
86+import sys
87 import urllib2
88 import urlparse
89+from subprocess import Popen, PIPE
90
91 _fake_files = None
92 _fake_paths = None
93
94+class Tee(file):
95+ """ A file-like object that optionally mimics tee functionality.
96+
97+ By default, output will go to both stdout and the file specified.
98+ Optionally, quiet=True can be used to mute the output to stdout.
99+ """
100+ def __init__(self, *args, **kwargs):
101+ try:
102+ self.quiet = kwargs.pop('quiet')
103+ except KeyError:
104+ self.quiet = False
105+ super(Tee, self).__init__(*args, **kwargs)
106+
107+ def write(self, data):
108+ super(Tee, self).write(data)
109+ if self.quiet is False:
110+ sys.stdout.write(data)
111+
112 def geturl(url, path=""):
113 urlpath = urlparse.urlsplit(url).path
114 filename = os.path.basename(urlpath)
115@@ -77,3 +97,14 @@
116 global _fake_paths
117 _fake_files = {}
118 _fake_paths = {}
119+
120+def run_and_log(cmd, fd):
121+ """
122+ Run a command and log the output to fd
123+ """
124+ proc = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
125+ while proc.poll() is None:
126+ output, err = proc.communicate()
127+ if output is not None:
128+ fd.write(output)
129+ return proc.returncode
130
131=== modified file 'tests/test_abrektestrunner.py'
132--- tests/test_abrektestrunner.py 2010-09-10 17:09:14 +0000
133+++ tests/test_abrektestrunner.py 2010-09-21 22:42:49 +0000
134@@ -20,9 +20,13 @@
135 from datetime import datetime
136
137 from abrek.testdef import AbrekTestRunner
138-
139-
140-class testAbrekTestInstaller(unittest.TestCase):
141+from imposters import OutputImposter
142+from fixtures import TestCaseWithFixtures
143+
144+def makerunner(**kwargs):
145+ return AbrekTestRunner(**kwargs)
146+
147+class testAbrekTestRunner(unittest.TestCase):
148 def setUp(self):
149 self.origdir = os.path.abspath(os.curdir)
150 self.tmpdir = tempfile.mkdtemp()
151@@ -33,33 +37,68 @@
152 os.chdir(self.origdir)
153 shutil.rmtree(self.tmpdir)
154
155- def makerunner(self,**kwargs):
156- return AbrekTestRunner(**kwargs)
157-
158 def test_starttime(self):
159- runner = self.makerunner()
160+ runner = makerunner()
161 runner.run(self.tmpdir)
162 self.assertTrue(isinstance(runner.starttime, datetime))
163
164 def test_endtime(self):
165- runner = self.makerunner()
166+ runner = makerunner()
167 runner.run(self.tmpdir)
168 self.assertTrue(isinstance(runner.endtime, datetime))
169
170 def test_timediff(self):
171 steps = ['sleep 2']
172- runner = self.makerunner(steps=steps)
173+ runner = makerunner(steps=steps)
174 runner.run(self.tmpdir)
175 self.assertNotEqual(runner.starttime, runner.endtime)
176
177 def test_runsteps(self):
178 steps = ["echo test > foo"]
179- runner = self.makerunner(steps=steps)
180+ runner = makerunner(steps=steps)
181 runner._runsteps(self.tmpdir)
182 self.assertTrue(os.path.exists("./foo"))
183
184 def test_logoutput(self):
185 steps = ["echo test > foo"]
186- runner = self.makerunner(steps=steps)
187+ runner = makerunner(steps=steps)
188 runner._runsteps(self.tmpdir)
189 self.assertTrue(os.path.exists("./testoutput.log"))
190+
191+class testAbrekTestRunnerVerbosity(TestCaseWithFixtures):
192+ def setUp(self):
193+ super(testAbrekTestRunnerVerbosity, self).setUp()
194+ self.origdir = os.path.abspath(os.curdir)
195+ self.tmpdir = tempfile.mkdtemp()
196+ self.filename = os.path.abspath(__file__)
197+ os.chdir(self.tmpdir)
198+ self.out = self.add_fixture(OutputImposter())
199+
200+ def tearDown(self):
201+ super(testAbrekTestRunnerVerbosity, self).tearDown()
202+ os.chdir(self.origdir)
203+ shutil.rmtree(self.tmpdir)
204+
205+ def test_runsteps_quiet_true(self):
206+ steps = ["echo test"]
207+ runner = makerunner(steps=steps)
208+ runner._runsteps(self.tmpdir, quiet=True)
209+ self.assertEqual("", self.out.getvalue().strip())
210+
211+ def test_runsteps_quiet_false(self):
212+ steps = ["echo test"]
213+ runner = makerunner(steps=steps)
214+ runner._runsteps(self.tmpdir, quiet=False)
215+ self.assertEqual("test", self.out.getvalue().strip())
216+
217+ def test_run_quiet_true(self):
218+ steps = ["echo test"]
219+ runner = makerunner(steps=steps)
220+ runner.run(self.tmpdir, quiet=True)
221+ self.assertEqual("", self.out.getvalue().strip())
222+
223+ def test_run_quiet_false(self):
224+ steps = ["echo test"]
225+ runner = makerunner(steps=steps)
226+ runner.run(self.tmpdir, quiet=False)
227+ self.assertEqual("test", self.out.getvalue().strip())

Subscribers

People subscribed via source and target branches