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 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochABS_PATH_PREFIX = os.getcwd() + os.sep 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ProgressIndicator(object): 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def __init__(self): 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.runner = None 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def SetRunner(self, runner): 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.runner = runner 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Starting(self): 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pass 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Done(self): 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pass 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def AboutToRun(self, test): 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pass 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pass 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def Heartbeat(self): 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pass 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def PrintFailureHeader(self, test): 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.suite.IsNegativeTest(test): 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negative_marker = '[negative] ' 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negative_marker = '' 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "=== %(label)s %(negative)s===" % { 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'label': test.GetLabel(), 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'negative': negative_marker 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def _EscapeCommand(self, test): 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch command = execution.GetCommand(test, self.runner.context) 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parts = [] 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for part in command: 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ' ' in part: 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # Escape spaces. We may need to escape more characters for this 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # to work properly. 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parts.append('"%s"' % part) 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch else: 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parts.append(part) 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return " ".join(parts) 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass IndicatorNotifier(object): 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch """Holds a list of progress indicators and notifies them all on events.""" 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def __init__(self): 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.indicators = [] 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def Register(self, indicator): 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.indicators.append(indicator) 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch# Forge all generic event-dispatching methods in IndicatorNotifier, which are 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch# part of the ProgressIndicator interface. 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfor func_name in ProgressIndicator.__dict__: 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch func = getattr(ProgressIndicator, func_name) 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if callable(func) and not func.__name__.startswith('_'): 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def wrap_functor(f): 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch @wraps(f) 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def functor(self, *args, **kwargs): 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch """Generic event dispatcher.""" 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for indicator in self.indicators: 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch getattr(indicator, f.__name__)(*args, **kwargs) 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return functor 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch setattr(IndicatorNotifier, func_name, wrap_functor(func)) 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SimpleProgressIndicator(ProgressIndicator): 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch """Abstract base class for {Verbose,Dots}ProgressIndicator""" 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Starting(self): 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print 'Running %i tests' % self.runner.total 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Done(self): 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for failed in self.runner.failed: 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.PrintFailureHeader(failed) 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if failed.output.stderr: 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- stderr ---" 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print failed.output.stderr.strip() 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if failed.output.stdout: 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- stdout ---" 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print failed.output.stdout.strip() 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print "Command: %s" % self._EscapeCommand(failed) 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if failed.output.HasCrashed(): 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "exit code: %d" % failed.output.exit_code 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- CRASHED ---" 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if failed.output.HasTimedOut(): 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- TIMEOUT ---" 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if len(self.runner.failed) == 0: 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "===" 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "=== All tests succeeded" 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "===" 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "===" 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "=== %i tests failed" % len(self.runner.failed) 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if self.runner.crashed > 0: 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "=== %i tests CRASHED" % self.runner.crashed 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "===" 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass VerboseProgressIndicator(SimpleProgressIndicator): 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def AboutToRun(self, test): 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print 'Starting %s...' % test.GetLabel() 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if has_unexpected_output: 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasCrashed(): 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outcome = 'CRASH' 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outcome = 'FAIL' 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outcome = 'pass' 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print 'Done running %s: %s' % (test.GetLabel(), outcome) 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sys.stdout.flush() 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def Heartbeat(self): 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print 'Still working...' 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sys.stdout.flush() 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DotsProgressIndicator(SimpleProgressIndicator): 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch total = self.runner.succeeded + len(self.runner.failed) 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (total > 1) and (total % 50 == 1): 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.write('\n') 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if has_unexpected_output: 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasCrashed(): 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.write('C') 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elif test.output.HasTimedOut(): 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.write('T') 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.write('F') 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.write('.') 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CompactProgressIndicator(ProgressIndicator): 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch """Abstract base class for {Color,Monochrome}ProgressIndicator""" 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def __init__(self, templates): 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch super(CompactProgressIndicator, self).__init__() 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.templates = templates 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.last_status_length = 0 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.start_time = time.time() 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Done(self): 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.PrintProgress('Done') 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "" # Line break. 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def AboutToRun(self, test): 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.PrintProgress(test.GetLabel()) 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if has_unexpected_output: 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.ClearLine(self.last_status_length) 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.PrintFailureHeader(test) 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stdout = test.output.stdout.strip() 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if len(stdout): 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print self.templates['stdout'] % stdout 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stderr = test.output.stderr.strip() 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if len(stderr): 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print self.templates['stderr'] % stderr 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print "Command: %s" % self._EscapeCommand(test) 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasCrashed(): 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "exit code: %d" % test.output.exit_code 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- CRASHED ---" 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasTimedOut(): 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "--- TIMEOUT ---" 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Truncate(self, string, length): 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if length and (len(string) > (length - 3)): 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return string[:(length - 3)] + "..." 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return string 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def PrintProgress(self, name): 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.ClearLine(self.last_status_length) 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elapsed = time.time() - self.start_time 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch progress = 0 if not self.runner.total else ( 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ((self.runner.total - self.runner.remaining) * 100) // 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.runner.total) 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status = self.templates['status_line'] % { 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'passed': self.runner.succeeded, 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 'progress': progress, 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'failed': len(self.runner.failed), 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'test': name, 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'mins': int(elapsed) / 60, 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'secs': int(elapsed) % 60 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch status = self.Truncate(status, 78) 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.last_status_length = len(status) 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print status, 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sys.stdout.flush() 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ColorProgressIndicator(CompactProgressIndicator): 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def __init__(self): 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch templates = { 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'status_line': ("[%(mins)02i:%(secs)02i|" 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "\033[34m%%%(progress) 4d\033[0m|" 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "\033[32m+%(passed) 4d\033[0m|" 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "\033[31m-%(failed) 4d\033[0m]: %(test)s"), 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'stdout': "\033[1m%s\033[0m", 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'stderr': "\033[31m%s\033[0m", 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch super(ColorProgressIndicator, self).__init__(templates) 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def ClearLine(self, last_line_length): 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print "\033[1K\r", 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MonochromeProgressIndicator(CompactProgressIndicator): 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def __init__(self): 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch templates = { 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 'status_line': ("[%(mins)02i:%(secs)02i|%%%(progress) 4d|" 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "+%(passed) 4d|-%(failed) 4d]: %(test)s"), 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'stdout': '%s', 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'stderr': '%s', 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch super(MonochromeProgressIndicator, self).__init__(templates) 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def ClearLine(self, last_line_length): 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch print ("\r" + (" " * last_line_length) + "\r"), 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass JUnitTestProgressIndicator(ProgressIndicator): 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def __init__(self, junitout, junittestsuite): 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outputter = junit_output.JUnitTestOutput(junittestsuite) 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if junitout: 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outfile = open(junitout, "w") 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch else: 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outfile = sys.stdout 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Done(self): 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outputter.FinishAndWrite(self.outfile) 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if self.outfile != sys.stdout: 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outfile.close() 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text = "" 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if has_unexpected_output: 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stdout = test.output.stdout.strip() 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if len(stdout): 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text += "stdout:\n%s\n" % stdout 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stderr = test.output.stderr.strip() 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if len(stderr): 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text += "stderr:\n%s\n" % stderr 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch fail_text += "Command: %s" % self._EscapeCommand(test) 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasCrashed(): 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text += "exit code: %d\n--- CRASHED ---" % test.output.exit_code 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if test.output.HasTimedOut(): 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text += "--- TIMEOUT ---" 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.outputter.HasRunTest( 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch [test.GetLabel()] + self.runner.context.mode_flags + test.flags, 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch test.duration, 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fail_text) 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass JsonTestProgressIndicator(ProgressIndicator): 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def __init__(self, json_test_results, arch, mode, random_seed): 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.json_test_results = json_test_results 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.arch = arch 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.mode = mode 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.random_seed = random_seed 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.results = [] 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.tests = [] 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def Done(self): 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch complete_results = [] 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if os.path.exists(self.json_test_results): 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch with open(self.json_test_results, "r") as f: 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch # Buildbot might start out with an empty file. 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch complete_results = json.loads(f.read() or "[]") 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # Sort tests by duration. 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch timed_tests = [t for t in self.tests if t.duration is not None] 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch timed_tests.sort(lambda a, b: cmp(b.duration, a.duration)) 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch slowest_tests = [ 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "name": test.GetLabel(), 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "flags": test.flags, 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "command": self._EscapeCommand(test).replace(ABS_PATH_PREFIX, ""), 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "duration": test.duration, 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } for test in timed_tests[:20] 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ] 343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch complete_results.append({ 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "arch": self.arch, 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "mode": self.mode, 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "results": self.results, 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "slowest_tests": slowest_tests, 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }) 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch with open(self.json_test_results, "w") as f: 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f.write(json.dumps(complete_results)) 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch def HasRun(self, test, has_unexpected_output): 355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # Buffer all tests for sorting the durations in the end. 356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch self.tests.append(test) 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if not has_unexpected_output: 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch # Omit tests that run as expected. Passing tests of reruns after failures 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch # will have unexpected_output to be reported here has well. 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch self.results.append({ 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "name": test.GetLabel(), 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "flags": test.flags, 365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "command": self._EscapeCommand(test).replace(ABS_PATH_PREFIX, ""), 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "run": test.run, 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "stdout": test.output.stdout, 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "stderr": test.output.stderr, 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "exit_code": test.output.exit_code, 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "result": test.suite.GetOutcome(test), 371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier "expected": list(test.outcomes or ["PASS"]), 372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "duration": test.duration, 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # TODO(machenbach): This stores only the global random seed from the 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # context and not possible overrides when using random-seed stress. 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "random_seed": self.random_seed, 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "target_name": test.suite.shell(), 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch "variant": test.variant, 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }) 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochPROGRESS_INDICATORS = { 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'verbose': VerboseProgressIndicator, 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'dots': DotsProgressIndicator, 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'color': ColorProgressIndicator, 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 'mono': MonochromeProgressIndicator 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 388