test.py revision 0b874dacc570d6ed42cad26e0907548d459dfde5
1#!/usr/bin/python2.4
2#
3# Copyright 2010 Google Inc. All Rights Reserved.
4
5"""RenderScript Compiler Test.
6
7Runs subdirectories of tests for the RenderScript compiler.
8"""
9
10import filecmp
11import glob
12import os
13import shutil
14import string
15import subprocess
16import sys
17
18__author__ = 'Android'
19
20
21class Options(object):
22  def __init__(self):
23    return
24  verbose = 0
25  cleanup = 1
26
27
28def CompareFiles(filename):
29  """Compares filename and filename.expect for equality."""
30  actual = filename
31  expect = filename + '.expect'
32
33  if not os.path.isfile(actual):
34    if Options.verbose:
35      print 'Could not find %s' % actual
36    return False
37  if not os.path.isfile(expect):
38    if Options.verbose:
39      print 'Could not find %s' % expect
40    return False
41
42  return filecmp.cmp(actual, expect, False)
43
44
45def GetCommandLineArgs(filename):
46  """Extracts command line arguments from first comment line in a file"""
47  f = open(filename, 'r')
48  line = f.readline()
49  if line[0] == '/' and line [1] == '/':
50    return string.strip(line[2:])
51  else:
52    return ""
53
54
55def ExecTest(dirname):
56  """Executes an llvm-rs-cc test from dirname."""
57  passed = True
58
59  if Options.verbose != 0:
60    print 'Testing %s' % dirname
61
62  os.chdir(dirname)
63  stdout_file = open('stdout.txt', 'w+')
64  stderr_file = open('stderr.txt', 'w+')
65
66  cmd_string = ('../../../../../out/host/linux-x86/bin/llvm-rs-cc '
67                '-o tmp/ -p tmp/ '
68                '-I ../../../../../frameworks/base/libs/rs/scriptc/ '
69                '-I ../../../../../external/clang/lib/Headers/')
70  base_args = cmd_string.split()
71  rs_files = glob.glob('*.rs')
72  rs_files.sort()
73
74  # Extra command line arguments can be placed as // comments at the start of
75  # any .rs file. We automatically bundle up all of these extra args and invoke
76  # llvm-rs-cc with them.
77  extra_args_str = ""
78  for rs_file in rs_files:
79    extra_args_str += GetCommandLineArgs(rs_file)
80  extra_args = extra_args_str.split()
81
82  args = base_args + extra_args + rs_files
83
84  if Options.verbose > 1:
85    print 'Executing:',
86    for arg in args:
87      print arg,
88    print
89
90  # Execute the command and check the resulting shell return value.
91  # All tests that are expected to FAIL have directory names that
92  # start with 'F_'. Other tests that are expected to PASS have
93  # directory names that start with 'P_'.
94  ret = 0
95  try:
96    ret = subprocess.call(args, stdout=stdout_file, stderr=stderr_file)
97  except:
98    passed = False
99
100  stdout_file.flush()
101  stderr_file.flush()
102
103  if Options.verbose > 1:
104    stdout_file.seek(0)
105    stderr_file.seek(0)
106    for line in stdout_file:
107      print 'STDOUT>', line,
108    for line in stderr_file:
109      print 'STDERR>', line,
110
111  stdout_file.close()
112  stderr_file.close()
113
114  if dirname[0:2] == 'F_':
115    if ret == 0:
116      passed = False
117      if Options.verbose:
118        print 'Command passed on invalid input'
119  elif dirname[0:2] == 'P_':
120    if ret != 0:
121      passed = False
122      if Options.verbose:
123        print 'Command failed on valid input'
124  else:
125    passed = (ret == 0)
126    if Options.verbose:
127      print 'Test Directory name should start with an F or a P'
128
129  if not CompareFiles('stdout.txt'):
130    passed = False
131    if Options.verbose:
132      print 'stdout is different'
133  if not CompareFiles('stderr.txt'):
134    passed = False
135    if Options.verbose:
136      print 'stderr is different'
137
138  if Options.cleanup:
139    try:
140      os.remove('stdout.txt')
141      os.remove('stderr.txt')
142      shutil.rmtree('tmp/')
143    except:
144      pass
145
146  os.chdir('..')
147  return passed
148
149
150def Usage():
151  print ('Usage: %s [OPTION]... [TESTNAME]...'
152         'RenderScript Compiler Test Harness\n'
153         'Runs TESTNAMEs (all tests by default)\n'
154         'Available Options:\n'
155         '  -h, --help          Help message\n'
156         '  -n, --no-cleanup    Don\'t clean up after running tests\n'
157         '  -v, --verbose       Verbose output\n'
158        ) % (sys.argv[0]),
159  return
160
161
162def main():
163  passed = 0
164  failed = 0
165  files = []
166  failed_tests = []
167
168  for arg in sys.argv[1:]:
169    if arg in ('-h', '--help'):
170      Usage()
171      return 0
172    elif arg in ('-n', '--no-cleanup'):
173      Options.cleanup = 0
174    elif arg in ('-v', '--verbose'):
175      Options.verbose += 1
176    else:
177      # Test list to run
178      if os.path.isdir(arg):
179        files.append(arg)
180      else:
181        print >> sys.stderr, 'Invalid test or option: %s' % arg
182        return 1
183
184  if not files:
185    tmp_files = os.listdir('.')
186    # Only run tests that are known to PASS or FAIL
187    # Disabled tests can be marked D_ and invoked explicitly
188    for f in tmp_files:
189      if os.path.isdir(f) and (f[0:2] == 'F_' or f[0:2] == 'P_'):
190        files.append(f)
191
192  for f in files:
193    if os.path.isdir(f):
194      if ExecTest(f):
195        passed += 1
196      else:
197        failed += 1
198        failed_tests.append(f)
199
200  print 'Tests Passed: %d\n' % passed,
201  print 'Tests Failed: %d\n' % failed,
202  if failed:
203    print 'Failures:',
204    for t in failed_tests:
205      print t,
206
207  return failed != 0
208
209
210if __name__ == '__main__':
211  sys.exit(main())
212