]> granicus.if.org Git - clang/commitdiff
Remove old test runner, this has moved to LLVM/utils/lit and all known clients
authorDaniel Dunbar <daniel@zuster.org>
Tue, 22 Sep 2009 05:16:02 +0000 (05:16 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 22 Sep 2009 05:16:02 +0000 (05:16 +0000)
have been updated.
 - Please let me know of any problems.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82524 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
test/Makefile
test/lit.cfg
utils/test/ExampleTests/fail.c [deleted file]
utils/test/ExampleTests/lit.cfg [deleted file]
utils/test/ExampleTests/pass.c [deleted file]
utils/test/ExampleTests/xfail.c [deleted file]
utils/test/ExampleTests/xpass.c [deleted file]
utils/test/MultiTestRunner.py [deleted file]
utils/test/ProgressBar.py [deleted file]
utils/test/ShUtil.py [deleted file]
utils/test/TestRunner.py [deleted file]
utils/test/TestingConfig.py [deleted file]
utils/test/Util.py [deleted file]

index 9ed683435f44e248501fc9a5ce910d9ee333f3a2..6ed13d6b88e1535b53f22386bbeae825254fd4ae 100644 (file)
@@ -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:
 
index 0a99aa4ee9dd3e5e3165db6cd6b1ecbad7018410..450b6149223c08da72058e641f5d85bcdc27004c 100644 (file)
 # -*- 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 (file)
index 749ba56..0000000
+++ /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 (file)
index 3bd18dc..0000000
+++ /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 (file)
index 5c1031c..0000000
+++ /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 (file)
index a650709..0000000
+++ /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 (file)
index ad84990..0000000
+++ /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 (executable)
index 6e15f1c..0000000
+++ /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 (file)
index 13db7ec..0000000
+++ /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 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/ShUtil.py b/utils/test/ShUtil.py
deleted file mode 100644 (file)
index dd4b584..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-import itertools
-
-import Util
-
-class ShLexer:
-    def __init__(self, data, win32Escapes = False):
-        self.data = data
-        self.pos = 0
-        self.end = len(data)
-        self.win32Escapes = win32Escapes
-
-    def eat(self):
-        c = self.data[self.pos]
-        self.pos += 1
-        return c
-
-    def look(self):
-        return self.data[self.pos]
-
-    def maybe_eat(self, c):
-        """
-        maybe_eat(c) - Consume the character c if it is the next character,
-        returning True if a character was consumed. """
-        if self.data[self.pos] == c:
-            self.pos += 1
-            return True
-        return False
-
-    def lex_arg_fast(self, c):
-        # Get the leading whitespace free section.
-        chunk = self.data[self.pos - 1:].split(None, 1)[0]
-        
-        # If it has special characters, the fast path failed.
-        if ('|' in chunk or '&' in chunk or 
-            '<' in chunk or '>' in chunk or
-            "'" in chunk or '"' in chunk or
-            '\\' in chunk):
-            return None
-        
-        self.pos = self.pos - 1 + len(chunk)
-        return chunk
-        
-    def lex_arg_slow(self, c):
-        if c in "'\"":
-            str = self.lex_arg_quoted(c)
-        else:
-            str = c
-        while self.pos != self.end:
-            c = self.look()
-            if c.isspace() or c in "|&":
-                break
-            elif c in '><':
-                # This is an annoying case; we treat '2>' as a single token so
-                # we don't have to track whitespace tokens.
-
-                # If the parse string isn't an integer, do the usual thing.
-                if not str.isdigit():
-                    break
-
-                # Otherwise, lex the operator and convert to a redirection
-                # token.
-                num = int(str)
-                tok = self.lex_one_token()
-                assert isinstance(tok, tuple) and len(tok) == 1
-                return (tok[0], num)                    
-            elif c == '"':
-                self.eat()
-                str += self.lex_arg_quoted('"')\r
-            elif not self.win32Escapes and c == '\\':
-                # Outside of a string, '\\' escapes everything.
-                self.eat()
-                if self.pos == self.end:
-                    Util.warning("escape at end of quoted argument in: %r" % 
-                                 self.data)
-                    return str
-                str += self.eat()
-            else:
-                str += self.eat()
-        return str
-
-    def lex_arg_quoted(self, delim):
-        str = ''
-        while self.pos != self.end:
-            c = self.eat()
-            if c == delim:
-                return str
-            elif c == '\\' and delim == '"':
-                # Inside a '"' quoted string, '\\' only escapes the quote
-                # character and backslash, otherwise it is preserved.
-                if self.pos == self.end:
-                    Util.warning("escape at end of quoted argument in: %r" % 
-                                 self.data)
-                    return str
-                c = self.eat()
-                if c == '"': # 
-                    str += '"'
-                elif c == '\\':
-                    str += '\\'
-                else:
-                    str += '\\' + c
-            else:
-                str += c
-        Util.warning("missing quote character in %r" % self.data)
-        return str
-    
-    def lex_arg_checked(self, c):
-        pos = self.pos
-        res = self.lex_arg_fast(c)
-        end = self.pos
-
-        self.pos = pos
-        reference = self.lex_arg_slow(c)
-        if res is not None:
-            if res != reference:
-                raise ValueError,"Fast path failure: %r != %r" % (res, reference)
-            if self.pos != end:
-                raise ValueError,"Fast path failure: %r != %r" % (self.pos, end)
-        return reference
-        
-    def lex_arg(self, c):
-        return self.lex_arg_fast(c) or self.lex_arg_slow(c)
-        
-    def lex_one_token(self):
-        """
-        lex_one_token - Lex a single 'sh' token. """
-
-        c = self.eat()
-        if c in ';!':
-            return (c,)
-        if c == '|':
-            if self.maybe_eat('|'):
-                return ('||',)
-            return (c,)
-        if c == '&':
-            if self.maybe_eat('&'):
-                return ('&&',)
-            if self.maybe_eat('>'): 
-                return ('&>',)
-            return (c,)
-        if c == '>':
-            if self.maybe_eat('&'):
-                return ('>&',)
-            if self.maybe_eat('>'):
-                return ('>>',)
-            return (c,)
-        if c == '<':
-            if self.maybe_eat('&'):
-                return ('<&',)
-            if self.maybe_eat('>'):
-                return ('<<',)
-            return (c,)
-
-        return self.lex_arg(c)
-
-    def lex(self):
-        while self.pos != self.end:
-            if self.look().isspace():
-                self.eat()
-            else:
-                yield self.lex_one_token()
-
-###
-
-class Command:
-    def __init__(self, args, redirects):
-        self.args = list(args)
-        self.redirects = list(redirects)
-        
-    def __repr__(self):
-        return 'Command(%r, %r)' % (self.args, self.redirects)
-
-    def __cmp__(self, other):
-        if not isinstance(other, Command):
-            return -1
-
-        return cmp((self.args, self.redirects),
-                   (other.args, other.redirects))
-
-class Pipeline:
-    def __init__(self, commands, negate):
-        self.commands = commands
-        self.negate = negate
-
-    def __repr__(self):
-        return 'Pipeline(%r, %r)' % (self.commands, self.negate)
-
-    def __cmp__(self, other):
-        if not isinstance(other, Pipeline):
-            return -1
-
-        return cmp((self.commands, self.negate), 
-                   (other.commands, other.negate))
-
-class Seq:
-    def __init__(self, lhs, op, rhs):
-        assert op in (';', '&', '||', '&&')
-        self.op = op
-        self.lhs = lhs
-        self.rhs = rhs
-    
-    def __repr__(self):
-        return 'Seq(%r, %r, %r)' % (self.lhs, self.op, self.rhs)
-
-    def __cmp__(self, other):
-        if not isinstance(other, Seq):
-            return -1
-
-        return cmp((self.lhs, self.op, self.rhs), 
-                   (other.lhs, other.op, other.rhs))
-
-class ShParser:
-    def __init__(self, data, win32Escapes = False):
-        self.data = data
-        self.tokens = ShLexer(data, win32Escapes = win32Escapes).lex()
-    
-    def lex(self):
-        try:
-            return self.tokens.next()
-        except StopIteration:
-            return None
-    
-    def look(self):
-        next = self.lex()
-        if next is not None:
-            self.tokens = itertools.chain([next], self.tokens)
-        return next
-    
-    def parse_command(self):
-        tok = self.lex()
-        if not tok:
-            raise ValueError,"empty command!"
-        if isinstance(tok, tuple):
-            raise ValueError,"syntax error near unexpected token %r" % tok[0]
-        
-        args = [tok]
-        redirects = []
-        while 1:
-            tok = self.look()
-
-            # EOF?
-            if tok is None:
-                break
-
-            # If this is an argument, just add it to the current command.
-            if isinstance(tok, str):
-                args.append(self.lex())
-                continue
-
-            # Otherwise see if it is a terminator.
-            assert isinstance(tok, tuple)
-            if tok[0] in ('|',';','&','||','&&'):
-                break
-            
-            # Otherwise it must be a redirection.
-            op = self.lex()
-            arg = self.lex()
-            if not arg:
-                raise ValueError,"syntax error near token %r" % op[0]
-            redirects.append((op, arg))
-
-        return Command(args, redirects)
-
-    def parse_pipeline(self):
-        negate = False
-        if self.look() == ('!',):
-            self.lex()
-            negate = True
-
-        commands = [self.parse_command()]
-        while self.look() == ('|',):
-            self.lex()
-            commands.append(self.parse_command())
-        return Pipeline(commands, negate)
-            
-    def parse(self):
-        lhs = self.parse_pipeline()
-
-        while self.look():
-            operator = self.lex()
-            assert isinstance(operator, tuple) and len(operator) == 1
-
-            if not self.look():
-                raise ValueError, "missing argument to operator %r" % operator[0]
-            
-            # FIXME: Operator precedence!!
-            lhs = Seq(lhs, operator[0], self.parse_pipeline())
-
-        return lhs
-
-###
-
-import unittest
-
-class TestShLexer(unittest.TestCase):
-    def lex(self, str, *args, **kwargs):
-        return list(ShLexer(str, *args, **kwargs).lex())
-
-    def test_basic(self):
-        self.assertEqual(self.lex('a|b>c&d<e'),
-                         ['a', ('|',), 'b', ('>',), 'c', ('&',), 'd', 
-                          ('<',), 'e'])
-
-    def test_redirection_tokens(self):
-        self.assertEqual(self.lex('a2>c'),
-                         ['a2', ('>',), 'c'])
-        self.assertEqual(self.lex('a 2>c'),
-                         ['a', ('>',2), 'c'])
-        
-    def test_quoting(self):
-        self.assertEqual(self.lex(""" 'a' """),
-                         ['a'])
-        self.assertEqual(self.lex(""" "hello\\"world" """),
-                         ['hello"world'])
-        self.assertEqual(self.lex(""" "hello\\'world" """),
-                         ["hello\\'world"])
-        self.assertEqual(self.lex(""" "hello\\\\world" """),
-                         ["hello\\world"])
-        self.assertEqual(self.lex(""" he"llo wo"rld """),
-                         ["hello world"])
-        self.assertEqual(self.lex(""" a\\ b a\\\\b """),
-                         ["a b", "a\\b"])
-        self.assertEqual(self.lex(""" "" "" """),
-                         ["", ""])
-        self.assertEqual(self.lex(""" a\\ b """, win32Escapes = True),
-                         ['a\\', 'b'])
-
-class TestShParse(unittest.TestCase):
-    def parse(self, str):
-        return ShParser(str).parse()
-
-    def test_basic(self):
-        self.assertEqual(self.parse('echo hello'),
-                         Pipeline([Command(['echo', 'hello'], [])], False))
-        self.assertEqual(self.parse('echo ""'),
-                         Pipeline([Command(['echo', ''], [])], False))
-
-    def test_redirection(self):
-        self.assertEqual(self.parse('echo hello > c'),
-                         Pipeline([Command(['echo', 'hello'], 
-                                           [((('>'),), 'c')])], False))
-        self.assertEqual(self.parse('echo hello > c >> d'),
-                         Pipeline([Command(['echo', 'hello'], [(('>',), 'c'),
-                                                     (('>>',), 'd')])], False))
-
-    def test_pipeline(self):
-        self.assertEqual(self.parse('a | b'),
-                         Pipeline([Command(['a'], []),
-                                   Command(['b'], [])],
-                                  False))
-
-        self.assertEqual(self.parse('a | b | c'),
-                         Pipeline([Command(['a'], []),
-                                   Command(['b'], []),
-                                   Command(['c'], [])],
-                                  False))
-
-        self.assertEqual(self.parse('! a'),
-                         Pipeline([Command(['a'], [])],
-                                  True))
-
-    def test_list(self):        
-        self.assertEqual(self.parse('a ; b'),
-                         Seq(Pipeline([Command(['a'], [])], False),
-                             ';',
-                             Pipeline([Command(['b'], [])], False)))
-
-        self.assertEqual(self.parse('a & b'),
-                         Seq(Pipeline([Command(['a'], [])], False),
-                             '&',
-                             Pipeline([Command(['b'], [])], False)))
-
-        self.assertEqual(self.parse('a && b'),
-                         Seq(Pipeline([Command(['a'], [])], False),
-                             '&&',
-                             Pipeline([Command(['b'], [])], False)))
-
-        self.assertEqual(self.parse('a || b'),
-                         Seq(Pipeline([Command(['a'], [])], False),
-                             '||',
-                             Pipeline([Command(['b'], [])], False)))
-
-        self.assertEqual(self.parse('a && b || c'),
-                         Seq(Seq(Pipeline([Command(['a'], [])], False),
-                                 '&&',
-                                 Pipeline([Command(['b'], [])], False)),
-                             '||',
-                             Pipeline([Command(['c'], [])], False)))
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/utils/test/TestRunner.py b/utils/test/TestRunner.py
deleted file mode 100755 (executable)
index 2fdede0..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-import os
-import platform
-import re
-import signal
-import subprocess
-import sys
-
-import ShUtil
-import Util
-
-kSystemName = platform.system()
-
-class TestStatus:
-    Pass = 0 
-    XFail = 1
-    Fail = 2
-    XPass = 3
-    Invalid = 4
-
-    kNames = ['Pass','XFail','Fail','XPass','Invalid']
-    @staticmethod
-    def getName(code): 
-        return TestStatus.kNames[code]
-
-def executeShCmd(cmd, cfg, cwd, results):
-    if isinstance(cmd, ShUtil.Seq):
-        if cmd.op == ';':
-            res = executeShCmd(cmd.lhs, cfg, cwd, results)
-            return executeShCmd(cmd.rhs, cfg, cwd, results)
-
-        if cmd.op == '&':
-            raise NotImplementedError,"unsupported test command: '&'"
-
-        if cmd.op == '||':
-            res = executeShCmd(cmd.lhs, cfg, cwd, results)
-            if res != 0:
-                res = executeShCmd(cmd.rhs, cfg, cwd, results)
-            return res
-        if cmd.op == '&&':
-            res = executeShCmd(cmd.lhs, cfg, cwd, results)
-            if res is None:
-                return res
-
-            if res == 0:
-                res = executeShCmd(cmd.rhs, cfg, cwd, results)
-            return res
-            
-        raise ValueError,'Unknown shell command: %r' % cmd.op
-
-    assert isinstance(cmd, ShUtil.Pipeline)
-    procs = []
-    input = subprocess.PIPE
-    for j in cmd.commands:
-        # FIXME: This is broken, it doesn't account for the accumulative nature
-        # of redirects.
-        stdin = input
-        stdout = stderr = subprocess.PIPE
-        for r in j.redirects:
-            if r[0] == ('>',2):
-                stderr = open(r[1], 'w')
-            elif r[0] == ('>&',2) and r[1] == '1':
-                stderr = subprocess.STDOUT
-            elif r[0] == ('>',):
-                stdout = open(r[1], 'w')
-            elif r[0] == ('<',):
-                stdin = open(r[1], 'r')
-            else:
-                raise NotImplementedError,"Unsupported redirect: %r" % r
-
-        procs.append(subprocess.Popen(j.args, cwd=cwd,
-                                      stdin = stdin,
-                                      stdout = stdout,
-                                      stderr = stderr,
-                                      env = cfg.environment))
-
-        # Immediately close stdin for any process taking stdin from us.
-        if stdin == subprocess.PIPE:
-            procs[-1].stdin.close()
-            procs[-1].stdin = None
-
-        if stdout == subprocess.PIPE:
-            input = procs[-1].stdout
-        else:
-            input = subprocess.PIPE
-    
-    # FIXME: There is a potential for deadlock here, when we have a pipe and
-    # some process other than the last one ends up blocked on stderr.
-    procData = [None] * len(procs)
-    procData[-1] = procs[-1].communicate()
-    for i in range(len(procs) - 1):
-        if procs[i].stdout is not None:
-            out = procs[i].stdout.read()
-        else:
-            out = ''
-        if procs[i].stderr is not None:
-            err = procs[i].stderr.read()
-        else:
-            err = ''
-        procData[i] = (out,err)
-
-    # FIXME: Fix tests to work with pipefail, and make exitCode max across
-    # procs.
-    for i,(out,err) in enumerate(procData):
-        exitCode = res = procs[i].wait()
-        results.append((cmd.commands[i], out, err, res))
-
-    if cmd.negate:
-        exitCode = not exitCode
-
-    return exitCode
-        
-def executeScriptInternal(cfg, commands, cwd):
-    cmd = ShUtil.ShParser(' &&\n'.join(commands), 
-                          kSystemName == 'Windows').parse()
-
-    results = []
-    try:
-        exitCode = executeShCmd(cmd, cfg, cwd, results)
-    except:
-        import traceback
-
-        out = ''
-        err = 'Exception during script execution:\n%s\n' % traceback.format_exc()
-        return out, err, 127
-
-    out = err = ''
-    for i,(cmd, cmd_out,cmd_err,res) in enumerate(results):
-        out += 'Command %d: %s\n' % (i, ' '.join('"%s"' % s for s in cmd.args))
-        out += 'Command %d Result: %r\n' % (i, res)
-        out += 'Command %d Output:\n%s\n\n' % (i, cmd_out)
-        out += 'Command %d Stderr:\n%s\n\n' % (i, cmd_err)
-
-    return out, err, exitCode
-
-def executeScript(cfg, script, commands, cwd):
-    # Write script file
-    f = open(script,'w')
-    if kSystemName == 'Windows':
-        f.write('\nif %ERRORLEVEL% NEQ 0 EXIT\n'.join(commands))
-    else:
-        f.write(' &&\n'.join(commands))
-    f.write('\n')
-    f.close()
-
-    if kSystemName == 'Windows':
-        command = ['cmd','/c', script]
-    else:
-        command = ['/bin/sh', script]
-        if cfg.useValgrind:
-            # FIXME: Running valgrind on sh is overkill. We probably could just
-            # run on clang with no real loss.
-            valgrindArgs = ['valgrind', '-q',
-                            '--tool=memcheck', '--trace-children=yes',
-                            '--error-exitcode=123'] + cfg.valgrindArgs
-            command = valgrindArgs + command
-
-    p = subprocess.Popen(command, cwd=cwd,
-                         stdin=subprocess.PIPE,
-                         stdout=subprocess.PIPE,
-                         stderr=subprocess.PIPE,
-                         env=cfg.environment)
-    out,err = p.communicate()
-    exitCode = p.wait()
-
-    return out, err, exitCode
-
-import StringIO
-def runOneTest(cfg, testPath, tmpBase):
-    # Make paths absolute.
-    tmpBase = os.path.abspath(tmpBase)
-    testPath = os.path.abspath(testPath)
-
-    # Create the output directory if it does not already exist.
-
-    Util.mkdir_p(os.path.dirname(tmpBase))
-    script = tmpBase + '.script'
-    if kSystemName == 'Windows':
-        script += '.bat'
-
-    substitutions = [('%s', testPath),
-                     ('%S', os.path.dirname(testPath)),
-                     ('%t', tmpBase + '.tmp'),
-                     (' clang ', ' ' + cfg.clang + ' '),
-                     (' clang-cc ', ' ' + cfg.clangcc + ' ')]
-
-    # Collect the test lines from the script.
-    scriptLines = []
-    xfailLines = []
-    for ln in open(testPath):
-        if 'RUN:' in ln:
-            # Isolate the command to run.
-            index = ln.index('RUN:')
-            ln = ln[index+4:]
-            
-            # Strip trailing newline.
-            scriptLines.append(ln)
-        elif 'XFAIL' in ln:
-            xfailLines.append(ln)
-        
-        # FIXME: Support something like END, in case we need to process large
-        # files.
-
-    # Verify the script contains a run line.
-    if not scriptLines:
-        return (TestStatus.Fail, "Test has no run line!")
-    
-    # Apply substitutions to the script.
-    def processLine(ln):
-        # Apply substitutions
-        for a,b in substitutions:
-            ln = ln.replace(a,b)
-
-        # Strip the trailing newline and any extra whitespace.
-        return ln.strip()
-    scriptLines = map(processLine, scriptLines)    
-
-    # Validate interior lines for '&&', a lovely historical artifact.
-    for i in range(len(scriptLines) - 1):
-        ln = scriptLines[i]
-
-        if not ln.endswith('&&'):
-            return (TestStatus.Fail, 
-                    ("MISSING \'&&\': %s\n"  +
-                     "FOLLOWED BY   : %s\n") % (ln, scriptLines[i + 1]))
-    
-        # Strip off '&&'
-        scriptLines[i] = ln[:-2]
-
-    if not cfg.useExternalShell:
-        res = executeScriptInternal(cfg, scriptLines, os.path.dirname(testPath))
-
-        if res is not None:
-            out, err, exitCode = res
-        elif True:
-            return (TestStatus.Fail, 
-                    "Unable to execute internally:\n%s\n" 
-                    % '\n'.join(scriptLines))
-        else:
-            out, err, exitCode = executeScript(cfg, script, scriptLines, 
-                                               os.path.dirname(testPath))
-    else:
-        out, err, exitCode = executeScript(cfg, script, scriptLines, 
-                                           os.path.dirname(testPath))
-
-    # Detect Ctrl-C in subprocess.
-    if exitCode == -signal.SIGINT:
-        raise KeyboardInterrupt
-
-    if xfailLines:
-        ok = exitCode != 0
-        status = (TestStatus.XPass, TestStatus.XFail)[ok]
-    else:
-        ok = exitCode == 0
-        status = (TestStatus.Fail, TestStatus.Pass)[ok]
-
-    if ok:
-        return (status,'')
-
-    output = StringIO.StringIO()
-    print >>output, "Script:"
-    print >>output, "--"
-    print >>output, '\n'.join(scriptLines)
-    print >>output, "--"
-    print >>output, "Exit Code: %r" % exitCode
-    print >>output, "Command Output (stdout):"
-    print >>output, "--"
-    output.write(out)
-    print >>output, "--"
-    print >>output, "Command Output (stderr):"
-    print >>output, "--"
-    output.write(err)
-    print >>output, "--"
-    return (status, output.getvalue())
-
-def capture(args):
-    p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    out,_ = p.communicate()
-    return out
-
-def inferClang(cfg):
-    # 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 = Util.which('clang', cfg.environment['PATH'])
-
-    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(cfg, 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.
-    if clang.endswith('.exe'):
-        clangccName = clang[:-4] + '-cc.exe'
-    else:
-        clangccName = clang + '-cc'
-    clangcc = Util.which(clangccName, cfg.environment['PATH'])
-    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 getTestOutputBase(dir, testpath):
-    """getTestOutputBase(dir, testpath) - Get the full path for temporary files
-    corresponding to the given test path."""
-
-    # Form the output base out of the test parent directory name and the test
-    # name. FIXME: Find a better way to organize test results.
-    return os.path.join(dir, 
-                        os.path.basename(os.path.dirname(testpath)),
-                        os.path.basename(testpath))
diff --git a/utils/test/TestingConfig.py b/utils/test/TestingConfig.py
deleted file mode 100644 (file)
index b611d78..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-class TestingConfig:
-    """"
-    TestingConfig - Information on a how to run a group of tests.
-    """
-    
-    @staticmethod
-    def frompath(path):
-        data = {}
-        f = open(path)
-        exec f in {},data
-
-        return TestingConfig(suffixes = data.get('suffixes', []),
-                             environment = data.get('environment', {}))
-
-    def __init__(self, suffixes, environment):
-        self.suffixes = set(suffixes)
-        self.environment = dict(environment)
-
-        # Variables set internally.
-        self.root = None
-        self.useValgrind = None
-        self.useExternalShell = None
-        self.valgrindArgs = []
-
-        # FIXME: These need to move into a substitutions mechanism.
-        self.clang = None
-        self.clangcc = None
diff --git a/utils/test/Util.py b/utils/test/Util.py
deleted file mode 100644 (file)
index 66cbd0d..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-import errno, os, sys
-
-def warning(msg):
-    print >>sys.stderr, '%s: warning: %s' % (sys.argv[0], msg)
-
-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 mkdir_p(path):
-    """mkdir_p(path) - Make the "path" directory, if it does not exist; this
-    will also make directories for any missing parent directories."""
-
-    if not path or os.path.exists(path):
-        return
-
-    parent = os.path.dirname(path) 
-    if parent != path:
-        mkdir_p(parent)
-
-    try:
-        os.mkdir(path)
-    except OSError,e:
-        # Ignore EEXIST, which may occur during a race condition.
-        if e.errno != errno.EEXIST:
-            raise
-
-def which(command, paths = None):
-    """which(command, [paths]) - Look up the given command in the paths string (or
-    the PATH environment variable, if unspecified)."""
-
-    if paths is None:
-        paths = os.environ.get('PATH','')
-
-    # Check for absolute match first.
-    if os.path.exists(command):
-        return command
-
-    # Would be nice if Python had a lib function for this.
-    if not paths:
-        paths = os.defpath
-
-    # Get suffixes to search.
-    pathext = os.environ.get('PATHEXT', '').split(os.pathsep)
-
-    # Search the paths...
-    for path in paths.split(os.pathsep):
-        for ext in pathext:
-            p = os.path.join(path, command + ext)
-            if os.path.exists(p):
-                return p
-
-    return None
-