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