tests/harness.py
author David Anderson <dvander@alliedmods.net>
Sun Nov 18 15:26:12 2012 -0800 (2012-11-18)
changeset 216 ea63f1680097
parent 214 e1a6deaa6ebe
child 263 ba85a47ee414
permissions -rw-r--r--
More GCC bogosity.
     1 # vim: set ts=2 sw=4 tw=99 ft=python et:
     2 import os
     3 import re
     4 import sys
     5 import time
     6 import os.path
     7 from test import Test
     8 from subprocess import *
     9 from threading import Thread
    10 from display import Interactive
    11 
    12 def FindTests(tests, root, folder):
    13   folders = []
    14   for name in os.listdir(os.path.join(root, folder)):
    15     path = os.path.join(root, folder, name)
    16     if os.path.isdir(path):
    17       folders.append(name)
    18       continue
    19 
    20     out = re.match("^([^\.]+)\.out$", name)
    21     err = re.match("^([^\.]+)\.err$", name)
    22     if out:
    23         name = os.path.join(folder, out.group(1))
    24         tests.append(Test(root, name, 'out'))
    25     elif err:
    26         name = os.path.join(folder, err.group(1))
    27         tests.append(Test(root, name, 'err'))
    28 
    29   for name in folders:
    30     path = os.path.join(folder, name)
    31     FindTests(tests, root, path)
    32 
    33 def IsTestRoot(path, name):
    34   return os.path.isdir(path)
    35 
    36 def RunTest_(argv, options, L):
    37   if sys.platform != 'win32':
    38     options['close_fds'] = True
    39 
    40   p = Popen(argv, stdin=PIPE, stdout=PIPE, stderr=PIPE, **options)
    41 
    42   L[0] = p
    43   out, err = p.communicate()
    44   L[1] = (out, err, p.returncode)
    45 
    46 def RunTest(test, options, shell):
    47   argv = [shell, test.cmd()]
    48 
    49   L = [None, None]
    50   timeout = False
    51   th = Thread(target = RunTest_, args = (argv, options, L))
    52   th.start()
    53   th.join(10.0)
    54   while th.isAlive():
    55     if L[0] is not None:
    56       try:
    57         L[0].kill()
    58         time.sleep(.1)
    59         timeout = True
    60       except e:
    61         pass
    62 
    63   th.join()
    64   (out, err, code) = L[1]
    65 
    66   return test.check(out, err, code, timeout)
    67 
    68 def RunTests(display, tests, shell):
    69   display.begin(tests)
    70   ok = True
    71   try:
    72     for test in tests:
    73       options = { }
    74       result = RunTest(test, options, shell)
    75 
    76       ok = ok and result.ok
    77       
    78       display.result(test, result)
    79   except KeyboardInterrupt:
    80     display.cancel()
    81     ok = False
    82 
    83   return ok
    84 
    85   
    86 def main(argv):
    87   root = os.path.dirname(os.path.abspath(__file__))
    88 
    89   from optparse import OptionParser
    90   op = OptionParser(usage='%prog [options] <shell>')
    91   (options, args) = op.parse_args(argv)
    92 
    93   if len(args) != 1:
    94     op.error('missing <shell> argument')
    95 
    96   shell = os.path.normpath(args[0])
    97 
    98   tests = []
    99   for name in os.listdir(root):
   100     path = os.path.join(root, name)
   101     if IsTestRoot(path, name):
   102       FindTests(tests, root, name)
   103 
   104   if len(tests) == 0:
   105     op.error('no test cases found')
   106 
   107   display = Interactive()
   108   ok = RunTests(display, tests, shell)
   109   if ok:
   110     sys.exit(0)
   111   else:
   112     sys.exit(1)
   113 
   114 if __name__ == '__main__':
   115   main(sys.argv[1:])
   116