1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#!/usr/bin/env python 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# 33ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch# Copyright 2012 the V8 project authors. All rights reserved. 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# Redistribution and use in source and binary forms, with or without 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# modification, are permitted provided that the following conditions are 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# met: 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# * Redistributions of source code must retain the above copyright 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# notice, this list of conditions and the following disclaimer. 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# * Redistributions in binary form must reproduce the above 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# copyright notice, this list of conditions and the following 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# disclaimer in the documentation and/or other materials provided 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# with the distribution. 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# * Neither the name of Google Inc. nor the names of its 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# contributors may be used to endorse or promote products derived 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# from this software without specific prior written permission. 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport imp 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport optparse 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport os 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfrom os.path import join, dirname, abspath, basename, isdir, exists 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport platform 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport re 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport signal 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport subprocess 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport sys 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport tempfile 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport time 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport threading 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport utils 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfrom Queue import Queue, Empty 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockVERBOSE = False 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# --------------------------------------------- 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# --- P r o g r e s s I n d i c a t o r s --- 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# --------------------------------------------- 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ProgressIndicator(object): 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, cases): 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.cases = cases 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.queue = Queue(len(cases)) 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for case in cases: 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.queue.put_nowait(case) 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.succeeded = 0 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.remaining = len(cases) 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.total = len(cases) 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.failed = [ ] 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.crashed = 0 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.terminate = False 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.lock = threading.Lock() 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def PrintFailureHeader(self, test): 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if test.IsNegative(): 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block negative_marker = '[negative] ' 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block negative_marker = '' 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "=== %(label)s %(negative)s===" % { 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'label': test.GetLabel(), 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'negative': negative_marker 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Path: %s" % "/".join(test.path) 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Run(self, tasks): 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Starting() 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threads = [] 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Spawn N-1 threads and then use this thread as the last one. 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # That way -j1 avoids threading altogether which is a nice fallback 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # in case of threading problems. 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for i in xrange(tasks - 1): 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread = threading.Thread(target=self.RunSingle, args=[]) 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threads.append(thread) 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread.start() 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try: 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.RunSingle() 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Wait for the remaining threads 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for thread in threads: 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Use a timeout so that signals (ctrl-c) will be processed. 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread.join(timeout=10000000) 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block except Exception, e: 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # If there's an exception we schedule an interruption for any 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # remaining threads. 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.terminate = True 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # ...and then reraise the exception to bail out 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block raise 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Done() 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return not self.failed 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def RunSingle(self): 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while not self.terminate: 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try: 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block test = self.queue.get_nowait() 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block except Empty: 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case = test.case 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.lock.acquire() 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.AboutToRun(case) 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.lock.release() 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try: 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start = time.time() 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block output = case.Run() 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case.duration = (time.time() - start) 120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch except BreakNowException: 121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch self.terminate = True 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block except IOError, e: 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assert self.terminate 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.terminate: 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.lock.acquire() 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if output.UnexpectedOutput(): 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.failed.append(output) 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if output.HasCrashed(): 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.crashed += 1 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.succeeded += 1 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.remaining -= 1 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.HasRun(output) 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.lock.release() 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef EscapeCommand(command): 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parts = [] 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for part in command: 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ' ' in part: 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Escape spaces. We may need to escape more characters for this 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # to work properly. 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parts.append('"%s"' % part) 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parts.append(part) 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return " ".join(parts) 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SimpleProgressIndicator(ProgressIndicator): 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Starting(self): 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print 'Running %i tests' % len(self.cases) 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Done(self): 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for failed in self.failed: 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.PrintFailureHeader(failed.test) 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if failed.output.stderr: 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "--- stderr ---" 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print failed.output.stderr.strip() 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if failed.output.stdout: 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "--- stdout ---" 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print failed.output.stdout.strip() 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Command: %s" % EscapeCommand(failed.command) 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if failed.HasCrashed(): 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "--- CRASHED ---" 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if failed.HasTimedOut(): 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "--- TIMEOUT ---" 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if len(self.failed) == 0: 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "===" 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "=== All tests succeeded" 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "===" 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "===" 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "=== %i tests failed" % len(self.failed) 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.crashed > 0: 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "=== %i tests CRASHED" % self.crashed 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "===" 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass VerboseProgressIndicator(SimpleProgressIndicator): 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def AboutToRun(self, case): 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print 'Starting %s...' % case.GetLabel() 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.flush() 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def HasRun(self, output): 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if output.UnexpectedOutput(): 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if output.HasCrashed(): 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block outcome = 'CRASH' 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block outcome = 'FAIL' 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block outcome = 'pass' 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print 'Done running %s: %s' % (output.test.GetLabel(), outcome) 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DotsProgressIndicator(SimpleProgressIndicator): 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def AboutToRun(self, case): 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pass 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def HasRun(self, output): 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block total = self.succeeded + len(self.failed) 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (total > 1) and (total % 50 == 1): 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.write('\n') 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if output.UnexpectedOutput(): 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if output.HasCrashed(): 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.write('C') 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.flush() 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif output.HasTimedOut(): 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.write('T') 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.flush() 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.write('F') 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.flush() 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.write('.') 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.flush() 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CompactProgressIndicator(ProgressIndicator): 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, cases, templates): 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block super(CompactProgressIndicator, self).__init__(cases) 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.templates = templates 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.last_status_length = 0 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.start_time = time.time() 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Starting(self): 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pass 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Done(self): 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.PrintProgress('Done') 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def AboutToRun(self, case): 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.PrintProgress(case.GetLabel()) 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def HasRun(self, output): 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if output.UnexpectedOutput(): 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.ClearLine(self.last_status_length) 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.PrintFailureHeader(output.test) 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stdout = output.output.stdout.strip() 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if len(stdout): 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print self.templates['stdout'] % stdout 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stderr = output.output.stderr.strip() 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if len(stderr): 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print self.templates['stderr'] % stderr 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Command: %s" % EscapeCommand(output.command) 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if output.HasCrashed(): 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "--- CRASHED ---" 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if output.HasTimedOut(): 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "--- TIMEOUT ---" 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Truncate(self, str, length): 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if length and (len(str) > (length - 3)): 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return str[:(length-3)] + "..." 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return str 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def PrintProgress(self, name): 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.ClearLine(self.last_status_length) 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elapsed = time.time() - self.start_time 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block status = self.templates['status_line'] % { 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'passed': self.succeeded, 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'remaining': (((self.total - self.remaining) * 100) // self.total), 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'failed': len(self.failed), 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'test': name, 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'mins': int(elapsed) / 60, 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'secs': int(elapsed) % 60 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block status = self.Truncate(status, 78) 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.last_status_length = len(status) 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print status, 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stdout.flush() 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ColorProgressIndicator(CompactProgressIndicator): 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, cases): 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block templates = { 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'status_line': "[%(mins)02i:%(secs)02i|\033[34m%%%(remaining) 4d\033[0m|\033[32m+%(passed) 4d\033[0m|\033[31m-%(failed) 4d\033[0m]: %(test)s", 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'stdout': "\033[1m%s\033[0m", 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'stderr': "\033[31m%s\033[0m", 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block super(ColorProgressIndicator, self).__init__(cases, templates) 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def ClearLine(self, last_line_length): 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "\033[1K\r", 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass MonochromeProgressIndicator(CompactProgressIndicator): 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, cases): 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block templates = { 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'status_line': "[%(mins)02i:%(secs)02i|%%%(remaining) 4d|+%(passed) 4d|-%(failed) 4d]: %(test)s", 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'stdout': '%s', 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'stderr': '%s', 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'clear': lambda last_line_length: ("\r" + (" " * last_line_length) + "\r"), 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'max_length': 78 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block super(MonochromeProgressIndicator, self).__init__(cases, templates) 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def ClearLine(self, last_line_length): 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print ("\r" + (" " * last_line_length) + "\r"), 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockPROGRESS_INDICATORS = { 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'verbose': VerboseProgressIndicator, 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'dots': DotsProgressIndicator, 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'color': ColorProgressIndicator, 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'mono': MonochromeProgressIndicator 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# ------------------------- 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# --- F r a m e w o r k --- 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# ------------------------- 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 323257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass BreakNowException(Exception): 324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch def __init__(self, value): 325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch self.value = value 326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch def __str__(self): 327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return repr(self.value) 328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CommandOutput(object): 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, exit_code, timed_out, stdout, stderr): 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.exit_code = exit_code 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.timed_out = timed_out 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.stdout = stdout 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.stderr = stderr 3373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block self.failed = None 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TestCase(object): 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen def __init__(self, context, path, mode): 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.path = path 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.context = context 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.duration = None 34680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen self.mode = mode 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IsNegative(self): 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35144f0eee88ff00398ff7f715fab053374d808c90dSteve Block def TestsIsolates(self): 35244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return False 35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def CompareTime(self, other): 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return cmp(other.duration, self.duration) 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def DidFail(self, output): 3583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if output.failed is None: 3593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block output.failed = self.IsFailureOutput(output) 3603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return output.failed 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IsFailureOutput(self, output): 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return output.exit_code != 0 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetSource(self): 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "(no source available)" 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def RunCommand(self, command): 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block full_command = self.context.processor(command) 37080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen output = Execute(full_command, 37180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen self.context, 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch self.context.GetTimeout(self, self.mode)) 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Cleanup() 37480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return TestOutput(self, 37580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen full_command, 37680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen output, 37780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen self.context.store_unexpected_output) 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 379d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block def BeforeRun(self): 380d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block pass 381d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 38280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen def AfterRun(self, result): 383d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block pass 384d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 38544f0eee88ff00398ff7f715fab053374d808c90dSteve Block def GetCustomFlags(self, mode): 38644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return None 38744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Run(self): 389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block self.BeforeRun() 390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch result = None 391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block try: 392d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block result = self.RunCommand(self.GetCommand()) 393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch except: 394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch self.terminate = True 395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch raise BreakNowException("User pressed CTRL+C or IO went wrong") 396d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block finally: 39780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen self.AfterRun(result) 398d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return result 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Cleanup(self): 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TestOutput(object): 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen def __init__(self, test, command, output, store_unexpected_output): 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.test = test 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.command = command 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.output = output 41080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen self.store_unexpected_output = store_unexpected_output 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def UnexpectedOutput(self): 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.HasCrashed(): 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block outcome = CRASH 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.HasTimedOut(): 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block outcome = TIMEOUT 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.HasFailed(): 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block outcome = FAIL 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block outcome = PASS 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return not outcome in self.test.outcomes 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen def HasPreciousOutput(self): 42480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return self.UnexpectedOutput() and self.store_unexpected_output 42580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def HasCrashed(self): 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if utils.IsWindows(): 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0x80000000 & self.output.exit_code and not (0x3FFFFF00 & self.output.exit_code) 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Timed out tests will have exit_code -signal.SIGTERM. 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.output.timed_out: 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.output.exit_code < 0 and \ 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.output.exit_code != -signal.SIGABRT 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def HasTimedOut(self): 437257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return self.output.timed_out 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def HasFailed(self): 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block execution_failed = self.test.DidFail(self.output) 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.test.IsNegative(): 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return not execution_failed 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return execution_failed 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef KillProcessWithID(pid): 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if utils.IsWindows(): 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block os.popen('taskkill /T /F /PID %d' % pid) 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block os.kill(pid, signal.SIGTERM) 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAX_SLEEP_TIME = 0.1 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockINITIAL_SLEEP_TIME = 0.0001 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSLEEP_TIME_FACTOR = 1.25 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSEM_INVALID_VALUE = -1 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef Win32SetErrorMode(mode): 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block prev_error_mode = SEM_INVALID_VALUE 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try: 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block import ctypes 465257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch prev_error_mode = ctypes.windll.kernel32.SetErrorMode(mode) 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block except ImportError: 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pass 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return prev_error_mode 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef RunProcess(context, timeout, args, **rest): 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if context.verbose: print "#", " ".join(args) 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block popen_args = args 473257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch prev_error_mode = SEM_INVALID_VALUE 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if utils.IsWindows(): 4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch popen_args = subprocess.list2cmdline(args) 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if context.suppress_dialogs: 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Try to change the error mode to avoid dialogs on fatal errors. Don't 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # touch any existing error mode flags by merging the existing error mode. 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # See http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx. 480257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch error_mode = SEM_NOGPFAULTERRORBOX 481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch prev_error_mode = Win32SetErrorMode(error_mode) 482257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Win32SetErrorMode(error_mode | prev_error_mode) 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block process = subprocess.Popen( 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shell = utils.IsWindows(), 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block args = popen_args, 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block **rest 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ) 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if utils.IsWindows() and context.suppress_dialogs and prev_error_mode != SEM_INVALID_VALUE: 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Win32SetErrorMode(prev_error_mode) 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Compute the end time - if the process crosses this limit we 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # consider it timed out. 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if timeout is None: end_time = None 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: end_time = time.time() + timeout 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block timed_out = False 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Repeatedly check the exit code from the process in a 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # loop and keep track of whether or not it times out. 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exit_code = None 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sleep_time = INITIAL_SLEEP_TIME 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while exit_code is None: 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (not end_time is None) and (time.time() >= end_time): 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Kill the process and wait for it to exit. 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block KillProcessWithID(process.pid) 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exit_code = process.wait() 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block timed_out = True 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exit_code = process.poll() 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block time.sleep(sleep_time) 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sleep_time = sleep_time * SLEEP_TIME_FACTOR 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if sleep_time > MAX_SLEEP_TIME: 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sleep_time = MAX_SLEEP_TIME 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (process, exit_code, timed_out) 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef PrintError(str): 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stderr.write(str) 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stderr.write('\n') 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef CheckedUnlink(name): 52044f0eee88ff00398ff7f715fab053374d808c90dSteve Block # On Windows, when run with -jN in parallel processes, 52144f0eee88ff00398ff7f715fab053374d808c90dSteve Block # OS often fails to unlink the temp file. Not sure why. 52244f0eee88ff00398ff7f715fab053374d808c90dSteve Block # Need to retry. 52344f0eee88ff00398ff7f715fab053374d808c90dSteve Block # Idea from https://bugs.webkit.org/attachment.cgi?id=75982&action=prettypatch 52444f0eee88ff00398ff7f715fab053374d808c90dSteve Block retry_count = 0 52544f0eee88ff00398ff7f715fab053374d808c90dSteve Block while retry_count < 30: 52644f0eee88ff00398ff7f715fab053374d808c90dSteve Block try: 52744f0eee88ff00398ff7f715fab053374d808c90dSteve Block os.unlink(name) 52844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return 52944f0eee88ff00398ff7f715fab053374d808c90dSteve Block except OSError, e: 530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch retry_count += 1 53144f0eee88ff00398ff7f715fab053374d808c90dSteve Block time.sleep(retry_count * 0.1) 53244f0eee88ff00398ff7f715fab053374d808c90dSteve Block PrintError("os.unlink() " + str(e)) 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef Execute(args, context, timeout=None): 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (fd_out, outname) = tempfile.mkstemp() 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (fd_err, errname) = tempfile.mkstemp() 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (process, exit_code, timed_out) = RunProcess( 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context, 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block timeout, 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block args = args, 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stdout = fd_out, 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stderr = fd_err, 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ) 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block os.close(fd_out) 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block os.close(fd_err) 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block output = file(outname).read() 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block errors = file(errname).read() 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckedUnlink(outname) 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckedUnlink(errname) 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CommandOutput(exit_code, timed_out, output, errors) 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ExecuteNoCapture(args, context, timeout=None): 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (process, exit_code, timed_out) = RunProcess( 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context, 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block timeout, 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block args = args, 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ) 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CommandOutput(exit_code, False, "", "") 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef CarCdr(path): 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if len(path) == 0: 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (None, [ ]) 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (path[0], path[1:]) 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch# Use this to run several variants of the tests, e.g.: 570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch# VARIANT_FLAGS = [[], ['--always_compact', '--noflush_code']] 571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochVARIANT_FLAGS = [[], 572257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ['--stress-opt', '--always-opt'], 573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ['--nocrankshaft']] 574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TestConfiguration(object): 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, context, root): 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.context = context 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.root = root 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Contains(self, path, file): 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if len(path) > len(file): 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for i in xrange(len(path)): 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not path[i].match(file[i]): 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return True 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetTestStatus(self, sections, defs): 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pass 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch def VariantFlags(self): 594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return VARIANT_FLAGS 595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 596257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 597257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TestSuite(object): 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, name): 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.name = name 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetName(self): 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.name 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TestRepository(TestSuite): 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, path): 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block normalized_path = abspath(path) 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block super(TestRepository, self).__init__(basename(normalized_path)) 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.path = normalized_path 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.is_loaded = False 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.config = None 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetConfiguration(self, context): 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.is_loaded: 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.config 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.is_loaded = True 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block file = None 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try: 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (file, pathname, description) = imp.find_module('testcfg', [ self.path ]) 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block module = imp.load_module('testcfg', file, pathname, description) 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.config = module.GetConfiguration(context, self.path) 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block finally: 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if file: 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block file.close() 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.config 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetBuildRequirements(self, path, context): 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.GetConfiguration(context).GetBuildRequirements() 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def DownloadData(self, context): 6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch config = self.GetConfiguration(context) 6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if 'DownloadData' in dir(config): 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch config.DownloadData() 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 63980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen def AddTestsToList(self, result, current_path, path, context, mode): 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch config = self.GetConfiguration(context) 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for v in config.VariantFlags(): 6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch tests = config.ListTests(current_path, path, mode, v) 64380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen for t in tests: t.variant_flags = v 64480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen result += tests 64580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetTestStatus(self, context, sections, defs): 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.GetConfiguration(context).GetTestStatus(sections, defs) 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass LiteralTestSuite(TestSuite): 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, tests): 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block super(LiteralTestSuite, self).__init__('root') 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.tests = tests 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetBuildRequirements(self, path, context): 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (name, rest) = CarCdr(path) 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = [ ] 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for test in self.tests: 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not name or name.match(test.GetName()): 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result += test.GetBuildRequirements(rest, context) 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch def DownloadData(self, path, context): 6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (name, rest) = CarCdr(path) 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for test in self.tests: 6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if not name or name.match(test.GetName()): 6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch test.DownloadData(context) 6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 67044f0eee88ff00398ff7f715fab053374d808c90dSteve Block def ListTests(self, current_path, path, context, mode, variant_flags): 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (name, rest) = CarCdr(path) 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = [ ] 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for test in self.tests: 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block test_name = test.GetName() 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not name or name.match(test_name): 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block full_path = current_path + [test_name] 67780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen test.AddTestsToList(result, full_path, path, context, mode) 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetTestStatus(self, context, sections, defs): 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for test in self.tests: 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block test.GetTestStatus(context, sections, defs) 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 68580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenSUFFIX = { 68680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 'debug' : '_g', 68780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 'release' : '' } 68880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenFLAGS = { 6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 'debug' : ['--nobreak-on-abort', '--enable-slow-asserts', '--debug-code', '--verify-heap'], 6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 'release' : ['--nobreak-on-abort']} 69180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenTIMEOUT_SCALEFACTOR = { 69280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 'debug' : 4, 69380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 'release' : 1 } 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Context(object): 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen def __init__(self, workspace, buildspace, verbose, vm, timeout, processor, suppress_dialogs, store_unexpected_output): 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.workspace = workspace 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.buildspace = buildspace 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.verbose = verbose 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.vm_root = vm 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.timeout = timeout 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.processor = processor 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.suppress_dialogs = suppress_dialogs 70680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen self.store_unexpected_output = store_unexpected_output 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetVm(self, mode): 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name = self.vm_root + SUFFIX[mode] 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if utils.IsWindows() and not name.endswith('.exe'): 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name = name + '.exe' 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return name 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 71480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen def GetVmCommand(self, testcase, mode): 71580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return [self.GetVm(mode)] + self.GetVmFlags(testcase, mode) 71680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 71780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen def GetVmFlags(self, testcase, mode): 71844f0eee88ff00398ff7f715fab053374d808c90dSteve Block flags = testcase.GetCustomFlags(mode) 71944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if flags is None: 72044f0eee88ff00398ff7f715fab053374d808c90dSteve Block flags = FLAGS[mode] 72144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return testcase.variant_flags + flags 72280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 723b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch def GetTimeout(self, testcase, mode): 724b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = self.timeout * TIMEOUT_SCALEFACTOR[mode] 725b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if '--stress-opt' in self.GetVmFlags(testcase, mode): 7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return result * 4 727b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch else: 728b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return result 72980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 730e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkedef RunTestCases(cases_to_run, progress, tasks): 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block progress = PROGRESS_INDICATORS[progress](cases_to_run) 732257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch result = 0 733257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch try: 734257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch result = progress.Run(tasks) 735257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch except Exception, e: 736257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch print "\n", e 737257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return result 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef BuildRequirements(context, requirements, mode, scons_flags): 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command_line = (['scons', '-Y', context.workspace, 'mode=' + ",".join(mode)] 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block + requirements 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block + scons_flags) 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block output = ExecuteNoCapture(command_line, context) 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return output.exit_code == 0 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# ------------------------------------------- 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# --- T e s t C o n f i g u r a t i o n --- 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# ------------------------------------------- 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSKIP = 'skip' 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockFAIL = 'fail' 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockPASS = 'pass' 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOKAY = 'okay' 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTIMEOUT = 'timeout' 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCRASH = 'crash' 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSLOW = 'slow' 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Expression(object): 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pass 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Constant(Expression): 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, value): 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.value = value 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Evaluate(self, env, defs): 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.value 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Variable(Expression): 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, name): 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.name = name 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetOutcomes(self, env, defs): 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.name in env: return ListSet([env[self.name]]) 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: return Nothing() 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch def Evaluate(self, env, defs): 785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return env[self.name] 786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Outcome(Expression): 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, name): 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.name = name 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetOutcomes(self, env, defs): 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.name in defs: 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return defs[self.name].GetOutcomes(env, defs) 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ListSet([self.name]) 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Set(object): 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pass 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ListSet(Set): 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, elms): 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.elms = elms 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __str__(self): 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return "ListSet%s" % str(self.elms) 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Intersect(self, that): 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not isinstance(that, ListSet): 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return that.Intersect(self) 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ListSet([ x for x in self.elms if x in that.elms ]) 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Union(self, that): 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not isinstance(that, ListSet): 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return that.Union(self) 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ListSet(self.elms + [ x for x in that.elms if x not in self.elms ]) 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IsEmpty(self): 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return len(self.elms) == 0 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Everything(Set): 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Intersect(self, that): 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return that 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Union(self, that): 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IsEmpty(self): 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Nothing(Set): 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Intersect(self, that): 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Union(self, that): 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return that 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IsEmpty(self): 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return True 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Operation(Expression): 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, left, op, right): 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.left = left 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.op = op 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.right = right 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Evaluate(self, env, defs): 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.op == '||' or self.op == ',': 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.left.Evaluate(env, defs) or self.right.Evaluate(env, defs) 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.op == 'if': 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.op == '==': 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inter = self.left.GetOutcomes(env, defs).Intersect(self.right.GetOutcomes(env, defs)) 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return not inter.IsEmpty() 8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elif self.op == '!=': 8663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inter = self.left.GetOutcomes(env, defs).Intersect(self.right.GetOutcomes(env, defs)) 8673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return inter.IsEmpty() 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assert self.op == '&&' 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.left.Evaluate(env, defs) and self.right.Evaluate(env, defs) 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetOutcomes(self, env, defs): 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.op == '||' or self.op == ',': 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.left.GetOutcomes(env, defs).Union(self.right.GetOutcomes(env, defs)) 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.op == 'if': 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.right.Evaluate(env, defs): return self.left.GetOutcomes(env, defs) 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: return Nothing() 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assert self.op == '&&' 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.left.GetOutcomes(env, defs).Intersect(self.right.GetOutcomes(env, defs)) 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef IsAlpha(str): 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for char in str: 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not (char.isalpha() or char.isdigit() or char == '_'): 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return True 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Tokenizer(object): 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """A simple string tokenizer that chops expressions into variables, 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parens and operators""" 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, expr): 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.index = 0 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.expr = expr 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.length = len(expr) 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.tokens = None 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Current(self, length = 1): 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not self.HasMore(length): return "" 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.expr[self.index:self.index+length] 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def HasMore(self, length = 1): 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.index < self.length + (length - 1) 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Advance(self, count = 1): 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.index = self.index + count 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def AddToken(self, token): 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.tokens.append(token) 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def SkipSpaces(self): 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while self.HasMore() and self.Current().isspace(): 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Advance() 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Tokenize(self): 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.tokens = [ ] 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while self.HasMore(): 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.SkipSpaces() 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not self.HasMore(): 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if self.Current() == '(': 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.AddToken('(') 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Advance() 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.Current() == ')': 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.AddToken(')') 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Advance() 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.Current() == '$': 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.AddToken('$') 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Advance() 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.Current() == ',': 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.AddToken(',') 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Advance() 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif IsAlpha(self.Current()): 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buf = "" 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while self.HasMore() and IsAlpha(self.Current()): 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buf += self.Current() 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Advance() 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.AddToken(buf) 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.Current(2) == '&&': 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.AddToken('&&') 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Advance(2) 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.Current(2) == '||': 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.AddToken('||') 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Advance(2) 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif self.Current(2) == '==': 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.AddToken('==') 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.Advance(2) 9503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elif self.Current(2) == '!=': 9513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.AddToken('!=') 9523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch self.Advance(2) 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.tokens 956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Scanner(object): 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """A simple scanner that can serve out tokens from a given list""" 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, tokens): 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.tokens = tokens 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.length = len(tokens) 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.index = 0 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def HasMore(self): 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.index < self.length 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Current(self): 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.tokens[self.index] 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Advance(self): 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.index = self.index + 1 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ParseAtomicExpression(scan): 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if scan.Current() == "true": 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan.Advance() 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Constant(True) 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif scan.Current() == "false": 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan.Advance() 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Constant(False) 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif IsAlpha(scan.Current()): 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name = scan.Current() 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan.Advance() 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Outcome(name.lower()) 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif scan.Current() == '$': 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan.Advance() 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not IsAlpha(scan.Current()): 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name = scan.Current() 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan.Advance() 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Variable(name.lower()) 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block elif scan.Current() == '(': 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan.Advance() 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = ParseLogicalExpression(scan) 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (not result) or (scan.Current() != ')'): 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan.Advance() 1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10053ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochBINARIES = ['==', '!='] 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ParseOperatorExpression(scan): 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block left = ParseAtomicExpression(scan) 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not left: return None 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while scan.HasMore() and (scan.Current() in BINARIES): 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block op = scan.Current() 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan.Advance() 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block right = ParseOperatorExpression(scan) 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not right: 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block left = Operation(left, op, right) 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return left 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ParseConditionalExpression(scan): 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block left = ParseOperatorExpression(scan) 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not left: return None 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while scan.HasMore() and (scan.Current() == 'if'): 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan.Advance() 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block right = ParseOperatorExpression(scan) 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not right: 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 10273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch left = Operation(left, 'if', right) 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return left 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLOGICALS = ["&&", "||", ","] 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ParseLogicalExpression(scan): 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block left = ParseConditionalExpression(scan) 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not left: return None 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while scan.HasMore() and (scan.Current() in LOGICALS): 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block op = scan.Current() 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan.Advance() 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block right = ParseConditionalExpression(scan) 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not right: 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block left = Operation(left, op, right) 1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return left 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ParseCondition(expr): 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """Parses a logical expression into an Expression object""" 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block tokens = Tokenizer(expr).Tokenize() 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not tokens: 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Malformed expression: '%s'" % expr 1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block scan = Scanner(tokens) 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ast = ParseLogicalExpression(scan) 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not ast: 1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Malformed expression: '%s'" % expr 1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if scan.HasMore(): 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Malformed expression: '%s'" % expr 1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return None 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ast 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ClassifiedTest(object): 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, case, outcomes): 1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.case = case 1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.outcomes = outcomes 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106844f0eee88ff00398ff7f715fab053374d808c90dSteve Block def TestsIsolates(self): 106944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return self.case.TestsIsolates() 107044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Configuration(object): 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """The parsed contents of a configuration file""" 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, sections, defs): 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.sections = sections 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.defs = defs 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def ClassifyTests(self, cases, env): 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sections = [s for s in self.sections if s.condition.Evaluate(env, self.defs)] 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block all_rules = reduce(list.__add__, [s.rules for s in sections], []) 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unused_rules = set(all_rules) 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = [ ] 1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block all_outcomes = set([]) 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for case in cases: 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block matches = [ r for r in all_rules if r.Contains(case.path) ] 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block outcomes = set([]) 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for rule in matches: 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block outcomes = outcomes.union(rule.GetOutcomes(env, self.defs)) 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unused_rules.discard(rule) 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not outcomes: 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block outcomes = [PASS] 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case.outcomes = outcomes 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block all_outcomes = all_outcomes.union(outcomes) 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.append(ClassifiedTest(case, outcomes)) 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (result, list(unused_rules), all_outcomes) 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Section(object): 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """A section of the configuration file. Sections are enabled or 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block disabled prior to running the tests, based on their conditions""" 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, condition): 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.condition = condition 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.rules = [ ] 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def AddRule(self, rule): 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.rules.append(rule) 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Rule(object): 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """A single rule that specifies the expected outcome for a single 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block test.""" 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, raw_path, path, value): 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.raw_path = raw_path 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.path = path 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.value = value 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetOutcomes(self, env, defs): 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set = self.value.GetOutcomes(env, defs) 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block assert isinstance(set, ListSet) 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return set.elms 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Contains(self, path): 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if len(self.path) > len(path): 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for i in xrange(len(self.path)): 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not self.path[i].match(path[i]): 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return True 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHEADER_PATTERN = re.compile(r'\[([^]]+)\]') 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRULE_PATTERN = re.compile(r'\s*([^: ]*)\s*:(.*)') 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockDEF_PATTERN = re.compile(r'^def\s*(\w+)\s*=(.*)$') 1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockPREFIX_PATTERN = re.compile(r'^\s*prefix\s+([\w\_\.\-\/]+)$') 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ReadConfigurationInto(path, sections, defs): 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_section = Section(Constant(True)) 1142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sections.append(current_section) 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block prefix = [] 1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for line in utils.ReadLinesFrom(path): 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block header_match = HEADER_PATTERN.match(line) 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if header_match: 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block condition_str = header_match.group(1).strip() 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block condition = ParseCondition(condition_str) 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new_section = Section(condition) 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sections.append(new_section) 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_section = new_section 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue 1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rule_match = RULE_PATTERN.match(line) 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if rule_match: 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block path = prefix + SplitPath(rule_match.group(1).strip()) 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value_str = rule_match.group(2).strip() 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value = ParseCondition(value_str) 1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not value: 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_section.AddRule(Rule(rule_match.group(1), path, value)) 1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def_match = DEF_PATTERN.match(line) 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if def_match: 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name = def_match.group(1).lower() 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value = ParseCondition(def_match.group(2).strip()) 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not value: 1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block defs[name] = value 1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block prefix_match = PREFIX_PATTERN.match(line) 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if prefix_match: 1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block prefix = SplitPath(prefix_match.group(1).strip()) 1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue 1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Malformed line: '%s'." % line 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return True 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# --------------- 1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# --- M a i n --- 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# --------------- 1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockARCH_GUESS = utils.GuessArchitecture() 1185589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochTIMEOUT_DEFAULT = 60; 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef BuildOptions(): 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = optparse.OptionParser() 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("-m", "--mode", help="The test modes in which to run (comma-separated)", 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default='release') 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("-v", "--verbose", help="Verbose output", 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=False, action="store_true") 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("-S", dest="scons_flags", help="Flag to pass through to scons", 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=[], action="append") 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("-p", "--progress", 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block help="The style of progress indicator (verbose, dots, color, mono)", 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block choices=PROGRESS_INDICATORS.keys(), default="mono") 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--no-build", help="Don't build requirements", 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=False, action="store_true") 1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--build-only", help="Only build requirements, don't run the tests", 1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=False, action="store_true") 120369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch result.add_option("--build-system", help="Build system in use (scons or gyp)", 120469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch default='scons') 1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--report", help="Print a summary of the tests to be run", 1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=False, action="store_true") 12073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result.add_option("--download-data", help="Download missing test suite data", 12083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default=False, action="store_true") 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("-s", "--suite", help="A test suite", 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=[], action="append") 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("-t", "--timeout", help="Timeout in seconds", 1212589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch default=-1, type="int") 1213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--arch", help='The architecture to run tests for', 1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default='none') 1215d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block result.add_option("--snapshot", help="Run the tests with snapshot turned on", 1216d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block default=False, action="store_true") 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--simulator", help="Run tests with architecture simulator", 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default='none') 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--special-command", default=None) 1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--valgrind", help="Run tests through valgrind", 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=False, action="store_true") 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--cat", help="Print the source of the tests", 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=False, action="store_true") 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--warn-unused", help="Report unused rules", 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=False, action="store_true") 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("-j", help="The number of parallel tasks to run", 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=1, type="int") 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--time", help="Print timing information after running", 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default=False, action="store_true") 1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--suppress-dialogs", help="Suppress Windows dialogs for crashing tests", 1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block dest="suppress_dialogs", default=True, action="store_true") 1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option("--no-suppress-dialogs", help="Display Windows dialogs for crashing tests", 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block dest="suppress_dialogs", action="store_false") 12343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result.add_option("--mips-arch-variant", help="mips architecture variant: mips32r1/mips32r2", default="mips32r2"); 123569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch result.add_option("--shell", help="Path to V8 shell", default="d8") 123644f0eee88ff00398ff7f715fab053374d808c90dSteve Block result.add_option("--isolates", help="Whether to test isolates", default=False, action="store_true") 1237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.add_option("--store-unexpected-output", 123880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen help="Store the temporary JS files from tests that fails", 123980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen dest="store_unexpected_output", default=True, action="store_true") 1240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.add_option("--no-store-unexpected-output", 124180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen help="Deletes the temporary JS files from tests that fails", 124280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen dest="store_unexpected_output", action="store_false") 1243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.add_option("--stress-only", 1244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch help="Only run tests with --always-opt --stress-opt", 1245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch default=False, action="store_true") 1246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.add_option("--nostress", 1247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch help="Don't run crankshaft --always-opt --stress-op test", 1248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch default=False, action="store_true") 1249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.add_option("--crankshaft", 1250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch help="Run with the --crankshaft flag", 1251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch default=False, action="store_true") 1252b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch result.add_option("--shard-count", 1253b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch help="Split testsuites into this number of shards", 1254b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch default=1, type="int") 1255b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch result.add_option("--shard-run", 1256b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch help="Run this shard from the split up tests.", 1257b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch default=1, type="int") 1258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result.add_option("--noprof", help="Disable profiling support", 1259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch default=False) 1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result 1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ProcessOptions(options): 1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global VERBOSE 1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VERBOSE = options.verbose 1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block options.mode = options.mode.split(',') 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for mode in options.mode: 1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not mode in ['debug', 'release']: 1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Unknown mode %s" % mode 1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.simulator != 'none': 1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Simulator argument was set. Make sure arch and simulator agree. 1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.simulator != options.arch: 1274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.arch == 'none': 1275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block options.arch = options.simulator 1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Architecture %s does not match sim %s" %(options.arch, options.simulator) 1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Ensure that the simulator argument is handed down to scons. 1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block options.scons_flags.append("simulator=" + options.simulator) 1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # If options.arch is not set by the command line and no simulator setting 1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # was found, set the arch to the guess. 1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.arch == 'none': 1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block options.arch = ARCH_GUESS 1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block options.scons_flags.append("arch=" + options.arch) 1287589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch # Simulators are slow, therefore allow a longer default timeout. 1288589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if options.timeout == -1: 1289589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if options.arch == 'arm' or options.arch == 'mips': 1290589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch options.timeout = 2 * TIMEOUT_DEFAULT; 1291589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch else: 1292589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch options.timeout = TIMEOUT_DEFAULT; 1293d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if options.snapshot: 1294d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block options.scons_flags.append("snapshot=on") 1295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch global VARIANT_FLAGS 12963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if options.mips_arch_variant: 12973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch options.scons_flags.append("mips_arch_variant=" + options.mips_arch_variant) 12983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if options.stress_only: 1300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VARIANT_FLAGS = [['--stress-opt', '--always-opt']] 1301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if options.nostress: 1302b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch VARIANT_FLAGS = [[],['--nocrankshaft']] 1303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if options.crankshaft: 1304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if options.special_command: 1305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch options.special_command += " --crankshaft" 1306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch else: 130769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch options.special_command = "@ --crankshaft" 130869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if options.shell.endswith("d8"): 13093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if options.special_command: 13103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch options.special_command += " --test" 13113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch else: 131269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch options.special_command = "@ --test" 1313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if options.noprof: 1314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch options.scons_flags.append("prof=off") 1315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch options.scons_flags.append("profilingsupport=off") 131669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if options.build_system == 'gyp': 131769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if options.build_only: 131869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch print "--build-only not supported for gyp, please build manually." 131969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch options.build_only = False 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return True 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochdef DoSkip(case): 132469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return (SKIP in case.outcomes) or (SLOW in case.outcomes) 132569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 132669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockREPORT_TEMPLATE = """\ 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTotal: %(total)i tests 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * %(skipped)4d tests will be skipped 133069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch * %(timeout)4d tests are expected to timeout sometimes 1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * %(nocrash)4d tests are expected to be flaky but not crash 1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * %(pass)4d tests are expected to pass 1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * %(fail_ok)4d tests are expected to fail that we won't fix 1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * %(fail)4d tests are expected to fail that we should fix\ 1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block""" 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef PrintReport(cases): 1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IsFlaky(o): 1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (PASS in o) and (FAIL in o) and (not CRASH in o) and (not OKAY in o) 1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IsFailOk(o): 1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (len(o) == 2) and (FAIL in o) and (OKAY in o) 134269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch unskipped = [c for c in cases if not DoSkip(c)] 1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print REPORT_TEMPLATE % { 1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'total': len(cases), 1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'skipped': len(cases) - len(unskipped), 134669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 'timeout': len([t for t in unskipped if TIMEOUT in t.outcomes]), 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'nocrash': len([t for t in unskipped if IsFlaky(t.outcomes)]), 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'pass': len([t for t in unskipped if list(t.outcomes) == [PASS]]), 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'fail_ok': len([t for t in unskipped if IsFailOk(t.outcomes)]), 1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'fail': len([t for t in unskipped if list(t.outcomes) == [FAIL]]) 1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Pattern(object): 1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __init__(self, pattern): 1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.pattern = pattern 1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.compiled = None 1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def match(self, str): 1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not self.compiled: 1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pattern = "^" + self.pattern.replace('*', '.*') + "$" 1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block self.compiled = re.compile(pattern) 1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.compiled.match(str) 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def __str__(self): 1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return self.pattern 1368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef SplitPath(s): 1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stripped = [ c.strip() for c in s.split('/') ] 1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return [ Pattern(s) for s in stripped if len(s) > 0 ] 1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef GetSpecialCommandProcessor(value): 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (not value) or (value.find('@') == -1): 1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def ExpandCommand(args): 1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return args 1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ExpandCommand 1380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 1381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos = value.find('@') 1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block import urllib 1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block prefix = urllib.unquote(value[:pos]).split() 1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block suffix = urllib.unquote(value[pos+1:]).split() 1385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def ExpandCommand(args): 1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return prefix + args + suffix 1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ExpandCommand 1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13908b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochBUILT_IN_TESTS = ['mjsunit', 'cctest', 'message', 'preparser'] 1391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef GetSuites(test_root): 1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IsSuite(path): 1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return isdir(path) and exists(join(path, 'testcfg.py')) 1396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return [ f for f in os.listdir(test_root) if IsSuite(join(test_root, f)) ] 1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef FormatTime(d): 1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block millis = round(d * 1000) % 1000 1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return time.strftime("%M:%S.", time.gmtime(d)) + ("%03i" % millis) 1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1403b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochdef ShardTests(tests, options): 1404b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if options.shard_count < 2: 1405b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return tests 1406b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if options.shard_run < 1 or options.shard_run > options.shard_count: 1407b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch print "shard-run not a valid number, should be in [1:shard-count]" 1408b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch print "defaulting back to running all tests" 1409b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return tests 1410257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch count = 0 1411b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch shard = [] 1412b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch for test in tests: 1413b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if count % options.shard_count == options.shard_run - 1: 1414257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch shard.append(test) 1415b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch count += 1 1416b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return shard 1417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef Main(): 1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parser = BuildOptions() 1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (options, args) = parser.parse_args() 1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not ProcessOptions(options): 1422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parser.print_help() 1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1 1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block workspace = abspath(join(dirname(sys.argv[0]), '..')) 1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block suites = GetSuites(join(workspace, 'test')) 1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block repositories = [TestRepository(join(workspace, 'test', name)) for name in suites] 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block repositories += [TestRepository(a) for a in options.suite] 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block root = LiteralTestSuite(repositories) 1431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if len(args) == 0: 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block paths = [SplitPath(t) for t in BUILT_IN_TESTS] 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block paths = [ ] 1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for arg in args: 1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block path = SplitPath(arg) 1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block paths.append(path) 1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Check for --valgrind option. If enabled, we overwrite the special 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # command flag with a command that uses the run-valgrind.py script. 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.valgrind: 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block run_valgrind = join(workspace, "tools", "run-valgrind.py") 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block options.special_command = "python -u " + run_valgrind + " @" 1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 144569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if options.build_system == 'gyp': 144669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SUFFIX['debug'] = '' 144769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shell = abspath(options.shell) 1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buildspace = dirname(shell) 145080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context = Context(workspace, buildspace, VERBOSE, 1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shell, 1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block options.timeout, 1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GetSpecialCommandProcessor(options.special_command), 145580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen options.suppress_dialogs, 145680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen options.store_unexpected_output) 1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # First build the required targets 1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not options.no_build: 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reqs = [ ] 1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for path in paths: 1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reqs += root.GetBuildRequirements(path, context) 1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reqs = list(set(reqs)) 1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if len(reqs) > 0: 1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.j != 1: 1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block options.scons_flags += ['-j', str(options.j)] 1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not BuildRequirements(context, reqs, options.mode, options.scons_flags): 1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1 1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Just return if we are only building the targets for running the tests. 1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.build_only: 1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0 147280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Get status for tests 1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sections = [ ] 1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block defs = { } 1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block root.GetTestStatus(context, sections, defs) 1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block config = Configuration(sections, defs) 1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch # Download missing test suite data if requested. 14803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if options.download_data: 14813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for path in paths: 14823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch root.DownloadData(path, context) 14833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # List the tests 1485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block all_cases = [ ] 1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block all_unused = [ ] 1487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unclassified_tests = [ ] 1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block globally_unused_rules = None 1489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for path in paths: 1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for mode in options.mode: 1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env = { 1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'mode': mode, 1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'system': utils.GuessOS(), 1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'arch': options.arch, 1495b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 'simulator': options.simulator, 14963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 'crankshaft': options.crankshaft, 14973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 'isolates': options.isolates 1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 149944f0eee88ff00398ff7f715fab053374d808c90dSteve Block test_list = root.ListTests([], path, context, mode, []) 1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unclassified_tests += test_list 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (cases, unused_rules, all_outcomes) = config.ClassifyTests(test_list, env) 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if globally_unused_rules is None: 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block globally_unused_rules = set(unused_rules) 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block globally_unused_rules = globally_unused_rules.intersection(unused_rules) 1506b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch all_cases += ShardTests(cases, options) 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block all_unused.append(unused_rules) 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.cat: 1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block visited = set() 1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for test in unclassified_tests: 1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block key = tuple(test.path) 1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if key in visited: 1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue 1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block visited.add(key) 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "--- begin source: %s ---" % test.GetLabel() 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = test.GetSource().strip() 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print source 1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "--- end source: %s ---" % test.GetLabel() 1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0 1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.warn_unused: 1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for rule in globally_unused_rules: 1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Rule for '%s' was not used." % '/'.join([str(s) for s in rule.path]) 1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 152669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if not options.isolates: 152769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch all_cases = [c for c in all_cases if not c.TestsIsolates()] 152869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.report: 1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintReport(all_cases) 1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = None 1533e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke cases_to_run = [ c for c in all_cases if not DoSkip(c) ] 1534e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if len(cases_to_run) == 0: 1535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "No tests to run." 1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0 1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try: 1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block start = time.time() 1540e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if RunTestCases(cases_to_run, options.progress, options.j): 1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = 0 1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = 1 1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block duration = time.time() - start 1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block except KeyboardInterrupt: 1546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "Interrupted" 1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if options.time: 1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # Write the times to stderr to make it easy to separate from the 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block # test output. 1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stderr.write("--- Total time: %s ---\n" % FormatTime(duration)) 1554e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke timed_tests = [ t.case for t in cases_to_run if not t.case.duration is None ] 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block timed_tests.sort(lambda a, b: a.CompareTime(b)) 1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block index = 1 1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for entry in timed_tests[:20]: 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t = FormatTime(entry.duration) 1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.stderr.write("%4i (%s) %s\n" % (index, t, entry.GetLabel())) 1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block index += 1 1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result 1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockif __name__ == '__main__': 1566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.exit(Main()) 1567