blob: 69ca549e875d70821627f8efe2abfdb8f9ca9fb2 [file] [log] [blame]
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001"""
2LLDB module which provides the abstract base class of lldb test case.
3
4The concrete subclass can override lldbtest.TesBase in order to inherit the
5common behavior for unitest.TestCase.setUp/tearDown implemented in this file.
6
7The subclass should override the attribute mydir in order for the python runtime
8to locate the individual test cases when running as part of a large test suite
9or when running each test case as a separate python invocation.
10
11./dotest.py provides a test driver which sets up the environment to run the
Johnny Chenc98892e2012-05-16 20:41:28 +000012entire of part of the test suite . Example:
Johnny Chenbf6ffa32010-07-03 03:41:59 +000013
Johnny Chenc98892e2012-05-16 20:41:28 +000014# Exercises the test suite in the types directory....
15/Volumes/data/lldb/svn/ToT/test $ ./dotest.py -A x86_64 types
Johnny Chen57b47382010-09-02 22:25:47 +000016...
Johnny Chend0190a62010-08-23 17:10:44 +000017
Johnny Chenc98892e2012-05-16 20:41:28 +000018Session logs for test failures/errors/unexpected successes will go into directory '2012-05-16-13_35_42'
19Command invoked: python ./dotest.py -A x86_64 types
20compilers=['clang']
Johnny Chend0190a62010-08-23 17:10:44 +000021
Johnny Chenc98892e2012-05-16 20:41:28 +000022Configuration: arch=x86_64 compiler=clang
Johnny Chend0190a62010-08-23 17:10:44 +000023----------------------------------------------------------------------
Johnny Chenc98892e2012-05-16 20:41:28 +000024Collected 72 tests
25
26........................................................................
27----------------------------------------------------------------------
28Ran 72 tests in 135.468s
Johnny Chend0190a62010-08-23 17:10:44 +000029
30OK
Johnny Chenbf6ffa32010-07-03 03:41:59 +000031$
32"""
33
Zachary Turnerff890da2015-10-19 23:45:41 +000034from __future__ import print_function
35
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +000036import abc
Adrian McCarthy6ecdbc82015-10-15 22:39:55 +000037import gc
Vince Harron9753dd92015-05-10 15:22:09 +000038import glob
Johnny Chen90312a82010-09-21 22:34:45 +000039import os, sys, traceback
Enrico Granata7e137e32012-10-24 18:14:21 +000040import os.path
Johnny Chenea88e942010-09-21 21:08:53 +000041import re
Daniel Malea69207462013-06-05 21:07:02 +000042import signal
Johnny Chen8952a2d2010-08-30 21:35:00 +000043from subprocess import *
Johnny Chen150c3cc2010-10-15 01:18:29 +000044import StringIO
Johnny Chenf2b70232010-08-25 18:49:48 +000045import time
Johnny Chena33a93c2010-08-30 23:08:52 +000046import types
Johnny Chen73258832010-08-05 23:42:46 +000047import unittest2
Johnny Chenbf6ffa32010-07-03 03:41:59 +000048import lldb
Vince Harron9753dd92015-05-10 15:22:09 +000049import lldbtest_config
Chaoren Lin3e2bdb42015-05-11 17:53:39 +000050import lldbutil
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +000051from _pyio import __metaclass__
Johnny Chenbf6ffa32010-07-03 03:41:59 +000052
Siva Chandra8af91662015-06-05 00:22:49 +000053if sys.version_info.major < 3:
54 import urlparse
55else:
56 import urllib.parse as urlparse
57
Vince Harron85d19652015-05-21 19:09:29 +000058# dosep.py starts lots and lots of dotest instances
59# This option helps you find if two (or more) dotest instances are using the same
60# directory at the same time
61# Enable it to cause test failures and stderr messages if dotest instances try to run in
62# the same directory simultaneously
63# it is disabled by default because it litters the test directories with ".dirlock" files
64debug_confirm_directory_exclusivity = False
65
Johnny Chen707b3c92010-10-11 22:25:46 +000066# See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
Johnny Chend2047fa2011-01-19 18:18:47 +000067# LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' options.
Johnny Chen707b3c92010-10-11 22:25:46 +000068
69# By default, traceAlways is False.
Johnny Chen8d55a342010-08-31 17:42:54 +000070if "LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"]=="YES":
71 traceAlways = True
72else:
73 traceAlways = False
74
Johnny Chen707b3c92010-10-11 22:25:46 +000075# By default, doCleanup is True.
76if "LLDB_DO_CLEANUP" in os.environ and os.environ["LLDB_DO_CLEANUP"]=="NO":
77 doCleanup = False
78else:
79 doCleanup = True
80
Johnny Chen8d55a342010-08-31 17:42:54 +000081
Johnny Chen00778092010-08-09 22:01:17 +000082#
83# Some commonly used assert messages.
84#
85
Johnny Chenaa902922010-09-17 22:45:27 +000086COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"
87
Johnny Chen00778092010-08-09 22:01:17 +000088CURRENT_EXECUTABLE_SET = "Current executable set successfully"
89
Johnny Chen7d1d7532010-09-02 21:23:12 +000090PROCESS_IS_VALID = "Process is valid"
91
92PROCESS_KILLED = "Process is killed successfully"
93
Johnny Chend5f66fc2010-12-23 01:12:19 +000094PROCESS_EXITED = "Process exited successfully"
95
96PROCESS_STOPPED = "Process status should be stopped"
97
Sean Callanan05834cd2015-07-01 23:56:30 +000098RUN_SUCCEEDED = "Process is launched successfully"
Johnny Chen00778092010-08-09 22:01:17 +000099
Johnny Chen17941842010-08-09 23:44:24 +0000100RUN_COMPLETED = "Process exited successfully"
Johnny Chen00778092010-08-09 22:01:17 +0000101
Johnny Chen67af43f2010-10-05 19:27:32 +0000102BACKTRACE_DISPLAYED_CORRECTLY = "Backtrace displayed correctly"
103
Johnny Chen17941842010-08-09 23:44:24 +0000104BREAKPOINT_CREATED = "Breakpoint created successfully"
105
Johnny Chenf10af382010-12-04 00:07:24 +0000106BREAKPOINT_STATE_CORRECT = "Breakpoint state is correct"
107
Johnny Chene76896c2010-08-17 21:33:31 +0000108BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
109
Johnny Chen17941842010-08-09 23:44:24 +0000110BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
Johnny Chen00778092010-08-09 22:01:17 +0000111
Johnny Chen703dbd02010-09-30 17:06:24 +0000112BREAKPOINT_HIT_TWICE = "Breakpoint resolved with hit cout = 2"
113
Johnny Chen164f1e12010-10-15 18:07:09 +0000114BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3"
115
Greg Clayton5db6b792012-10-24 18:24:14 +0000116MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."
117
Johnny Chen89109ed12011-06-27 20:05:23 +0000118OBJECT_PRINTED_CORRECTLY = "Object printed correctly"
119
Johnny Chen5b3a3572010-12-09 18:22:12 +0000120SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"
121
Johnny Chenc70b02a2010-09-22 23:00:20 +0000122STEP_OUT_SUCCEEDED = "Thread step-out succeeded"
123
Johnny Chen1691a162011-04-15 16:44:48 +0000124STOPPED_DUE_TO_EXC_BAD_ACCESS = "Process should be stopped due to bad access exception"
125
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000126STOPPED_DUE_TO_ASSERT = "Process should be stopped due to an assertion"
127
Johnny Chen5d6c4642010-11-10 23:46:38 +0000128STOPPED_DUE_TO_BREAKPOINT = "Process should be stopped due to breakpoint"
Johnny Chende0338b2010-11-10 20:20:06 +0000129
Johnny Chen5d6c4642010-11-10 23:46:38 +0000130STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS = "%s, %s" % (
131 STOPPED_DUE_TO_BREAKPOINT, "instead, the actual stop reason is: '%s'")
Johnny Chen00778092010-08-09 22:01:17 +0000132
Johnny Chen2e431ce2010-10-20 18:38:48 +0000133STOPPED_DUE_TO_BREAKPOINT_CONDITION = "Stopped due to breakpoint condition"
134
Johnny Chen0a3d1ca2010-12-13 21:49:58 +0000135STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT = "Stopped due to breakpoint and ignore count"
136
Johnny Chenc066ab42010-10-14 01:22:03 +0000137STOPPED_DUE_TO_SIGNAL = "Process state is stopped due to signal"
138
Johnny Chen00778092010-08-09 22:01:17 +0000139STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
140
Johnny Chenf68cc122011-09-15 21:09:59 +0000141STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"
142
Johnny Chen3c884a02010-08-24 22:07:56 +0000143DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
144
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000145VALID_BREAKPOINT = "Got a valid breakpoint"
146
Johnny Chen5bfb8ee2010-10-22 18:10:25 +0000147VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location"
148
Johnny Chen7209d84f2011-05-06 23:26:12 +0000149VALID_COMMAND_INTERPRETER = "Got a valid command interpreter"
150
Johnny Chen5ee88192010-08-27 23:47:36 +0000151VALID_FILESPEC = "Got a valid filespec"
152
Johnny Chen025d1b82010-12-08 01:25:21 +0000153VALID_MODULE = "Got a valid module"
154
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000155VALID_PROCESS = "Got a valid process"
156
Johnny Chen025d1b82010-12-08 01:25:21 +0000157VALID_SYMBOL = "Got a valid symbol"
158
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000159VALID_TARGET = "Got a valid target"
160
Matthew Gardinerc928de32014-10-22 07:22:56 +0000161VALID_PLATFORM = "Got a valid platform"
162
Johnny Chen15f247a2012-02-03 20:43:00 +0000163VALID_TYPE = "Got a valid type"
164
Johnny Chen5819ab42011-07-15 22:28:10 +0000165VALID_VARIABLE = "Got a valid variable"
166
Johnny Chen981463d2010-08-25 19:00:04 +0000167VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
Johnny Chen00778092010-08-09 22:01:17 +0000168
Johnny Chenf68cc122011-09-15 21:09:59 +0000169WATCHPOINT_CREATED = "Watchpoint created successfully"
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000170
Sean Callanan05834cd2015-07-01 23:56:30 +0000171def CMD_MSG(str):
172 '''A generic "Command '%s' returns successfully" message generator.'''
173 return "Command '%s' returns successfully" % str
Johnny Chenc0c67f22010-11-09 18:42:22 +0000174
Johnny Chen3bc8ae42012-03-15 19:10:00 +0000175def COMPLETION_MSG(str_before, str_after):
Johnny Chen98aceb02012-01-20 23:02:51 +0000176 '''A generic message generator for the completion mechanism.'''
177 return "'%s' successfully completes to '%s'" % (str_before, str_after)
178
Johnny Chenc0c67f22010-11-09 18:42:22 +0000179def EXP_MSG(str, exe):
Johnny Chenaacf92e2011-05-31 22:16:51 +0000180 '''A generic "'%s' returns expected result" message generator if exe.
181 Otherwise, it generates "'%s' matches expected result" message.'''
Johnny Chenc0c67f22010-11-09 18:42:22 +0000182 return "'%s' %s expected result" % (str, 'returns' if exe else 'matches')
Johnny Chen17941842010-08-09 23:44:24 +0000183
Johnny Chen3343f042010-10-19 19:11:38 +0000184def SETTING_MSG(setting):
Johnny Chenaacf92e2011-05-31 22:16:51 +0000185 '''A generic "Value of setting '%s' is correct" message generator.'''
Johnny Chen3343f042010-10-19 19:11:38 +0000186 return "Value of setting '%s' is correct" % setting
187
Johnny Chen27c41232010-08-26 21:49:29 +0000188def EnvArray():
Johnny Chenaacf92e2011-05-31 22:16:51 +0000189 """Returns an env variable array from the os.environ map object."""
Johnny Chen27c41232010-08-26 21:49:29 +0000190 return map(lambda k,v: k+"="+v, os.environ.keys(), os.environ.values())
191
Johnny Chen47ceb032010-10-11 23:52:19 +0000192def line_number(filename, string_to_match):
193 """Helper function to return the line number of the first matched string."""
194 with open(filename, 'r') as f:
195 for i, line in enumerate(f):
196 if line.find(string_to_match) != -1:
197 # Found our match.
Johnny Chencd9b7772010-10-12 00:09:25 +0000198 return i+1
Johnny Chen1691a162011-04-15 16:44:48 +0000199 raise Exception("Unable to find '%s' within file %s" % (string_to_match, filename))
Johnny Chen47ceb032010-10-11 23:52:19 +0000200
Johnny Chen67af43f2010-10-05 19:27:32 +0000201def pointer_size():
202 """Return the pointer size of the host system."""
203 import ctypes
204 a_pointer = ctypes.c_void_p(0xffff)
205 return 8 * ctypes.sizeof(a_pointer)
206
Johnny Chen57816732012-02-09 02:01:59 +0000207def is_exe(fpath):
208 """Returns true if fpath is an executable."""
209 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
210
211def which(program):
212 """Returns the full path to a program; None otherwise."""
213 fpath, fname = os.path.split(program)
214 if fpath:
215 if is_exe(program):
216 return program
217 else:
218 for path in os.environ["PATH"].split(os.pathsep):
219 exe_file = os.path.join(path, program)
220 if is_exe(exe_file):
221 return exe_file
222 return None
223
Johnny Chen150c3cc2010-10-15 01:18:29 +0000224class recording(StringIO.StringIO):
225 """
226 A nice little context manager for recording the debugger interactions into
227 our session object. If trace flag is ON, it also emits the interactions
228 into the stderr.
229 """
230 def __init__(self, test, trace):
Johnny Chen690fcef2010-10-15 23:55:05 +0000231 """Create a StringIO instance; record the session obj and trace flag."""
Johnny Chen150c3cc2010-10-15 01:18:29 +0000232 StringIO.StringIO.__init__(self)
Johnny Chen0241f142011-08-16 22:06:17 +0000233 # The test might not have undergone the 'setUp(self)' phase yet, so that
234 # the attribute 'session' might not even exist yet.
Johnny Chenbfcf37f2011-08-16 17:06:45 +0000235 self.session = getattr(test, "session", None) if test else None
Johnny Chen150c3cc2010-10-15 01:18:29 +0000236 self.trace = trace
237
238 def __enter__(self):
239 """
240 Context management protocol on entry to the body of the with statement.
241 Just return the StringIO object.
242 """
243 return self
244
245 def __exit__(self, type, value, tb):
246 """
247 Context management protocol on exit from the body of the with statement.
248 If trace is ON, it emits the recordings into stderr. Always add the
249 recordings to our session object. And close the StringIO object, too.
250 """
251 if self.trace:
Zachary Turnerff890da2015-10-19 23:45:41 +0000252 print(self.getvalue(), file=sys.stderr)
Johnny Chen690fcef2010-10-15 23:55:05 +0000253 if self.session:
Zachary Turnerff890da2015-10-19 23:45:41 +0000254 print(self.getvalue(), file=self.session)
Johnny Chen150c3cc2010-10-15 01:18:29 +0000255 self.close()
256
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000257class _BaseProcess(object):
258 __metaclass__ = abc.ABCMeta
259
260 @abc.abstractproperty
261 def pid(self):
262 """Returns process PID if has been launched already."""
263
264 @abc.abstractmethod
265 def launch(self, executable, args):
266 """Launches new process with given executable and args."""
267
268 @abc.abstractmethod
269 def terminate(self):
270 """Terminates previously launched process.."""
271
272class _LocalProcess(_BaseProcess):
273
274 def __init__(self, trace_on):
275 self._proc = None
276 self._trace_on = trace_on
Ilia K725abcb2015-04-15 13:35:49 +0000277 self._delayafterterminate = 0.1
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000278
279 @property
280 def pid(self):
281 return self._proc.pid
282
283 def launch(self, executable, args):
284 self._proc = Popen([executable] + args,
285 stdout = open(os.devnull) if not self._trace_on else None,
286 stdin = PIPE)
287
288 def terminate(self):
289 if self._proc.poll() == None:
Ilia K725abcb2015-04-15 13:35:49 +0000290 # Terminate _proc like it does the pexpect
Adrian McCarthy137d7ba2015-07-07 14:47:34 +0000291 signals_to_try = [sig for sig in ['SIGHUP', 'SIGCONT', 'SIGINT'] if sig in dir(signal)]
292 for sig in signals_to_try:
293 try:
294 self._proc.send_signal(getattr(signal, sig))
295 time.sleep(self._delayafterterminate)
296 if self._proc.poll() != None:
297 return
298 except ValueError:
299 pass # Windows says SIGINT is not a valid signal to send
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000300 self._proc.terminate()
Ilia K725abcb2015-04-15 13:35:49 +0000301 time.sleep(self._delayafterterminate)
302 if self._proc.poll() != None:
303 return
304 self._proc.kill()
305 time.sleep(self._delayafterterminate)
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000306
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000307 def poll(self):
308 return self._proc.poll()
309
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000310class _RemoteProcess(_BaseProcess):
311
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000312 def __init__(self, install_remote):
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000313 self._pid = None
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000314 self._install_remote = install_remote
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000315
316 @property
317 def pid(self):
318 return self._pid
319
320 def launch(self, executable, args):
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000321 if self._install_remote:
322 src_path = executable
Chaoren Lin5d76b1b2015-06-06 00:25:50 +0000323 dst_path = lldbutil.append_to_process_working_directory(os.path.basename(executable))
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000324
325 dst_file_spec = lldb.SBFileSpec(dst_path, False)
326 err = lldb.remote_platform.Install(lldb.SBFileSpec(src_path, True), dst_file_spec)
327 if err.Fail():
328 raise Exception("remote_platform.Install('%s', '%s') failed: %s" % (src_path, dst_path, err))
329 else:
330 dst_path = executable
331 dst_file_spec = lldb.SBFileSpec(executable, False)
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000332
333 launch_info = lldb.SBLaunchInfo(args)
334 launch_info.SetExecutableFile(dst_file_spec, True)
Chaoren Lin3e2bdb42015-05-11 17:53:39 +0000335 launch_info.SetWorkingDirectory(lldb.remote_platform.GetWorkingDirectory())
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000336
337 # Redirect stdout and stderr to /dev/null
338 launch_info.AddSuppressFileAction(1, False, True)
339 launch_info.AddSuppressFileAction(2, False, True)
340
341 err = lldb.remote_platform.Launch(launch_info)
342 if err.Fail():
343 raise Exception("remote_platform.Launch('%s', '%s') failed: %s" % (dst_path, args, err))
344 self._pid = launch_info.GetProcessID()
345
346 def terminate(self):
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000347 lldb.remote_platform.Kill(self._pid)
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000348
Johnny Chen690fcef2010-10-15 23:55:05 +0000349# From 2.7's subprocess.check_output() convenience function.
Johnny Chenac77f3b2011-03-23 20:28:59 +0000350# Return a tuple (stdoutdata, stderrdata).
Zachary Turner9ef307b2014-07-22 16:19:29 +0000351def system(commands, **kwargs):
Johnny Chen8eb14a92011-11-16 22:44:28 +0000352 r"""Run an os command with arguments and return its output as a byte string.
Johnny Chen690fcef2010-10-15 23:55:05 +0000353
354 If the exit code was non-zero it raises a CalledProcessError. The
355 CalledProcessError object will have the return code in the returncode
356 attribute and output in the output attribute.
357
358 The arguments are the same as for the Popen constructor. Example:
359
360 >>> check_output(["ls", "-l", "/dev/null"])
361 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
362
363 The stdout argument is not allowed as it is used internally.
364 To capture standard error in the result, use stderr=STDOUT.
365
366 >>> check_output(["/bin/sh", "-c",
367 ... "ls -l non_existent_file ; exit 0"],
368 ... stderr=STDOUT)
369 'ls: non_existent_file: No such file or directory\n'
370 """
371
372 # Assign the sender object to variable 'test' and remove it from kwargs.
373 test = kwargs.pop('sender', None)
374
Zachary Turner9ef307b2014-07-22 16:19:29 +0000375 # [['make', 'clean', 'foo'], ['make', 'foo']] -> ['make clean foo', 'make foo']
376 commandList = [' '.join(x) for x in commands]
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000377 output = ""
378 error = ""
379 for shellCommand in commandList:
380 if 'stdout' in kwargs:
381 raise ValueError('stdout argument not allowed, it will be overridden.')
382 if 'shell' in kwargs and kwargs['shell']==False:
383 raise ValueError('shell=False not allowed')
384 process = Popen(shellCommand, stdout=PIPE, stderr=PIPE, shell=True, **kwargs)
385 pid = process.pid
386 this_output, this_error = process.communicate()
387 retcode = process.poll()
Zachary Turner9ef307b2014-07-22 16:19:29 +0000388
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000389 # Enable trace on failure return while tracking down FreeBSD buildbot issues
390 trace = traceAlways
391 if not trace and retcode and sys.platform.startswith("freebsd"):
392 trace = True
Johnny Chen690fcef2010-10-15 23:55:05 +0000393
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000394 with recording(test, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +0000395 print(file=sbuf)
396 print("os command:", shellCommand, file=sbuf)
397 print("with pid:", pid, file=sbuf)
398 print("stdout:", this_output, file=sbuf)
399 print("stderr:", this_error, file=sbuf)
400 print("retcode:", retcode, file=sbuf)
401 print(file=sbuf)
Ed Maste6e496332014-08-05 20:33:17 +0000402
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000403 if retcode:
404 cmd = kwargs.get("args")
405 if cmd is None:
406 cmd = shellCommand
407 raise CalledProcessError(retcode, cmd)
408 output = output + this_output
409 error = error + this_error
Johnny Chenac77f3b2011-03-23 20:28:59 +0000410 return (output, error)
Johnny Chen690fcef2010-10-15 23:55:05 +0000411
Johnny Chenab9c1dd2010-11-01 20:35:01 +0000412def getsource_if_available(obj):
413 """
414 Return the text of the source code for an object if available. Otherwise,
415 a print representation is returned.
416 """
417 import inspect
418 try:
419 return inspect.getsource(obj)
420 except:
421 return repr(obj)
422
Peter Collingbourne19f48d52011-06-20 19:06:20 +0000423def builder_module():
Ed Maste4d90f0f2013-07-25 13:24:34 +0000424 if sys.platform.startswith("freebsd"):
425 return __import__("builder_freebsd")
Peter Collingbourne19f48d52011-06-20 19:06:20 +0000426 return __import__("builder_" + sys.platform)
427
Siva Chandra8af91662015-06-05 00:22:49 +0000428def run_adb_command(cmd, device_id):
429 device_id_args = []
430 if device_id:
431 device_id_args = ["-s", device_id]
432 full_cmd = ["adb"] + device_id_args + cmd
433 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE)
434 stdout, stderr = p.communicate()
435 return p.returncode, stdout, stderr
436
Chaoren Line9bbabc2015-07-18 00:37:55 +0000437def append_android_envs(dictionary):
438 if dictionary is None:
439 dictionary = {}
440 dictionary["OS"] = "Android"
441 if android_device_api() >= 16:
442 dictionary["PIE"] = 1
443 return dictionary
444
Chaoren Lin9070f532015-07-17 22:13:29 +0000445def target_is_android():
446 if not hasattr(target_is_android, 'result'):
447 triple = lldb.DBG.GetSelectedPlatform().GetTriple()
448 match = re.match(".*-.*-.*-android", triple)
449 target_is_android.result = match is not None
450 return target_is_android.result
451
Siva Chandra8af91662015-06-05 00:22:49 +0000452def android_device_api():
Chaoren Lin9070f532015-07-17 22:13:29 +0000453 if not hasattr(android_device_api, 'result'):
454 assert lldb.platform_url is not None
455 device_id = None
456 parsed_url = urlparse.urlparse(lldb.platform_url)
457 if parsed_url.scheme == "adb":
458 device_id = parsed_url.netloc.split(":")[0]
459 retcode, stdout, stderr = run_adb_command(
460 ["shell", "getprop", "ro.build.version.sdk"], device_id)
461 if retcode == 0:
462 android_device_api.result = int(stdout)
463 else:
464 raise LookupError(
465 ">>> Unable to determine the API level of the Android device.\n"
466 ">>> stdout:\n%s\n"
467 ">>> stderr:\n%s\n" % (stdout, stderr))
468 return android_device_api.result
Siva Chandra8af91662015-06-05 00:22:49 +0000469
Johnny Chena74bb0a2011-08-01 18:46:13 +0000470#
471# Decorators for categorizing test cases.
472#
473
474from functools import wraps
475def python_api_test(func):
476 """Decorate the item as a Python API only test."""
477 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
478 raise Exception("@python_api_test can only be used to decorate a test method")
479 @wraps(func)
480 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000481 if lldb.dont_do_python_api_test:
482 self.skipTest("python api tests")
Johnny Chena74bb0a2011-08-01 18:46:13 +0000483 return func(self, *args, **kwargs)
484
485 # Mark this function as such to separate them from lldb command line tests.
486 wrapper.__python_api_test__ = True
487 return wrapper
488
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +0000489def lldbmi_test(func):
490 """Decorate the item as a lldb-mi only test."""
491 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
492 raise Exception("@lldbmi_test can only be used to decorate a test method")
493 @wraps(func)
494 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000495 if lldb.dont_do_lldbmi_test:
496 self.skipTest("lldb-mi tests")
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +0000497 return func(self, *args, **kwargs)
498
499 # Mark this function as such to separate them from lldb command line tests.
500 wrapper.__lldbmi_test__ = True
501 return wrapper
502
Johnny Chena74bb0a2011-08-01 18:46:13 +0000503def benchmarks_test(func):
504 """Decorate the item as a benchmarks test."""
505 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
506 raise Exception("@benchmarks_test can only be used to decorate a test method")
507 @wraps(func)
508 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000509 if not lldb.just_do_benchmarks_test:
510 self.skipTest("benchmarks tests")
Johnny Chena74bb0a2011-08-01 18:46:13 +0000511 return func(self, *args, **kwargs)
512
513 # Mark this function as such to separate them from the regular tests.
514 wrapper.__benchmarks_test__ = True
515 return wrapper
516
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000517def no_debug_info_test(func):
518 """Decorate the item as a test what don't use any debug info. If this annotation is specified
519 then the test runner won't generate a separate test for each debug info format. """
520 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
521 raise Exception("@no_debug_info_test can only be used to decorate a test method")
522 @wraps(func)
523 def wrapper(self, *args, **kwargs):
524 return func(self, *args, **kwargs)
525
526 # Mark this function as such to separate them from the regular tests.
527 wrapper.__no_debug_info_test__ = True
528 return wrapper
529
Johnny Chenf1548d42012-04-06 00:56:05 +0000530def dsym_test(func):
531 """Decorate the item as a dsym test."""
532 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
533 raise Exception("@dsym_test can only be used to decorate a test method")
534 @wraps(func)
535 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000536 if lldb.dont_do_dsym_test:
537 self.skipTest("dsym tests")
Johnny Chenf1548d42012-04-06 00:56:05 +0000538 return func(self, *args, **kwargs)
539
540 # Mark this function as such to separate them from the regular tests.
541 wrapper.__dsym_test__ = True
542 return wrapper
543
544def dwarf_test(func):
545 """Decorate the item as a dwarf test."""
546 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
547 raise Exception("@dwarf_test can only be used to decorate a test method")
548 @wraps(func)
549 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000550 if lldb.dont_do_dwarf_test:
551 self.skipTest("dwarf tests")
Johnny Chenf1548d42012-04-06 00:56:05 +0000552 return func(self, *args, **kwargs)
553
554 # Mark this function as such to separate them from the regular tests.
555 wrapper.__dwarf_test__ = True
556 return wrapper
557
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +0000558def dwo_test(func):
559 """Decorate the item as a dwo test."""
560 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
561 raise Exception("@dwo_test can only be used to decorate a test method")
562 @wraps(func)
563 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000564 if lldb.dont_do_dwo_test:
565 self.skipTest("dwo tests")
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +0000566 return func(self, *args, **kwargs)
567
568 # Mark this function as such to separate them from the regular tests.
569 wrapper.__dwo_test__ = True
570 return wrapper
571
Todd Fialaa41d48c2014-04-28 04:49:40 +0000572def debugserver_test(func):
573 """Decorate the item as a debugserver test."""
574 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
575 raise Exception("@debugserver_test can only be used to decorate a test method")
576 @wraps(func)
577 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000578 if lldb.dont_do_debugserver_test:
579 self.skipTest("debugserver tests")
Todd Fialaa41d48c2014-04-28 04:49:40 +0000580 return func(self, *args, **kwargs)
581
582 # Mark this function as such to separate them from the regular tests.
583 wrapper.__debugserver_test__ = True
584 return wrapper
585
586def llgs_test(func):
Robert Flack8cc4cf12015-03-06 14:36:33 +0000587 """Decorate the item as a lldb-server test."""
Todd Fialaa41d48c2014-04-28 04:49:40 +0000588 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
589 raise Exception("@llgs_test can only be used to decorate a test method")
590 @wraps(func)
591 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000592 if lldb.dont_do_llgs_test:
593 self.skipTest("llgs tests")
Todd Fialaa41d48c2014-04-28 04:49:40 +0000594 return func(self, *args, **kwargs)
595
596 # Mark this function as such to separate them from the regular tests.
597 wrapper.__llgs_test__ = True
598 return wrapper
599
Daniel Maleae0f8f572013-08-26 23:57:52 +0000600def not_remote_testsuite_ready(func):
601 """Decorate the item as a test which is not ready yet for remote testsuite."""
602 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
603 raise Exception("@not_remote_testsuite_ready can only be used to decorate a test method")
604 @wraps(func)
605 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000606 if lldb.lldbtest_remote_sandbox or lldb.remote_platform:
607 self.skipTest("not ready for remote testsuite")
Daniel Maleae0f8f572013-08-26 23:57:52 +0000608 return func(self, *args, **kwargs)
609
610 # Mark this function as such to separate them from the regular tests.
611 wrapper.__not_ready_for_remote_testsuite_test__ = True
612 return wrapper
613
Ed Maste433790a2014-04-23 12:55:41 +0000614def expectedFailure(expected_fn, bugnumber=None):
615 def expectedFailure_impl(func):
616 @wraps(func)
617 def wrapper(*args, **kwargs):
Enrico Granata43f62132013-02-23 01:28:30 +0000618 from unittest2 import case
619 self = args[0]
Enrico Granata43f62132013-02-23 01:28:30 +0000620 try:
Ed Maste433790a2014-04-23 12:55:41 +0000621 func(*args, **kwargs)
Enrico Granata43f62132013-02-23 01:28:30 +0000622 except Exception:
Ed Maste433790a2014-04-23 12:55:41 +0000623 if expected_fn(self):
624 raise case._ExpectedFailure(sys.exc_info(), bugnumber)
Enrico Granata43f62132013-02-23 01:28:30 +0000625 else:
626 raise
Ed Maste433790a2014-04-23 12:55:41 +0000627 if expected_fn(self):
628 raise case._UnexpectedSuccess(sys.exc_info(), bugnumber)
629 return wrapper
Ying Chen464d1e12015-03-27 00:26:52 +0000630 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
631 # return decorator in this case, so it will be used to decorating original method
632 if callable(bugnumber):
633 return expectedFailure_impl(bugnumber)
634 else:
635 return expectedFailure_impl
Ed Maste433790a2014-04-23 12:55:41 +0000636
Ying Chen7091c2c2015-04-21 01:15:47 +0000637# provide a function to xfail on defined oslist, compiler version, and archs
638# if none is specified for any argument, that argument won't be checked and thus means for all
639# for example,
640# @expectedFailureAll, xfail for all platform/compiler/arch,
641# @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
642# @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000643def expectedFailureAll(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, triple=None, debug_info=None):
Ying Chen7091c2c2015-04-21 01:15:47 +0000644 def fn(self):
645 return ((oslist is None or self.getPlatform() in oslist) and
646 (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
Tamas Berghammercf6f92a2015-09-07 15:50:19 +0000647 self.expectedArch(archs) and
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000648 (triple is None or re.match(triple, lldb.DBG.GetSelectedPlatform().GetTriple())) and
649 (debug_info is None or self.debug_info in debug_info))
Ying Chen7091c2c2015-04-21 01:15:47 +0000650 return expectedFailure(fn, bugnumber)
651
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000652def expectedFailureDwarf(bugnumber=None):
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +0000653 return expectedFailureAll(bugnumber=bugnumber, debug_info="dwarf")
654
655def expectedFailureDwo(bugnumber=None):
656 return expectedFailureAll(bugnumber=bugnumber, debug_info="dwo")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000657
658def expectedFailureDsym(bugnumber=None):
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +0000659 return expectedFailureAll(bugnumber=bugnumber, debug_info="dsym")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000660
661def expectedFailureCompiler(compiler, compiler_version=None, bugnumber=None):
662 if compiler_version is None:
663 compiler_version=['=', None]
664 return expectedFailureAll(bugnumber=bugnumber, compiler=compiler, compiler_version=compiler_version)
665
Vince Harron8974ce22015-03-13 19:54:54 +0000666# to XFAIL a specific clang versions, try this
667# @expectedFailureClang('bugnumber', ['<=', '3.4'])
668def expectedFailureClang(bugnumber=None, compiler_version=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000669 return expectedFailureCompiler('clang', compiler_version, bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000670
671def expectedFailureGcc(bugnumber=None, compiler_version=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000672 return expectedFailureCompiler('gcc', compiler_version, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000673
Matt Kopec0de53f02013-03-15 19:10:12 +0000674def expectedFailureIcc(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000675 return expectedFailureCompiler('icc', None, bugnumber)
Matt Kopec0de53f02013-03-15 19:10:12 +0000676
Ed Maste433790a2014-04-23 12:55:41 +0000677def expectedFailureArch(arch, bugnumber=None):
678 def fn(self):
679 return arch in self.getArchitecture()
Ying Chen464d1e12015-03-27 00:26:52 +0000680 return expectedFailure(fn, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000681
Enrico Granatae6cedc12013-02-23 01:05:23 +0000682def expectedFailurei386(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000683 return expectedFailureArch('i386', bugnumber)
Johnny Chena33843f2011-12-22 21:14:31 +0000684
Matt Kopecee969f92013-09-26 23:30:59 +0000685def expectedFailurex86_64(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000686 return expectedFailureArch('x86_64', bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000687
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000688def expectedFailureOS(oslist, bugnumber=None, compilers=None, debug_info=None):
Ed Maste433790a2014-04-23 12:55:41 +0000689 def fn(self):
Robert Flack13c7ad92015-03-30 14:12:17 +0000690 return (self.getPlatform() in oslist and
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000691 self.expectedCompiler(compilers) and
692 (debug_info is None or self.debug_info in debug_info))
Ying Chen464d1e12015-03-27 00:26:52 +0000693 return expectedFailure(fn, bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000694
Chaoren Linf7160f32015-06-09 17:39:27 +0000695def expectedFailureHostOS(oslist, bugnumber=None, compilers=None):
696 def fn(self):
697 return (getHostPlatform() in oslist and
698 self.expectedCompiler(compilers))
699 return expectedFailure(fn, bugnumber)
700
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000701def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None):
Robert Flackefa49c22015-03-26 19:34:26 +0000702 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000703 return expectedFailureOS(getDarwinOSTriples(), bugnumber, compilers, debug_info=debug_info)
Matt Kopecee969f92013-09-26 23:30:59 +0000704
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000705def expectedFailureFreeBSD(bugnumber=None, compilers=None, debug_info=None):
706 return expectedFailureOS(['freebsd'], bugnumber, compilers, debug_info=debug_info)
Ed Maste24a7f7d2013-07-24 19:47:08 +0000707
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000708def expectedFailureLinux(bugnumber=None, compilers=None, debug_info=None):
709 return expectedFailureOS(['linux'], bugnumber, compilers, debug_info=debug_info)
Matt Kopece9ea0da2013-05-07 19:29:28 +0000710
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000711def expectedFailureWindows(bugnumber=None, compilers=None, debug_info=None):
712 return expectedFailureOS(['windows'], bugnumber, compilers, debug_info=debug_info)
Zachary Turner80c2c602014-12-09 19:28:00 +0000713
Chaoren Linf7160f32015-06-09 17:39:27 +0000714def expectedFailureHostWindows(bugnumber=None, compilers=None):
715 return expectedFailureHostOS(['windows'], bugnumber, compilers)
716
Pavel Labath090152b2015-08-20 11:37:19 +0000717def matchAndroid(api_levels=None, archs=None):
718 def match(self):
719 if not target_is_android():
720 return False
721 if archs is not None and self.getArchitecture() not in archs:
722 return False
723 if api_levels is not None and android_device_api() not in api_levels:
724 return False
725 return True
726 return match
727
728
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000729def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
Siva Chandra8af91662015-06-05 00:22:49 +0000730 """ Mark a test as xfail for Android.
731
732 Arguments:
733 bugnumber - The LLVM pr associated with the problem.
734 api_levels - A sequence of numbers specifying the Android API levels
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000735 for which a test is expected to fail. None means all API level.
736 arch - A sequence of architecture names specifying the architectures
737 for which a test is expected to fail. None means all architectures.
Siva Chandra8af91662015-06-05 00:22:49 +0000738 """
Pavel Labath090152b2015-08-20 11:37:19 +0000739 return expectedFailure(matchAndroid(api_levels, archs), bugnumber)
Pavel Labath674bc7b2015-05-29 14:54:46 +0000740
Vince Harron7ac3ea42015-06-26 15:13:21 +0000741# if the test passes on the first try, we're done (success)
742# if the test fails once, then passes on the second try, raise an ExpectedFailure
743# if the test fails twice in a row, re-throw the exception from the second test run
744def expectedFlakey(expected_fn, bugnumber=None):
745 def expectedFailure_impl(func):
746 @wraps(func)
747 def wrapper(*args, **kwargs):
748 from unittest2 import case
749 self = args[0]
750 try:
751 func(*args, **kwargs)
Ying Chen0a7202b2015-07-01 22:44:27 +0000752 # don't retry if the test case is already decorated with xfail or skip
753 except (case._ExpectedFailure, case.SkipTest, case._UnexpectedSuccess):
754 raise
Vince Harron7ac3ea42015-06-26 15:13:21 +0000755 except Exception:
756 if expected_fn(self):
Ying Chen0a7202b2015-07-01 22:44:27 +0000757 # before retry, run tearDown for previous run and setup for next
Vince Harron7ac3ea42015-06-26 15:13:21 +0000758 try:
Ying Chen0a7202b2015-07-01 22:44:27 +0000759 self.tearDown()
760 self.setUp()
Vince Harron7ac3ea42015-06-26 15:13:21 +0000761 func(*args, **kwargs)
762 except Exception:
763 # oh snap! two failures in a row, record a failure/error
764 raise
765 # record the expected failure
766 raise case._ExpectedFailure(sys.exc_info(), bugnumber)
767 else:
768 raise
769 return wrapper
770 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
771 # return decorator in this case, so it will be used to decorating original method
772 if callable(bugnumber):
773 return expectedFailure_impl(bugnumber)
774 else:
775 return expectedFailure_impl
776
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000777def expectedFlakeyDwarf(bugnumber=None):
778 def fn(self):
779 return self.debug_info == "dwarf"
780 return expectedFlakey(fn, bugnumber)
781
782def expectedFlakeyDsym(bugnumber=None):
783 def fn(self):
784 return self.debug_info == "dwarf"
785 return expectedFlakey(fn, bugnumber)
786
Vince Harron7ac3ea42015-06-26 15:13:21 +0000787def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
788 def fn(self):
789 return (self.getPlatform() in oslist and
790 self.expectedCompiler(compilers))
791 return expectedFlakey(fn, bugnumber)
792
793def expectedFlakeyDarwin(bugnumber=None, compilers=None):
794 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
795 return expectedFlakeyOS(getDarwinOSTriples(), bugnumber, compilers)
796
797def expectedFlakeyLinux(bugnumber=None, compilers=None):
798 return expectedFlakeyOS(['linux'], bugnumber, compilers)
799
800def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
801 return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
802
803def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
804 if compiler_version is None:
805 compiler_version=['=', None]
806 def fn(self):
807 return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
808 return expectedFlakey(fn, bugnumber)
809
810# @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
811def expectedFlakeyClang(bugnumber=None, compiler_version=None):
812 return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
813
814# @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
815def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
816 return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
817
Pavel Labath63a579c2015-09-07 12:15:27 +0000818def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
819 return expectedFlakey(matchAndroid(api_levels, archs), bugnumber)
820
Greg Clayton12514562013-12-05 22:22:32 +0000821def skipIfRemote(func):
822 """Decorate the item to skip tests if testing remotely."""
823 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
824 raise Exception("@skipIfRemote can only be used to decorate a test method")
825 @wraps(func)
826 def wrapper(*args, **kwargs):
827 from unittest2 import case
828 if lldb.remote_platform:
829 self = args[0]
830 self.skipTest("skip on remote platform")
831 else:
832 func(*args, **kwargs)
833 return wrapper
834
Siva Chandra4470f382015-06-17 22:32:27 +0000835def skipUnlessListedRemote(remote_list=None):
836 def myImpl(func):
837 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
838 raise Exception("@skipIfRemote can only be used to decorate a "
839 "test method")
840
841 @wraps(func)
842 def wrapper(*args, **kwargs):
843 if remote_list and lldb.remote_platform:
844 self = args[0]
845 triple = self.dbg.GetSelectedPlatform().GetTriple()
846 for r in remote_list:
847 if r in triple:
848 func(*args, **kwargs)
849 return
850 self.skipTest("skip on remote platform %s" % str(triple))
851 else:
852 func(*args, **kwargs)
853 return wrapper
854
855 return myImpl
856
Greg Clayton12514562013-12-05 22:22:32 +0000857def skipIfRemoteDueToDeadlock(func):
858 """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
859 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
860 raise Exception("@skipIfRemote can only be used to decorate a test method")
861 @wraps(func)
862 def wrapper(*args, **kwargs):
863 from unittest2 import case
864 if lldb.remote_platform:
865 self = args[0]
866 self.skipTest("skip on remote platform (deadlocks)")
867 else:
868 func(*args, **kwargs)
869 return wrapper
870
Enrico Granatab633e432014-10-06 21:37:06 +0000871def skipIfNoSBHeaders(func):
872 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
873 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Ed Maste59cca5d2014-10-07 01:57:52 +0000874 raise Exception("@skipIfNoSBHeaders can only be used to decorate a test method")
Enrico Granatab633e432014-10-06 21:37:06 +0000875 @wraps(func)
876 def wrapper(*args, **kwargs):
877 from unittest2 import case
878 self = args[0]
Shawn Best181b09b2014-11-08 00:04:04 +0000879 if sys.platform.startswith("darwin"):
880 header = os.path.join(self.lib_dir, 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
881 else:
882 header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
Enrico Granatab633e432014-10-06 21:37:06 +0000883 platform = sys.platform
Enrico Granatab633e432014-10-06 21:37:06 +0000884 if not os.path.exists(header):
885 self.skipTest("skip because LLDB.h header not found")
886 else:
887 func(*args, **kwargs)
888 return wrapper
889
Robert Flack13c7ad92015-03-30 14:12:17 +0000890def skipIfFreeBSD(func):
891 """Decorate the item to skip tests that should be skipped on FreeBSD."""
892 return skipIfPlatform(["freebsd"])(func)
Zachary Turnerc7826522014-08-13 17:44:53 +0000893
Greg Claytone0d0a762015-04-02 18:24:03 +0000894def getDarwinOSTriples():
895 return ['darwin', 'macosx', 'ios']
896
Daniel Maleab3d41a22013-07-09 00:08:01 +0000897def skipIfDarwin(func):
898 """Decorate the item to skip tests that should be skipped on Darwin."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000899 return skipIfPlatform(getDarwinOSTriples())(func)
Daniel Maleab3d41a22013-07-09 00:08:01 +0000900
Robert Flack13c7ad92015-03-30 14:12:17 +0000901def skipIfLinux(func):
902 """Decorate the item to skip tests that should be skipped on Linux."""
903 return skipIfPlatform(["linux"])(func)
904
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000905def skipUnlessHostLinux(func):
906 """Decorate the item to skip tests that should be skipped on any non Linux host."""
907 return skipUnlessHostPlatform(["linux"])(func)
908
Robert Flack13c7ad92015-03-30 14:12:17 +0000909def skipIfWindows(func):
910 """Decorate the item to skip tests that should be skipped on Windows."""
911 return skipIfPlatform(["windows"])(func)
912
Chaoren Line6eea5d2015-06-08 22:13:28 +0000913def skipIfHostWindows(func):
914 """Decorate the item to skip tests that should be skipped on Windows."""
915 return skipIfHostPlatform(["windows"])(func)
916
Adrian McCarthyd9dbae52015-09-16 18:17:11 +0000917def skipUnlessWindows(func):
918 """Decorate the item to skip tests that should be skipped on any non-Windows platform."""
919 return skipUnlessPlatform(["windows"])(func)
920
Robert Flack13c7ad92015-03-30 14:12:17 +0000921def skipUnlessDarwin(func):
922 """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000923 return skipUnlessPlatform(getDarwinOSTriples())(func)
Robert Flack13c7ad92015-03-30 14:12:17 +0000924
Ryan Brown57bee1e2015-09-14 22:45:11 +0000925def skipUnlessGoInstalled(func):
926 """Decorate the item to skip tests when no Go compiler is available."""
927 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
928 raise Exception("@skipIfGcc can only be used to decorate a test method")
929 @wraps(func)
930 def wrapper(*args, **kwargs):
931 from unittest2 import case
932 self = args[0]
933 compiler = self.getGoCompilerVersion()
934 if not compiler:
935 self.skipTest("skipping because go compiler not found")
936 else:
Todd Fialabe5dfc52015-10-06 19:15:56 +0000937 # Ensure the version is the minimum version supported by
Todd Fiala02c08d02015-10-06 22:14:33 +0000938 # the LLDB go support.
Todd Fialabe5dfc52015-10-06 19:15:56 +0000939 match_version = re.search(r"(\d+\.\d+(\.\d+)?)", compiler)
940 if not match_version:
941 # Couldn't determine version.
942 self.skipTest(
943 "skipping because go version could not be parsed "
944 "out of {}".format(compiler))
945 else:
946 from distutils.version import StrictVersion
Todd Fiala02c08d02015-10-06 22:14:33 +0000947 min_strict_version = StrictVersion("1.4.0")
Todd Fialabe5dfc52015-10-06 19:15:56 +0000948 compiler_strict_version = StrictVersion(match_version.group(1))
949 if compiler_strict_version < min_strict_version:
950 self.skipTest(
951 "skipping because available go version ({}) does "
Todd Fiala02c08d02015-10-06 22:14:33 +0000952 "not meet minimum required go version ({})".format(
Todd Fialabe5dfc52015-10-06 19:15:56 +0000953 compiler_strict_version,
954 min_strict_version))
Todd Fiala9f236802015-10-06 19:23:22 +0000955 func(*args, **kwargs)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000956 return wrapper
957
Robert Flack068898c2015-04-09 18:07:58 +0000958def getPlatform():
Robert Flack6e1fd352015-05-15 12:39:33 +0000959 """Returns the target platform which the tests are running on."""
Robert Flack068898c2015-04-09 18:07:58 +0000960 platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
961 if platform.startswith('freebsd'):
962 platform = 'freebsd'
963 return platform
964
Robert Flack6e1fd352015-05-15 12:39:33 +0000965def getHostPlatform():
966 """Returns the host platform running the test suite."""
967 # Attempts to return a platform name matching a target Triple platform.
968 if sys.platform.startswith('linux'):
969 return 'linux'
970 elif sys.platform.startswith('win32'):
971 return 'windows'
972 elif sys.platform.startswith('darwin'):
973 return 'darwin'
974 elif sys.platform.startswith('freebsd'):
975 return 'freebsd'
976 else:
977 return sys.platform
978
Robert Flackfb2f6c62015-04-17 08:02:18 +0000979def platformIsDarwin():
980 """Returns true if the OS triple for the selected platform is any valid apple OS"""
981 return getPlatform() in getDarwinOSTriples()
982
Robert Flack6e1fd352015-05-15 12:39:33 +0000983def skipIfHostIncompatibleWithRemote(func):
984 """Decorate the item to skip tests if binaries built on this host are incompatible."""
985 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
986 raise Exception("@skipIfHostIncompatibleWithRemote can only be used to decorate a test method")
987 @wraps(func)
988 def wrapper(*args, **kwargs):
989 from unittest2 import case
990 self = args[0]
991 host_arch = self.getLldbArchitecture()
992 host_platform = getHostPlatform()
993 target_arch = self.getArchitecture()
Robert Flack4629c4b2015-05-15 18:54:32 +0000994 target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
Robert Flack6e1fd352015-05-15 12:39:33 +0000995 if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
996 self.skipTest("skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch))
997 elif target_platform != host_platform:
998 self.skipTest("skipping because target is %s but host is %s" % (target_platform, host_platform))
999 else:
1000 func(*args, **kwargs)
1001 return wrapper
1002
Chaoren Line6eea5d2015-06-08 22:13:28 +00001003def skipIfHostPlatform(oslist):
1004 """Decorate the item to skip tests if running on one of the listed host platforms."""
1005 return unittest2.skipIf(getHostPlatform() in oslist,
1006 "skip on %s" % (", ".join(oslist)))
1007
1008def skipUnlessHostPlatform(oslist):
1009 """Decorate the item to skip tests unless running on one of the listed host platforms."""
1010 return unittest2.skipUnless(getHostPlatform() in oslist,
1011 "requires on of %s" % (", ".join(oslist)))
1012
Zachary Turner793d9972015-08-14 23:29:24 +00001013def skipUnlessArch(archlist):
1014 """Decorate the item to skip tests unless running on one of the listed architectures."""
1015 def myImpl(func):
1016 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1017 raise Exception("@skipUnlessArch can only be used to decorate a test method")
1018
1019 @wraps(func)
1020 def wrapper(*args, **kwargs):
1021 self = args[0]
1022 if self.getArchitecture() not in archlist:
1023 self.skipTest("skipping for architecture %s (requires one of %s)" %
1024 (self.getArchitecture(), ", ".join(archlist)))
1025 else:
1026 func(*args, **kwargs)
1027 return wrapper
1028
1029 return myImpl
1030
Robert Flack13c7ad92015-03-30 14:12:17 +00001031def skipIfPlatform(oslist):
1032 """Decorate the item to skip tests if running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +00001033 return unittest2.skipIf(getPlatform() in oslist,
1034 "skip on %s" % (", ".join(oslist)))
Robert Flack13c7ad92015-03-30 14:12:17 +00001035
1036def skipUnlessPlatform(oslist):
1037 """Decorate the item to skip tests unless running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +00001038 return unittest2.skipUnless(getPlatform() in oslist,
1039 "requires on of %s" % (", ".join(oslist)))
Daniel Maleab3d41a22013-07-09 00:08:01 +00001040
Daniel Malea48359902013-05-14 20:48:54 +00001041def skipIfLinuxClang(func):
1042 """Decorate the item to skip tests that should be skipped if building on
1043 Linux with clang.
1044 """
1045 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1046 raise Exception("@skipIfLinuxClang can only be used to decorate a test method")
1047 @wraps(func)
1048 def wrapper(*args, **kwargs):
1049 from unittest2 import case
1050 self = args[0]
1051 compiler = self.getCompiler()
Vince Harronc8492672015-05-04 02:59:19 +00001052 platform = self.getPlatform()
1053 if "clang" in compiler and platform == "linux":
Daniel Malea48359902013-05-14 20:48:54 +00001054 self.skipTest("skipping because Clang is used on Linux")
1055 else:
1056 func(*args, **kwargs)
1057 return wrapper
1058
Ying Chen7091c2c2015-04-21 01:15:47 +00001059# provide a function to skip on defined oslist, compiler version, and archs
1060# if none is specified for any argument, that argument won't be checked and thus means for all
1061# for example,
1062# @skipIf, skip for all platform/compiler/arch,
1063# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
1064# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
1065
1066# TODO: refactor current code, to make skipIfxxx functions to call this function
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00001067def skipIf(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, debug_info=None):
Ying Chen7091c2c2015-04-21 01:15:47 +00001068 def fn(self):
1069 return ((oslist is None or self.getPlatform() in oslist) and
1070 (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00001071 self.expectedArch(archs) and
1072 (debug_info is None or self.debug_info in debug_info))
1073 return skipTestIfFn(fn, bugnumber, skipReason="skipping because os:%s compiler: %s %s arch: %s debug info: %s"%(oslist, compiler, compiler_version, archs, debug_info))
1074
1075def skipIfDebugInfo(bugnumber=None, debug_info=None):
1076 return skipIf(bugnumber=bugnumber, debug_info=debug_info)
1077
Greg Claytonedea2372015-10-07 20:01:13 +00001078def skipIfDWO(bugnumber=None):
1079 return skipIfDebugInfo(bugnumber, ["dwo"])
1080
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00001081def skipIfDwarf(bugnumber=None):
1082 return skipIfDebugInfo(bugnumber, ["dwarf"])
1083
1084def skipIfDsym(bugnumber=None):
1085 return skipIfDebugInfo(bugnumber, ["dsym"])
Ying Chen7091c2c2015-04-21 01:15:47 +00001086
1087def skipTestIfFn(expected_fn, bugnumber=None, skipReason=None):
1088 def skipTestIfFn_impl(func):
1089 @wraps(func)
1090 def wrapper(*args, **kwargs):
1091 from unittest2 import case
1092 self = args[0]
1093 if expected_fn(self):
1094 self.skipTest(skipReason)
1095 else:
1096 func(*args, **kwargs)
1097 return wrapper
1098 if callable(bugnumber):
1099 return skipTestIfFn_impl(bugnumber)
1100 else:
1101 return skipTestIfFn_impl
1102
Daniel Maleabe230792013-01-24 23:52:09 +00001103def skipIfGcc(func):
1104 """Decorate the item to skip tests that should be skipped if building with gcc ."""
1105 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Daniel Malea0aea0162013-02-27 17:29:46 +00001106 raise Exception("@skipIfGcc can only be used to decorate a test method")
Daniel Maleabe230792013-01-24 23:52:09 +00001107 @wraps(func)
1108 def wrapper(*args, **kwargs):
1109 from unittest2 import case
1110 self = args[0]
1111 compiler = self.getCompiler()
1112 if "gcc" in compiler:
1113 self.skipTest("skipping because gcc is the test compiler")
1114 else:
1115 func(*args, **kwargs)
1116 return wrapper
1117
Matt Kopec0de53f02013-03-15 19:10:12 +00001118def skipIfIcc(func):
1119 """Decorate the item to skip tests that should be skipped if building with icc ."""
1120 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1121 raise Exception("@skipIfIcc can only be used to decorate a test method")
1122 @wraps(func)
1123 def wrapper(*args, **kwargs):
1124 from unittest2 import case
1125 self = args[0]
1126 compiler = self.getCompiler()
1127 if "icc" in compiler:
1128 self.skipTest("skipping because icc is the test compiler")
1129 else:
1130 func(*args, **kwargs)
1131 return wrapper
1132
Daniel Malea55faa402013-05-02 21:44:31 +00001133def skipIfi386(func):
1134 """Decorate the item to skip tests that should be skipped if building 32-bit."""
1135 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1136 raise Exception("@skipIfi386 can only be used to decorate a test method")
1137 @wraps(func)
1138 def wrapper(*args, **kwargs):
1139 from unittest2 import case
1140 self = args[0]
1141 if "i386" == self.getArchitecture():
1142 self.skipTest("skipping because i386 is not a supported architecture")
1143 else:
1144 func(*args, **kwargs)
1145 return wrapper
1146
Pavel Labath090152b2015-08-20 11:37:19 +00001147def skipIfTargetAndroid(api_levels=None, archs=None):
Siva Chandra77f20fc2015-06-05 19:54:49 +00001148 """Decorator to skip tests when the target is Android.
1149
1150 Arguments:
1151 api_levels - The API levels for which the test should be skipped. If
1152 it is None, then the test will be skipped for all API levels.
Pavel Labath090152b2015-08-20 11:37:19 +00001153 arch - A sequence of architecture names specifying the architectures
1154 for which a test is skipped. None means all architectures.
Siva Chandra77f20fc2015-06-05 19:54:49 +00001155 """
1156 def myImpl(func):
1157 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1158 raise Exception("@skipIfTargetAndroid can only be used to "
1159 "decorate a test method")
1160 @wraps(func)
1161 def wrapper(*args, **kwargs):
1162 from unittest2 import case
1163 self = args[0]
Pavel Labath090152b2015-08-20 11:37:19 +00001164 if matchAndroid(api_levels, archs)(self):
1165 self.skipTest("skiped on Android target with API %d and architecture %s" %
1166 (android_device_api(), self.getArchitecture()))
Tamas Berghammer1253a812015-03-13 10:12:25 +00001167 func(*args, **kwargs)
Siva Chandra77f20fc2015-06-05 19:54:49 +00001168 return wrapper
1169 return myImpl
Tamas Berghammer1253a812015-03-13 10:12:25 +00001170
Ilia Kd9953052015-03-12 07:19:41 +00001171def skipUnlessCompilerRt(func):
1172 """Decorate the item to skip tests if testing remotely."""
1173 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1174 raise Exception("@skipUnless can only be used to decorate a test method")
1175 @wraps(func)
1176 def wrapper(*args, **kwargs):
1177 from unittest2 import case
1178 import os.path
1179 compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "projects", "compiler-rt")
1180 if not os.path.exists(compilerRtPath):
1181 self = args[0]
1182 self.skipTest("skip if compiler-rt not found")
1183 else:
1184 func(*args, **kwargs)
1185 return wrapper
Daniel Malea55faa402013-05-02 21:44:31 +00001186
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001187class _PlatformContext(object):
1188 """Value object class which contains platform-specific options."""
1189
1190 def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
1191 self.shlib_environment_var = shlib_environment_var
1192 self.shlib_prefix = shlib_prefix
1193 self.shlib_extension = shlib_extension
1194
1195
Johnny Chena74bb0a2011-08-01 18:46:13 +00001196class Base(unittest2.TestCase):
Johnny Chen8334dad2010-10-22 23:15:46 +00001197 """
Johnny Chena74bb0a2011-08-01 18:46:13 +00001198 Abstract base for performing lldb (see TestBase) or other generic tests (see
1199 BenchBase for one example). lldbtest.Base works with the test driver to
1200 accomplish things.
1201
Johnny Chen8334dad2010-10-22 23:15:46 +00001202 """
Enrico Granata5020f952012-10-24 21:42:49 +00001203
Enrico Granata19186272012-10-24 21:44:48 +00001204 # The concrete subclass should override this attribute.
1205 mydir = None
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001206
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001207 # Keep track of the old current working directory.
1208 oldcwd = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001209
Greg Clayton4570d3e2013-12-10 23:19:29 +00001210 @staticmethod
1211 def compute_mydir(test_file):
1212 '''Subclasses should call this function to correctly calculate the required "mydir" attribute as follows:
1213
1214 mydir = TestBase.compute_mydir(__file__)'''
1215 test_dir = os.path.dirname(test_file)
1216 return test_dir[len(os.environ["LLDB_TEST"])+1:]
1217
Johnny Chenfb4264c2011-08-01 19:50:58 +00001218 def TraceOn(self):
1219 """Returns True if we are in trace mode (tracing detailed test execution)."""
1220 return traceAlways
Greg Clayton4570d3e2013-12-10 23:19:29 +00001221
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001222 @classmethod
1223 def setUpClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001224 """
1225 Python unittest framework class setup fixture.
1226 Do current directory manipulation.
1227 """
Johnny Chenf02ec122010-07-03 20:41:42 +00001228 # Fail fast if 'mydir' attribute is not overridden.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001229 if not cls.mydir or len(cls.mydir) == 0:
Johnny Chenf02ec122010-07-03 20:41:42 +00001230 raise Exception("Subclasses must override the 'mydir' attribute.")
Enrico Granata7e137e32012-10-24 18:14:21 +00001231
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001232 # Save old working directory.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001233 cls.oldcwd = os.getcwd()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001234
1235 # Change current working directory if ${LLDB_TEST} is defined.
1236 # See also dotest.py which sets up ${LLDB_TEST}.
1237 if ("LLDB_TEST" in os.environ):
Vince Harron85d19652015-05-21 19:09:29 +00001238 full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001239 if traceAlways:
Zachary Turnerff890da2015-10-19 23:45:41 +00001240 print("Change dir to:", full_dir, file=sys.stderr)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001241 os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
1242
Vince Harron85d19652015-05-21 19:09:29 +00001243 if debug_confirm_directory_exclusivity:
Zachary Turnerb48b4042015-05-21 20:16:02 +00001244 import lock
Vince Harron85d19652015-05-21 19:09:29 +00001245 cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
1246 try:
1247 cls.dir_lock.try_acquire()
1248 # write the class that owns the lock into the lock file
1249 cls.dir_lock.handle.write(cls.__name__)
1250 except IOError as ioerror:
1251 # nothing else should have this directory lock
1252 # wait here until we get a lock
1253 cls.dir_lock.acquire()
1254 # read the previous owner from the lock file
1255 lock_id = cls.dir_lock.handle.read()
Zachary Turnerff890da2015-10-19 23:45:41 +00001256 print("LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id), file=sys.stderr)
Vince Harron85d19652015-05-21 19:09:29 +00001257 raise ioerror
1258
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001259 # Set platform context.
Robert Flackfb2f6c62015-04-17 08:02:18 +00001260 if platformIsDarwin():
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001261 cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
Robert Flackfb2f6c62015-04-17 08:02:18 +00001262 elif getPlatform() == "linux" or getPlatform() == "freebsd":
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001263 cls.platformContext = _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001264 else:
1265 cls.platformContext = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001266
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001267 @classmethod
1268 def tearDownClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001269 """
1270 Python unittest framework class teardown fixture.
1271 Do class-wide cleanup.
1272 """
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001273
Johnny Chen0fddfb22011-11-17 19:57:27 +00001274 if doCleanup and not lldb.skip_build_and_cleanup:
Johnny Chen707b3c92010-10-11 22:25:46 +00001275 # First, let's do the platform-specific cleanup.
Peter Collingbourne19f48d52011-06-20 19:06:20 +00001276 module = builder_module()
Zachary Turnerb1490b62015-08-26 19:44:56 +00001277 module.cleanup()
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001278
Johnny Chen707b3c92010-10-11 22:25:46 +00001279 # Subclass might have specific cleanup function defined.
1280 if getattr(cls, "classCleanup", None):
1281 if traceAlways:
Zachary Turnerff890da2015-10-19 23:45:41 +00001282 print("Call class-specific cleanup function for class:", cls, file=sys.stderr)
Johnny Chen707b3c92010-10-11 22:25:46 +00001283 try:
1284 cls.classCleanup()
1285 except:
1286 exc_type, exc_value, exc_tb = sys.exc_info()
1287 traceback.print_exception(exc_type, exc_value, exc_tb)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001288
Vince Harron85d19652015-05-21 19:09:29 +00001289 if debug_confirm_directory_exclusivity:
1290 cls.dir_lock.release()
1291 del cls.dir_lock
1292
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001293 # Restore old working directory.
1294 if traceAlways:
Zachary Turnerff890da2015-10-19 23:45:41 +00001295 print("Restore dir to:", cls.oldcwd, file=sys.stderr)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001296 os.chdir(cls.oldcwd)
1297
Johnny Chena74bb0a2011-08-01 18:46:13 +00001298 @classmethod
1299 def skipLongRunningTest(cls):
1300 """
1301 By default, we skip long running test case.
1302 This can be overridden by passing '-l' to the test driver (dotest.py).
1303 """
1304 if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
1305 return False
1306 else:
1307 return True
Johnny Chened492022011-06-21 00:53:00 +00001308
Vince Harron6d3d0f12015-05-10 22:01:59 +00001309 def enableLogChannelsForCurrentTest(self):
1310 if len(lldbtest_config.channels) == 0:
1311 return
1312
1313 # if debug channels are specified in lldbtest_config.channels,
1314 # create a new set of log files for every test
1315 log_basename = self.getLogBasenameForCurrentTest()
1316
1317 # confirm that the file is writeable
1318 host_log_path = "{}-host.log".format(log_basename)
1319 open(host_log_path, 'w').close()
1320
1321 log_enable = "log enable -Tpn -f {} ".format(host_log_path)
1322 for channel_with_categories in lldbtest_config.channels:
1323 channel_then_categories = channel_with_categories.split(' ', 1)
1324 channel = channel_then_categories[0]
1325 if len(channel_then_categories) > 1:
1326 categories = channel_then_categories[1]
1327 else:
1328 categories = "default"
1329
1330 if channel == "gdb-remote":
1331 # communicate gdb-remote categories to debugserver
1332 os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
1333
1334 self.ci.HandleCommand(log_enable + channel_with_categories, self.res)
1335 if not self.res.Succeeded():
1336 raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
1337
1338 # Communicate log path name to debugserver & lldb-server
1339 server_log_path = "{}-server.log".format(log_basename)
1340 open(server_log_path, 'w').close()
1341 os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
1342
1343 # Communicate channels to lldb-server
1344 os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
1345
1346 if len(lldbtest_config.channels) == 0:
1347 return
1348
1349 def disableLogChannelsForCurrentTest(self):
1350 # close all log files that we opened
1351 for channel_and_categories in lldbtest_config.channels:
1352 # channel format - <channel-name> [<category0> [<category1> ...]]
1353 channel = channel_and_categories.split(' ', 1)[0]
1354 self.ci.HandleCommand("log disable " + channel, self.res)
1355 if not self.res.Succeeded():
1356 raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
1357
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001358 def setUp(self):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001359 """Fixture for unittest test case setup.
1360
1361 It works with the test driver to conditionally skip tests and does other
1362 initializations."""
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001363 #import traceback
1364 #traceback.print_stack()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001365
Daniel Malea9115f072013-08-06 15:02:32 +00001366 if "LIBCXX_PATH" in os.environ:
1367 self.libcxxPath = os.environ["LIBCXX_PATH"]
1368 else:
1369 self.libcxxPath = None
1370
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001371 if "LLDBMI_EXEC" in os.environ:
1372 self.lldbMiExec = os.environ["LLDBMI_EXEC"]
1373 else:
1374 self.lldbMiExec = None
1375 self.dont_do_lldbmi_test = True
Vince Harron790d95c2015-05-18 19:39:03 +00001376
Johnny Chenebe51722011-10-07 19:21:09 +00001377 # If we spawn an lldb process for test (via pexpect), do not load the
1378 # init file unless told otherwise.
1379 if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
1380 self.lldbOption = ""
1381 else:
1382 self.lldbOption = "--no-lldbinit"
Johnny Chenaaa82ff2011-08-02 22:54:37 +00001383
Johnny Chen985e7402011-08-01 21:13:26 +00001384 # Assign the test method name to self.testMethodName.
1385 #
1386 # For an example of the use of this attribute, look at test/types dir.
1387 # There are a bunch of test cases under test/types and we don't want the
1388 # module cacheing subsystem to be confused with executable name "a.out"
1389 # used for all the test cases.
1390 self.testMethodName = self._testMethodName
1391
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001392 # Python API only test is decorated with @python_api_test,
1393 # which also sets the "__python_api_test__" attribute of the
1394 # function object to True.
Johnny Chen4533dad2011-05-31 23:21:42 +00001395 try:
1396 if lldb.just_do_python_api_test:
1397 testMethod = getattr(self, self._testMethodName)
1398 if getattr(testMethod, "__python_api_test__", False):
1399 pass
1400 else:
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001401 self.skipTest("non python api test")
1402 except AttributeError:
1403 pass
1404
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001405 # lldb-mi only test is decorated with @lldbmi_test,
1406 # which also sets the "__lldbmi_test__" attribute of the
1407 # function object to True.
1408 try:
1409 if lldb.just_do_lldbmi_test:
1410 testMethod = getattr(self, self._testMethodName)
1411 if getattr(testMethod, "__lldbmi_test__", False):
1412 pass
1413 else:
1414 self.skipTest("non lldb-mi test")
1415 except AttributeError:
1416 pass
1417
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001418 # Benchmarks test is decorated with @benchmarks_test,
1419 # which also sets the "__benchmarks_test__" attribute of the
1420 # function object to True.
1421 try:
1422 if lldb.just_do_benchmarks_test:
1423 testMethod = getattr(self, self._testMethodName)
1424 if getattr(testMethod, "__benchmarks_test__", False):
1425 pass
1426 else:
1427 self.skipTest("non benchmarks test")
Johnny Chen4533dad2011-05-31 23:21:42 +00001428 except AttributeError:
1429 pass
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001430
Johnny Chen985e7402011-08-01 21:13:26 +00001431 # This is for the case of directly spawning 'lldb'/'gdb' and interacting
1432 # with it using pexpect.
1433 self.child = None
1434 self.child_prompt = "(lldb) "
1435 # If the child is interacting with the embedded script interpreter,
1436 # there are two exits required during tear down, first to quit the
1437 # embedded script interpreter and second to quit the lldb command
1438 # interpreter.
1439 self.child_in_script_interpreter = False
1440
Johnny Chenfb4264c2011-08-01 19:50:58 +00001441 # These are for customized teardown cleanup.
1442 self.dict = None
1443 self.doTearDownCleanup = False
1444 # And in rare cases where there are multiple teardown cleanups.
1445 self.dicts = []
1446 self.doTearDownCleanups = False
1447
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001448 # List of spawned subproces.Popen objects
1449 self.subprocesses = []
1450
Daniel Malea69207462013-06-05 21:07:02 +00001451 # List of forked process PIDs
1452 self.forkedProcessPids = []
1453
Johnny Chenfb4264c2011-08-01 19:50:58 +00001454 # Create a string buffer to record the session info, to be dumped into a
1455 # test case specific file if test failure is encountered.
Vince Harron1f160372015-05-21 18:51:20 +00001456 self.log_basename = self.getLogBasenameForCurrentTest()
Vince Harron35b17dc2015-05-21 18:20:21 +00001457
Vince Harron1f160372015-05-21 18:51:20 +00001458 session_file = "{}.log".format(self.log_basename)
Vince Harron35b17dc2015-05-21 18:20:21 +00001459 unbuffered = 0 # 0 is the constant for unbuffered
Vince Harron1f160372015-05-21 18:51:20 +00001460 self.session = open(session_file, "w", unbuffered)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001461
1462 # Optimistically set __errored__, __failed__, __expected__ to False
1463 # initially. If the test errored/failed, the session info
1464 # (self.session) is then dumped into a session specific file for
1465 # diagnosis.
Zachary Turnerb1490b62015-08-26 19:44:56 +00001466 self.__cleanup_errored__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001467 self.__errored__ = False
1468 self.__failed__ = False
1469 self.__expected__ = False
1470 # We are also interested in unexpected success.
1471 self.__unexpected__ = False
Johnny Chenf79b0762011-08-16 00:48:58 +00001472 # And skipped tests.
1473 self.__skipped__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001474
1475 # See addTearDownHook(self, hook) which allows the client to add a hook
1476 # function to be run during tearDown() time.
1477 self.hooks = []
1478
1479 # See HideStdout(self).
1480 self.sys_stdout_hidden = False
1481
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001482 if self.platformContext:
1483 # set environment variable names for finding shared libraries
1484 self.dylibPath = self.platformContext.shlib_environment_var
Daniel Malea179ff292012-11-26 21:21:11 +00001485
Vince Harron6d3d0f12015-05-10 22:01:59 +00001486 # Create the debugger instance if necessary.
1487 try:
1488 self.dbg = lldb.DBG
1489 except AttributeError:
1490 self.dbg = lldb.SBDebugger.Create()
1491
1492 if not self.dbg:
1493 raise Exception('Invalid debugger instance')
1494
1495 # Retrieve the associated command interpreter instance.
1496 self.ci = self.dbg.GetCommandInterpreter()
1497 if not self.ci:
1498 raise Exception('Could not get the command interpreter')
1499
1500 # And the result object.
1501 self.res = lldb.SBCommandReturnObject()
1502
1503 self.enableLogChannelsForCurrentTest()
1504
Johnny Chen2a808582011-10-19 16:48:07 +00001505 def runHooks(self, child=None, child_prompt=None, use_cmd_api=False):
Johnny Chena737ba52011-10-19 01:06:21 +00001506 """Perform the run hooks to bring lldb debugger to the desired state.
1507
Johnny Chen2a808582011-10-19 16:48:07 +00001508 By default, expect a pexpect spawned child and child prompt to be
1509 supplied (use_cmd_api=False). If use_cmd_api is true, ignore the child
1510 and child prompt and use self.runCmd() to run the hooks one by one.
1511
Johnny Chena737ba52011-10-19 01:06:21 +00001512 Note that child is a process spawned by pexpect.spawn(). If not, your
1513 test case is mostly likely going to fail.
1514
1515 See also dotest.py where lldb.runHooks are processed/populated.
1516 """
1517 if not lldb.runHooks:
1518 self.skipTest("No runhooks specified for lldb, skip the test")
Johnny Chen2a808582011-10-19 16:48:07 +00001519 if use_cmd_api:
1520 for hook in lldb.runhooks:
1521 self.runCmd(hook)
1522 else:
1523 if not child or not child_prompt:
1524 self.fail("Both child and child_prompt need to be defined.")
1525 for hook in lldb.runHooks:
1526 child.sendline(hook)
1527 child.expect_exact(child_prompt)
Johnny Chena737ba52011-10-19 01:06:21 +00001528
Daniel Malea249287a2013-02-19 16:08:57 +00001529 def setAsync(self, value):
1530 """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
1531 old_async = self.dbg.GetAsync()
1532 self.dbg.SetAsync(value)
1533 self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
1534
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001535 def cleanupSubprocesses(self):
1536 # Ensure any subprocesses are cleaned up
1537 for p in self.subprocesses:
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001538 p.terminate()
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001539 del p
1540 del self.subprocesses[:]
Daniel Malea69207462013-06-05 21:07:02 +00001541 # Ensure any forked processes are cleaned up
1542 for pid in self.forkedProcessPids:
1543 if os.path.exists("/proc/" + str(pid)):
1544 os.kill(pid, signal.SIGTERM)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001545
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001546 def spawnSubprocess(self, executable, args=[], install_remote=True):
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001547 """ Creates a subprocess.Popen object with the specified executable and arguments,
1548 saves it in self.subprocesses, and returns the object.
1549 NOTE: if using this function, ensure you also call:
1550
1551 self.addTearDownHook(self.cleanupSubprocesses)
1552
1553 otherwise the test suite will leak processes.
1554 """
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001555 proc = _RemoteProcess(install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001556 proc.launch(executable, args)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001557 self.subprocesses.append(proc)
1558 return proc
1559
Daniel Malea69207462013-06-05 21:07:02 +00001560 def forkSubprocess(self, executable, args=[]):
1561 """ Fork a subprocess with its own group ID.
1562 NOTE: if using this function, ensure you also call:
1563
1564 self.addTearDownHook(self.cleanupSubprocesses)
1565
1566 otherwise the test suite will leak processes.
1567 """
1568 child_pid = os.fork()
1569 if child_pid == 0:
1570 # If more I/O support is required, this can be beefed up.
1571 fd = os.open(os.devnull, os.O_RDWR)
Daniel Malea69207462013-06-05 21:07:02 +00001572 os.dup2(fd, 1)
1573 os.dup2(fd, 2)
1574 # This call causes the child to have its of group ID
1575 os.setpgid(0,0)
1576 os.execvp(executable, [executable] + args)
1577 # Give the child time to get through the execvp() call
1578 time.sleep(0.1)
1579 self.forkedProcessPids.append(child_pid)
1580 return child_pid
1581
Johnny Chenfb4264c2011-08-01 19:50:58 +00001582 def HideStdout(self):
1583 """Hide output to stdout from the user.
1584
1585 During test execution, there might be cases where we don't want to show the
1586 standard output to the user. For example,
1587
1588 self.runCmd(r'''sc print "\n\n\tHello!\n"''')
1589
1590 tests whether command abbreviation for 'script' works or not. There is no
1591 need to show the 'Hello' output to the user as long as the 'script' command
1592 succeeds and we are not in TraceOn() mode (see the '-t' option).
1593
1594 In this case, the test method calls self.HideStdout(self) to redirect the
1595 sys.stdout to a null device, and restores the sys.stdout upon teardown.
1596
1597 Note that you should only call this method at most once during a test case
1598 execution. Any subsequent call has no effect at all."""
1599 if self.sys_stdout_hidden:
1600 return
1601
1602 self.sys_stdout_hidden = True
1603 old_stdout = sys.stdout
1604 sys.stdout = open(os.devnull, 'w')
1605 def restore_stdout():
1606 sys.stdout = old_stdout
1607 self.addTearDownHook(restore_stdout)
1608
1609 # =======================================================================
1610 # Methods for customized teardown cleanups as well as execution of hooks.
1611 # =======================================================================
1612
1613 def setTearDownCleanup(self, dictionary=None):
1614 """Register a cleanup action at tearDown() time with a dictinary"""
1615 self.dict = dictionary
1616 self.doTearDownCleanup = True
1617
1618 def addTearDownCleanup(self, dictionary):
1619 """Add a cleanup action at tearDown() time with a dictinary"""
1620 self.dicts.append(dictionary)
1621 self.doTearDownCleanups = True
1622
1623 def addTearDownHook(self, hook):
1624 """
1625 Add a function to be run during tearDown() time.
1626
1627 Hooks are executed in a first come first serve manner.
1628 """
1629 if callable(hook):
1630 with recording(self, traceAlways) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00001631 print("Adding tearDown hook:", getsource_if_available(hook), file=sbuf)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001632 self.hooks.append(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001633
1634 return self
Johnny Chenfb4264c2011-08-01 19:50:58 +00001635
Jim Inghamda3a3862014-10-16 23:02:14 +00001636 def deletePexpectChild(self):
Johnny Chen985e7402011-08-01 21:13:26 +00001637 # This is for the case of directly spawning 'lldb' and interacting with it
1638 # using pexpect.
Johnny Chen985e7402011-08-01 21:13:26 +00001639 if self.child and self.child.isalive():
Zachary Turner9ef307b2014-07-22 16:19:29 +00001640 import pexpect
Johnny Chen985e7402011-08-01 21:13:26 +00001641 with recording(self, traceAlways) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00001642 print("tearing down the child process....", file=sbuf)
Johnny Chen985e7402011-08-01 21:13:26 +00001643 try:
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001644 if self.child_in_script_interpreter:
1645 self.child.sendline('quit()')
1646 self.child.expect_exact(self.child_prompt)
1647 self.child.sendline('settings set interpreter.prompt-on-quit false')
1648 self.child.sendline('quit')
Johnny Chen985e7402011-08-01 21:13:26 +00001649 self.child.expect(pexpect.EOF)
Ilia K47448c22015-02-11 21:41:58 +00001650 except (ValueError, pexpect.ExceptionPexpect):
1651 # child is already terminated
1652 pass
1653 except OSError as exception:
1654 import errno
1655 if exception.errno != errno.EIO:
1656 # unexpected error
1657 raise
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001658 # child is already terminated
Johnny Chen985e7402011-08-01 21:13:26 +00001659 pass
Shawn Besteb3e9052014-11-06 17:52:15 +00001660 finally:
1661 # Give it one final blow to make sure the child is terminated.
1662 self.child.close()
Jim Inghamda3a3862014-10-16 23:02:14 +00001663
1664 def tearDown(self):
1665 """Fixture for unittest test case teardown."""
1666 #import traceback
1667 #traceback.print_stack()
1668
1669 self.deletePexpectChild()
1670
Johnny Chenfb4264c2011-08-01 19:50:58 +00001671 # Check and run any hook functions.
1672 for hook in reversed(self.hooks):
1673 with recording(self, traceAlways) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00001674 print("Executing tearDown hook:", getsource_if_available(hook), file=sbuf)
Enrico Granataab0e8312014-11-05 21:31:57 +00001675 import inspect
1676 hook_argc = len(inspect.getargspec(hook).args)
Enrico Granata6e0566c2014-11-17 19:00:20 +00001677 if hook_argc == 0 or getattr(hook,'im_self',None):
Enrico Granataab0e8312014-11-05 21:31:57 +00001678 hook()
1679 elif hook_argc == 1:
1680 hook(self)
1681 else:
1682 hook() # try the plain call and hope it works
Johnny Chenfb4264c2011-08-01 19:50:58 +00001683
1684 del self.hooks
1685
1686 # Perform registered teardown cleanup.
1687 if doCleanup and self.doTearDownCleanup:
Johnny Chen0fddfb22011-11-17 19:57:27 +00001688 self.cleanup(dictionary=self.dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001689
1690 # In rare cases where there are multiple teardown cleanups added.
1691 if doCleanup and self.doTearDownCleanups:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001692 if self.dicts:
1693 for dict in reversed(self.dicts):
Johnny Chen0fddfb22011-11-17 19:57:27 +00001694 self.cleanup(dictionary=dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001695
Vince Harron9753dd92015-05-10 15:22:09 +00001696 self.disableLogChannelsForCurrentTest()
1697
Johnny Chenfb4264c2011-08-01 19:50:58 +00001698 # =========================================================
1699 # Various callbacks to allow introspection of test progress
1700 # =========================================================
1701
1702 def markError(self):
1703 """Callback invoked when an error (unexpected exception) errored."""
1704 self.__errored__ = True
1705 with recording(self, False) as sbuf:
1706 # False because there's no need to write "ERROR" to the stderr twice.
1707 # Once by the Python unittest framework, and a second time by us.
Zachary Turnerff890da2015-10-19 23:45:41 +00001708 print("ERROR", file=sbuf)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001709
Zachary Turnerb1490b62015-08-26 19:44:56 +00001710 def markCleanupError(self):
1711 """Callback invoked when an error occurs while a test is cleaning up."""
1712 self.__cleanup_errored__ = True
1713 with recording(self, False) as sbuf:
1714 # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
1715 # Once by the Python unittest framework, and a second time by us.
Zachary Turnerff890da2015-10-19 23:45:41 +00001716 print("CLEANUP_ERROR", file=sbuf)
Zachary Turnerb1490b62015-08-26 19:44:56 +00001717
Johnny Chenfb4264c2011-08-01 19:50:58 +00001718 def markFailure(self):
1719 """Callback invoked when a failure (test assertion failure) occurred."""
1720 self.__failed__ = True
1721 with recording(self, False) as sbuf:
1722 # False because there's no need to write "FAIL" to the stderr twice.
1723 # Once by the Python unittest framework, and a second time by us.
Zachary Turnerff890da2015-10-19 23:45:41 +00001724 print("FAIL", file=sbuf)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001725
Enrico Granatae6cedc12013-02-23 01:05:23 +00001726 def markExpectedFailure(self,err,bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001727 """Callback invoked when an expected failure/error occurred."""
1728 self.__expected__ = True
1729 with recording(self, False) as sbuf:
1730 # False because there's no need to write "expected failure" to the
1731 # stderr twice.
1732 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001733 if bugnumber == None:
Zachary Turnerff890da2015-10-19 23:45:41 +00001734 print("expected failure", file=sbuf)
Enrico Granatae6cedc12013-02-23 01:05:23 +00001735 else:
Zachary Turnerff890da2015-10-19 23:45:41 +00001736 print("expected failure (problem id:" + str(bugnumber) + ")", file=sbuf)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001737
Johnny Chenc5cc6252011-08-15 23:09:08 +00001738 def markSkippedTest(self):
1739 """Callback invoked when a test is skipped."""
1740 self.__skipped__ = True
1741 with recording(self, False) as sbuf:
1742 # False because there's no need to write "skipped test" to the
1743 # stderr twice.
1744 # Once by the Python unittest framework, and a second time by us.
Zachary Turnerff890da2015-10-19 23:45:41 +00001745 print("skipped test", file=sbuf)
Johnny Chenc5cc6252011-08-15 23:09:08 +00001746
Enrico Granatae6cedc12013-02-23 01:05:23 +00001747 def markUnexpectedSuccess(self, bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001748 """Callback invoked when an unexpected success occurred."""
1749 self.__unexpected__ = True
1750 with recording(self, False) as sbuf:
1751 # False because there's no need to write "unexpected success" to the
1752 # stderr twice.
1753 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001754 if bugnumber == None:
Zachary Turnerff890da2015-10-19 23:45:41 +00001755 print("unexpected success", file=sbuf)
Enrico Granatae6cedc12013-02-23 01:05:23 +00001756 else:
Zachary Turnerff890da2015-10-19 23:45:41 +00001757 print("unexpected success (problem id:" + str(bugnumber) + ")", file=sbuf)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001758
Greg Clayton70995582015-01-07 22:25:50 +00001759 def getRerunArgs(self):
1760 return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
Vince Harron9753dd92015-05-10 15:22:09 +00001761
1762 def getLogBasenameForCurrentTest(self, prefix=None):
1763 """
1764 returns a partial path that can be used as the beginning of the name of multiple
1765 log files pertaining to this test
1766
1767 <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
1768 """
1769 dname = os.path.join(os.environ["LLDB_TEST"],
1770 os.environ["LLDB_SESSION_DIRNAME"])
1771 if not os.path.isdir(dname):
1772 os.mkdir(dname)
1773
1774 compiler = self.getCompiler()
1775
1776 if compiler[1] == ':':
1777 compiler = compiler[2:]
Chaoren Lin636a0e32015-07-17 21:40:11 +00001778 if os.path.altsep is not None:
1779 compiler = compiler.replace(os.path.altsep, os.path.sep)
Vince Harron9753dd92015-05-10 15:22:09 +00001780
Vince Harron19e300f2015-05-12 00:50:54 +00001781 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
Vince Harron9753dd92015-05-10 15:22:09 +00001782 if len(fname) > 200:
Vince Harron19e300f2015-05-12 00:50:54 +00001783 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
Vince Harron9753dd92015-05-10 15:22:09 +00001784
1785 if prefix is not None:
1786 fname = "{}-{}".format(prefix, fname)
1787
1788 return os.path.join(dname, fname)
1789
Johnny Chenfb4264c2011-08-01 19:50:58 +00001790 def dumpSessionInfo(self):
1791 """
1792 Dump the debugger interactions leading to a test error/failure. This
1793 allows for more convenient postmortem analysis.
1794
1795 See also LLDBTestResult (dotest.py) which is a singlton class derived
1796 from TextTestResult and overwrites addError, addFailure, and
1797 addExpectedFailure methods to allow us to to mark the test instance as
1798 such.
1799 """
1800
1801 # We are here because self.tearDown() detected that this test instance
1802 # either errored or failed. The lldb.test_result singleton contains
1803 # two lists (erros and failures) which get populated by the unittest
1804 # framework. Look over there for stack trace information.
1805 #
1806 # The lists contain 2-tuples of TestCase instances and strings holding
1807 # formatted tracebacks.
1808 #
1809 # See http://docs.python.org/library/unittest.html#unittest.TestResult.
Vince Harron9753dd92015-05-10 15:22:09 +00001810
Vince Harron35b17dc2015-05-21 18:20:21 +00001811 # output tracebacks into session
Vince Harron9753dd92015-05-10 15:22:09 +00001812 pairs = []
Johnny Chenfb4264c2011-08-01 19:50:58 +00001813 if self.__errored__:
1814 pairs = lldb.test_result.errors
1815 prefix = 'Error'
Zachary Turner14181db2015-09-11 21:27:37 +00001816 elif self.__cleanup_errored__:
Zachary Turnerb1490b62015-08-26 19:44:56 +00001817 pairs = lldb.test_result.cleanup_errors
1818 prefix = 'CleanupError'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001819 elif self.__failed__:
1820 pairs = lldb.test_result.failures
1821 prefix = 'Failure'
1822 elif self.__expected__:
1823 pairs = lldb.test_result.expectedFailures
1824 prefix = 'ExpectedFailure'
Johnny Chenc5cc6252011-08-15 23:09:08 +00001825 elif self.__skipped__:
1826 prefix = 'SkippedTest'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001827 elif self.__unexpected__:
Vince Harron35b17dc2015-05-21 18:20:21 +00001828 prefix = 'UnexpectedSuccess'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001829 else:
Vince Harron35b17dc2015-05-21 18:20:21 +00001830 prefix = 'Success'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001831
Johnny Chenc5cc6252011-08-15 23:09:08 +00001832 if not self.__unexpected__ and not self.__skipped__:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001833 for test, traceback in pairs:
1834 if test is self:
Zachary Turnerff890da2015-10-19 23:45:41 +00001835 print(traceback, file=self.session)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001836
Vince Harron35b17dc2015-05-21 18:20:21 +00001837 # put footer (timestamp/rerun instructions) into session
Johnny Chen8082a002011-08-11 00:16:28 +00001838 testMethod = getattr(self, self._testMethodName)
1839 if getattr(testMethod, "__benchmarks_test__", False):
1840 benchmarks = True
1841 else:
1842 benchmarks = False
1843
Vince Harron35b17dc2015-05-21 18:20:21 +00001844 import datetime
Zachary Turnerff890da2015-10-19 23:45:41 +00001845 print("Session info generated @", datetime.datetime.now().ctime(), file=self.session)
1846 print("To rerun this test, issue the following command from the 'test' directory:\n", file=self.session)
1847 print("./dotest.py %s -v %s %s" % (self.getRunOptions(),
Vince Harron35b17dc2015-05-21 18:20:21 +00001848 ('+b' if benchmarks else '-t'),
Zachary Turnerff890da2015-10-19 23:45:41 +00001849 self.getRerunArgs()), file=self.session)
Vince Harron35b17dc2015-05-21 18:20:21 +00001850 self.session.close()
1851 del self.session
1852
1853 # process the log files
Vince Harron1f160372015-05-21 18:51:20 +00001854 log_files_for_this_test = glob.glob(self.log_basename + "*")
Vince Harron35b17dc2015-05-21 18:20:21 +00001855
1856 if prefix != 'Success' or lldbtest_config.log_success:
1857 # keep all log files, rename them to include prefix
1858 dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1859 for src in log_files_for_this_test:
Zachary Turner306278f2015-05-26 20:26:29 +00001860 if os.path.isfile(src):
1861 dst = src.replace(self.log_basename, dst_log_basename)
1862 if os.name == "nt" and os.path.isfile(dst):
1863 # On Windows, renaming a -> b will throw an exception if b exists. On non-Windows platforms
1864 # it silently replaces the destination. Ultimately this means that atomic renames are not
1865 # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
1866 # destination first if it already exists.
1867 os.remove(dst)
Zachary Turner5de068b2015-05-26 19:52:24 +00001868
Zachary Turner306278f2015-05-26 20:26:29 +00001869 os.rename(src, dst)
Vince Harron35b17dc2015-05-21 18:20:21 +00001870 else:
1871 # success! (and we don't want log files) delete log files
1872 for log_file in log_files_for_this_test:
Adrian McCarthya7292042015-09-04 20:48:48 +00001873 try:
1874 os.unlink(log_file)
1875 except:
1876 # We've seen consistent unlink failures on Windows, perhaps because the
1877 # just-created log file is being scanned by anti-virus. Empirically, this
1878 # sleep-and-retry approach allows tests to succeed much more reliably.
1879 # Attempts to figure out exactly what process was still holding a file handle
1880 # have failed because running instrumentation like Process Monitor seems to
1881 # slow things down enough that the problem becomes much less consistent.
1882 time.sleep(0.5)
1883 os.unlink(log_file)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001884
1885 # ====================================================
1886 # Config. methods supported through a plugin interface
1887 # (enables reading of the current test configuration)
1888 # ====================================================
1889
1890 def getArchitecture(self):
1891 """Returns the architecture in effect the test suite is running with."""
1892 module = builder_module()
Ed Maste0f434e62015-04-06 15:50:48 +00001893 arch = module.getArchitecture()
1894 if arch == 'amd64':
1895 arch = 'x86_64'
1896 return arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00001897
Vince Harron02613762015-05-04 00:17:53 +00001898 def getLldbArchitecture(self):
1899 """Returns the architecture of the lldb binary."""
1900 if not hasattr(self, 'lldbArchitecture'):
1901
1902 # spawn local process
1903 command = [
Vince Harron790d95c2015-05-18 19:39:03 +00001904 lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001905 "-o",
Vince Harron790d95c2015-05-18 19:39:03 +00001906 "file " + lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001907 "-o",
1908 "quit"
1909 ]
1910
1911 output = check_output(command)
1912 str = output.decode("utf-8");
1913
1914 for line in str.splitlines():
1915 m = re.search("Current executable set to '.*' \\((.*)\\)\\.", line)
1916 if m:
1917 self.lldbArchitecture = m.group(1)
1918 break
1919
1920 return self.lldbArchitecture
1921
Johnny Chenfb4264c2011-08-01 19:50:58 +00001922 def getCompiler(self):
1923 """Returns the compiler in effect the test suite is running with."""
1924 module = builder_module()
1925 return module.getCompiler()
1926
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001927 def getCompilerBinary(self):
1928 """Returns the compiler binary the test suite is running with."""
1929 return self.getCompiler().split()[0]
1930
Daniel Malea0aea0162013-02-27 17:29:46 +00001931 def getCompilerVersion(self):
1932 """ Returns a string that represents the compiler version.
1933 Supports: llvm, clang.
1934 """
1935 from lldbutil import which
1936 version = 'unknown'
1937
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001938 compiler = self.getCompilerBinary()
Zachary Turner9ef307b2014-07-22 16:19:29 +00001939 version_output = system([[which(compiler), "-v"]])[1]
Daniel Malea0aea0162013-02-27 17:29:46 +00001940 for line in version_output.split(os.linesep):
Greg Clayton2a844b72013-03-06 02:34:51 +00001941 m = re.search('version ([0-9\.]+)', line)
Daniel Malea0aea0162013-02-27 17:29:46 +00001942 if m:
1943 version = m.group(1)
1944 return version
1945
Ryan Brown57bee1e2015-09-14 22:45:11 +00001946 def getGoCompilerVersion(self):
1947 """ Returns a string that represents the go compiler version, or None if go is not found.
1948 """
1949 compiler = which("go")
1950 if compiler:
1951 version_output = system([[compiler, "version"]])[0]
1952 for line in version_output.split(os.linesep):
1953 m = re.search('go version (devel|go\\S+)', line)
1954 if m:
1955 return m.group(1)
1956 return None
1957
Greg Claytone0d0a762015-04-02 18:24:03 +00001958 def platformIsDarwin(self):
1959 """Returns true if the OS triple for the selected platform is any valid apple OS"""
Robert Flackfb2f6c62015-04-17 08:02:18 +00001960 return platformIsDarwin()
Vince Harron20952cc2015-04-03 01:00:06 +00001961
Robert Flack13c7ad92015-03-30 14:12:17 +00001962 def getPlatform(self):
Robert Flackfb2f6c62015-04-17 08:02:18 +00001963 """Returns the target platform the test suite is running on."""
Robert Flack068898c2015-04-09 18:07:58 +00001964 return getPlatform()
Robert Flack13c7ad92015-03-30 14:12:17 +00001965
Daniel Maleaadaaec92013-08-06 20:51:41 +00001966 def isIntelCompiler(self):
1967 """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1968 return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1969
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001970 def expectedCompilerVersion(self, compiler_version):
1971 """Returns True iff compiler_version[1] matches the current compiler version.
1972 Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1973 Any operator other than the following defaults to an equality test:
1974 '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1975 """
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001976 if (compiler_version == None):
1977 return True
1978 operator = str(compiler_version[0])
1979 version = compiler_version[1]
1980
1981 if (version == None):
1982 return True
1983 if (operator == '>'):
1984 return self.getCompilerVersion() > version
1985 if (operator == '>=' or operator == '=>'):
1986 return self.getCompilerVersion() >= version
1987 if (operator == '<'):
1988 return self.getCompilerVersion() < version
1989 if (operator == '<=' or operator == '=<'):
1990 return self.getCompilerVersion() <= version
1991 if (operator == '!=' or operator == '!' or operator == 'not'):
1992 return str(version) not in str(self.getCompilerVersion())
1993 return str(version) in str(self.getCompilerVersion())
1994
1995 def expectedCompiler(self, compilers):
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001996 """Returns True iff any element of compilers is a sub-string of the current compiler."""
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001997 if (compilers == None):
1998 return True
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001999
2000 for compiler in compilers:
2001 if compiler in self.getCompiler():
2002 return True
2003
2004 return False
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00002005
Ying Chen7091c2c2015-04-21 01:15:47 +00002006 def expectedArch(self, archs):
2007 """Returns True iff any element of archs is a sub-string of the current architecture."""
2008 if (archs == None):
2009 return True
2010
2011 for arch in archs:
2012 if arch in self.getArchitecture():
2013 return True
2014
2015 return False
2016
Johnny Chenfb4264c2011-08-01 19:50:58 +00002017 def getRunOptions(self):
2018 """Command line option for -A and -C to run this test again, called from
2019 self.dumpSessionInfo()."""
2020 arch = self.getArchitecture()
2021 comp = self.getCompiler()
Johnny Chenb7bdd102011-08-24 19:48:51 +00002022 if arch:
2023 option_str = "-A " + arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00002024 else:
Johnny Chenb7bdd102011-08-24 19:48:51 +00002025 option_str = ""
2026 if comp:
Johnny Chen531c0852012-03-16 20:44:00 +00002027 option_str += " -C " + comp
Johnny Chenb7bdd102011-08-24 19:48:51 +00002028 return option_str
Johnny Chenfb4264c2011-08-01 19:50:58 +00002029
2030 # ==================================================
2031 # Build methods supported through a plugin interface
2032 # ==================================================
2033
Ed Mastec97323e2014-04-01 18:47:58 +00002034 def getstdlibFlag(self):
2035 """ Returns the proper -stdlib flag, or empty if not required."""
Robert Flack4629c4b2015-05-15 18:54:32 +00002036 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Ed Mastec97323e2014-04-01 18:47:58 +00002037 stdlibflag = "-stdlib=libc++"
2038 else:
2039 stdlibflag = ""
2040 return stdlibflag
2041
Matt Kopec7663b3a2013-09-25 17:44:00 +00002042 def getstdFlag(self):
2043 """ Returns the proper stdflag. """
Daniel Malea55faa402013-05-02 21:44:31 +00002044 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
Daniel Malea0b7c6112013-05-06 19:31:31 +00002045 stdflag = "-std=c++0x"
Daniel Malea55faa402013-05-02 21:44:31 +00002046 else:
2047 stdflag = "-std=c++11"
Matt Kopec7663b3a2013-09-25 17:44:00 +00002048 return stdflag
2049
2050 def buildDriver(self, sources, exe_name):
2051 """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
2052 or LLDB.framework).
2053 """
2054
2055 stdflag = self.getstdFlag()
Ed Mastec97323e2014-04-01 18:47:58 +00002056 stdlibflag = self.getstdlibFlag()
Daniel Malea55faa402013-05-02 21:44:31 +00002057
2058 if sys.platform.startswith("darwin"):
2059 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
2060 d = {'CXX_SOURCES' : sources,
2061 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00002062 'CFLAGS_EXTRAS' : "%s %s" % (stdflag, stdlibflag),
Daniel Malea55faa402013-05-02 21:44:31 +00002063 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
Stefanus Du Toit04004442013-07-30 19:19:49 +00002064 'LD_EXTRAS' : "%s -Wl,-rpath,%s" % (dsym, self.lib_dir),
Daniel Malea55faa402013-05-02 21:44:31 +00002065 }
Ed Maste372c24d2013-07-25 21:02:34 +00002066 elif sys.platform.startswith('freebsd') or sys.platform.startswith("linux") or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00002067 d = {'CXX_SOURCES' : sources,
Daniel Malea55faa402013-05-02 21:44:31 +00002068 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00002069 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
Daniel Malea55faa402013-05-02 21:44:31 +00002070 'LD_EXTRAS' : "-L%s -llldb" % self.lib_dir}
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00002071 elif sys.platform.startswith('win'):
2072 d = {'CXX_SOURCES' : sources,
2073 'EXE' : exe_name,
2074 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2075 'LD_EXTRAS' : "-L%s -lliblldb" % self.implib_dir}
Daniel Malea55faa402013-05-02 21:44:31 +00002076 if self.TraceOn():
Zachary Turnerff890da2015-10-19 23:45:41 +00002077 print("Building LLDB Driver (%s) from sources %s" % (exe_name, sources))
Daniel Malea55faa402013-05-02 21:44:31 +00002078
2079 self.buildDefault(dictionary=d)
2080
Matt Kopec7663b3a2013-09-25 17:44:00 +00002081 def buildLibrary(self, sources, lib_name):
2082 """Platform specific way to build a default library. """
2083
2084 stdflag = self.getstdFlag()
2085
Robert Flack4629c4b2015-05-15 18:54:32 +00002086 if self.platformIsDarwin():
Matt Kopec7663b3a2013-09-25 17:44:00 +00002087 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
2088 d = {'DYLIB_CXX_SOURCES' : sources,
2089 'DYLIB_NAME' : lib_name,
2090 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
2091 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
2092 'LD_EXTRAS' : "%s -Wl,-rpath,%s -dynamiclib" % (dsym, self.lib_dir),
2093 }
Robert Flack4629c4b2015-05-15 18:54:32 +00002094 elif self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux' or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
Matt Kopec7663b3a2013-09-25 17:44:00 +00002095 d = {'DYLIB_CXX_SOURCES' : sources,
2096 'DYLIB_NAME' : lib_name,
2097 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2098 'LD_EXTRAS' : "-shared -L%s -llldb" % self.lib_dir}
Robert Flack4629c4b2015-05-15 18:54:32 +00002099 elif self.getPlatform() == 'windows':
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00002100 d = {'DYLIB_CXX_SOURCES' : sources,
2101 'DYLIB_NAME' : lib_name,
2102 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2103 'LD_EXTRAS' : "-shared -l%s\liblldb.lib" % self.implib_dir}
Matt Kopec7663b3a2013-09-25 17:44:00 +00002104 if self.TraceOn():
Zachary Turnerff890da2015-10-19 23:45:41 +00002105 print("Building LLDB Library (%s) from sources %s" % (lib_name, sources))
Matt Kopec7663b3a2013-09-25 17:44:00 +00002106
2107 self.buildDefault(dictionary=d)
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002108
Daniel Malea55faa402013-05-02 21:44:31 +00002109 def buildProgram(self, sources, exe_name):
2110 """ Platform specific way to build an executable from C/C++ sources. """
2111 d = {'CXX_SOURCES' : sources,
2112 'EXE' : exe_name}
2113 self.buildDefault(dictionary=d)
2114
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002115 def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002116 """Platform specific way to build the default binaries."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002117 if lldb.skip_build_and_cleanup:
2118 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002119 module = builder_module()
Chaoren Line9bbabc2015-07-18 00:37:55 +00002120 if target_is_android():
2121 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002122 if not module.buildDefault(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002123 raise Exception("Don't know how to build default binary")
2124
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002125 def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002126 """Platform specific way to build binaries with dsym info."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002127 if lldb.skip_build_and_cleanup:
2128 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002129 module = builder_module()
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002130 if not module.buildDsym(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002131 raise Exception("Don't know how to build binary with dsym")
2132
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002133 def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002134 """Platform specific way to build binaries with dwarf maps."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002135 if lldb.skip_build_and_cleanup:
2136 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002137 module = builder_module()
Chaoren Lin9070f532015-07-17 22:13:29 +00002138 if target_is_android():
Chaoren Line9bbabc2015-07-18 00:37:55 +00002139 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002140 if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002141 raise Exception("Don't know how to build binary with dwarf")
Johnny Chena74bb0a2011-08-01 18:46:13 +00002142
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +00002143 def buildDwo(self, architecture=None, compiler=None, dictionary=None, clean=True):
2144 """Platform specific way to build binaries with dwarf maps."""
2145 if lldb.skip_build_and_cleanup:
2146 return
2147 module = builder_module()
2148 if target_is_android():
2149 dictionary = append_android_envs(dictionary)
2150 if not module.buildDwo(self, architecture, compiler, dictionary, clean):
2151 raise Exception("Don't know how to build binary with dwo")
2152
Ryan Brown57bee1e2015-09-14 22:45:11 +00002153 def buildGo(self):
2154 """Build the default go binary.
2155 """
2156 system([[which('go'), 'build -gcflags "-N -l" -o a.out main.go']])
2157
Oleksiy Vyalov49b71c62015-01-22 20:03:21 +00002158 def signBinary(self, binary_path):
2159 if sys.platform.startswith("darwin"):
2160 codesign_cmd = "codesign --force --sign lldb_codesign %s" % (binary_path)
2161 call(codesign_cmd, shell=True)
2162
Kuba Breckabeed8212014-09-04 01:03:18 +00002163 def findBuiltClang(self):
2164 """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
2165 paths_to_try = [
2166 "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
2167 "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
2168 "llvm-build/Release/x86_64/Release/bin/clang",
2169 "llvm-build/Debug/x86_64/Debug/bin/clang",
2170 ]
2171 lldb_root_path = os.path.join(os.path.dirname(__file__), "..")
2172 for p in paths_to_try:
2173 path = os.path.join(lldb_root_path, p)
2174 if os.path.exists(path):
2175 return path
Ilia Kd9953052015-03-12 07:19:41 +00002176
2177 # Tries to find clang at the same folder as the lldb
Vince Harron790d95c2015-05-18 19:39:03 +00002178 path = os.path.join(os.path.dirname(lldbtest_config.lldbExec), "clang")
Ilia Kd9953052015-03-12 07:19:41 +00002179 if os.path.exists(path):
2180 return path
Kuba Breckabeed8212014-09-04 01:03:18 +00002181
2182 return os.environ["CC"]
2183
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002184 def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False):
Andrew Kaylor93132f52013-05-28 23:04:25 +00002185 """ Returns a dictionary (which can be provided to build* functions above) which
2186 contains OS-specific build flags.
2187 """
2188 cflags = ""
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002189 ldflags = ""
Daniel Malea9115f072013-08-06 15:02:32 +00002190
2191 # On Mac OS X, unless specifically requested to use libstdc++, use libc++
Robert Flack4629c4b2015-05-15 18:54:32 +00002192 if not use_libstdcxx and self.platformIsDarwin():
Daniel Malea9115f072013-08-06 15:02:32 +00002193 use_libcxx = True
2194
2195 if use_libcxx and self.libcxxPath:
2196 cflags += "-stdlib=libc++ "
2197 if self.libcxxPath:
2198 libcxxInclude = os.path.join(self.libcxxPath, "include")
2199 libcxxLib = os.path.join(self.libcxxPath, "lib")
2200 if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
2201 cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (libcxxInclude, libcxxLib, libcxxLib)
2202
Andrew Kaylor93132f52013-05-28 23:04:25 +00002203 if use_cpp11:
2204 cflags += "-std="
2205 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2206 cflags += "c++0x"
2207 else:
2208 cflags += "c++11"
Robert Flack4629c4b2015-05-15 18:54:32 +00002209 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Andrew Kaylor93132f52013-05-28 23:04:25 +00002210 cflags += " -stdlib=libc++"
2211 elif "clang" in self.getCompiler():
2212 cflags += " -stdlib=libstdc++"
2213
Andrew Kaylor93132f52013-05-28 23:04:25 +00002214 return {'CFLAGS_EXTRAS' : cflags,
2215 'LD_EXTRAS' : ldflags,
2216 }
2217
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002218 def cleanup(self, dictionary=None):
2219 """Platform specific way to do cleanup after build."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002220 if lldb.skip_build_and_cleanup:
2221 return
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002222 module = builder_module()
2223 if not module.cleanup(self, dictionary):
Johnny Chen0fddfb22011-11-17 19:57:27 +00002224 raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002225
Daniel Malea55faa402013-05-02 21:44:31 +00002226 def getLLDBLibraryEnvVal(self):
2227 """ Returns the path that the OS-specific library search environment variable
2228 (self.dylibPath) should be set to in order for a program to find the LLDB
2229 library. If an environment variable named self.dylibPath is already set,
2230 the new path is appended to it and returned.
2231 """
2232 existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
2233 if existing_library_path:
2234 return "%s:%s" % (existing_library_path, self.lib_dir)
2235 elif sys.platform.startswith("darwin"):
2236 return os.path.join(self.lib_dir, 'LLDB.framework')
2237 else:
2238 return self.lib_dir
Johnny Chena74bb0a2011-08-01 18:46:13 +00002239
Ed Maste437f8f62013-09-09 14:04:04 +00002240 def getLibcPlusPlusLibs(self):
Robert Flackfa5ad652015-05-13 20:17:34 +00002241 if self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux':
Ed Maste437f8f62013-09-09 14:04:04 +00002242 return ['libc++.so.1']
2243 else:
2244 return ['libc++.1.dylib','libc++abi.dylib']
2245
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002246# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
2247# We change the test methods to create a new test method for each test for each debug info we are
2248# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
2249# the new test method we remove the old method at the same time.
2250class LLDBTestCaseFactory(type):
2251 def __new__(cls, name, bases, attrs):
2252 newattrs = {}
2253 for attrname, attrvalue in attrs.iteritems():
2254 if attrname.startswith("test") and not getattr(attrvalue, "__no_debug_info_test__", False):
2255 @dsym_test
2256 def dsym_test_method(self, attrvalue=attrvalue):
2257 self.debug_info = "dsym"
2258 return attrvalue(self)
2259 dsym_method_name = attrname + "_dsym"
2260 dsym_test_method.__name__ = dsym_method_name
2261 newattrs[dsym_method_name] = dsym_test_method
2262
2263 @dwarf_test
2264 def dwarf_test_method(self, attrvalue=attrvalue):
2265 self.debug_info = "dwarf"
2266 return attrvalue(self)
2267 dwarf_method_name = attrname + "_dwarf"
2268 dwarf_test_method.__name__ = dwarf_method_name
2269 newattrs[dwarf_method_name] = dwarf_test_method
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +00002270
2271 @dwo_test
2272 def dwo_test_method(self, attrvalue=attrvalue):
2273 self.debug_info = "dwo"
2274 return attrvalue(self)
2275 dwo_method_name = attrname + "_dwo"
2276 dwo_test_method.__name__ = dwo_method_name
2277 newattrs[dwo_method_name] = dwo_test_method
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002278 else:
2279 newattrs[attrname] = attrvalue
2280 return super(LLDBTestCaseFactory, cls).__new__(cls, name, bases, newattrs)
2281
Johnny Chena74bb0a2011-08-01 18:46:13 +00002282class TestBase(Base):
2283 """
2284 This abstract base class is meant to be subclassed. It provides default
2285 implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
2286 among other things.
2287
2288 Important things for test class writers:
2289
2290 - Overwrite the mydir class attribute, otherwise your test class won't
2291 run. It specifies the relative directory to the top level 'test' so
2292 the test harness can change to the correct working directory before
2293 running your test.
2294
2295 - The setUp method sets up things to facilitate subsequent interactions
2296 with the debugger as part of the test. These include:
2297 - populate the test method name
2298 - create/get a debugger set with synchronous mode (self.dbg)
2299 - get the command interpreter from with the debugger (self.ci)
2300 - create a result object for use with the command interpreter
2301 (self.res)
2302 - plus other stuffs
2303
2304 - The tearDown method tries to perform some necessary cleanup on behalf
2305 of the test to return the debugger to a good state for the next test.
2306 These include:
2307 - execute any tearDown hooks registered by the test method with
2308 TestBase.addTearDownHook(); examples can be found in
2309 settings/TestSettings.py
2310 - kill the inferior process associated with each target, if any,
2311 and, then delete the target from the debugger's target list
2312 - perform build cleanup before running the next test method in the
2313 same test class; examples of registering for this service can be
2314 found in types/TestIntegerTypes.py with the call:
2315 - self.setTearDownCleanup(dictionary=d)
2316
2317 - Similarly setUpClass and tearDownClass perform classwise setup and
2318 teardown fixtures. The tearDownClass method invokes a default build
2319 cleanup for the entire test class; also, subclasses can implement the
2320 classmethod classCleanup(cls) to perform special class cleanup action.
2321
2322 - The instance methods runCmd and expect are used heavily by existing
2323 test cases to send a command to the command interpreter and to perform
2324 string/pattern matching on the output of such command execution. The
2325 expect method also provides a mode to peform string/pattern matching
2326 without running a command.
2327
2328 - The build methods buildDefault, buildDsym, and buildDwarf are used to
2329 build the binaries used during a particular test scenario. A plugin
2330 should be provided for the sys.platform running the test suite. The
2331 Mac OS X implementation is located in plugins/darwin.py.
2332 """
2333
2334 # Maximum allowed attempts when launching the inferior process.
2335 # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
2336 maxLaunchCount = 3;
2337
2338 # Time to wait before the next launching attempt in second(s).
2339 # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
2340 timeWaitNextLaunch = 1.0;
2341
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002342 # Setup the metaclass for this class to change the list of the test methods when a new class is loaded
2343 __metaclass__ = LLDBTestCaseFactory
2344
Johnny Chena74bb0a2011-08-01 18:46:13 +00002345 def doDelay(self):
2346 """See option -w of dotest.py."""
2347 if ("LLDB_WAIT_BETWEEN_TEST_CASES" in os.environ and
2348 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] == 'YES'):
2349 waitTime = 1.0
2350 if "LLDB_TIME_WAIT_BETWEEN_TEST_CASES" in os.environ:
2351 waitTime = float(os.environ["LLDB_TIME_WAIT_BETWEEN_TEST_CASES"])
2352 time.sleep(waitTime)
2353
Enrico Granata165f8af2012-09-21 19:10:53 +00002354 # Returns the list of categories to which this test case belongs
2355 # by default, look for a ".categories" file, and read its contents
2356 # if no such file exists, traverse the hierarchy - we guarantee
2357 # a .categories to exist at the top level directory so we do not end up
2358 # looping endlessly - subclasses are free to define their own categories
2359 # in whatever way makes sense to them
2360 def getCategories(self):
2361 import inspect
2362 import os.path
2363 folder = inspect.getfile(self.__class__)
2364 folder = os.path.dirname(folder)
2365 while folder != '/':
2366 categories_file_name = os.path.join(folder,".categories")
2367 if os.path.exists(categories_file_name):
2368 categories_file = open(categories_file_name,'r')
2369 categories = categories_file.readline()
2370 categories_file.close()
2371 categories = str.replace(categories,'\n','')
2372 categories = str.replace(categories,'\r','')
2373 return categories.split(',')
2374 else:
2375 folder = os.path.dirname(folder)
2376 continue
2377
Johnny Chena74bb0a2011-08-01 18:46:13 +00002378 def setUp(self):
2379 #import traceback
2380 #traceback.print_stack()
2381
2382 # Works with the test driver to conditionally skip tests via decorators.
2383 Base.setUp(self)
2384
Johnny Chena74bb0a2011-08-01 18:46:13 +00002385 try:
2386 if lldb.blacklist:
2387 className = self.__class__.__name__
2388 classAndMethodName = "%s.%s" % (className, self._testMethodName)
2389 if className in lldb.blacklist:
2390 self.skipTest(lldb.blacklist.get(className))
2391 elif classAndMethodName in lldb.blacklist:
2392 self.skipTest(lldb.blacklist.get(classAndMethodName))
2393 except AttributeError:
2394 pass
2395
Johnny Chened492022011-06-21 00:53:00 +00002396 # Insert some delay between successive test cases if specified.
2397 self.doDelay()
Johnny Chen0ed37c92010-10-07 02:04:14 +00002398
Johnny Chenf2b70232010-08-25 18:49:48 +00002399 if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
2400 self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
2401
Johnny Chen430eb762010-10-19 16:00:42 +00002402 if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
Johnny Chen4921b112010-11-29 20:20:34 +00002403 self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
Johnny Chenf2b70232010-08-25 18:49:48 +00002404
Daniel Maleae0f8f572013-08-26 23:57:52 +00002405 #
2406 # Warning: MAJOR HACK AHEAD!
2407 # If we are running testsuite remotely (by checking lldb.lldbtest_remote_sandbox),
2408 # redefine the self.dbg.CreateTarget(filename) method to execute a "file filename"
2409 # command, instead. See also runCmd() where it decorates the "file filename" call
2410 # with additional functionality when running testsuite remotely.
2411 #
2412 if lldb.lldbtest_remote_sandbox:
2413 def DecoratedCreateTarget(arg):
2414 self.runCmd("file %s" % arg)
2415 target = self.dbg.GetSelectedTarget()
2416 #
Greg Claytonc6947512013-12-13 19:18:59 +00002417 # SBtarget.LaunchSimple () currently not working for remote platform?
Daniel Maleae0f8f572013-08-26 23:57:52 +00002418 # johnny @ 04/23/2012
2419 #
2420 def DecoratedLaunchSimple(argv, envp, wd):
2421 self.runCmd("run")
2422 return target.GetProcess()
2423 target.LaunchSimple = DecoratedLaunchSimple
2424
2425 return target
2426 self.dbg.CreateTarget = DecoratedCreateTarget
2427 if self.TraceOn():
Zachary Turnerff890da2015-10-19 23:45:41 +00002428 print("self.dbg.Create is redefined to:\n%s" % getsource_if_available(DecoratedCreateTarget))
Daniel Maleae0f8f572013-08-26 23:57:52 +00002429
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002430 # We want our debugger to be synchronous.
2431 self.dbg.SetAsync(False)
2432
2433 # Retrieve the associated command interpreter instance.
2434 self.ci = self.dbg.GetCommandInterpreter()
2435 if not self.ci:
2436 raise Exception('Could not get the command interpreter')
2437
2438 # And the result object.
2439 self.res = lldb.SBCommandReturnObject()
2440
Johnny Chen44d24972012-04-16 18:55:15 +00002441 # Run global pre-flight code, if defined via the config file.
2442 if lldb.pre_flight:
2443 lldb.pre_flight(self)
2444
Enrico Granatabd0998a2015-10-02 22:53:32 +00002445 if lldb.remote_platform and lldb.remote_platform_working_dir:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00002446 remote_test_dir = lldbutil.join_remote_paths(
2447 lldb.remote_platform_working_dir,
2448 self.getArchitecture(),
2449 str(self.test_number),
2450 self.mydir)
Greg Claytonfb909312013-11-23 01:58:15 +00002451 error = lldb.remote_platform.MakeDirectory(remote_test_dir, 0700)
2452 if error.Success():
Greg Claytonfb909312013-11-23 01:58:15 +00002453 lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
Tamas Berghammerf2addf82015-10-07 12:38:29 +00002454
Tamas Berghammer11db2d32015-10-07 14:52:16 +00002455 # This function removes all files from the current working directory while leaving
2456 # the directories in place. The cleaup is required to reduce the disk space required
2457 # by the test suit while leaving the directories untached is neccessary because
2458 # sub-directories might belong to an other test
2459 def clean_working_directory():
Tamas Berghammerf2addf82015-10-07 12:38:29 +00002460 # TODO: Make it working on Windows when we need it for remote debugging support
Tamas Berghammer11db2d32015-10-07 14:52:16 +00002461 # TODO: Replace the heuristic to remove the files with a logic what collects the
2462 # list of files we have to remove during test runs.
2463 shell_cmd = lldb.SBPlatformShellCommand("rm %s/*" % remote_test_dir)
Tamas Berghammerf2addf82015-10-07 12:38:29 +00002464 lldb.remote_platform.Run(shell_cmd)
Tamas Berghammer11db2d32015-10-07 14:52:16 +00002465 self.addTearDownHook(clean_working_directory)
Greg Claytonfb909312013-11-23 01:58:15 +00002466 else:
Zachary Turnerff890da2015-10-19 23:45:41 +00002467 print("error: making remote directory '%s': %s" % (remote_test_dir, error))
Greg Claytonfb909312013-11-23 01:58:15 +00002468
Greg Clayton35c91342014-11-17 18:40:27 +00002469 def registerSharedLibrariesWithTarget(self, target, shlibs):
2470 '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
2471
2472 Any modules in the target that have their remote install file specification set will
2473 get uploaded to the remote host. This function registers the local copies of the
2474 shared libraries with the target and sets their remote install locations so they will
2475 be uploaded when the target is run.
2476 '''
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00002477 if not shlibs or not self.platformContext:
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002478 return None
Greg Clayton35c91342014-11-17 18:40:27 +00002479
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002480 shlib_environment_var = self.platformContext.shlib_environment_var
2481 shlib_prefix = self.platformContext.shlib_prefix
2482 shlib_extension = '.' + self.platformContext.shlib_extension
2483
2484 working_dir = self.get_process_working_directory()
2485 environment = ['%s=%s' % (shlib_environment_var, working_dir)]
2486 # Add any shared libraries to our target if remote so they get
2487 # uploaded into the working directory on the remote side
2488 for name in shlibs:
2489 # The path can be a full path to a shared library, or a make file name like "Foo" for
2490 # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
2491 # basename like "libFoo.so". So figure out which one it is and resolve the local copy
2492 # of the shared library accordingly
2493 if os.path.exists(name):
2494 local_shlib_path = name # name is the full path to the local shared library
2495 else:
2496 # Check relative names
2497 local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
2498 if not os.path.exists(local_shlib_path):
2499 local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
Greg Clayton35c91342014-11-17 18:40:27 +00002500 if not os.path.exists(local_shlib_path):
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002501 local_shlib_path = os.path.join(os.getcwd(), name)
Greg Clayton35c91342014-11-17 18:40:27 +00002502
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002503 # Make sure we found the local shared library in the above code
2504 self.assertTrue(os.path.exists(local_shlib_path))
2505
2506 # Add the shared library to our target
2507 shlib_module = target.AddModule(local_shlib_path, None, None, None)
2508 if lldb.remote_platform:
Greg Clayton35c91342014-11-17 18:40:27 +00002509 # We must set the remote install location if we want the shared library
2510 # to get uploaded to the remote target
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00002511 remote_shlib_path = lldbutil.append_to_process_working_directory(os.path.basename(local_shlib_path))
Greg Clayton35c91342014-11-17 18:40:27 +00002512 shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002513
2514 return environment
2515
Enrico Granata44818162012-10-24 01:23:57 +00002516 # utility methods that tests can use to access the current objects
2517 def target(self):
2518 if not self.dbg:
2519 raise Exception('Invalid debugger instance')
2520 return self.dbg.GetSelectedTarget()
2521
2522 def process(self):
2523 if not self.dbg:
2524 raise Exception('Invalid debugger instance')
2525 return self.dbg.GetSelectedTarget().GetProcess()
2526
2527 def thread(self):
2528 if not self.dbg:
2529 raise Exception('Invalid debugger instance')
2530 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2531
2532 def frame(self):
2533 if not self.dbg:
2534 raise Exception('Invalid debugger instance')
2535 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
2536
Greg Claytonc6947512013-12-13 19:18:59 +00002537 def get_process_working_directory(self):
2538 '''Get the working directory that should be used when launching processes for local or remote processes.'''
2539 if lldb.remote_platform:
2540 # Remote tests set the platform working directory up in TestBase.setUp()
2541 return lldb.remote_platform.GetWorkingDirectory()
2542 else:
2543 # local tests change directory into each test subdirectory
2544 return os.getcwd()
2545
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002546 def tearDown(self):
Johnny Chen7d1d7532010-09-02 21:23:12 +00002547 #import traceback
2548 #traceback.print_stack()
2549
Adrian McCarthy6ecdbc82015-10-15 22:39:55 +00002550 # Ensure all the references to SB objects have gone away so that we can
2551 # be sure that all test-specific resources have been freed before we
2552 # attempt to delete the targets.
2553 gc.collect()
2554
Johnny Chen3794ad92011-06-15 21:24:24 +00002555 # Delete the target(s) from the debugger as a general cleanup step.
2556 # This includes terminating the process for each target, if any.
2557 # We'd like to reuse the debugger for our next test without incurring
2558 # the initialization overhead.
2559 targets = []
2560 for target in self.dbg:
2561 if target:
2562 targets.append(target)
2563 process = target.GetProcess()
2564 if process:
2565 rc = self.invoke(process, "Kill")
2566 self.assertTrue(rc.Success(), PROCESS_KILLED)
2567 for target in targets:
2568 self.dbg.DeleteTarget(target)
Johnny Chen6ca006c2010-08-16 21:28:10 +00002569
Johnny Chen44d24972012-04-16 18:55:15 +00002570 # Run global post-flight code, if defined via the config file.
2571 if lldb.post_flight:
2572 lldb.post_flight(self)
2573
Zachary Turner65fe1eb2015-03-26 16:43:25 +00002574 # Do this last, to make sure it's in reverse order from how we setup.
2575 Base.tearDown(self)
2576
Zachary Turner95812042015-03-26 18:54:21 +00002577 # This must be the last statement, otherwise teardown hooks or other
2578 # lines might depend on this still being active.
2579 del self.dbg
2580
Johnny Chen86268e42011-09-30 21:48:35 +00002581 def switch_to_thread_with_stop_reason(self, stop_reason):
2582 """
2583 Run the 'thread list' command, and select the thread with stop reason as
2584 'stop_reason'. If no such thread exists, no select action is done.
2585 """
2586 from lldbutil import stop_reason_to_str
2587 self.runCmd('thread list')
2588 output = self.res.GetOutput()
2589 thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
2590 stop_reason_to_str(stop_reason))
2591 for line in output.splitlines():
2592 matched = thread_line_pattern.match(line)
2593 if matched:
2594 self.runCmd('thread select %s' % matched.group(1))
2595
Enrico Granata7594f142013-06-17 22:51:50 +00002596 def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
Johnny Chen27f212d2010-08-19 23:26:59 +00002597 """
2598 Ask the command interpreter to handle the command and then check its
2599 return status.
2600 """
2601 # Fail fast if 'cmd' is not meaningful.
2602 if not cmd or len(cmd) == 0:
2603 raise Exception("Bad 'cmd' parameter encountered")
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002604
Johnny Chen8d55a342010-08-31 17:42:54 +00002605 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002606
Daniel Maleae0f8f572013-08-26 23:57:52 +00002607 # This is an opportunity to insert the 'platform target-install' command if we are told so
2608 # via the settig of lldb.lldbtest_remote_sandbox.
2609 if cmd.startswith("target create "):
2610 cmd = cmd.replace("target create ", "file ")
2611 if cmd.startswith("file ") and lldb.lldbtest_remote_sandbox:
2612 with recording(self, trace) as sbuf:
2613 the_rest = cmd.split("file ")[1]
2614 # Split the rest of the command line.
2615 atoms = the_rest.split()
2616 #
2617 # NOTE: This assumes that the options, if any, follow the file command,
2618 # instead of follow the specified target.
2619 #
2620 target = atoms[-1]
2621 # Now let's get the absolute pathname of our target.
2622 abs_target = os.path.abspath(target)
Zachary Turnerff890da2015-10-19 23:45:41 +00002623 print("Found a file command, target (with absolute pathname)=%s" % abs_target, file=sbuf)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002624 fpath, fname = os.path.split(abs_target)
2625 parent_dir = os.path.split(fpath)[0]
2626 platform_target_install_command = 'platform target-install %s %s' % (fpath, lldb.lldbtest_remote_sandbox)
Zachary Turnerff890da2015-10-19 23:45:41 +00002627 print("Insert this command to be run first: %s" % platform_target_install_command, file=sbuf)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002628 self.ci.HandleCommand(platform_target_install_command, self.res)
2629 # And this is the file command we want to execute, instead.
2630 #
2631 # Warning: SIDE EFFECT AHEAD!!!
2632 # Populate the remote executable pathname into the lldb namespace,
2633 # so that test cases can grab this thing out of the namespace.
2634 #
2635 lldb.lldbtest_remote_sandboxed_executable = abs_target.replace(parent_dir, lldb.lldbtest_remote_sandbox)
2636 cmd = "file -P %s %s %s" % (lldb.lldbtest_remote_sandboxed_executable, the_rest.replace(target, ''), abs_target)
Zachary Turnerff890da2015-10-19 23:45:41 +00002637 print("And this is the replaced file command: %s" % cmd, file=sbuf)
Daniel Maleae0f8f572013-08-26 23:57:52 +00002638
Johnny Chen63dfb272010-09-01 00:15:19 +00002639 running = (cmd.startswith("run") or cmd.startswith("process launch"))
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002640
Johnny Chen63dfb272010-09-01 00:15:19 +00002641 for i in range(self.maxLaunchCount if running else 1):
Enrico Granata7594f142013-06-17 22:51:50 +00002642 self.ci.HandleCommand(cmd, self.res, inHistory)
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002643
Johnny Chen150c3cc2010-10-15 01:18:29 +00002644 with recording(self, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00002645 print("runCmd:", cmd, file=sbuf)
Johnny Chenab254f52010-10-15 16:13:00 +00002646 if not check:
Zachary Turnerff890da2015-10-19 23:45:41 +00002647 print("check of return status not required", file=sbuf)
Johnny Chenf2b70232010-08-25 18:49:48 +00002648 if self.res.Succeeded():
Zachary Turnerff890da2015-10-19 23:45:41 +00002649 print("output:", self.res.GetOutput(), file=sbuf)
Johnny Chenf2b70232010-08-25 18:49:48 +00002650 else:
Zachary Turnerff890da2015-10-19 23:45:41 +00002651 print("runCmd failed!", file=sbuf)
2652 print(self.res.GetError(), file=sbuf)
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002653
Johnny Chenff3d01d2010-08-20 21:03:09 +00002654 if self.res.Succeeded():
Johnny Chenf2b70232010-08-25 18:49:48 +00002655 break
Johnny Chen150c3cc2010-10-15 01:18:29 +00002656 elif running:
Johnny Chencf7f74e2011-01-19 02:02:08 +00002657 # For process launch, wait some time before possible next try.
2658 time.sleep(self.timeWaitNextLaunch)
Johnny Chen552d6712012-08-01 19:56:04 +00002659 with recording(self, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00002660 print("Command '" + cmd + "' failed!", file=sbuf)
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002661
Johnny Chen27f212d2010-08-19 23:26:59 +00002662 if check:
Sean Callanan05834cd2015-07-01 23:56:30 +00002663 self.assertTrue(self.res.Succeeded(),
2664 msg if msg else CMD_MSG(cmd))
Johnny Chen27f212d2010-08-19 23:26:59 +00002665
Jim Ingham63dfc722012-09-22 00:05:11 +00002666 def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
2667 """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2668
2669 Otherwise, all the arguments have the same meanings as for the expect function"""
2670
2671 trace = (True if traceAlways else trace)
2672
2673 if exe:
2674 # First run the command. If we are expecting error, set check=False.
2675 # Pass the assert message along since it provides more semantic info.
2676 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
2677
2678 # Then compare the output against expected strings.
2679 output = self.res.GetError() if error else self.res.GetOutput()
2680
2681 # If error is True, the API client expects the command to fail!
2682 if error:
2683 self.assertFalse(self.res.Succeeded(),
2684 "Command '" + str + "' is expected to fail!")
2685 else:
2686 # No execution required, just compare str against the golden input.
2687 output = str
2688 with recording(self, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00002689 print("looking at:", output, file=sbuf)
Jim Ingham63dfc722012-09-22 00:05:11 +00002690
2691 # The heading says either "Expecting" or "Not expecting".
2692 heading = "Expecting" if matching else "Not expecting"
2693
2694 for pattern in patterns:
2695 # Match Objects always have a boolean value of True.
2696 match_object = re.search(pattern, output)
2697 matched = bool(match_object)
2698 with recording(self, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00002699 print("%s pattern: %s" % (heading, pattern), file=sbuf)
2700 print("Matched" if matched else "Not matched", file=sbuf)
Jim Ingham63dfc722012-09-22 00:05:11 +00002701 if matched:
2702 break
2703
2704 self.assertTrue(matched if matching else not matched,
2705 msg if msg else EXP_MSG(str, exe))
2706
2707 return match_object
2708
Enrico Granata7594f142013-06-17 22:51:50 +00002709 def expect(self, str, msg=None, patterns=None, startstr=None, endstr=None, substrs=None, trace=False, error=False, matching=True, exe=True, inHistory=False):
Johnny Chen27f212d2010-08-19 23:26:59 +00002710 """
2711 Similar to runCmd; with additional expect style output matching ability.
2712
2713 Ask the command interpreter to handle the command and then check its
2714 return status. The 'msg' parameter specifies an informational assert
2715 message. We expect the output from running the command to start with
Johnny Chenea88e942010-09-21 21:08:53 +00002716 'startstr', matches the substrings contained in 'substrs', and regexp
2717 matches the patterns contained in 'patterns'.
Johnny Chenb3307862010-09-17 22:28:51 +00002718
2719 If the keyword argument error is set to True, it signifies that the API
2720 client is expecting the command to fail. In this case, the error stream
Johnny Chenaa902922010-09-17 22:45:27 +00002721 from running the command is retrieved and compared against the golden
Johnny Chenb3307862010-09-17 22:28:51 +00002722 input, instead.
Johnny Chenea88e942010-09-21 21:08:53 +00002723
2724 If the keyword argument matching is set to False, it signifies that the API
2725 client is expecting the output of the command not to match the golden
2726 input.
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002727
2728 Finally, the required argument 'str' represents the lldb command to be
2729 sent to the command interpreter. In case the keyword argument 'exe' is
2730 set to False, the 'str' is treated as a string to be matched/not-matched
2731 against the golden input.
Johnny Chen27f212d2010-08-19 23:26:59 +00002732 """
Johnny Chen8d55a342010-08-31 17:42:54 +00002733 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002734
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002735 if exe:
2736 # First run the command. If we are expecting error, set check=False.
Johnny Chen62d4f862010-10-28 21:10:32 +00002737 # Pass the assert message along since it provides more semantic info.
Enrico Granata7594f142013-06-17 22:51:50 +00002738 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error, inHistory=inHistory)
Johnny Chen27f212d2010-08-19 23:26:59 +00002739
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002740 # Then compare the output against expected strings.
2741 output = self.res.GetError() if error else self.res.GetOutput()
Johnny Chenb3307862010-09-17 22:28:51 +00002742
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002743 # If error is True, the API client expects the command to fail!
2744 if error:
2745 self.assertFalse(self.res.Succeeded(),
2746 "Command '" + str + "' is expected to fail!")
2747 else:
2748 # No execution required, just compare str against the golden input.
Enrico Granatabc08ab42012-10-23 00:09:02 +00002749 if isinstance(str,lldb.SBCommandReturnObject):
2750 output = str.GetOutput()
2751 else:
2752 output = str
Johnny Chen150c3cc2010-10-15 01:18:29 +00002753 with recording(self, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00002754 print("looking at:", output, file=sbuf)
Johnny Chenb3307862010-09-17 22:28:51 +00002755
Johnny Chenea88e942010-09-21 21:08:53 +00002756 # The heading says either "Expecting" or "Not expecting".
Johnny Chen150c3cc2010-10-15 01:18:29 +00002757 heading = "Expecting" if matching else "Not expecting"
Johnny Chenea88e942010-09-21 21:08:53 +00002758
2759 # Start from the startstr, if specified.
2760 # If there's no startstr, set the initial state appropriately.
2761 matched = output.startswith(startstr) if startstr else (True if matching else False)
Johnny Chenb145bba2010-08-20 18:25:15 +00002762
Johnny Chen150c3cc2010-10-15 01:18:29 +00002763 if startstr:
2764 with recording(self, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00002765 print("%s start string: %s" % (heading, startstr), file=sbuf)
2766 print("Matched" if matched else "Not matched", file=sbuf)
Johnny Chenb145bba2010-08-20 18:25:15 +00002767
Johnny Chen86268e42011-09-30 21:48:35 +00002768 # Look for endstr, if specified.
2769 keepgoing = matched if matching else not matched
2770 if endstr:
2771 matched = output.endswith(endstr)
2772 with recording(self, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00002773 print("%s end string: %s" % (heading, endstr), file=sbuf)
2774 print("Matched" if matched else "Not matched", file=sbuf)
Johnny Chen86268e42011-09-30 21:48:35 +00002775
Johnny Chenea88e942010-09-21 21:08:53 +00002776 # Look for sub strings, if specified.
2777 keepgoing = matched if matching else not matched
2778 if substrs and keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002779 for str in substrs:
Johnny Chenb052f6c2010-09-23 23:35:28 +00002780 matched = output.find(str) != -1
Johnny Chen150c3cc2010-10-15 01:18:29 +00002781 with recording(self, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00002782 print("%s sub string: %s" % (heading, str), file=sbuf)
2783 print("Matched" if matched else "Not matched", file=sbuf)
Johnny Chenea88e942010-09-21 21:08:53 +00002784 keepgoing = matched if matching else not matched
2785 if not keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002786 break
2787
Johnny Chenea88e942010-09-21 21:08:53 +00002788 # Search for regular expression patterns, if specified.
2789 keepgoing = matched if matching else not matched
2790 if patterns and keepgoing:
2791 for pattern in patterns:
2792 # Match Objects always have a boolean value of True.
2793 matched = bool(re.search(pattern, output))
Johnny Chen150c3cc2010-10-15 01:18:29 +00002794 with recording(self, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00002795 print("%s pattern: %s" % (heading, pattern), file=sbuf)
2796 print("Matched" if matched else "Not matched", file=sbuf)
Johnny Chenea88e942010-09-21 21:08:53 +00002797 keepgoing = matched if matching else not matched
2798 if not keepgoing:
2799 break
Johnny Chenea88e942010-09-21 21:08:53 +00002800
2801 self.assertTrue(matched if matching else not matched,
Johnny Chenc0c67f22010-11-09 18:42:22 +00002802 msg if msg else EXP_MSG(str, exe))
Johnny Chen27f212d2010-08-19 23:26:59 +00002803
Johnny Chenf3c59232010-08-25 22:52:45 +00002804 def invoke(self, obj, name, trace=False):
Johnny Chen61703c92010-08-25 22:56:10 +00002805 """Use reflection to call a method dynamically with no argument."""
Johnny Chen8d55a342010-08-31 17:42:54 +00002806 trace = (True if traceAlways else trace)
Johnny Chenf3c59232010-08-25 22:52:45 +00002807
2808 method = getattr(obj, name)
2809 import inspect
2810 self.assertTrue(inspect.ismethod(method),
2811 name + "is a method name of object: " + str(obj))
2812 result = method()
Johnny Chen150c3cc2010-10-15 01:18:29 +00002813 with recording(self, trace) as sbuf:
Zachary Turnerff890da2015-10-19 23:45:41 +00002814 print(str(method) + ":", result, file=sbuf)
Johnny Chenf3c59232010-08-25 22:52:45 +00002815 return result
Johnny Chen827edff2010-08-27 00:15:48 +00002816
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002817 def build(self, architecture=None, compiler=None, dictionary=None, clean=True):
2818 """Platform specific way to build the default binaries."""
2819 if lldb.skip_build_and_cleanup:
2820 return
2821 module = builder_module()
2822 if target_is_android():
2823 dictionary = append_android_envs(dictionary)
2824 if self.debug_info is None:
2825 return self.buildDefault(architecture, compiler, dictionary, clean)
2826 elif self.debug_info == "dsym":
2827 return self.buildDsym(architecture, compiler, dictionary, clean)
2828 elif self.debug_info == "dwarf":
2829 return self.buildDwarf(architecture, compiler, dictionary, clean)
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +00002830 elif self.debug_info == "dwo":
2831 return self.buildDwo(architecture, compiler, dictionary, clean)
2832 else:
2833 self.fail("Can't build for debug info: %s" % self.debug_info)
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002834
Johnny Chenf359cf22011-05-27 23:36:52 +00002835 # =================================================
2836 # Misc. helper methods for debugging test execution
2837 # =================================================
2838
Johnny Chen56b92a72011-07-11 19:15:11 +00002839 def DebugSBValue(self, val):
Johnny Chen8d55a342010-08-31 17:42:54 +00002840 """Debug print a SBValue object, if traceAlways is True."""
Johnny Chende90f1d2011-04-27 17:43:07 +00002841 from lldbutil import value_type_to_str
Johnny Chen87bb5892010-11-03 21:37:58 +00002842
Johnny Chen8d55a342010-08-31 17:42:54 +00002843 if not traceAlways:
Johnny Chen827edff2010-08-27 00:15:48 +00002844 return
2845
2846 err = sys.stderr
2847 err.write(val.GetName() + ":\n")
Johnny Chen86268e42011-09-30 21:48:35 +00002848 err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n')
2849 err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n')
2850 err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n')
2851 err.write('\t' + "Value -> " + str(val.GetValue()) + '\n')
2852 err.write('\t' + "ValueAsUnsigned -> " + str(val.GetValueAsUnsigned())+ '\n')
2853 err.write('\t' + "ValueType -> " + value_type_to_str(val.GetValueType()) + '\n')
2854 err.write('\t' + "Summary -> " + str(val.GetSummary()) + '\n')
2855 err.write('\t' + "IsPointerType -> " + str(val.TypeIsPointerType()) + '\n')
2856 err.write('\t' + "Location -> " + val.GetLocation() + '\n')
Johnny Chen827edff2010-08-27 00:15:48 +00002857
Johnny Chen36c5eb12011-08-05 20:17:27 +00002858 def DebugSBType(self, type):
2859 """Debug print a SBType object, if traceAlways is True."""
2860 if not traceAlways:
2861 return
2862
2863 err = sys.stderr
2864 err.write(type.GetName() + ":\n")
2865 err.write('\t' + "ByteSize -> " + str(type.GetByteSize()) + '\n')
2866 err.write('\t' + "IsPointerType -> " + str(type.IsPointerType()) + '\n')
2867 err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
2868
Johnny Chenb877f1e2011-03-12 01:18:19 +00002869 def DebugPExpect(self, child):
2870 """Debug the spwaned pexpect object."""
2871 if not traceAlways:
2872 return
2873
Zachary Turnerff890da2015-10-19 23:45:41 +00002874 print(child)
Filipe Cabecinhas0eec15a2012-06-20 10:13:40 +00002875
2876 @classmethod
2877 def RemoveTempFile(cls, file):
2878 if os.path.exists(file):
2879 os.remove(file)