diff options
Diffstat (limited to 'utils/test')
-rw-r--r-- | utils/test/Makefile.multi | 21 | ||||
-rwxr-xr-x | utils/test/MultiTestRunner.py | 347 | ||||
-rw-r--r-- | utils/test/ProgressBar.py | 227 | ||||
-rwxr-xr-x | utils/test/TestRunner.py | 296 |
4 files changed, 0 insertions, 891 deletions
diff --git a/utils/test/Makefile.multi b/utils/test/Makefile.multi deleted file mode 100644 index 3e9cd5669aa8..000000000000 --- a/utils/test/Makefile.multi +++ /dev/null @@ -1,21 +0,0 @@ -LEVEL = ../../.. -include $(LEVEL)/Makefile.common - -# Test in all immediate subdirectories if unset. -TESTDIRS ?= $(shell echo $(PROJ_SRC_DIR)/*/) - -ifndef TESTARGS -ifdef VERBOSE -TESTARGS = -v -else -TESTARGS = -s -endif -endif - -all:: - @ PATH=$(ToolDir):$(LLVM_SRC_ROOT)/test/Scripts:$$PATH VG=$(VG) ../utils/test/MultiTestRunner.py $(TESTARGS) $(TESTDIRS) - -clean:: - @ rm -rf Output/ - -.PHONY: all report clean diff --git a/utils/test/MultiTestRunner.py b/utils/test/MultiTestRunner.py deleted file mode 100755 index 6d0c14afad40..000000000000 --- a/utils/test/MultiTestRunner.py +++ /dev/null @@ -1,347 +0,0 @@ -#!/usr/bin/python - -""" -MultiTestRunner - Harness for running multiple tests in the simple clang style. - -TODO --- - - Fix Ctrl-c issues - - Use a timeout - - Detect signalled failures (abort) - - Better support for finding tests -""" - -# TOD -import os, sys, re, random, time -import threading -import ProgressBar -import TestRunner -from TestRunner import TestStatus -from Queue import Queue - -kTestFileExtensions = set(['.mi','.i','.c','.cpp','.m','.mm','.ll']) - -def getTests(inputs): - for path in inputs: - if not os.path.exists(path): - print >>sys.stderr,"WARNING: Invalid test \"%s\""%(path,) - continue - - if os.path.isdir(path): - for dirpath,dirnames,filenames in os.walk(path): - dotTests = os.path.join(dirpath,'.tests') - if os.path.exists(dotTests): - for ln in open(dotTests): - if ln.strip(): - yield os.path.join(dirpath,ln.strip()) - else: - # FIXME: This doesn't belong here - if 'Output' in dirnames: - dirnames.remove('Output') - for f in filenames: - base,ext = os.path.splitext(f) - if ext in kTestFileExtensions: - yield os.path.join(dirpath,f) - else: - yield path - -class TestingProgressDisplay: - def __init__(self, opts, numTests, progressBar=None): - self.opts = opts - self.numTests = numTests - self.digits = len(str(self.numTests)) - self.current = None - self.lock = threading.Lock() - self.progressBar = progressBar - self.progress = 0. - - def update(self, index, tr): - # Avoid locking overhead in quiet mode - if self.opts.quiet and not tr.failed(): - return - - # Output lock - self.lock.acquire() - try: - self.handleUpdate(index, tr) - finally: - self.lock.release() - - def finish(self): - if self.progressBar: - self.progressBar.clear() - elif self.opts.succinct: - sys.stdout.write('\n') - - def handleUpdate(self, index, tr): - if self.progressBar: - if tr.failed(): - self.progressBar.clear() - else: - # Force monotonicity - self.progress = max(self.progress, float(index)/self.numTests) - self.progressBar.update(self.progress, tr.path) - return - elif self.opts.succinct: - if not tr.failed(): - sys.stdout.write('.') - sys.stdout.flush() - return - else: - sys.stdout.write('\n') - - extra = '' - if tr.code==TestStatus.Invalid: - extra = ' - (Invalid test)' - elif tr.code==TestStatus.NoRunLine: - extra = ' - (No RUN line)' - elif tr.failed(): - extra = ' - %s'%(TestStatus.getName(tr.code).upper(),) - print '%*d/%*d - %s%s'%(self.digits, index+1, self.digits, - self.numTests, tr.path, extra) - - if tr.failed() and self.opts.showOutput: - TestRunner.cat(tr.testResults, sys.stdout) - -class TestResult: - def __init__(self, path, code, testResults): - self.path = path - self.code = code - self.testResults = testResults - - def failed(self): - return self.code in (TestStatus.Fail,TestStatus.XPass) - -class TestProvider: - def __init__(self, opts, tests, display): - self.opts = opts - self.tests = tests - self.index = 0 - self.lock = threading.Lock() - self.results = [None]*len(self.tests) - self.startTime = time.time() - self.progress = display - - def get(self): - self.lock.acquire() - try: - if self.opts.maxTime is not None: - if time.time() - self.startTime > self.opts.maxTime: - return None - if self.index >= len(self.tests): - return None - item = self.tests[self.index],self.index - self.index += 1 - return item - finally: - self.lock.release() - - def setResult(self, index, result): - self.results[index] = result - self.progress.update(index, result) - -class Tester(threading.Thread): - def __init__(self, provider): - threading.Thread.__init__(self) - self.provider = provider - - def run(self): - while 1: - item = self.provider.get() - if item is None: - break - self.runTest(item) - - def runTest(self, (path,index)): - command = path - # Use hand concatentation here because we want to override - # absolute paths. - output = 'Output/' + path + '.out' - testname = path - testresults = 'Output/' + path + '.testresults' - TestRunner.mkdir_p(os.path.dirname(testresults)) - numTests = len(self.provider.tests) - digits = len(str(numTests)) - code = None - try: - opts = self.provider.opts - if opts.debugDoNotTest: - code = None - else: - code = TestRunner.runOneTest(path, command, output, testname, - opts.clang, opts.clangcc, - useValgrind=opts.useValgrind, - useDGCompat=opts.useDGCompat, - useScript=opts.testScript, - output=open(testresults,'w')) - except KeyboardInterrupt: - # This is a sad hack. Unfortunately subprocess goes - # bonkers with ctrl-c and we start forking merrily. - print 'Ctrl-C detected, goodbye.' - os.kill(0,9) - - self.provider.setResult(index, TestResult(path, code, testresults)) - -def detectCPUs(): - """ - Detects the number of CPUs on a system. Cribbed from pp. - """ - # Linux, Unix and MacOS: - if hasattr(os, "sysconf"): - if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"): - # Linux & Unix: - ncpus = os.sysconf("SC_NPROCESSORS_ONLN") - if isinstance(ncpus, int) and ncpus > 0: - return ncpus - else: # OSX: - return int(os.popen2("sysctl -n hw.ncpu")[1].read()) - # Windows: - if os.environ.has_key("NUMBER_OF_PROCESSORS"): - ncpus = int(os.environ["NUMBER_OF_PROCESSORS"]); - if ncpus > 0: - return ncpus - return 1 # Default - -def main(): - global options - from optparse import OptionParser - parser = OptionParser("usage: %prog [options] {inputs}") - parser.add_option("-j", "--threads", dest="numThreads", - help="Number of testing threads", - type=int, action="store", - default=detectCPUs()) - parser.add_option("", "--clang", dest="clang", - help="Program to use as \"clang\"", - action="store", default=None) - parser.add_option("", "--clang-cc", dest="clangcc", - help="Program to use as \"clang-cc\"", - action="store", default=None) - parser.add_option("", "--vg", dest="useValgrind", - help="Run tests under valgrind", - action="store_true", default=False) - parser.add_option("", "--dg", dest="useDGCompat", - help="Use llvm dejagnu compatibility mode", - action="store_true", default=False) - parser.add_option("", "--script", dest="testScript", - help="Default script to use", - action="store", default=None) - parser.add_option("-v", "--verbose", dest="showOutput", - help="Show all test output", - action="store_true", default=False) - parser.add_option("-q", "--quiet", dest="quiet", - help="Suppress no error output", - action="store_true", default=False) - parser.add_option("-s", "--succinct", dest="succinct", - help="Reduce amount of output", - action="store_true", default=False) - parser.add_option("", "--max-tests", dest="maxTests", - help="Maximum number of tests to run", - action="store", type=int, default=None) - parser.add_option("", "--max-time", dest="maxTime", - help="Maximum time to spend testing (in seconds)", - action="store", type=float, default=None) - parser.add_option("", "--shuffle", dest="shuffle", - help="Run tests in random order", - action="store_true", default=False) - parser.add_option("", "--seed", dest="seed", - help="Seed for random number generator (default: random)", - action="store", default=None) - parser.add_option("", "--no-progress-bar", dest="useProgressBar", - help="Do not use curses based progress bar", - action="store_false", default=True) - parser.add_option("", "--debug-do-not-test", dest="debugDoNotTest", - help="DEBUG: Skip running actual test script", - action="store_true", default=False) - parser.add_option("", "--path", dest="path", - help="Additional paths to add to testing environment", - action="store", type=str, default=None) - - (opts, args) = parser.parse_args() - - if not args: - parser.error('No inputs specified') - - if opts.clang is None: - opts.clang = TestRunner.inferClang() - if opts.clangcc is None: - opts.clangcc = TestRunner.inferClangCC(opts.clang) - - # FIXME: It could be worth loading these in parallel with testing. - allTests = list(getTests(args)) - allTests.sort() - - tests = allTests - if opts.seed is not None: - try: - seed = int(opts.seed) - except: - parser.error('--seed argument should be an integer') - random.seed(seed) - if opts.shuffle: - random.shuffle(tests) - if opts.maxTests is not None: - tests = tests[:opts.maxTests] - if opts.path is not None: - os.environ["PATH"] = opts.path + ":" + os.environ["PATH"]; - - extra = '' - if len(tests) != len(allTests): - extra = ' of %d'%(len(allTests),) - header = '-- Testing: %d%s tests, %d threads --'%(len(tests),extra, - opts.numThreads) - - progressBar = None - if not opts.quiet: - if opts.useProgressBar: - try: - tc = ProgressBar.TerminalController() - progressBar = ProgressBar.ProgressBar(tc, header) - except ValueError: - pass - - if not progressBar: - print header - - display = TestingProgressDisplay(opts, len(tests), progressBar) - provider = TestProvider(opts, tests, display) - - testers = [Tester(provider) for i in range(opts.numThreads)] - startTime = time.time() - for t in testers: - t.start() - try: - for t in testers: - t.join() - except KeyboardInterrupt: - sys.exit(1) - - display.finish() - - if not opts.quiet: - print 'Testing Time: %.2fs'%(time.time() - startTime) - - # List test results organized organized by kind. - byCode = {} - for t in provider.results: - if t: - if t.code not in byCode: - byCode[t.code] = [] - byCode[t.code].append(t) - for title,code in (('Expected Failures', TestStatus.XFail), - ('Unexpected Passing Tests', TestStatus.XPass), - ('Failing Tests', TestStatus.Fail)): - elts = byCode.get(code) - if not elts: - continue - print '*'*20 - print '%s (%d):' % (title, len(elts)) - for tr in elts: - print '\t%s'%(tr.path,) - - numFailures = len(byCode.get(TestStatus.Fail,[])) - if numFailures: - print '\nFailures: %d' % (numFailures,) - sys.exit(1) - -if __name__=='__main__': - main() diff --git a/utils/test/ProgressBar.py b/utils/test/ProgressBar.py deleted file mode 100644 index 2e1f24ae79a1..000000000000 --- a/utils/test/ProgressBar.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/python - -# Source: http://code.activestate.com/recipes/475116/, with -# modifications by Daniel Dunbar. - -import sys, re, time - -class TerminalController: - """ - A class that can be used to portably generate formatted output to - a terminal. - - `TerminalController` defines a set of instance variables whose - values are initialized to the control sequence necessary to - perform a given action. These can be simply included in normal - output to the terminal: - - >>> term = TerminalController() - >>> print 'This is '+term.GREEN+'green'+term.NORMAL - - Alternatively, the `render()` method can used, which replaces - '${action}' with the string required to perform 'action': - - >>> term = TerminalController() - >>> print term.render('This is ${GREEN}green${NORMAL}') - - If the terminal doesn't support a given action, then the value of - the corresponding instance variable will be set to ''. As a - result, the above code will still work on terminals that do not - support color, except that their output will not be colored. - Also, this means that you can test whether the terminal supports a - given action by simply testing the truth value of the - corresponding instance variable: - - >>> term = TerminalController() - >>> if term.CLEAR_SCREEN: - ... print 'This terminal supports clearning the screen.' - - Finally, if the width and height of the terminal are known, then - they will be stored in the `COLS` and `LINES` attributes. - """ - # Cursor movement: - BOL = '' #: Move the cursor to the beginning of the line - UP = '' #: Move the cursor up one line - DOWN = '' #: Move the cursor down one line - LEFT = '' #: Move the cursor left one char - RIGHT = '' #: Move the cursor right one char - - # Deletion: - CLEAR_SCREEN = '' #: Clear the screen and move to home position - CLEAR_EOL = '' #: Clear to the end of the line. - CLEAR_BOL = '' #: Clear to the beginning of the line. - CLEAR_EOS = '' #: Clear to the end of the screen - - # Output modes: - BOLD = '' #: Turn on bold mode - BLINK = '' #: Turn on blink mode - DIM = '' #: Turn on half-bright mode - REVERSE = '' #: Turn on reverse-video mode - NORMAL = '' #: Turn off all modes - - # Cursor display: - HIDE_CURSOR = '' #: Make the cursor invisible - SHOW_CURSOR = '' #: Make the cursor visible - - # Terminal size: - COLS = None #: Width of the terminal (None for unknown) - LINES = None #: Height of the terminal (None for unknown) - - # Foreground colors: - BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = '' - - # Background colors: - BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = '' - BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = '' - - _STRING_CAPABILITIES = """ - BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1 - CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold - BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0 - HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split() - _COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split() - _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split() - - def __init__(self, term_stream=sys.stdout): - """ - Create a `TerminalController` and initialize its attributes - with appropriate values for the current terminal. - `term_stream` is the stream that will be used for terminal - output; if this stream is not a tty, then the terminal is - assumed to be a dumb terminal (i.e., have no capabilities). - """ - # Curses isn't available on all platforms - try: import curses - except: return - - # If the stream isn't a tty, then assume it has no capabilities. - if not term_stream.isatty(): return - - # Check the terminal type. If we fail, then assume that the - # terminal has no capabilities. - try: curses.setupterm() - except: return - - # Look up numeric capabilities. - self.COLS = curses.tigetnum('cols') - self.LINES = curses.tigetnum('lines') - - # Look up string capabilities. - for capability in self._STRING_CAPABILITIES: - (attrib, cap_name) = capability.split('=') - setattr(self, attrib, self._tigetstr(cap_name) or '') - - # Colors - set_fg = self._tigetstr('setf') - if set_fg: - for i,color in zip(range(len(self._COLORS)), self._COLORS): - setattr(self, color, curses.tparm(set_fg, i) or '') - set_fg_ansi = self._tigetstr('setaf') - if set_fg_ansi: - for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): - setattr(self, color, curses.tparm(set_fg_ansi, i) or '') - set_bg = self._tigetstr('setb') - if set_bg: - for i,color in zip(range(len(self._COLORS)), self._COLORS): - setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '') - set_bg_ansi = self._tigetstr('setab') - if set_bg_ansi: - for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): - setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '') - - def _tigetstr(self, cap_name): - # String capabilities can include "delays" of the form "$<2>". - # For any modern terminal, we should be able to just ignore - # these, so strip them out. - import curses - cap = curses.tigetstr(cap_name) or '' - return re.sub(r'\$<\d+>[/*]?', '', cap) - - def render(self, template): - """ - Replace each $-substitutions in the given template string with - the corresponding terminal control string (if it's defined) or - '' (if it's not). - """ - return re.sub(r'\$\$|\${\w+}', self._render_sub, template) - - def _render_sub(self, match): - s = match.group() - if s == '$$': return s - else: return getattr(self, s[2:-1]) - -####################################################################### -# Example use case: progress bar -####################################################################### - -class ProgressBar: - """ - A 3-line progress bar, which looks like:: - - Header - 20% [===========----------------------------------] - progress message - - The progress bar is colored, if the terminal supports color - output; and adjusts to the width of the terminal. - """ - BAR = '%s${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}%s\n' - HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n' - - def __init__(self, term, header, useETA=True): - self.term = term - if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL): - raise ValueError("Terminal isn't capable enough -- you " - "should use a simpler progress dispaly.") - self.width = self.term.COLS or 75 - self.bar = term.render(self.BAR) - self.header = self.term.render(self.HEADER % header.center(self.width)) - self.cleared = 1 #: true if we haven't drawn the bar yet. - self.useETA = useETA - if self.useETA: - self.startTime = time.time() - self.update(0, '') - - def update(self, percent, message): - if self.cleared: - sys.stdout.write(self.header) - self.cleared = 0 - prefix = '%3d%% ' % (percent*100,) - suffix = '' - if self.useETA: - elapsed = time.time() - self.startTime - if percent > .0001 and elapsed > 1: - total = elapsed / percent - eta = int(total - elapsed) - h = eta//3600. - m = (eta//60) % 60 - s = eta % 60 - suffix = ' ETA: %02d:%02d:%02d'%(h,m,s) - barWidth = self.width - len(prefix) - len(suffix) - 2 - n = int(barWidth*percent) - if len(message) < self.width: - message = message + ' '*(self.width - len(message)) - else: - message = '... ' + message[-(self.width-4):] - sys.stdout.write( - self.term.BOL + self.term.UP + self.term.CLEAR_EOL + - (self.bar % (prefix, '='*n, '-'*(barWidth-n), suffix)) + - self.term.CLEAR_EOL + message) - - def clear(self): - if not self.cleared: - sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL + - self.term.UP + self.term.CLEAR_EOL + - self.term.UP + self.term.CLEAR_EOL) - self.cleared = 1 - -def test(): - import time - tc = TerminalController() - p = ProgressBar(tc, 'Tests') - for i in range(101): - p.update(i/100., str(i)) - time.sleep(.3) - -if __name__=='__main__': - test() diff --git a/utils/test/TestRunner.py b/utils/test/TestRunner.py deleted file mode 100755 index 9020622350dc..000000000000 --- a/utils/test/TestRunner.py +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/python -# -# TestRunner.py - This script is used to run arbitrary unit tests. Unit -# tests must contain the command used to run them in the input file, starting -# immediately after a "RUN:" string. -# -# This runner recognizes and replaces the following strings in the command: -# -# %s - Replaced with the input name of the program, or the program to -# execute, as appropriate. -# %S - Replaced with the directory where the input resides. -# %llvmgcc - llvm-gcc command -# %llvmgxx - llvm-g++ command -# %prcontext - prcontext.tcl script -# %t - temporary file name (derived from testcase name) -# - -import errno -import os -import re -import signal -import subprocess -import sys - -# Increase determinism for things that use the terminal width. -# -# FIXME: Find a better place for this hack. -os.environ['COLUMNS'] = '0' - -class TestStatus: - Pass = 0 - XFail = 1 - Fail = 2 - XPass = 3 - NoRunLine = 4 - Invalid = 5 - - kNames = ['Pass','XFail','Fail','XPass','NoRunLine','Invalid'] - @staticmethod - def getName(code): - return TestStatus.kNames[code] - -def mkdir_p(path): - if not path: - pass - elif os.path.exists(path): - pass - else: - parent = os.path.dirname(path) - if parent != path: - mkdir_p(parent) - try: - os.mkdir(path) - except OSError,e: - if e.errno != errno.EEXIST: - raise - -def remove(path): - try: - os.remove(path) - except OSError: - pass - -def cat(path, output): - f = open(path) - output.writelines(f) - f.close() - -def runOneTest(FILENAME, SUBST, OUTPUT, TESTNAME, CLANG, CLANGCC, - useValgrind=False, - useDGCompat=False, - useScript=None, - output=sys.stdout): - if useValgrind: - VG_OUTPUT = '%s.vg'%(OUTPUT,) - if os.path.exists: - remove(VG_OUTPUT) - CLANG = 'valgrind --leak-check=full --quiet --log-file=%s %s'%(VG_OUTPUT, CLANG) - - # Create the output directory if it does not already exist. - mkdir_p(os.path.dirname(OUTPUT)) - - # FIXME - #ulimit -t 40 - - # FIXME: Load script once - # FIXME: Support "short" script syntax - - if useScript: - scriptFile = useScript - else: - # See if we have a per-dir test script. - dirScriptFile = os.path.join(os.path.dirname(FILENAME), 'test.script') - if os.path.exists(dirScriptFile): - scriptFile = dirScriptFile - else: - scriptFile = FILENAME - - # Verify the script contains a run line. - for ln in open(scriptFile): - if 'RUN:' in ln: - break - else: - print >>output, "******************** TEST '%s' HAS NO RUN LINE! ********************"%(TESTNAME,) - output.flush() - return TestStatus.NoRunLine - - OUTPUT = os.path.abspath(OUTPUT) - FILENAME = os.path.abspath(FILENAME) - SCRIPT = OUTPUT + '.script' - TEMPOUTPUT = OUTPUT + '.tmp' - - substitutions = [('%s',SUBST), - ('%S',os.path.dirname(SUBST)), - ('%llvmgcc','llvm-gcc -emit-llvm -w'), - ('%llvmgxx','llvm-g++ -emit-llvm -w'), - ('%prcontext','prcontext.tcl'), - ('%t',TEMPOUTPUT), - (' clang ', ' ' + CLANG + ' '), - (' clang-cc ', ' ' + CLANGCC + ' ')] - scriptLines = [] - xfailLines = [] - for ln in open(scriptFile): - if 'RUN:' in ln: - # Isolate run parameters - index = ln.index('RUN:') - ln = ln[index+4:] - - # Apply substitutions - for a,b in substitutions: - ln = ln.replace(a,b) - - if useDGCompat: - ln = re.sub(r'\{(.*)\}', r'"\1"', ln) - scriptLines.append(ln) - elif 'XFAIL' in ln: - xfailLines.append(ln) - - if xfailLines: - print >>output, "XFAILED '%s':"%(TESTNAME,) - output.writelines(xfailLines) - - # Write script file - f = open(SCRIPT,'w') - f.write(''.join(scriptLines)) - f.close() - - outputFile = open(OUTPUT,'w') - p = None - try: - p = subprocess.Popen(["/bin/sh",SCRIPT], - cwd=os.path.dirname(FILENAME), - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - out,err = p.communicate() - outputFile.write(out) - outputFile.write(err) - SCRIPT_STATUS = p.wait() - - # Detect Ctrl-C in subprocess. - if SCRIPT_STATUS == -signal.SIGINT: - raise KeyboardInterrupt - except KeyboardInterrupt: - raise - outputFile.close() - - if xfailLines: - SCRIPT_STATUS = not SCRIPT_STATUS - - if useValgrind: - VG_STATUS = len(list(open(VG_OUTPUT))) - else: - VG_STATUS = 0 - - if SCRIPT_STATUS or VG_STATUS: - print >>output, "******************** TEST '%s' FAILED! ********************"%(TESTNAME,) - print >>output, "Command: " - output.writelines(scriptLines) - if not SCRIPT_STATUS: - print >>output, "Output:" - else: - print >>output, "Incorrect Output:" - cat(OUTPUT, output) - if VG_STATUS: - print >>output, "Valgrind Output:" - cat(VG_OUTPUT, output) - print >>output, "******************** TEST '%s' FAILED! ********************"%(TESTNAME,) - output.flush() - if xfailLines: - return TestStatus.XPass - else: - return TestStatus.Fail - - if xfailLines: - return TestStatus.XFail - else: - return TestStatus.Pass - -def capture(args): - p = subprocess.Popen(args, stdout=subprocess.PIPE) - out,_ = p.communicate() - return out - -def which(command): - # Would be nice if Python had a lib function for this. - res = capture(['which',command]) - res = res.strip() - if res and os.path.exists(res): - return res - return None - -def inferClang(): - # Determine which clang to use. - clang = os.getenv('CLANG') - - # If the user set clang in the environment, definitely use that and don't - # try to validate. - if clang: - return clang - - # Otherwise look in the path. - clang = which('clang') - - if not clang: - print >>sys.stderr, "error: couldn't find 'clang' program, try setting CLANG in your environment" - sys.exit(1) - - return clang - -def inferClangCC(clang): - clangcc = os.getenv('CLANGCC') - - # If the user set clang in the environment, definitely use that and don't - # try to validate. - if clangcc: - return clangcc - - # Otherwise try adding -cc since we expect to be looking in a build - # directory. - clangcc = which(clang + '-cc') - if not clangcc: - # Otherwise ask clang. - res = capture([clang, '-print-prog-name=clang-cc']) - res = res.strip() - if res and os.path.exists(res): - clangcc = res - - if not clangcc: - print >>sys.stderr, "error: couldn't find 'clang-cc' program, try setting CLANGCC in your environment" - sys.exit(1) - - return clangcc - -def main(): - global options - from optparse import OptionParser - parser = OptionParser("usage: %prog [options] {tests}") - parser.add_option("", "--clang", dest="clang", - help="Program to use as \"clang\"", - action="store", default=None) - parser.add_option("", "--clang-cc", dest="clangcc", - help="Program to use as \"clang-cc\"", - action="store", default=None) - parser.add_option("", "--vg", dest="useValgrind", - help="Run tests under valgrind", - action="store_true", default=False) - parser.add_option("", "--dg", dest="useDGCompat", - help="Use llvm dejagnu compatibility mode", - action="store_true", default=False) - (opts, args) = parser.parse_args() - - if not args: - parser.error('No tests specified') - - if opts.clang is None: - opts.clang = inferClang() - if opts.clangcc is None: - opts.clangcc = inferClangCC(opts.clang) - - for path in args: - command = path - # Use hand concatentation here because we want to override - # absolute paths. - output = 'Output/' + path + '.out' - testname = path - - res = runOneTest(path, command, output, testname, - opts.clang, opts.clangcc, - useValgrind=opts.useValgrind, - useDGCompat=opts.useDGCompat, - useScript=os.getenv("TEST_SCRIPT")) - - sys.exit(res == TestStatus.Fail or res == TestStatus.XPass) - -if __name__=='__main__': - main() |