Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: tools/testrunner/local/progress.py

Issue 1469833002: [test-runner] Move test case processing beyond the multi-process boundary. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/testrunner/local/pool.py ('k') | tools/testrunner/local/testsuite.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2012 the V8 project authors. All rights reserved. 1 # Copyright 2012 the V8 project authors. All rights reserved.
2 # Redistribution and use in source and binary forms, with or without 2 # Redistribution and use in source and binary forms, with or without
3 # modification, are permitted provided that the following conditions are 3 # modification, are permitted provided that the following conditions are
4 # met: 4 # met:
5 # 5 #
6 # * Redistributions of source code must retain the above copyright 6 # * Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer. 7 # notice, this list of conditions and the following disclaimer.
8 # * Redistributions in binary form must reproduce the above 8 # * Redistributions in binary form must reproduce the above
9 # copyright notice, this list of conditions and the following 9 # copyright notice, this list of conditions and the following
10 # disclaimer in the documentation and/or other materials provided 10 # disclaimer in the documentation and/or other materials provided
(...skipping 14 matching lines...) Expand all
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 28
29 from functools import wraps 29 from functools import wraps
30 import json 30 import json
31 import os 31 import os
32 import sys 32 import sys
33 import time 33 import time
34 34
35 from . import execution
35 from . import junit_output 36 from . import junit_output
36 37
37 38
38 ABS_PATH_PREFIX = os.getcwd() + os.sep 39 ABS_PATH_PREFIX = os.getcwd() + os.sep
39 40
40 41
41 def EscapeCommand(command):
42 parts = []
43 for part in command:
44 if ' ' in part:
45 # Escape spaces. We may need to escape more characters for this
46 # to work properly.
47 parts.append('"%s"' % part)
48 else:
49 parts.append(part)
50 return " ".join(parts)
51
52
53 class ProgressIndicator(object): 42 class ProgressIndicator(object):
54 43
55 def __init__(self): 44 def __init__(self):
56 self.runner = None 45 self.runner = None
57 46
58 def SetRunner(self, runner): 47 def SetRunner(self, runner):
59 self.runner = runner 48 self.runner = runner
60 49
61 def Starting(self): 50 def Starting(self):
62 pass 51 pass
(...skipping 13 matching lines...) Expand all
76 def PrintFailureHeader(self, test): 65 def PrintFailureHeader(self, test):
77 if test.suite.IsNegativeTest(test): 66 if test.suite.IsNegativeTest(test):
78 negative_marker = '[negative] ' 67 negative_marker = '[negative] '
79 else: 68 else:
80 negative_marker = '' 69 negative_marker = ''
81 print "=== %(label)s %(negative)s===" % { 70 print "=== %(label)s %(negative)s===" % {
82 'label': test.GetLabel(), 71 'label': test.GetLabel(),
83 'negative': negative_marker 72 'negative': negative_marker
84 } 73 }
85 74
75 def _EscapeCommand(self, test):
76 command = execution.GetCommand(test, self.runner.context)
77 parts = []
78 for part in command:
79 if ' ' in part:
80 # Escape spaces. We may need to escape more characters for this
81 # to work properly.
82 parts.append('"%s"' % part)
83 else:
84 parts.append(part)
85 return " ".join(parts)
86
86 87
87 class IndicatorNotifier(object): 88 class IndicatorNotifier(object):
88 """Holds a list of progress indicators and notifies them all on events.""" 89 """Holds a list of progress indicators and notifies them all on events."""
89 def __init__(self): 90 def __init__(self):
90 self.indicators = [] 91 self.indicators = []
91 92
92 def Register(self, indicator): 93 def Register(self, indicator):
93 self.indicators.append(indicator) 94 self.indicators.append(indicator)
94 95
95 96
(...skipping 21 matching lines...) Expand all
117 def Done(self): 118 def Done(self):
118 print 119 print
119 for failed in self.runner.failed: 120 for failed in self.runner.failed:
120 self.PrintFailureHeader(failed) 121 self.PrintFailureHeader(failed)
121 if failed.output.stderr: 122 if failed.output.stderr:
122 print "--- stderr ---" 123 print "--- stderr ---"
123 print failed.output.stderr.strip() 124 print failed.output.stderr.strip()
124 if failed.output.stdout: 125 if failed.output.stdout:
125 print "--- stdout ---" 126 print "--- stdout ---"
126 print failed.output.stdout.strip() 127 print failed.output.stdout.strip()
127 print "Command: %s" % EscapeCommand(self.runner.GetCommand(failed)) 128 print "Command: %s" % self._EscapeCommand(failed)
128 if failed.output.HasCrashed(): 129 if failed.output.HasCrashed():
129 print "exit code: %d" % failed.output.exit_code 130 print "exit code: %d" % failed.output.exit_code
130 print "--- CRASHED ---" 131 print "--- CRASHED ---"
131 if failed.output.HasTimedOut(): 132 if failed.output.HasTimedOut():
132 print "--- TIMEOUT ---" 133 print "--- TIMEOUT ---"
133 if len(self.runner.failed) == 0: 134 if len(self.runner.failed) == 0:
134 print "===" 135 print "==="
135 print "=== All tests succeeded" 136 print "=== All tests succeeded"
136 print "===" 137 print "==="
137 else: 138 else:
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 def HasRun(self, test, has_unexpected_output): 206 def HasRun(self, test, has_unexpected_output):
206 if has_unexpected_output: 207 if has_unexpected_output:
207 self.ClearLine(self.last_status_length) 208 self.ClearLine(self.last_status_length)
208 self.PrintFailureHeader(test) 209 self.PrintFailureHeader(test)
209 stdout = test.output.stdout.strip() 210 stdout = test.output.stdout.strip()
210 if len(stdout): 211 if len(stdout):
211 print self.templates['stdout'] % stdout 212 print self.templates['stdout'] % stdout
212 stderr = test.output.stderr.strip() 213 stderr = test.output.stderr.strip()
213 if len(stderr): 214 if len(stderr):
214 print self.templates['stderr'] % stderr 215 print self.templates['stderr'] % stderr
215 print "Command: %s" % EscapeCommand(self.runner.GetCommand(test)) 216 print "Command: %s" % self._EscapeCommand(test)
216 if test.output.HasCrashed(): 217 if test.output.HasCrashed():
217 print "exit code: %d" % test.output.exit_code 218 print "exit code: %d" % test.output.exit_code
218 print "--- CRASHED ---" 219 print "--- CRASHED ---"
219 if test.output.HasTimedOut(): 220 if test.output.HasTimedOut():
220 print "--- TIMEOUT ---" 221 print "--- TIMEOUT ---"
221 222
222 def Truncate(self, string, length): 223 def Truncate(self, string, length):
223 if length and (len(string) > (length - 3)): 224 if length and (len(string) > (length - 3)):
224 return string[:(length - 3)] + "..." 225 return string[:(length - 3)] + "..."
225 else: 226 else:
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 294
294 def HasRun(self, test, has_unexpected_output): 295 def HasRun(self, test, has_unexpected_output):
295 fail_text = "" 296 fail_text = ""
296 if has_unexpected_output: 297 if has_unexpected_output:
297 stdout = test.output.stdout.strip() 298 stdout = test.output.stdout.strip()
298 if len(stdout): 299 if len(stdout):
299 fail_text += "stdout:\n%s\n" % stdout 300 fail_text += "stdout:\n%s\n" % stdout
300 stderr = test.output.stderr.strip() 301 stderr = test.output.stderr.strip()
301 if len(stderr): 302 if len(stderr):
302 fail_text += "stderr:\n%s\n" % stderr 303 fail_text += "stderr:\n%s\n" % stderr
303 fail_text += "Command: %s" % EscapeCommand(self.runner.GetCommand(test)) 304 fail_text += "Command: %s" % self._EscapeCommand(test)
304 if test.output.HasCrashed(): 305 if test.output.HasCrashed():
305 fail_text += "exit code: %d\n--- CRASHED ---" % test.output.exit_code 306 fail_text += "exit code: %d\n--- CRASHED ---" % test.output.exit_code
306 if test.output.HasTimedOut(): 307 if test.output.HasTimedOut():
307 fail_text += "--- TIMEOUT ---" 308 fail_text += "--- TIMEOUT ---"
308 self.outputter.HasRunTest( 309 self.outputter.HasRunTest(
309 [test.GetLabel()] + self.runner.context.mode_flags + test.flags, 310 [test.GetLabel()] + self.runner.context.mode_flags + test.flags,
310 test.duration, 311 test.duration,
311 fail_text) 312 fail_text)
312 313
313 314
(...skipping 14 matching lines...) Expand all
328 # Buildbot might start out with an empty file. 329 # Buildbot might start out with an empty file.
329 complete_results = json.loads(f.read() or "[]") 330 complete_results = json.loads(f.read() or "[]")
330 331
331 # Sort tests by duration. 332 # Sort tests by duration.
332 timed_tests = [t for t in self.tests if t.duration is not None] 333 timed_tests = [t for t in self.tests if t.duration is not None]
333 timed_tests.sort(lambda a, b: cmp(b.duration, a.duration)) 334 timed_tests.sort(lambda a, b: cmp(b.duration, a.duration))
334 slowest_tests = [ 335 slowest_tests = [
335 { 336 {
336 "name": test.GetLabel(), 337 "name": test.GetLabel(),
337 "flags": test.flags, 338 "flags": test.flags,
338 "command": EscapeCommand(self.runner.GetCommand(test)).replace( 339 "command": self._EscapeCommand(test).replace(ABS_PATH_PREFIX, ""),
339 ABS_PATH_PREFIX, ""),
340 "duration": test.duration, 340 "duration": test.duration,
341 } for test in timed_tests[:20] 341 } for test in timed_tests[:20]
342 ] 342 ]
343 343
344 complete_results.append({ 344 complete_results.append({
345 "arch": self.arch, 345 "arch": self.arch,
346 "mode": self.mode, 346 "mode": self.mode,
347 "results": self.results, 347 "results": self.results,
348 "slowest_tests": slowest_tests, 348 "slowest_tests": slowest_tests,
349 }) 349 })
350 350
351 with open(self.json_test_results, "w") as f: 351 with open(self.json_test_results, "w") as f:
352 f.write(json.dumps(complete_results)) 352 f.write(json.dumps(complete_results))
353 353
354 def HasRun(self, test, has_unexpected_output): 354 def HasRun(self, test, has_unexpected_output):
355 # Buffer all tests for sorting the durations in the end. 355 # Buffer all tests for sorting the durations in the end.
356 self.tests.append(test) 356 self.tests.append(test)
357 if not has_unexpected_output: 357 if not has_unexpected_output:
358 # Omit tests that run as expected. Passing tests of reruns after failures 358 # Omit tests that run as expected. Passing tests of reruns after failures
359 # will have unexpected_output to be reported here has well. 359 # will have unexpected_output to be reported here has well.
360 return 360 return
361 361
362 self.results.append({ 362 self.results.append({
363 "name": test.GetLabel(), 363 "name": test.GetLabel(),
364 "flags": test.flags, 364 "flags": test.flags,
365 "command": EscapeCommand(self.runner.GetCommand(test)).replace( 365 "command": self._EscapeCommand(test).replace(ABS_PATH_PREFIX, ""),
366 ABS_PATH_PREFIX, ""),
367 "run": test.run, 366 "run": test.run,
368 "stdout": test.output.stdout, 367 "stdout": test.output.stdout,
369 "stderr": test.output.stderr, 368 "stderr": test.output.stderr,
370 "exit_code": test.output.exit_code, 369 "exit_code": test.output.exit_code,
371 "result": test.suite.GetOutcome(test), 370 "result": test.suite.GetOutcome(test),
372 "expected": list(test.outcomes or ["PASS"]), 371 "expected": list(test.outcomes or ["PASS"]),
373 "duration": test.duration, 372 "duration": test.duration,
374 373
375 # TODO(machenbach): This stores only the global random seed from the 374 # TODO(machenbach): This stores only the global random seed from the
376 # context and not possible overrides when using random-seed stress. 375 # context and not possible overrides when using random-seed stress.
377 "random_seed": self.random_seed, 376 "random_seed": self.random_seed,
378 "target_name": test.suite.shell(), 377 "target_name": test.suite.shell(),
379 "variant": test.variant, 378 "variant": test.variant,
380 }) 379 })
381 380
382 381
383 PROGRESS_INDICATORS = { 382 PROGRESS_INDICATORS = {
384 'verbose': VerboseProgressIndicator, 383 'verbose': VerboseProgressIndicator,
385 'dots': DotsProgressIndicator, 384 'dots': DotsProgressIndicator,
386 'color': ColorProgressIndicator, 385 'color': ColorProgressIndicator,
387 'mono': MonochromeProgressIndicator 386 'mono': MonochromeProgressIndicator
388 } 387 }
OLDNEW
« no previous file with comments | « tools/testrunner/local/pool.py ('k') | tools/testrunner/local/testsuite.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698