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