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