• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python2.4
2#
3# Copyright 2010-2012 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 re
14import shutil
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  updateCTS = 0
27
28
29def CompareFiles(actual, expect):
30  """Compares actual and expect for equality."""
31  if not os.path.isfile(actual):
32    if Options.verbose:
33      print 'Could not find %s' % actual
34    return False
35  if not os.path.isfile(expect):
36    if Options.verbose:
37      print 'Could not find %s' % expect
38    return False
39
40  return filecmp.cmp(actual, expect, False)
41
42
43def UpdateFiles(src, dst):
44  """Update dst if it is different from src."""
45  if not CompareFiles(src, dst):
46    print 'Copying from %s to %s' % (src, dst)
47    shutil.copyfile(src, dst)
48
49
50def GetCommandLineArgs(filename):
51  """Extracts command line arguments from first comment line in a file."""
52  f = open(filename, 'r')
53  line = f.readline()
54  if line[0] == '/' and line [1] == '/':
55    return line[2:].strip()
56  else:
57    return ''
58
59
60def ExecTest(dirname):
61  """Executes an llvm-rs-cc test from dirname."""
62  passed = True
63
64  if Options.verbose != 0:
65    print 'Testing %s' % dirname
66
67  os.chdir(dirname)
68  stdout_file = open('stdout.txt', 'w+')
69  stderr_file = open('stderr.txt', 'w+')
70
71  cmd_string = ('../../../../../out/host/linux-x86/bin/llvm-rs-cc '
72                '-o tmp/ -p tmp/ '
73                '-MD '
74                '-I ../../../../../frameworks/rs/scriptc/ '
75                '-I ../../../../../external/clang/lib/Headers/')
76  base_args = cmd_string.split()
77  rs_files = glob.glob('*.rs')
78  rs_files.sort()
79
80  # Extra command line arguments can be placed as // comments at the start of
81  # any .rs file. We automatically bundle up all of these extra args and invoke
82  # llvm-rs-cc with them.
83  extra_args_str = ''
84  for rs_file in rs_files:
85    extra_args_str += GetCommandLineArgs(rs_file)
86  extra_args = extra_args_str.split()
87
88  args = base_args + extra_args + rs_files
89
90  if Options.verbose > 1:
91    print 'Executing:',
92    for arg in args:
93      print arg,
94    print
95
96  # Execute the command and check the resulting shell return value.
97  # All tests that are expected to FAIL have directory names that
98  # start with 'F_'. Other tests that are expected to PASS have
99  # directory names that start with 'P_'.
100  ret = 0
101  try:
102    ret = subprocess.call(args, stdout=stdout_file, stderr=stderr_file)
103  except:
104    passed = False
105
106  stdout_file.flush()
107  stderr_file.flush()
108
109  if Options.verbose > 1:
110    stdout_file.seek(0)
111    stderr_file.seek(0)
112    for line in stdout_file:
113      print 'STDOUT>', line,
114    for line in stderr_file:
115      print 'STDERR>', line,
116
117  stdout_file.close()
118  stderr_file.close()
119
120  if dirname[0:2] == 'F_':
121    if ret == 0:
122      passed = False
123      if Options.verbose:
124        print 'Command passed on invalid input'
125  elif dirname[0:2] == 'P_':
126    if ret != 0:
127      passed = False
128      if Options.verbose:
129        print 'Command failed on valid input'
130  else:
131    passed = (ret == 0)
132    if Options.verbose:
133      print 'Test Directory name should start with an F or a P'
134
135  if not CompareFiles('stdout.txt', 'stdout.txt.expect'):
136    passed = False
137    if Options.verbose:
138      print 'stdout is different'
139  if not CompareFiles('stderr.txt', 'stderr.txt.expect'):
140    passed = False
141    if Options.verbose:
142      print 'stderr is different'
143
144  if Options.updateCTS:
145    # Copy resulting files to appropriate CTS directory (if different).
146    if passed and glob.glob('IN_CTS'):
147      cts_path = '../../../../../cts/'
148      cts_res_raw_path = cts_path + 'tests/res/raw/'
149      cts_src_path = cts_path + 'tests/tests/renderscript/src/'
150      for bc_src in glob.glob('tmp/*.bc'):
151        bc_dst = re.sub('tmp\/', cts_res_raw_path, bc_src, 1)
152        UpdateFiles(bc_src, bc_dst)
153      for java_src in glob.glob('tmp/android/renderscript/cts/*.java'):
154        java_dst = re.sub('tmp\/', cts_src_path, java_src, 1)
155        UpdateFiles(java_src, java_dst)
156
157  if Options.cleanup:
158    try:
159      os.remove('stdout.txt')
160      os.remove('stderr.txt')
161      shutil.rmtree('tmp/')
162    except:
163      pass
164
165  os.chdir('..')
166  return passed
167
168
169def Usage():
170  """Print out usage information."""
171  print ('Usage: %s [OPTION]... [TESTNAME]...'
172         'Renderscript Compiler Test Harness\n'
173         'Runs TESTNAMEs (all tests by default)\n'
174         'Available Options:\n'
175         '  -h, --help          Help message\n'
176         '  -n, --no-cleanup    Don\'t clean up after running tests\n'
177         '  -u, --update-cts    Update CTS test versions\n'
178         '  -v, --verbose       Verbose output\n'
179        ) % (sys.argv[0]),
180  return
181
182
183def main():
184  passed = 0
185  failed = 0
186  files = []
187  failed_tests = []
188
189  for arg in sys.argv[1:]:
190    if arg in ('-h', '--help'):
191      Usage()
192      return 0
193    elif arg in ('-n', '--no-cleanup'):
194      Options.cleanup = 0
195    elif arg in ('-u', '--update-cts'):
196      Options.updateCTS = 1
197    elif arg in ('-v', '--verbose'):
198      Options.verbose += 1
199    else:
200      # Test list to run
201      if os.path.isdir(arg):
202        files.append(arg)
203      else:
204        print >> sys.stderr, 'Invalid test or option: %s' % arg
205        return 1
206
207  if not files:
208    tmp_files = os.listdir('.')
209    # Only run tests that are known to PASS or FAIL
210    # Disabled tests can be marked D_ and invoked explicitly
211    for f in tmp_files:
212      if os.path.isdir(f) and (f[0:2] == 'F_' or f[0:2] == 'P_'):
213        files.append(f)
214
215  for f in files:
216    if os.path.isdir(f):
217      if ExecTest(f):
218        passed += 1
219      else:
220        failed += 1
221        failed_tests.append(f)
222
223  print 'Tests Passed: %d\n' % passed,
224  print 'Tests Failed: %d\n' % failed,
225  if failed:
226    print 'Failures:',
227    for t in failed_tests:
228      print t,
229
230  return failed != 0
231
232
233if __name__ == '__main__':
234  sys.exit(main())
235