diff options
Diffstat (limited to 'lldb/test/API/lldbtest.py')
-rw-r--r-- | lldb/test/API/lldbtest.py | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/lldb/test/API/lldbtest.py b/lldb/test/API/lldbtest.py new file mode 100644 index 00000000000..99eb1457259 --- /dev/null +++ b/lldb/test/API/lldbtest.py @@ -0,0 +1,116 @@ +from __future__ import absolute_import +import os + +import subprocess +import sys + +import lit.Test +import lit.TestRunner +import lit.util +from lit.formats.base import TestFormat + +def getBuildDir(cmd): + found = False + for arg in cmd: + if found: + return arg + if arg == '--build-dir': + found = True + return None + +def mkdir_p(path): + import errno + try: + os.makedirs(path) + except OSError as e: + if e.errno != errno.EEXIST: + raise + if not os.path.isdir(path): + raise OSError(errno.ENOTDIR, "%s is not a directory"%path) + +class LLDBTest(TestFormat): + def __init__(self, dotest_cmd): + self.dotest_cmd = dotest_cmd + + def getTestsInDirectory(self, testSuite, path_in_suite, litConfig, + localConfig): + source_path = testSuite.getSourcePath(path_in_suite) + for filename in os.listdir(source_path): + # Ignore dot files and excluded tests. + if (filename.startswith('.') or filename in localConfig.excludes): + continue + + # Ignore files that don't start with 'Test'. + if not filename.startswith('Test'): + continue + + filepath = os.path.join(source_path, filename) + if not os.path.isdir(filepath): + base, ext = os.path.splitext(filename) + if ext in localConfig.suffixes: + yield lit.Test.Test(testSuite, path_in_suite + + (filename, ), localConfig) + + def execute(self, test, litConfig): + if litConfig.noExecute: + return lit.Test.PASS, '' + + if test.config.lldb_disable_python: + return (lit.Test.UNSUPPORTED, 'Python module disabled') + + if test.config.unsupported: + return (lit.Test.UNSUPPORTED, 'Test is unsupported') + + testPath, testFile = os.path.split(test.getSourcePath()) + # On Windows, the system does not always correctly interpret + # shebang lines. To make sure we can execute the tests, add + # python exe as the first parameter of the command. + cmd = [sys.executable] + self.dotest_cmd + [testPath, '-p', testFile] + + # The macOS system integrity protection (SIP) doesn't allow injecting + # libraries into system binaries, but this can be worked around by + # copying the binary into a different location. + if 'DYLD_INSERT_LIBRARIES' in test.config.environment and \ + (sys.executable.startswith('/System/') or \ + sys.executable.startswith('/usr/')): + builddir = getBuildDir(cmd) + mkdir_p(builddir) + copied_python = os.path.join(builddir, 'copied-system-python') + if not os.path.isfile(copied_python): + import shutil, subprocess + python = subprocess.check_output([ + '/usr/bin/python2.7', '-c', + 'import sys; print sys.executable']).strip() + shutil.copy(python, copied_python) + cmd[0] = copied_python + + try: + out, err, exitCode = lit.util.executeCommand( + cmd, + env=test.config.environment, + timeout=litConfig.maxIndividualTestTime) + except lit.util.ExecuteCommandTimeoutException: + return (lit.Test.TIMEOUT, 'Reached timeout of {} seconds'.format( + litConfig.maxIndividualTestTime)) + + if exitCode: + # Match FAIL but not XFAIL. + for line in out.splitlines() + err.splitlines(): + if line.startswith('FAIL:'): + return lit.Test.FAIL, out + err + + if 'XPASS:' in out or 'XPASS:' in err: + return lit.Test.XPASS, out + err + + has_unsupported_tests = 'UNSUPPORTED:' in out or 'UNSUPPORTED:' in err + has_passing_tests = 'PASS:' in out or 'PASS:' in err + if has_unsupported_tests and not has_passing_tests: + return lit.Test.UNSUPPORTED, out + err + + passing_test_line = 'RESULT: PASSED' + if passing_test_line not in out and passing_test_line not in err: + msg = ('Unable to find %r in dotest output (exit code %d):\n\n%s%s' + % (passing_test_line, exitCode, out, err)) + return lit.Test.UNRESOLVED, msg + + return lit.Test.PASS, '' |