Home | History | Annotate | Download | only in tests
      1 #!/usr/bin/python2.4
      2 #
      3 # Copyright 2010-2012 Google Inc. All Rights Reserved.
      4 
      5 """Renderscript Compiler Test.
      6 
      7 Runs subdirectories of tests for the Renderscript compiler.
      8 """
      9 
     10 import filecmp
     11 import glob
     12 import os
     13 import re
     14 import shutil
     15 import subprocess
     16 import sys
     17 
     18 __author__ = 'Android'
     19 
     20 
     21 class Options(object):
     22   def __init__(self):
     23     return
     24   verbose = 0
     25   cleanup = 1
     26   updateCTS = 0
     27 
     28 
     29 def 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 
     43 def 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 
     50 def 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 
     60 def 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 
    169 def 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 
    183 def 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 
    233 if __name__ == '__main__':
    234   sys.exit(main())
    235