lldbtest.py
4.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from __future__ import absolute_import
import os
import tempfile
import subprocess
import sys
import platform
import lit.Test
import lit.TestRunner
import lit.util
from lit.formats.base import TestFormat
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 not getattr(test.config, 'lldb_enable_python', False):
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())
# The Python used to run lit can be different from the Python LLDB was
# build with.
executable = test.config.python_executable
# 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 = [executable] + self.dotest_cmd + [testPath, '-p', testFile]
if 'lldb-repro-capture' in test.config.available_features or \
'lldb-repro-replay' in test.config.available_features:
reproducer_path = os.path.join(
test.config.lldb_reproducer_directory, testFile)
if 'lldb-repro-capture' in test.config.available_features:
cmd.extend(['--capture-path', reproducer_path])
else:
cmd.extend(['--replay-path', reproducer_path])
timeoutInfo = None
try:
out, err, exitCode = lit.util.executeCommand(
cmd,
env=test.config.environment,
timeout=litConfig.maxIndividualTestTime)
except lit.util.ExecuteCommandTimeoutException as e:
out = e.out
err = e.err
exitCode = e.exitCode
timeoutInfo = 'Reached timeout of {} seconds'.format(
litConfig.maxIndividualTestTime)
if sys.version_info.major == 2:
# In Python 2, string objects can contain Unicode characters. Use
# the non-strict 'replace' decoding mode. We cannot use the strict
# mode right now because lldb's StringPrinter facility and the
# Python utf8 decoder have different interpretations of which
# characters are "printable". This leads to Python utf8 decoding
# exceptions even though lldb is behaving as expected.
out = out.decode('utf-8', 'replace')
err = err.decode('utf-8', 'replace')
output = """Script:\n--\n%s\n--\nExit Code: %d\n""" % (
' '.join(cmd), exitCode)
if timeoutInfo is not None:
output += """Timeout: %s\n""" % (timeoutInfo,)
output += "\n"
if out:
output += """Command Output (stdout):\n--\n%s\n--\n""" % (out,)
if err:
output += """Command Output (stderr):\n--\n%s\n--\n""" % (err,)
if timeoutInfo:
return lit.Test.TIMEOUT, output
if exitCode:
if 'XPASS:' in out or 'XPASS:' in err:
return lit.Test.XPASS, output
# Otherwise this is just a failure.
return lit.Test.FAIL, output
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, output
passing_test_line = 'RESULT: PASSED'
if passing_test_line not in out and passing_test_line not in err:
return lit.Test.UNRESOLVED, output
return lit.Test.PASS, output