aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/Makefile14
-rw-r--r--test/lit.cfg286
-rw-r--r--utils/test/ExampleTests/fail.c3
-rw-r--r--utils/test/ExampleTests/lit.cfg12
-rw-r--r--utils/test/ExampleTests/pass.c1
-rw-r--r--utils/test/ExampleTests/xfail.c2
-rw-r--r--utils/test/ExampleTests/xpass.c2
-rwxr-xr-xutils/test/MultiTestRunner.py399
-rw-r--r--utils/test/ProgressBar.py227
-rw-r--r--utils/test/ShUtil.py390
-rwxr-xr-xutils/test/TestRunner.py334
-rw-r--r--utils/test/TestingConfig.py27
-rw-r--r--utils/test/Util.py70
13 files changed, 135 insertions, 1632 deletions
diff --git a/test/Makefile b/test/Makefile
index 9ed683435f..6ed13d6b88 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -8,8 +8,8 @@ else
TESTDIRS ?= $(PROJ_SRC_DIR)
endif
-# LIT2 wants objdir paths, so it will pick up the lit.site.cfg.
-LIT2_TESTDIRS := $(TESTDIRS:$(PROJ_SRC_DIR)%=$(PROJ_OBJ_DIR)%)
+# 'lit' wants objdir paths, so it will pick up the lit.site.cfg.
+TESTDIRS := $(TESTDIRS:$(PROJ_SRC_DIR)%=$(PROJ_OBJ_DIR)%)
ifndef TESTARGS
ifdef VERBOSE
@@ -25,20 +25,10 @@ else
VGARG=
endif
-ifndef LIT1
all:: lit.site.cfg
@ echo '--- Running clang tests for $(TARGET_TRIPLE) ---'
@ $(LLVM_SRC_ROOT)/utils/lit/lit.py \
- $(TESTARGS) $(LIT2_TESTDIRS) $(VGARG)
-else
-all::
- @ echo '--- Running clang tests for $(TARGET_TRIPLE) ---'
- @ $(PROJ_SRC_DIR)/../utils/test/MultiTestRunner.py \
- --root $(PROJ_SRC_DIR) \
- --path $(ToolDir) \
- --path $(LLVM_SRC_ROOT)/test/Scripts \
$(TESTARGS) $(TESTDIRS) $(VGARG)
-endif
FORCE:
diff --git a/test/lit.cfg b/test/lit.cfg
index 0a99aa4ee9..450b614922 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -1,166 +1,146 @@
# -*- Python -*-
-def config_new():
- import os
+import os
- # Configuration file for the 'lit' test runner.
+# Configuration file for the 'lit' test runner.
- # name: The name of this test suite.
- config.name = 'Clang'
+# name: The name of this test suite.
+config.name = 'Clang'
- # testFormat: The test format to use to interpret tests.
- #
- # For now we require '&&' between commands, until they get globally killed and
- # the test runner updated.
- config.test_format = lit.formats.ShTest(execute_external = True,
- require_and_and = True)
-
- # suffixes: A list of file extensions to treat as test files.
- config.suffixes = ['.c', '.cpp', '.m', '.mm']
-
- # test_source_root: The root path where tests are located.
- config.test_source_root = os.path.dirname(__file__)
-
- # test_exec_root: The root path where tests should be run.
- clang_obj_root = getattr(config, 'clang_obj_root', None)
- if clang_obj_root is not None:
- config.test_exec_root = os.path.join(clang_obj_root, 'test')
-
- # Set llvm_{src,obj}_root for use by others.
- config.llvm_src_root = getattr(config, 'llvm_src_root', None)
- config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)
-
- # Tweak the PATH to include the tools dir and the scripts dir.
- if clang_obj_root is not None:
- llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
- if not llvm_tools_dir:
- lit.fatal('No LLVM tools dir set!')
- path = os.path.pathsep.join((llvm_tools_dir,
- os.path.join(config.llvm_src_root,
- 'test', 'Scripts'),
- config.environment['PATH']))
- config.environment['PATH'] = path
-
- ###
-
- # Check that the object root is known.
- if config.test_exec_root is None:
- # Otherwise, we haven't loaded the site specific configuration (the user is
- # probably trying to run on a test file directly, and either the site
- # configuration hasn't been created by the build system, or we are in an
- # out-of-tree build situation).
-
- # Try to detect the situation where we are using an out-of-tree build by
- # looking for 'llvm-config'.
- #
- # FIXME: I debated (i.e., wrote and threw away) adding logic to
- # automagically generate the lit.site.cfg if we are in some kind of fresh
- # build situation. This means knowing how to invoke the build system
- # though, and I decided it was too much magic.
-
- llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
- if not llvm_config:
- lit.fatal('No site specific configuration available!')
-
- # Get the source and object roots.
- llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip()
- llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip()
- clang_src_root = os.path.join(llvm_src_root, "tools", "clang")
- clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang")
-
- # Validate that we got a tree which points to here, using the standard
- # tools/clang layout.
- this_src_root = os.path.dirname(config.test_source_root)
- if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root):
- lit.fatal('No site specific configuration available!')
-
- # Check that the site specific configuration exists.
- site_cfg = os.path.join(clang_obj_root, 'test', 'lit.site.cfg')
- if not os.path.exists(site_cfg):
- lit.fatal('No site specific configuration available!')
-
- # Okay, that worked. Notify the user of the automagic, and reconfigure.
- lit.note('using out-of-tree build at %r' % clang_obj_root)
- lit.load_config(config, site_cfg)
- raise SystemExit
-
- ###
-
- # Discover the 'clang' and 'clangcc' to use.
-
- import os
-
- def inferClang(PATH):
- # 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 = lit.util.which('clang', PATH)
-
- if not clang:
- lit.fatal("couldn't find 'clang' program, try setting "
- "CLANG in your environment")
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+config.test_format = lit.formats.ShTest(execute_external = True,
+ require_and_and = True)
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.c', '.cpp', '.m', '.mm']
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+clang_obj_root = getattr(config, 'clang_obj_root', None)
+if clang_obj_root is not None:
+ config.test_exec_root = os.path.join(clang_obj_root, 'test')
+
+# Set llvm_{src,obj}_root for use by others.
+config.llvm_src_root = getattr(config, 'llvm_src_root', None)
+config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)
+
+# Tweak the PATH to include the tools dir and the scripts dir.
+if clang_obj_root is not None:
+ llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
+ if not llvm_tools_dir:
+ lit.fatal('No LLVM tools dir set!')
+ path = os.path.pathsep.join((llvm_tools_dir,
+ os.path.join(config.llvm_src_root,
+ 'test', 'Scripts'),
+ config.environment['PATH']))
+ config.environment['PATH'] = path
+
+###
+
+# Check that the object root is known.
+if config.test_exec_root is None:
+ # Otherwise, we haven't loaded the site specific configuration (the user is
+ # probably trying to run on a test file directly, and either the site
+ # configuration hasn't been created by the build system, or we are in an
+ # out-of-tree build situation).
+
+ # Try to detect the situation where we are using an out-of-tree build by
+ # looking for 'llvm-config'.
+ #
+ # FIXME: I debated (i.e., wrote and threw away) adding logic to
+ # automagically generate the lit.site.cfg if we are in some kind of fresh
+ # build situation. This means knowing how to invoke the build system
+ # though, and I decided it was too much magic.
+
+ llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
+ if not llvm_config:
+ lit.fatal('No site specific configuration available!')
+
+ # Get the source and object roots.
+ llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip()
+ llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip()
+ clang_src_root = os.path.join(llvm_src_root, "tools", "clang")
+ clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang")
+
+ # Validate that we got a tree which points to here, using the standard
+ # tools/clang layout.
+ this_src_root = os.path.dirname(config.test_source_root)
+ if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root):
+ lit.fatal('No site specific configuration available!')
+
+ # Check that the site specific configuration exists.
+ site_cfg = os.path.join(clang_obj_root, 'test', 'lit.site.cfg')
+ if not os.path.exists(site_cfg):
+ lit.fatal('No site specific configuration available!')
+
+ # Okay, that worked. Notify the user of the automagic, and reconfigure.
+ lit.note('using out-of-tree build at %r' % clang_obj_root)
+ lit.load_config(config, site_cfg)
+ raise SystemExit
+
+###
+
+# Discover the 'clang' and 'clangcc' to use.
+
+import os
+
+def inferClang(PATH):
+ # 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
- def inferClangCC(clang, PATH):
- 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.
- if clang.endswith('.exe'):
- clangccName = clang[:-4] + '-cc.exe'
- else:
- clangccName = clang + '-cc'
- clangcc = lit.util.which(clangccName, PATH)
- if not clangcc:
- # Otherwise ask clang.
- res = lit.util.capture([clang, '-print-prog-name=clang-cc'])
- res = res.strip()
- if res and os.path.exists(res):
- clangcc = res
-
- if not clangcc:
- lit.fatal("couldn't find 'clang-cc' program, try setting "
- "CLANGCC in your environment")
-
- return clangcc
+ # Otherwise look in the path.
+ clang = lit.util.which('clang', PATH)
- config.clang = inferClang(config.environment['PATH'])
- if not lit.quiet:
- lit.note('using clang: %r' % config.clang)
- config.substitutions.append( (' clang ', ' ' + config.clang + ' ') )
+ if not clang:
+ lit.fatal("couldn't find 'clang' program, try setting "
+ "CLANG in your environment")
- config.clang_cc = inferClangCC(config.clang, config.environment['PATH'])
- if not lit.quiet:
- lit.note('using clang-cc: %r' % config.clang_cc)
- config.substitutions.append( (' clang-cc ', ' ' + config.clang_cc + ' ') )
+ return clang
-if 'config' in globals():
- config_new()
- raise SystemExit # End configuration.
+def inferClangCC(clang, PATH):
+ clangcc = os.getenv('CLANGCC')
-# Configuration file for the 'lit' test runner.
-
-# suffixes: A list of file extensions to treat as test files.
-suffixes = ['.c', '.cpp', '.m', '.mm']
-
-# environment: The base environment to use when running test commands.
-#
-# The 'PATH' and 'SYSTEMROOT' variables will be set automatically from the lit
-# command line variables.
-environment = {}
+ # If the user set clang in the environment, definitely use that and don't
+ # try to validate.
+ if clangcc:
+ return clangcc
-# requireAndAnd: Require '&&' between commands, until they get globally killed
-# and the test runner updated.
-requireAndAnd = True
+ # Otherwise try adding -cc since we expect to be looking in a build
+ # directory.
+ if clang.endswith('.exe'):
+ clangccName = clang[:-4] + '-cc.exe'
+ else:
+ clangccName = clang + '-cc'
+ clangcc = lit.util.which(clangccName, PATH)
+ if not clangcc:
+ # Otherwise ask clang.
+ res = lit.util.capture([clang, '-print-prog-name=clang-cc'])
+ res = res.strip()
+ if res and os.path.exists(res):
+ clangcc = res
+
+ if not clangcc:
+ lit.fatal("couldn't find 'clang-cc' program, try setting "
+ "CLANGCC in your environment")
+
+ return clangcc
+
+config.clang = inferClang(config.environment['PATH'])
+if not lit.quiet:
+ lit.note('using clang: %r' % config.clang)
+config.substitutions.append( (' clang ', ' ' + config.clang + ' ') )
+
+config.clang_cc = inferClangCC(config.clang, config.environment['PATH'])
+if not lit.quiet:
+ lit.note('using clang-cc: %r' % config.clang_cc)
+config.substitutions.append( (' clang-cc ', ' ' + config.clang_cc + ' ') )
diff --git a/utils/test/ExampleTests/fail.c b/utils/test/ExampleTests/fail.c
deleted file mode 100644
index 749ba56391..0000000000
--- a/utils/test/ExampleTests/fail.c
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: echo 'I am some stdout' &&
-// RUN: echo 'I am some stderr' 1>&2 &&
-// RUN: false
diff --git a/utils/test/ExampleTests/lit.cfg b/utils/test/ExampleTests/lit.cfg
deleted file mode 100644
index 3bd18dc0f1..0000000000
--- a/utils/test/ExampleTests/lit.cfg
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- Python -*-
-
-# Configuration file for the 'lit' test runner.
-
-# suffixes: A list of file extensions to treat as test files.
-suffixes = ['.c', '.cpp', '.m', '.mm']
-
-# environment: The base environment to use when running test commands.
-#
-# The 'PATH' and 'SYSTEMROOT' variables will be set automatically from the lit
-# command line variables.
-environment = {}
diff --git a/utils/test/ExampleTests/pass.c b/utils/test/ExampleTests/pass.c
deleted file mode 100644
index 5c1031cccc..0000000000
--- a/utils/test/ExampleTests/pass.c
+++ /dev/null
@@ -1 +0,0 @@
-// RUN: true
diff --git a/utils/test/ExampleTests/xfail.c b/utils/test/ExampleTests/xfail.c
deleted file mode 100644
index a650709906..0000000000
--- a/utils/test/ExampleTests/xfail.c
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: false
-// XFAIL
diff --git a/utils/test/ExampleTests/xpass.c b/utils/test/ExampleTests/xpass.c
deleted file mode 100644
index ad84990f7e..0000000000
--- a/utils/test/ExampleTests/xpass.c
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: true
-// XFAIL
diff --git a/utils/test/MultiTestRunner.py b/utils/test/MultiTestRunner.py
deleted file mode 100755
index 6e15f1cd8f..0000000000
--- a/utils/test/MultiTestRunner.py
+++ /dev/null
@@ -1,399 +0,0 @@
-#!/usr/bin/env python
-
-"""
-MultiTestRunner - Harness for running multiple tests in the simple clang style.
-
-TODO
---
- - Use configuration file for clang specific stuff
- - Use a timeout / ulimit
- - Detect signaled failures (abort)
- - Better support for finding tests
-
- - Support "disabling" tests? The advantage of making this distinct from XFAIL
- is it makes it more obvious that it is a temporary measure (and MTR can put
- in a separate category).
-"""
-
-import os, sys, re, random, time
-import threading
-from Queue import Queue
-
-import ProgressBar
-import TestRunner
-import Util
-
-from TestingConfig import TestingConfig
-from TestRunner import TestStatus
-
-kConfigName = 'lit.cfg'
-
-def getTests(cfg, inputs):
- for path in inputs:
- if not os.path.exists(path):
- Util.warning('Invalid test %r' % path)
- continue
-
- if not os.path.isdir(path):
- yield path
- continue
-
- foundOne = False
- for dirpath,dirnames,filenames in os.walk(path):
- # 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 cfg.suffixes:
- yield os.path.join(dirpath,f)
- foundOne = True
- if not foundOne:
- Util.warning('No tests in input directory %r' % 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')
-
- status = TestStatus.getName(tr.code).upper()
- print '%s: %s (%*d of %*d)' % (status, tr.path,
- self.digits, index+1,
- self.digits, self.numTests)
-
- if tr.failed() and self.opts.showOutput:
- print "%s TEST '%s' FAILED %s" % ('*'*20, tr.path, '*'*20)
- print tr.output
- print "*" * 20
-
- sys.stdout.flush()
-
-class TestResult:
- def __init__(self, path, code, output, elapsed):
- self.path = path
- self.code = code
- self.output = output
- self.elapsed = elapsed
-
- def failed(self):
- return self.code in (TestStatus.Fail,TestStatus.XPass)
-
-class TestProvider:
- def __init__(self, config, opts, tests, display):
- self.config = config
- 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)):
- base = TestRunner.getTestOutputBase('Output', path)
- numTests = len(self.provider.tests)
- digits = len(str(numTests))
- code = None
- elapsed = None
- try:
- opts = self.provider.opts
- startTime = time.time()
- code, output = TestRunner.runOneTest(self.provider.config,
- path, base)
- elapsed = time.time() - startTime
- except KeyboardInterrupt:
- # This is a sad hack. Unfortunately subprocess goes
- # bonkers with ctrl-c and we start forking merrily.
- print '\nCtrl-C detected, goodbye.'
- os.kill(0,9)
-
- self.provider.setResult(index, TestResult(path, code, output, elapsed))
-
-def findConfigPath(root):
- prev = None
- while root != prev:
- cfg = os.path.join(root, kConfigName)
- if os.path.exists(cfg):
- return cfg
-
- prev,root = root,os.path.dirname(root)
-
- raise ValueError,"Unable to find config file %r" % kConfigName
-
-def runTests(opts, provider):
- # If only using one testing thread, don't use threads at all; this lets us
- # profile, among other things.
- if opts.numThreads == 1:
- t = Tester(provider)
- t.run()
- return
-
- # Otherwise spin up the testing threads and wait for them to finish.
- testers = [Tester(provider) for i in range(opts.numThreads)]
- for t in testers:
- t.start()
- try:
- for t in testers:
- t.join()
- except KeyboardInterrupt:
- sys.exit(1)
-
-def main():
- global options
- from optparse import OptionParser, OptionGroup
- parser = OptionParser("usage: %prog [options] {file-or-path}")
-
- parser.add_option("", "--root", dest="root",
- help="Path to root test directory",
- action="store", default=None)
- parser.add_option("", "--config", dest="config",
- help="Testing configuration file [default='%s']" % kConfigName,
- action="store", default=None)
-
- group = OptionGroup(parser, "Output Format")
- # FIXME: I find these names very confusing, although I like the
- # functionality.
- group.add_option("-q", "--quiet", dest="quiet",
- help="Suppress no error output",
- action="store_true", default=False)
- group.add_option("-s", "--succinct", dest="succinct",
- help="Reduce amount of output",
- action="store_true", default=False)
- group.add_option("-v", "--verbose", dest="showOutput",
- help="Show all test output",
- action="store_true", default=False)
- group.add_option("", "--no-progress-bar", dest="useProgressBar",
- help="Do not use curses based progress bar",
- action="store_false", default=True)
- parser.add_option_group(group)
-
- group = OptionGroup(parser, "Test Execution")
- group.add_option("-j", "--threads", dest="numThreads",
- help="Number of testing threads",
- type=int, action="store",
- default=None)
- group.add_option("", "--clang", dest="clang",
- help="Program to use as \"clang\"",
- action="store", default=None)
- group.add_option("", "--clang-cc", dest="clangcc",
- help="Program to use as \"clang-cc\"",
- action="store", default=None)
- group.add_option("", "--path", dest="path",
- help="Additional paths to add to testing environment",
- action="append", type=str, default=[])
- group.add_option("", "--no-sh", dest="useExternalShell",
- help="Run tests using an external shell",
- action="store_false", default=True)
- group.add_option("", "--vg", dest="useValgrind",
- help="Run tests under valgrind",
- action="store_true", default=False)
- group.add_option("", "--vg-arg", dest="valgrindArgs",
- help="Specify an extra argument for valgrind",
- type=str, action="append", default=[])
- group.add_option("", "--time-tests", dest="timeTests",
- help="Track elapsed wall time for each test",
- action="store_true", default=False)
- parser.add_option_group(group)
-
- group = OptionGroup(parser, "Test Selection")
- group.add_option("", "--max-tests", dest="maxTests",
- help="Maximum number of tests to run",
- action="store", type=int, default=None)
- group.add_option("", "--max-time", dest="maxTime",
- help="Maximum time to spend testing (in seconds)",
- action="store", type=float, default=None)
- group.add_option("", "--shuffle", dest="shuffle",
- help="Run tests in random order",
- action="store_true", default=False)
- parser.add_option_group(group)
-
- (opts, args) = parser.parse_args()
-
- if not args:
- parser.error('No inputs specified')
-
- if opts.numThreads is None:
- opts.numThreads = Util.detectCPUs()
-
- inputs = args
-
- # Resolve root if not given, either infer it from the config file if given,
- # otherwise from the inputs.
- if not opts.root:
- if opts.config:
- opts.root = os.path.dirname(opts.config)
- else:
- opts.root = os.path.commonprefix([os.path.abspath(p)
- for p in inputs])
-
- # Find the config file, if not specified.
- if not opts.config:
- try:
- opts.config = findConfigPath(opts.root)
- except ValueError,e:
- parser.error(e.args[0])
-
- cfg = TestingConfig.frompath(opts.config)
-
- # Update the configuration based on the command line arguments.
- for name in ('PATH','SYSTEMROOT'):
- if name in cfg.environment:
- parser.error("'%s' should not be set in configuration!" % name)
-
- cfg.root = opts.root
- cfg.environment['PATH'] = os.pathsep.join(opts.path +
- [os.environ.get('PATH','')])
- cfg.environment['SYSTEMROOT'] = os.environ.get('SYSTEMROOT','')
-
- if opts.clang is None:
- opts.clang = TestRunner.inferClang(cfg)
- if opts.clangcc is None:
- opts.clangcc = TestRunner.inferClangCC(cfg, opts.clang)
-
- cfg.clang = opts.clang
- cfg.clangcc = opts.clangcc
- cfg.useValgrind = opts.useValgrind
- cfg.valgrindArgs = opts.valgrindArgs
- cfg.useExternalShell = opts.useExternalShell
-
- # FIXME: It could be worth loading these in parallel with testing.
- allTests = list(getTests(cfg, args))
- allTests.sort()
-
- tests = allTests
- if opts.shuffle:
- random.shuffle(tests)
- if opts.maxTests is not None:
- tests = tests[:opts.maxTests]
-
- 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
-
- # Don't create more threads than tests.
- opts.numThreads = min(len(tests), opts.numThreads)
-
- startTime = time.time()
- display = TestingProgressDisplay(opts, len(tests), progressBar)
- provider = TestProvider(cfg, opts, tests, display)
- runTests(opts, provider)
- display.finish()
-
- if not opts.quiet:
- print 'Testing Time: %.2fs'%(time.time() - startTime)
-
- # List test results 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 (('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 opts.timeTests:
- print '\nTest Times:'
- provider.results.sort(key=lambda t: t and t.elapsed)
- for tr in provider.results:
- if tr:
- print '%.2fs: %s' % (tr.elapsed, tr.path)
-
-if __name__=='__main__':
- main()
diff --git a/utils/test/ProgressBar.py b/utils/test/ProgressBar.py
deleted file mode 100644
index 13db7eccc9..0000000000
--- a/utils/test/ProgressBar.py
+++ /dev/null
@@ -1,227 +0,0 @@
-#!/usr/bin/env 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