1from __future__ import absolute_import 2import os 3import sys 4 5import lit.Test 6import lit.TestRunner 7import lit.util 8from .base import TestFormat 9 10kIsWindows = sys.platform in ['win32', 'cygwin'] 11 12class 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 prefix = '' 47 index = 0 48 while ln[index*2:index*2+2] == ' ': 49 index += 1 50 while len(nested_tests) > index: 51 nested_tests.pop() 52 53 ln = ln[index*2:] 54 if ln.endswith('.'): 55 nested_tests.append(ln) 56 elif any([name.startswith('DISABLED_') 57 for name in nested_tests + [ln]]): 58 # Gtest will internally skip these tests. No need to launch a 59 # child process for it. 60 continue 61 else: 62 yield ''.join(nested_tests) + ln 63 64 # Note: path_in_suite should not include the executable name. 65 def getTestsInExecutable(self, testSuite, path_in_suite, execpath, 66 litConfig, localConfig): 67 if not execpath.endswith(self.test_suffix): 68 return 69 (dirname, basename) = os.path.split(execpath) 70 # Discover the tests in this executable. 71 for testname in self.getGTestTests(execpath, litConfig, localConfig): 72 testPath = path_in_suite + (basename, testname) 73 yield lit.Test.Test(testSuite, testPath, localConfig, file_path=execpath) 74 75 def getTestsInDirectory(self, testSuite, path_in_suite, 76 litConfig, localConfig): 77 source_path = testSuite.getSourcePath(path_in_suite) 78 for filename in os.listdir(source_path): 79 filepath = os.path.join(source_path, filename) 80 if os.path.isdir(filepath): 81 # Iterate over executables in a directory. 82 if not os.path.normcase(filename) in self.test_sub_dir: 83 continue 84 dirpath_in_suite = path_in_suite + (filename, ) 85 for subfilename in os.listdir(filepath): 86 execpath = os.path.join(filepath, subfilename) 87 for test in self.getTestsInExecutable( 88 testSuite, dirpath_in_suite, execpath, 89 litConfig, localConfig): 90 yield test 91 elif ('.' in self.test_sub_dir): 92 for test in self.getTestsInExecutable( 93 testSuite, path_in_suite, filepath, 94 litConfig, localConfig): 95 yield test 96 97 def execute(self, test, litConfig): 98 testPath,testName = os.path.split(test.getSourcePath()) 99 while not os.path.exists(testPath): 100 # Handle GTest parametrized and typed tests, whose name includes 101 # some '/'s. 102 testPath, namePrefix = os.path.split(testPath) 103 testName = namePrefix + '/' + testName 104 105 cmd = [testPath, '--gtest_filter=' + testName] 106 if litConfig.useValgrind: 107 cmd = litConfig.valgrindArgs + cmd 108 109 if litConfig.noExecute: 110 return lit.Test.PASS, '' 111 112 out, err, exitCode = lit.util.executeCommand( 113 cmd, env=test.config.environment) 114 115 if exitCode: 116 return lit.Test.FAIL, out + err 117 118 passing_test_line = '[ PASSED ] 1 test.' 119 if passing_test_line not in out: 120 msg = ('Unable to find %r in gtest output:\n\n%s%s' % 121 (passing_test_line, out, err)) 122 return lit.Test.UNRESOLVED, msg 123 124 return lit.Test.PASS,'' 125 126