1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# Redistribution and use in source and binary forms, with or without 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# modification, are permitted provided that the following conditions are 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# met: 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# * Redistributions of source code must retain the above copyright 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# notice, this list of conditions and the following disclaimer. 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# * Redistributions in binary form must reproduce the above 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# copyright notice, this list of conditions and the following 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# disclaimer in the documentation and/or other materials provided 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# with the distribution. 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# * Neither the name of Google Inc. nor the names of its 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# contributors may be used to endorse or promote products derived 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# from this software without specific prior written permission. 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfrom functools import wraps 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport json 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport os 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport sys 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport time 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfrom . import execution 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfrom . import junit_output 37bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochfrom . import statusfile 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochABS_PATH_PREFIX = os.getcwd() + os.sep 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ProgressIndicator(object): 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def __init__(self): 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.runner = None 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def SetRunner(self, runner): 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.runner = runner 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Starting(self): 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pass 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Done(self): 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pass 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pass 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def Heartbeat(self): 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pass 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def PrintFailureHeader(self, test): 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.suite.IsNegativeTest(test): 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negative_marker = '[negative] ' 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negative_marker = '' 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "=== %(label)s %(negative)s===" % { 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'label': test.GetLabel(), 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'negative': negative_marker 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def _EscapeCommand(self, test): 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch command = execution.GetCommand(test, self.runner.context) 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parts = [] 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for part in command: 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ' ' in part: 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # Escape spaces. We may need to escape more characters for this 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # to work properly. 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parts.append('"%s"' % part) 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch else: 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parts.append(part) 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return " ".join(parts) 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass IndicatorNotifier(object): 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch """Holds a list of progress indicators and notifies them all on events.""" 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def __init__(self): 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.indicators = [] 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def Register(self, indicator): 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.indicators.append(indicator) 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch# Forge all generic event-dispatching methods in IndicatorNotifier, which are 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch# part of the ProgressIndicator interface. 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfor func_name in ProgressIndicator.__dict__: 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch func = getattr(ProgressIndicator, func_name) 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if callable(func) and not func.__name__.startswith('_'): 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def wrap_functor(f): 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch @wraps(f) 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def functor(self, *args, **kwargs): 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch """Generic event dispatcher.""" 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for indicator in self.indicators: 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch getattr(indicator, f.__name__)(*args, **kwargs) 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return functor 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch setattr(IndicatorNotifier, func_name, wrap_functor(func)) 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SimpleProgressIndicator(ProgressIndicator): 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch """Abstract base class for {Verbose,Dots}ProgressIndicator""" 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Starting(self): 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print 'Running %i tests' % self.runner.total 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Done(self): 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for failed in self.runner.failed: 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.PrintFailureHeader(failed) 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if failed.output.stderr: 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- stderr ---" 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print failed.output.stderr.strip() 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if failed.output.stdout: 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- stdout ---" 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print failed.output.stdout.strip() 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print "Command: %s" % self._EscapeCommand(failed) 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if failed.output.HasCrashed(): 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "exit code: %d" % failed.output.exit_code 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- CRASHED ---" 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if failed.output.HasTimedOut(): 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- TIMEOUT ---" 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if len(self.runner.failed) == 0: 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "===" 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "=== All tests succeeded" 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "===" 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "===" 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "=== %i tests failed" % len(self.runner.failed) 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if self.runner.crashed > 0: 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "=== %i tests CRASHED" % self.runner.crashed 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "===" 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass VerboseProgressIndicator(SimpleProgressIndicator): 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if has_unexpected_output: 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasCrashed(): 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outcome = 'CRASH' 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outcome = 'FAIL' 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outcome = 'pass' 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print 'Done running %s: %s' % (test.GetLabel(), outcome) 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sys.stdout.flush() 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def Heartbeat(self): 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print 'Still working...' 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sys.stdout.flush() 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DotsProgressIndicator(SimpleProgressIndicator): 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total = self.runner.succeeded + len(self.runner.failed) 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (total > 1) and (total % 50 == 1): 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.write('\n') 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if has_unexpected_output: 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasCrashed(): 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.write('C') 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elif test.output.HasTimedOut(): 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.write('T') 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.write('F') 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.write('.') 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CompactProgressIndicator(ProgressIndicator): 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch """Abstract base class for {Color,Monochrome}ProgressIndicator""" 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def __init__(self, templates): 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch super(CompactProgressIndicator, self).__init__() 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.templates = templates 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.last_status_length = 0 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.start_time = time.time() 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Done(self): 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.PrintProgress('Done') 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "" # Line break. 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 198bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch self.PrintProgress(test.GetLabel()) 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if has_unexpected_output: 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.ClearLine(self.last_status_length) 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.PrintFailureHeader(test) 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stdout = test.output.stdout.strip() 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if len(stdout): 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print self.templates['stdout'] % stdout 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stderr = test.output.stderr.strip() 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if len(stderr): 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print self.templates['stderr'] % stderr 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print "Command: %s" % self._EscapeCommand(test) 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasCrashed(): 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "exit code: %d" % test.output.exit_code 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- CRASHED ---" 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasTimedOut(): 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- TIMEOUT ---" 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Truncate(self, string, length): 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if length and (len(string) > (length - 3)): 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return string[:(length - 3)] + "..." 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return string 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def PrintProgress(self, name): 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.ClearLine(self.last_status_length) 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elapsed = time.time() - self.start_time 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch progress = 0 if not self.runner.total else ( 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ((self.runner.total - self.runner.remaining) * 100) // 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.runner.total) 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status = self.templates['status_line'] % { 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'passed': self.runner.succeeded, 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 'progress': progress, 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'failed': len(self.runner.failed), 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'test': name, 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'mins': int(elapsed) / 60, 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'secs': int(elapsed) % 60 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status = self.Truncate(status, 78) 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.last_status_length = len(status) 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print status, 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ColorProgressIndicator(CompactProgressIndicator): 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def __init__(self): 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch templates = { 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'status_line': ("[%(mins)02i:%(secs)02i|" 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "\033[34m%%%(progress) 4d\033[0m|" 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "\033[32m+%(passed) 4d\033[0m|" 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "\033[31m-%(failed) 4d\033[0m]: %(test)s"), 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'stdout': "\033[1m%s\033[0m", 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'stderr': "\033[31m%s\033[0m", 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch super(ColorProgressIndicator, self).__init__(templates) 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def ClearLine(self, last_line_length): 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "\033[1K\r", 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MonochromeProgressIndicator(CompactProgressIndicator): 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def __init__(self): 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch templates = { 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 'status_line': ("[%(mins)02i:%(secs)02i|%%%(progress) 4d|" 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "+%(passed) 4d|-%(failed) 4d]: %(test)s"), 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'stdout': '%s', 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'stderr': '%s', 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch super(MonochromeProgressIndicator, self).__init__(templates) 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def ClearLine(self, last_line_length): 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print ("\r" + (" " * last_line_length) + "\r"), 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass JUnitTestProgressIndicator(ProgressIndicator): 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def __init__(self, junitout, junittestsuite): 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outputter = junit_output.JUnitTestOutput(junittestsuite) 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if junitout: 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outfile = open(junitout, "w") 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outfile = sys.stdout 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Done(self): 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outputter.FinishAndWrite(self.outfile) 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if self.outfile != sys.stdout: 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outfile.close() 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text = "" 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if has_unexpected_output: 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stdout = test.output.stdout.strip() 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if len(stdout): 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text += "stdout:\n%s\n" % stdout 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stderr = test.output.stderr.strip() 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if len(stderr): 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text += "stderr:\n%s\n" % stderr 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch fail_text += "Command: %s" % self._EscapeCommand(test) 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasCrashed(): 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text += "exit code: %d\n--- CRASHED ---" % test.output.exit_code 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasTimedOut(): 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text += "--- TIMEOUT ---" 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outputter.HasRunTest( 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch [test.GetLabel()] + self.runner.context.mode_flags + test.flags, 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch test.duration, 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text) 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass JsonTestProgressIndicator(ProgressIndicator): 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def __init__(self, json_test_results, arch, mode, random_seed): 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.json_test_results = json_test_results 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.arch = arch 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.mode = mode 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.random_seed = random_seed 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.results = [] 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.tests = [] 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Done(self): 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch complete_results = [] 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if os.path.exists(self.json_test_results): 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch with open(self.json_test_results, "r") as f: 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch # Buildbot might start out with an empty file. 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch complete_results = json.loads(f.read() or "[]") 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 324bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch duration_mean = None 325bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if self.tests: 326bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch # Get duration mean. 327bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch duration_mean = ( 328bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch sum(t.duration for t in self.tests) / float(len(self.tests))) 329bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # Sort tests by duration. 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch timed_tests = [t for t in self.tests if t.duration is not None] 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch timed_tests.sort(lambda a, b: cmp(b.duration, a.duration)) 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch slowest_tests = [ 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "name": test.GetLabel(), 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "flags": test.flags, 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "command": self._EscapeCommand(test).replace(ABS_PATH_PREFIX, ""), 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "duration": test.duration, 339bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch "marked_slow": statusfile.IsSlow(test.outcomes), 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } for test in timed_tests[:20] 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ] 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch complete_results.append({ 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "arch": self.arch, 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "mode": self.mode, 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "results": self.results, 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "slowest_tests": slowest_tests, 348bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch "duration_mean": duration_mean, 349bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch "test_total": len(self.tests), 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }) 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch with open(self.json_test_results, "w") as f: 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.write(json.dumps(complete_results)) 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # Buffer all tests for sorting the durations in the end. 357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.tests.append(test) 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if not has_unexpected_output: 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch # Omit tests that run as expected. Passing tests of reruns after failures 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch # will have unexpected_output to be reported here has well. 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.results.append({ 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "name": test.GetLabel(), 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "flags": test.flags, 366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "command": self._EscapeCommand(test).replace(ABS_PATH_PREFIX, ""), 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "run": test.run, 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "stdout": test.output.stdout, 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "stderr": test.output.stderr, 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "exit_code": test.output.exit_code, 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "result": test.suite.GetOutcome(test), 372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "expected": list(test.outcomes or ["PASS"]), 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "duration": test.duration, 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # TODO(machenbach): This stores only the global random seed from the 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # context and not possible overrides when using random-seed stress. 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "random_seed": self.random_seed, 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "target_name": test.suite.shell(), 379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "variant": test.variant, 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }) 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochPROGRESS_INDICATORS = { 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'verbose': VerboseProgressIndicator, 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'dots': DotsProgressIndicator, 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'color': ColorProgressIndicator, 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'mono': MonochromeProgressIndicator 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 389