[lldb] Remove LLDB session dir and just store test traces in the respective test...
[lldb.git] / lldb / test / API / lit.cfg.py
1 # -*- Python -*-
2
3 # Configuration file for the 'lit' test runner.
4
5 import os
6 import platform
7 import shlex
8 import shutil
9 import subprocess
10
11 import lit.formats
12
13 # name: The name of this test suite.
14 config.name = 'lldb-api'
15
16 # suffixes: A list of file extensions to treat as test files.
17 config.suffixes = ['.py']
18
19 # test_source_root: The root path where tests are located.
20 # test_exec_root: The root path where tests should be run.
21 config.test_source_root = os.path.dirname(__file__)
22 config.test_exec_root = config.test_source_root
23
24
25 def mkdir_p(path):
26   import errno
27   try:
28     os.makedirs(path)
29   except OSError as e:
30     if e.errno != errno.EEXIST:
31       raise
32   if not os.path.isdir(path):
33     raise OSError(errno.ENOTDIR, "%s is not a directory"%path)
34
35
36 def find_sanitizer_runtime(name):
37   resource_dir = subprocess.check_output(
38       [config.cmake_cxx_compiler,
39        '-print-resource-dir']).decode('utf-8').strip()
40   return os.path.join(resource_dir, 'lib', 'darwin', name)
41
42
43 def find_shlibpath_var():
44   if platform.system() in ['Linux', 'FreeBSD', 'NetBSD', 'SunOS']:
45     yield 'LD_LIBRARY_PATH'
46   elif platform.system() == 'Darwin':
47     yield 'DYLD_LIBRARY_PATH'
48   elif platform.system() == 'Windows':
49     yield 'PATH'
50
51
52 # On macOS, we can't do the DYLD_INSERT_LIBRARIES trick with a shim python
53 # binary as the ASan interceptors get loaded too late. Also, when SIP is
54 # enabled, we can't inject libraries into system binaries at all, so we need a
55 # copy of the "real" python to work with.
56 def find_python_interpreter():
57   # Avoid doing any work if we already copied the binary.
58   copied_python = os.path.join(config.lldb_build_directory, 'copied-python')
59   if os.path.isfile(copied_python):
60     return copied_python
61
62   # Find the "real" python binary.
63   real_python = subprocess.check_output([
64       config.python_executable,
65       os.path.join(os.path.dirname(os.path.realpath(__file__)),
66                    'get_darwin_real_python.py')
67   ]).decode('utf-8').strip()
68
69   shutil.copy(real_python, copied_python)
70
71   # Now make sure the copied Python works. The Python in Xcode has a relative
72   # RPATH and cannot be copied.
73   try:
74     # We don't care about the output, just make sure it runs.
75     subprocess.check_output([copied_python, '-V'], stderr=subprocess.STDOUT)
76   except subprocess.CalledProcessError:
77     # The copied Python didn't work. Assume we're dealing with the Python
78     # interpreter in Xcode. Given that this is not a system binary SIP
79     # won't prevent us form injecting the interceptors so we get away with
80     # not copying the executable.
81     os.remove(copied_python)
82     return real_python
83
84   # The copied Python works.
85   return copied_python
86
87
88 def is_configured(attr):
89   """Return the configuration attribute if it exists and None otherwise.
90
91   This allows us to check if the attribute exists before trying to access it."""
92   return getattr(config, attr, None)
93
94
95 def delete_module_cache(path):
96   """Clean the module caches in the test build directory.
97
98   This is necessary in an incremental build whenever clang changes underneath,
99   so doing it once per lit.py invocation is close enough. """
100   if os.path.isdir(path):
101     print("Deleting module cache at %s." % path)
102     shutil.rmtree(path)
103
104 if is_configured('llvm_use_sanitizer'):
105   if 'Address' in config.llvm_use_sanitizer:
106     config.environment['ASAN_OPTIONS'] = 'detect_stack_use_after_return=1'
107     if 'Darwin' in config.host_os and 'x86' in config.host_triple:
108       config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime(
109           'libclang_rt.asan_osx_dynamic.dylib')
110
111   if 'Thread' in config.llvm_use_sanitizer:
112     if 'Darwin' in config.host_os and 'x86' in config.host_triple:
113       config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime(
114           'libclang_rt.tsan_osx_dynamic.dylib')
115
116 if 'DYLD_INSERT_LIBRARIES' in config.environment and platform.system() == 'Darwin':
117   config.python_executable = find_python_interpreter()
118
119 # Shared library build of LLVM may require LD_LIBRARY_PATH or equivalent.
120 if is_configured('shared_libs'):
121   for shlibpath_var in find_shlibpath_var():
122     # In stand-alone build llvm_shlib_dir specifies LLDB's lib directory while
123     # llvm_libs_dir specifies LLVM's lib directory.
124     shlibpath = os.path.pathsep.join(
125         (config.llvm_shlib_dir, config.llvm_libs_dir,
126          config.environment.get(shlibpath_var, '')))
127     config.environment[shlibpath_var] = shlibpath
128   else:
129     lit_config.warning("unable to inject shared library path on '{}'".format(
130         platform.system()))
131
132 # Propagate LLDB_CAPTURE_REPRODUCER
133 if 'LLDB_CAPTURE_REPRODUCER' in os.environ:
134   config.environment['LLDB_CAPTURE_REPRODUCER'] = os.environ[
135       'LLDB_CAPTURE_REPRODUCER']
136
137 # Support running the test suite under the lldb-repro wrapper. This makes it
138 # possible to capture a test suite run and then rerun all the test from the
139 # just captured reproducer.
140 lldb_repro_mode = lit_config.params.get('lldb-run-with-repro', None)
141 if lldb_repro_mode:
142   lit_config.note("Running API tests in {} mode.".format(lldb_repro_mode))
143   mkdir_p(config.lldb_reproducer_directory)
144   if lldb_repro_mode == 'capture':
145     config.available_features.add('lldb-repro-capture')
146   elif lldb_repro_mode == 'replay':
147     config.available_features.add('lldb-repro-replay')
148
149 lldb_use_simulator = lit_config.params.get('lldb-run-with-simulator', None)
150 if lldb_use_simulator:
151   if lldb_use_simulator == "ios":
152     lit_config.note("Running API tests on iOS simulator")
153     config.available_features.add('lldb-simulator-ios')
154   elif lldb_use_simulator == "watchos":
155     lit_config.note("Running API tests on watchOS simulator")
156     config.available_features.add('lldb-simulator-watchos')
157   elif lldb_use_simulator == "tvos":
158     lit_config.note("Running API tests on tvOS simulator")
159     config.available_features.add('lldb-simulator-tvos')
160   else:
161     lit_config.error("Unknown simulator id '{}'".format(lldb_use_simulator))
162
163 # Set a default per-test timeout of 10 minutes. Setting a timeout per test
164 # requires that killProcessAndChildren() is supported on the platform and
165 # lit complains if the value is set but it is not supported.
166 supported, errormsg = lit_config.maxIndividualTestTimeIsSupported
167 if supported:
168   lit_config.maxIndividualTestTime = 600
169 else:
170   lit_config.warning("Could not set a default per-test timeout. " + errormsg)
171
172 # Build dotest command.
173 dotest_cmd = [os.path.join(config.lldb_src_root, 'test', 'API', 'dotest.py')]
174
175 if is_configured('dotest_args_str'):
176   dotest_cmd.extend(config.dotest_args_str.split(';'))
177
178 # Library path may be needed to locate just-built clang.
179 if is_configured('llvm_libs_dir'):
180   dotest_cmd += ['--env', 'LLVM_LIBS_DIR=' + config.llvm_libs_dir]
181
182 # Forward ASan-specific environment variables to tests, as a test may load an
183 # ASan-ified dylib.
184 for env_var in ('ASAN_OPTIONS', 'DYLD_INSERT_LIBRARIES'):
185   if env_var in config.environment:
186     dotest_cmd += ['--inferior-env', env_var + '=' + config.environment[env_var]]
187
188 if is_configured('test_arch'):
189   dotest_cmd += ['--arch', config.test_arch]
190
191 if is_configured('lldb_build_directory'):
192   dotest_cmd += ['--build-dir', config.lldb_build_directory]
193
194 if is_configured('lldb_module_cache'):
195   delete_module_cache(config.lldb_module_cache)
196   dotest_cmd += ['--lldb-module-cache-dir', config.lldb_module_cache]
197
198 if is_configured('clang_module_cache'):
199   delete_module_cache(config.clang_module_cache)
200   dotest_cmd += ['--clang-module-cache-dir', config.clang_module_cache]
201
202 if is_configured('lldb_executable'):
203   dotest_cmd += ['--executable', config.lldb_executable]
204
205 if is_configured('test_compiler'):
206   dotest_cmd += ['--compiler', config.test_compiler]
207
208 if is_configured('dsymutil'):
209   dotest_cmd += ['--dsymutil', config.dsymutil]
210
211 if is_configured('filecheck'):
212   dotest_cmd += ['--filecheck', config.filecheck]
213
214 if is_configured('yaml2obj'):
215   dotest_cmd += ['--yaml2obj', config.yaml2obj]
216
217 if is_configured('server'):
218   dotest_cmd += ['--server', config.server]
219
220 if is_configured('lldb_libs_dir'):
221   dotest_cmd += ['--lldb-libs-dir', config.lldb_libs_dir]
222
223 if is_configured('lldb_framework_dir'):
224   dotest_cmd += ['--framework', config.lldb_framework_dir]
225
226 if 'lldb-repro-capture' in config.available_features or \
227     'lldb-repro-replay' in config.available_features:
228   dotest_cmd += ['--skip-category=lldb-vscode', '--skip-category=std-module']
229
230 if 'lldb-simulator-ios' in config.available_features:
231   dotest_cmd += ['--apple-sdk', 'iphonesimulator',
232                  '--platform-name', 'ios-simulator']
233 elif 'lldb-simulator-watchos' in config.available_features:
234   dotest_cmd += ['--apple-sdk', 'watchsimulator',
235                  '--platform-name', 'watchos-simulator']
236 elif 'lldb-simulator-tvos' in config.available_features:
237   dotest_cmd += ['--apple-sdk', 'appletvsimulator',
238                  '--platform-name', 'tvos-simulator']
239
240 if is_configured('enabled_plugins'):
241   for plugin in config.enabled_plugins:
242     dotest_cmd += ['--enable-plugin', plugin]
243
244 if is_configured('dotest_lit_args_str'):
245   # We don't want to force users passing arguments to lit to use `;` as a
246   # separator. We use Python's simple lexical analyzer to turn the args into a
247   # list. Pass there arguments last so they can override anything that was
248   # already configured.
249   dotest_cmd.extend(shlex.split(config.dotest_lit_args_str))
250
251 # Load LLDB test format.
252 sys.path.append(os.path.join(config.lldb_src_root, "test", "API"))
253 import lldbtest
254
255 # testFormat: The test format to use to interpret tests.
256 config.test_format = lldbtest.LLDBTest(dotest_cmd)
257
258 # Propagate FREEBSD_LEGACY_PLUGIN
259 if 'FREEBSD_LEGACY_PLUGIN' in os.environ:
260   config.environment['FREEBSD_LEGACY_PLUGIN'] = os.environ[
261       'FREEBSD_LEGACY_PLUGIN']