Home | History | Annotate | Download | only in formats
      1 from __future__ import absolute_import
      2 import os
      3 import sys
      4 
      5 import lit.Test
      6 import lit.TestRunner
      7 import lit.util
      8 from .base import TestFormat
      9 
     10 kIsWindows = sys.platform in ['win32', 'cygwin']
     11 
     12 class GoogleTest(TestFormat):
     13     def __init__(self, test_sub_dir, test_suffix):
     14         self.test_sub_dir = os.path.normcase(str(test_sub_dir)).split(';')
     15         self.test_suffix = str(test_suffix)
     16 
     17         # On Windows, assume tests will also end in '.exe'.
     18         if kIsWindows:
     19             self.test_suffix += '.exe'
     20 
     21     def getGTestTests(self, path, litConfig, localConfig):
     22         """getGTestTests(path) - [name]
     23 
     24         Return the tests available in gtest executable.
     25 
     26         Args:
     27           path: String path to a gtest executable
     28           litConfig: LitConfig instance
     29           localConfig: TestingConfig instance"""
     30 
     31         try:
     32             lines = lit.util.capture([path, '--gtest_list_tests'],
     33                                      env=localConfig.environment)
     34             if kIsWindows:
     35               lines = lines.replace('\r', '')
     36             lines = lines.split('\n')
     37         except:
     38             litConfig.error("unable to discover google-tests in %r" % path)
     39             raise StopIteration
     40 
     41         nested_tests = []
     42         for ln in lines:
     43             if not ln.strip():
     44                 continue
     45 
     46             if 'Running main() from gtest_main.cc' in ln:
     47                 # Upstream googletest prints this to stdout prior to running
     48                 # tests. LLVM removed that print statement in r61540, but we
     49                 # handle it here in case upstream googletest is being used.
     50                 continue
     51 
     52             prefix = ''
     53             index = 0
     54             while ln[index*2:index*2+2] == '  ':
     55                 index += 1
     56             while len(nested_tests) > index:
     57                 nested_tests.pop()
     58 
     59             ln = ln[index*2:]
     60             if ln.endswith('.'):
     61                 nested_tests.append(ln)
     62             elif any([name.startswith('DISABLED_')
     63                       for name in nested_tests + [ln]]):
     64                 # Gtest will internally skip these tests. No need to launch a
     65                 # child process for it.
     66                 continue
     67             else:
     68                 yield ''.join(nested_tests) + ln
     69 
     70     # Note: path_in_suite should not include the executable name.
     71     def getTestsInExecutable(self, testSuite, path_in_suite, execpath,
     72                              litConfig, localConfig):
     73         if not execpath.endswith(self.test_suffix):
     74             return
     75         (dirname, basename) = os.path.split(execpath)
     76         # Discover the tests in this executable.
     77         for testname in self.getGTestTests(execpath, litConfig, localConfig):
     78             testPath = path_in_suite + (basename, testname)
     79             yield lit.Test.Test(testSuite, testPath, localConfig, file_path=execpath)
     80 
     81     def getTestsInDirectory(self, testSuite, path_in_suite,
     82                             litConfig, localConfig):
     83         source_path = testSuite.getSourcePath(path_in_suite)
     84         for filename in os.listdir(source_path):
     85             filepath = os.path.join(source_path, filename)
     86             if os.path.isdir(filepath):
     87                 # Iterate over executables in a directory.
     88                 if not os.path.normcase(filename) in self.test_sub_dir:
     89                     continue
     90                 dirpath_in_suite = path_in_suite + (filename, )
     91                 for subfilename in os.listdir(filepath):
     92                     execpath = os.path.join(filepath, subfilename)
     93                     for test in self.getTestsInExecutable(
     94                             testSuite, dirpath_in_suite, execpath,
     95                             litConfig, localConfig):
     96                       yield test
     97             elif ('.' in self.test_sub_dir):
     98                 for test in self.getTestsInExecutable(
     99                         testSuite, path_in_suite, filepath,
    100                         litConfig, localConfig):
    101                     yield test
    102 
    103     def execute(self, test, litConfig):
    104         testPath,testName = os.path.split(test.getSourcePath())
    105         while not os.path.exists(testPath):
    106             # Handle GTest parametrized and typed tests, whose name includes
    107             # some '/'s.
    108             testPath, namePrefix = os.path.split(testPath)
    109             testName = namePrefix + '/' + testName
    110 
    111         cmd = [testPath, '--gtest_filter=' + testName]
    112         if litConfig.useValgrind:
    113             cmd = litConfig.valgrindArgs + cmd
    114 
    115         if litConfig.noExecute:
    116             return lit.Test.PASS, ''
    117 
    118         try:
    119             out, err, exitCode = lit.util.executeCommand(
    120                 cmd, env=test.config.environment,
    121                 timeout=litConfig.maxIndividualTestTime)
    122         except lit.util.ExecuteCommandTimeoutException:
    123             return (lit.Test.TIMEOUT,
    124                     'Reached timeout of {} seconds'.format(
    125                         litConfig.maxIndividualTestTime)
    126                    )
    127 
    128         if exitCode:
    129             return lit.Test.FAIL, out + err
    130 
    131         passing_test_line = '[  PASSED  ] 1 test.'
    132         if passing_test_line not in out:
    133             msg = ('Unable to find %r in gtest output:\n\n%s%s' %
    134                    (passing_test_line, out, err))
    135             return lit.Test.UNRESOLVED, msg
    136 
    137         return lit.Test.PASS,''
    138 
    139