summaryrefslogtreecommitdiff
path: root/utils/test
diff options
context:
space:
mode:
Diffstat (limited to 'utils/test')
-rw-r--r--utils/test/Makefile.multi21
-rwxr-xr-xutils/test/MultiTestRunner.py347
-rw-r--r--utils/test/ProgressBar.py227
-rwxr-xr-xutils/test/TestRunner.py296
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()