1from __future__ import absolute_import 2import os 3import re 4import operator 5 6import lit.Test 7import lit.TestRunner 8import lit.util 9from lit.formats.base import TestFormat 10 11 12class LLDBTest(TestFormat): 13 def __init__(self, dotest_cmd): 14 self.dotest_cmd = dotest_cmd 15 16 def getTestsInDirectory(self, testSuite, path_in_suite, litConfig, 17 localConfig): 18 source_path = testSuite.getSourcePath(path_in_suite) 19 for filename in os.listdir(source_path): 20 # Ignore dot files and excluded tests. 21 if (filename.startswith('.') or filename in localConfig.excludes): 22 continue 23 24 # Ignore files that don't start with 'Test'. 25 if not filename.startswith('Test'): 26 continue 27 28 filepath = os.path.join(source_path, filename) 29 if not os.path.isdir(filepath): 30 base, ext = os.path.splitext(filename) 31 if ext in localConfig.suffixes: 32 yield lit.Test.Test(testSuite, path_in_suite + 33 (filename, ), localConfig) 34 35 def execute(self, test, litConfig): 36 if litConfig.noExecute: 37 return lit.Test.PASS, '' 38 39 if not getattr(test.config, 'lldb_enable_python', False): 40 return (lit.Test.UNSUPPORTED, 'Python module disabled') 41 42 if test.config.unsupported: 43 return (lit.Test.UNSUPPORTED, 'Test is unsupported') 44 45 testPath, testFile = os.path.split(test.getSourcePath()) 46 47 # The Python used to run lit can be different from the Python LLDB was 48 # build with. 49 executable = test.config.python_executable 50 51 isLuaTest = testFile == test.config.lua_test_entry 52 53 # On Windows, the system does not always correctly interpret 54 # shebang lines. To make sure we can execute the tests, add 55 # python exe as the first parameter of the command. 56 cmd = [executable] + self.dotest_cmd + [testPath, '-p', testFile] 57 58 if isLuaTest: 59 luaExecutable = test.config.lua_executable 60 cmd.extend(['--env', 'LUA_EXECUTABLE=%s' % luaExecutable]) 61 62 timeoutInfo = None 63 try: 64 out, err, exitCode = lit.util.executeCommand( 65 cmd, 66 env=test.config.environment, 67 timeout=litConfig.maxIndividualTestTime) 68 except lit.util.ExecuteCommandTimeoutException as e: 69 out = e.out 70 err = e.err 71 exitCode = e.exitCode 72 timeoutInfo = 'Reached timeout of {} seconds'.format( 73 litConfig.maxIndividualTestTime) 74 75 output = """Script:\n--\n%s\n--\nExit Code: %d\n""" % ( 76 ' '.join(cmd), exitCode) 77 if timeoutInfo is not None: 78 output += """Timeout: %s\n""" % (timeoutInfo,) 79 output += "\n" 80 81 if out: 82 output += """Command Output (stdout):\n--\n%s\n--\n""" % (out,) 83 if err: 84 output += """Command Output (stderr):\n--\n%s\n--\n""" % (err,) 85 86 if timeoutInfo: 87 return lit.Test.TIMEOUT, output 88 89 # Parse the dotest output from stderr. 90 result_regex = r"\((\d+) passes, (\d+) failures, (\d+) errors, (\d+) skipped, (\d+) expected failures, (\d+) unexpected successes\)" 91 results = re.search(result_regex, err) 92 93 # If parsing fails mark this test as unresolved. 94 if not results: 95 return lit.Test.UNRESOLVED, output 96 97 passes = int(results.group(1)) 98 failures = int(results.group(2)) 99 errors = int(results.group(3)) 100 skipped = int(results.group(4)) 101 expected_failures = int(results.group(5)) 102 unexpected_successes = int(results.group(6)) 103 104 if exitCode: 105 # Mark this test as FAIL if at least one test failed. 106 if failures > 0: 107 return lit.Test.FAIL, output 108 lit_results = [(failures, lit.Test.FAIL), 109 (errors, lit.Test.UNRESOLVED), 110 (unexpected_successes, lit.Test.XPASS)] 111 else: 112 # Mark this test as PASS if at least one test passed. 113 if passes > 0: 114 return lit.Test.PASS, output 115 lit_results = [(passes, lit.Test.PASS), 116 (skipped, lit.Test.UNSUPPORTED), 117 (expected_failures, lit.Test.XFAIL)] 118 119 # Return the lit result code with the maximum occurrence. Only look at 120 # the first element and rely on the original order to break ties. 121 return max(lit_results, key=operator.itemgetter(0))[1], output 122