blob: 0e08e8e18ed150d2c01e46ff288d3fa81d3d9fd0 [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
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +000034import abc
Adrian McCarthy6ecdbc82015-10-15 22:39:55 +000035import gc
Vince Harron9753dd92015-05-10 15:22:09 +000036import glob
Johnny Chen90312a82010-09-21 22:34:45 +000037import os, sys, traceback
Enrico Granata7e137e32012-10-24 18:14:21 +000038import os.path
Johnny Chenea88e942010-09-21 21:08:53 +000039import re
Daniel Malea69207462013-06-05 21:07:02 +000040import signal
Johnny Chen8952a2d2010-08-30 21:35:00 +000041from subprocess import *
Johnny Chen150c3cc2010-10-15 01:18:29 +000042import StringIO
Johnny Chenf2b70232010-08-25 18:49:48 +000043import time
Johnny Chena33a93c2010-08-30 23:08:52 +000044import types
Johnny Chen73258832010-08-05 23:42:46 +000045import unittest2
Johnny Chenbf6ffa32010-07-03 03:41:59 +000046import lldb
Vince Harron9753dd92015-05-10 15:22:09 +000047import lldbtest_config
Chaoren Lin3e2bdb42015-05-11 17:53:39 +000048import lldbutil
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +000049from _pyio import __metaclass__
Johnny Chenbf6ffa32010-07-03 03:41:59 +000050
Siva Chandra8af91662015-06-05 00:22:49 +000051if sys.version_info.major < 3:
52 import urlparse
53else:
54 import urllib.parse as urlparse
55
Vince Harron85d19652015-05-21 19:09:29 +000056# dosep.py starts lots and lots of dotest instances
57# This option helps you find if two (or more) dotest instances are using the same
58# directory at the same time
59# Enable it to cause test failures and stderr messages if dotest instances try to run in
60# the same directory simultaneously
61# it is disabled by default because it litters the test directories with ".dirlock" files
62debug_confirm_directory_exclusivity = False
63
Johnny Chen707b3c92010-10-11 22:25:46 +000064# See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
Johnny Chend2047fa2011-01-19 18:18:47 +000065# LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' options.
Johnny Chen707b3c92010-10-11 22:25:46 +000066
67# By default, traceAlways is False.
Johnny Chen8d55a342010-08-31 17:42:54 +000068if "LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"]=="YES":
69 traceAlways = True
70else:
71 traceAlways = False
72
Johnny Chen707b3c92010-10-11 22:25:46 +000073# By default, doCleanup is True.
74if "LLDB_DO_CLEANUP" in os.environ and os.environ["LLDB_DO_CLEANUP"]=="NO":
75 doCleanup = False
76else:
77 doCleanup = True
78
Johnny Chen8d55a342010-08-31 17:42:54 +000079
Johnny Chen00778092010-08-09 22:01:17 +000080#
81# Some commonly used assert messages.
82#
83
Johnny Chenaa902922010-09-17 22:45:27 +000084COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"
85
Johnny Chen00778092010-08-09 22:01:17 +000086CURRENT_EXECUTABLE_SET = "Current executable set successfully"
87
Johnny Chen7d1d7532010-09-02 21:23:12 +000088PROCESS_IS_VALID = "Process is valid"
89
90PROCESS_KILLED = "Process is killed successfully"
91
Johnny Chend5f66fc2010-12-23 01:12:19 +000092PROCESS_EXITED = "Process exited successfully"
93
94PROCESS_STOPPED = "Process status should be stopped"
95
Sean Callanan05834cd2015-07-01 23:56:30 +000096RUN_SUCCEEDED = "Process is launched successfully"
Johnny Chen00778092010-08-09 22:01:17 +000097
Johnny Chen17941842010-08-09 23:44:24 +000098RUN_COMPLETED = "Process exited successfully"
Johnny Chen00778092010-08-09 22:01:17 +000099
Johnny Chen67af43f2010-10-05 19:27:32 +0000100BACKTRACE_DISPLAYED_CORRECTLY = "Backtrace displayed correctly"
101
Johnny Chen17941842010-08-09 23:44:24 +0000102BREAKPOINT_CREATED = "Breakpoint created successfully"
103
Johnny Chenf10af382010-12-04 00:07:24 +0000104BREAKPOINT_STATE_CORRECT = "Breakpoint state is correct"
105
Johnny Chene76896c2010-08-17 21:33:31 +0000106BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
107
Johnny Chen17941842010-08-09 23:44:24 +0000108BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
Johnny Chen00778092010-08-09 22:01:17 +0000109
Johnny Chen703dbd02010-09-30 17:06:24 +0000110BREAKPOINT_HIT_TWICE = "Breakpoint resolved with hit cout = 2"
111
Johnny Chen164f1e12010-10-15 18:07:09 +0000112BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3"
113
Greg Clayton5db6b792012-10-24 18:24:14 +0000114MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."
115
Johnny Chen89109ed12011-06-27 20:05:23 +0000116OBJECT_PRINTED_CORRECTLY = "Object printed correctly"
117
Johnny Chen5b3a3572010-12-09 18:22:12 +0000118SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"
119
Johnny Chenc70b02a2010-09-22 23:00:20 +0000120STEP_OUT_SUCCEEDED = "Thread step-out succeeded"
121
Johnny Chen1691a162011-04-15 16:44:48 +0000122STOPPED_DUE_TO_EXC_BAD_ACCESS = "Process should be stopped due to bad access exception"
123
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000124STOPPED_DUE_TO_ASSERT = "Process should be stopped due to an assertion"
125
Johnny Chen5d6c4642010-11-10 23:46:38 +0000126STOPPED_DUE_TO_BREAKPOINT = "Process should be stopped due to breakpoint"
Johnny Chende0338b2010-11-10 20:20:06 +0000127
Johnny Chen5d6c4642010-11-10 23:46:38 +0000128STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS = "%s, %s" % (
129 STOPPED_DUE_TO_BREAKPOINT, "instead, the actual stop reason is: '%s'")
Johnny Chen00778092010-08-09 22:01:17 +0000130
Johnny Chen2e431ce2010-10-20 18:38:48 +0000131STOPPED_DUE_TO_BREAKPOINT_CONDITION = "Stopped due to breakpoint condition"
132
Johnny Chen0a3d1ca2010-12-13 21:49:58 +0000133STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT = "Stopped due to breakpoint and ignore count"
134
Johnny Chenc066ab42010-10-14 01:22:03 +0000135STOPPED_DUE_TO_SIGNAL = "Process state is stopped due to signal"
136
Johnny Chen00778092010-08-09 22:01:17 +0000137STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
138
Johnny Chenf68cc122011-09-15 21:09:59 +0000139STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"
140
Johnny Chen3c884a02010-08-24 22:07:56 +0000141DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
142
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000143VALID_BREAKPOINT = "Got a valid breakpoint"
144
Johnny Chen5bfb8ee2010-10-22 18:10:25 +0000145VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location"
146
Johnny Chen7209d84f2011-05-06 23:26:12 +0000147VALID_COMMAND_INTERPRETER = "Got a valid command interpreter"
148
Johnny Chen5ee88192010-08-27 23:47:36 +0000149VALID_FILESPEC = "Got a valid filespec"
150
Johnny Chen025d1b82010-12-08 01:25:21 +0000151VALID_MODULE = "Got a valid module"
152
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000153VALID_PROCESS = "Got a valid process"
154
Johnny Chen025d1b82010-12-08 01:25:21 +0000155VALID_SYMBOL = "Got a valid symbol"
156
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000157VALID_TARGET = "Got a valid target"
158
Matthew Gardinerc928de32014-10-22 07:22:56 +0000159VALID_PLATFORM = "Got a valid platform"
160
Johnny Chen15f247a2012-02-03 20:43:00 +0000161VALID_TYPE = "Got a valid type"
162
Johnny Chen5819ab42011-07-15 22:28:10 +0000163VALID_VARIABLE = "Got a valid variable"
164
Johnny Chen981463d2010-08-25 19:00:04 +0000165VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
Johnny Chen00778092010-08-09 22:01:17 +0000166
Johnny Chenf68cc122011-09-15 21:09:59 +0000167WATCHPOINT_CREATED = "Watchpoint created successfully"
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000168
Sean Callanan05834cd2015-07-01 23:56:30 +0000169def CMD_MSG(str):
170 '''A generic "Command '%s' returns successfully" message generator.'''
171 return "Command '%s' returns successfully" % str
Johnny Chenc0c67f22010-11-09 18:42:22 +0000172
Johnny Chen3bc8ae42012-03-15 19:10:00 +0000173def COMPLETION_MSG(str_before, str_after):
Johnny Chen98aceb02012-01-20 23:02:51 +0000174 '''A generic message generator for the completion mechanism.'''
175 return "'%s' successfully completes to '%s'" % (str_before, str_after)
176
Johnny Chenc0c67f22010-11-09 18:42:22 +0000177def EXP_MSG(str, exe):
Johnny Chenaacf92e2011-05-31 22:16:51 +0000178 '''A generic "'%s' returns expected result" message generator if exe.
179 Otherwise, it generates "'%s' matches expected result" message.'''
Johnny Chenc0c67f22010-11-09 18:42:22 +0000180 return "'%s' %s expected result" % (str, 'returns' if exe else 'matches')
Johnny Chen17941842010-08-09 23:44:24 +0000181
Johnny Chen3343f042010-10-19 19:11:38 +0000182def SETTING_MSG(setting):
Johnny Chenaacf92e2011-05-31 22:16:51 +0000183 '''A generic "Value of setting '%s' is correct" message generator.'''
Johnny Chen3343f042010-10-19 19:11:38 +0000184 return "Value of setting '%s' is correct" % setting
185
Johnny Chen27c41232010-08-26 21:49:29 +0000186def EnvArray():
Johnny Chenaacf92e2011-05-31 22:16:51 +0000187 """Returns an env variable array from the os.environ map object."""
Johnny Chen27c41232010-08-26 21:49:29 +0000188 return map(lambda k,v: k+"="+v, os.environ.keys(), os.environ.values())
189
Johnny Chen47ceb032010-10-11 23:52:19 +0000190def line_number(filename, string_to_match):
191 """Helper function to return the line number of the first matched string."""
192 with open(filename, 'r') as f:
193 for i, line in enumerate(f):
194 if line.find(string_to_match) != -1:
195 # Found our match.
Johnny Chencd9b7772010-10-12 00:09:25 +0000196 return i+1
Johnny Chen1691a162011-04-15 16:44:48 +0000197 raise Exception("Unable to find '%s' within file %s" % (string_to_match, filename))
Johnny Chen47ceb032010-10-11 23:52:19 +0000198
Johnny Chen67af43f2010-10-05 19:27:32 +0000199def pointer_size():
200 """Return the pointer size of the host system."""
201 import ctypes
202 a_pointer = ctypes.c_void_p(0xffff)
203 return 8 * ctypes.sizeof(a_pointer)
204
Johnny Chen57816732012-02-09 02:01:59 +0000205def is_exe(fpath):
206 """Returns true if fpath is an executable."""
207 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
208
209def which(program):
210 """Returns the full path to a program; None otherwise."""
211 fpath, fname = os.path.split(program)
212 if fpath:
213 if is_exe(program):
214 return program
215 else:
216 for path in os.environ["PATH"].split(os.pathsep):
217 exe_file = os.path.join(path, program)
218 if is_exe(exe_file):
219 return exe_file
220 return None
221
Johnny Chen150c3cc2010-10-15 01:18:29 +0000222class recording(StringIO.StringIO):
223 """
224 A nice little context manager for recording the debugger interactions into
225 our session object. If trace flag is ON, it also emits the interactions
226 into the stderr.
227 """
228 def __init__(self, test, trace):
Johnny Chen690fcef2010-10-15 23:55:05 +0000229 """Create a StringIO instance; record the session obj and trace flag."""
Johnny Chen150c3cc2010-10-15 01:18:29 +0000230 StringIO.StringIO.__init__(self)
Johnny Chen0241f142011-08-16 22:06:17 +0000231 # The test might not have undergone the 'setUp(self)' phase yet, so that
232 # the attribute 'session' might not even exist yet.
Johnny Chenbfcf37f2011-08-16 17:06:45 +0000233 self.session = getattr(test, "session", None) if test else None
Johnny Chen150c3cc2010-10-15 01:18:29 +0000234 self.trace = trace
235
236 def __enter__(self):
237 """
238 Context management protocol on entry to the body of the with statement.
239 Just return the StringIO object.
240 """
241 return self
242
243 def __exit__(self, type, value, tb):
244 """
245 Context management protocol on exit from the body of the with statement.
246 If trace is ON, it emits the recordings into stderr. Always add the
247 recordings to our session object. And close the StringIO object, too.
248 """
249 if self.trace:
Johnny Chen690fcef2010-10-15 23:55:05 +0000250 print >> sys.stderr, self.getvalue()
251 if self.session:
252 print >> self.session, self.getvalue()
Johnny Chen150c3cc2010-10-15 01:18:29 +0000253 self.close()
254
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000255class _BaseProcess(object):
256 __metaclass__ = abc.ABCMeta
257
258 @abc.abstractproperty
259 def pid(self):
260 """Returns process PID if has been launched already."""
261
262 @abc.abstractmethod
263 def launch(self, executable, args):
264 """Launches new process with given executable and args."""
265
266 @abc.abstractmethod
267 def terminate(self):
268 """Terminates previously launched process.."""
269
270class _LocalProcess(_BaseProcess):
271
272 def __init__(self, trace_on):
273 self._proc = None
274 self._trace_on = trace_on
Ilia K725abcb2015-04-15 13:35:49 +0000275 self._delayafterterminate = 0.1
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000276
277 @property
278 def pid(self):
279 return self._proc.pid
280
281 def launch(self, executable, args):
282 self._proc = Popen([executable] + args,
283 stdout = open(os.devnull) if not self._trace_on else None,
284 stdin = PIPE)
285
286 def terminate(self):
287 if self._proc.poll() == None:
Ilia K725abcb2015-04-15 13:35:49 +0000288 # Terminate _proc like it does the pexpect
Adrian McCarthy137d7ba2015-07-07 14:47:34 +0000289 signals_to_try = [sig for sig in ['SIGHUP', 'SIGCONT', 'SIGINT'] if sig in dir(signal)]
290 for sig in signals_to_try:
291 try:
292 self._proc.send_signal(getattr(signal, sig))
293 time.sleep(self._delayafterterminate)
294 if self._proc.poll() != None:
295 return
296 except ValueError:
297 pass # Windows says SIGINT is not a valid signal to send
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000298 self._proc.terminate()
Ilia K725abcb2015-04-15 13:35:49 +0000299 time.sleep(self._delayafterterminate)
300 if self._proc.poll() != None:
301 return
302 self._proc.kill()
303 time.sleep(self._delayafterterminate)
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000304
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000305 def poll(self):
306 return self._proc.poll()
307
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000308class _RemoteProcess(_BaseProcess):
309
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000310 def __init__(self, install_remote):
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000311 self._pid = None
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000312 self._install_remote = install_remote
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000313
314 @property
315 def pid(self):
316 return self._pid
317
318 def launch(self, executable, args):
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000319 if self._install_remote:
320 src_path = executable
Chaoren Lin5d76b1b2015-06-06 00:25:50 +0000321 dst_path = lldbutil.append_to_process_working_directory(os.path.basename(executable))
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000322
323 dst_file_spec = lldb.SBFileSpec(dst_path, False)
324 err = lldb.remote_platform.Install(lldb.SBFileSpec(src_path, True), dst_file_spec)
325 if err.Fail():
326 raise Exception("remote_platform.Install('%s', '%s') failed: %s" % (src_path, dst_path, err))
327 else:
328 dst_path = executable
329 dst_file_spec = lldb.SBFileSpec(executable, False)
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000330
331 launch_info = lldb.SBLaunchInfo(args)
332 launch_info.SetExecutableFile(dst_file_spec, True)
Chaoren Lin3e2bdb42015-05-11 17:53:39 +0000333 launch_info.SetWorkingDirectory(lldb.remote_platform.GetWorkingDirectory())
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000334
335 # Redirect stdout and stderr to /dev/null
336 launch_info.AddSuppressFileAction(1, False, True)
337 launch_info.AddSuppressFileAction(2, False, True)
338
339 err = lldb.remote_platform.Launch(launch_info)
340 if err.Fail():
341 raise Exception("remote_platform.Launch('%s', '%s') failed: %s" % (dst_path, args, err))
342 self._pid = launch_info.GetProcessID()
343
344 def terminate(self):
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000345 lldb.remote_platform.Kill(self._pid)
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000346
Johnny Chen690fcef2010-10-15 23:55:05 +0000347# From 2.7's subprocess.check_output() convenience function.
Johnny Chenac77f3b2011-03-23 20:28:59 +0000348# Return a tuple (stdoutdata, stderrdata).
Zachary Turner9ef307b2014-07-22 16:19:29 +0000349def system(commands, **kwargs):
Johnny Chen8eb14a92011-11-16 22:44:28 +0000350 r"""Run an os command with arguments and return its output as a byte string.
Johnny Chen690fcef2010-10-15 23:55:05 +0000351
352 If the exit code was non-zero it raises a CalledProcessError. The
353 CalledProcessError object will have the return code in the returncode
354 attribute and output in the output attribute.
355
356 The arguments are the same as for the Popen constructor. Example:
357
358 >>> check_output(["ls", "-l", "/dev/null"])
359 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
360
361 The stdout argument is not allowed as it is used internally.
362 To capture standard error in the result, use stderr=STDOUT.
363
364 >>> check_output(["/bin/sh", "-c",
365 ... "ls -l non_existent_file ; exit 0"],
366 ... stderr=STDOUT)
367 'ls: non_existent_file: No such file or directory\n'
368 """
369
370 # Assign the sender object to variable 'test' and remove it from kwargs.
371 test = kwargs.pop('sender', None)
372
Zachary Turner9ef307b2014-07-22 16:19:29 +0000373 # [['make', 'clean', 'foo'], ['make', 'foo']] -> ['make clean foo', 'make foo']
374 commandList = [' '.join(x) for x in commands]
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000375 output = ""
376 error = ""
377 for shellCommand in commandList:
378 if 'stdout' in kwargs:
379 raise ValueError('stdout argument not allowed, it will be overridden.')
380 if 'shell' in kwargs and kwargs['shell']==False:
381 raise ValueError('shell=False not allowed')
382 process = Popen(shellCommand, stdout=PIPE, stderr=PIPE, shell=True, **kwargs)
383 pid = process.pid
384 this_output, this_error = process.communicate()
385 retcode = process.poll()
Zachary Turner9ef307b2014-07-22 16:19:29 +0000386
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000387 # Enable trace on failure return while tracking down FreeBSD buildbot issues
388 trace = traceAlways
389 if not trace and retcode and sys.platform.startswith("freebsd"):
390 trace = True
Johnny Chen690fcef2010-10-15 23:55:05 +0000391
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000392 with recording(test, trace) as sbuf:
393 print >> sbuf
394 print >> sbuf, "os command:", shellCommand
395 print >> sbuf, "with pid:", pid
Adrian McCarthy1d574332015-04-03 17:10:30 +0000396 print >> sbuf, "stdout:", this_output
397 print >> sbuf, "stderr:", this_error
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000398 print >> sbuf, "retcode:", retcode
399 print >> sbuf
Ed Maste6e496332014-08-05 20:33:17 +0000400
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000401 if retcode:
402 cmd = kwargs.get("args")
403 if cmd is None:
404 cmd = shellCommand
405 raise CalledProcessError(retcode, cmd)
406 output = output + this_output
407 error = error + this_error
Johnny Chenac77f3b2011-03-23 20:28:59 +0000408 return (output, error)
Johnny Chen690fcef2010-10-15 23:55:05 +0000409
Johnny Chenab9c1dd2010-11-01 20:35:01 +0000410def getsource_if_available(obj):
411 """
412 Return the text of the source code for an object if available. Otherwise,
413 a print representation is returned.
414 """
415 import inspect
416 try:
417 return inspect.getsource(obj)
418 except:
419 return repr(obj)
420
Peter Collingbourne19f48d52011-06-20 19:06:20 +0000421def builder_module():
Ed Maste4d90f0f2013-07-25 13:24:34 +0000422 if sys.platform.startswith("freebsd"):
423 return __import__("builder_freebsd")
Peter Collingbourne19f48d52011-06-20 19:06:20 +0000424 return __import__("builder_" + sys.platform)
425
Siva Chandra8af91662015-06-05 00:22:49 +0000426def run_adb_command(cmd, device_id):
427 device_id_args = []
428 if device_id:
429 device_id_args = ["-s", device_id]
430 full_cmd = ["adb"] + device_id_args + cmd
431 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE)
432 stdout, stderr = p.communicate()
433 return p.returncode, stdout, stderr
434
Chaoren Line9bbabc2015-07-18 00:37:55 +0000435def append_android_envs(dictionary):
436 if dictionary is None:
437 dictionary = {}
438 dictionary["OS"] = "Android"
439 if android_device_api() >= 16:
440 dictionary["PIE"] = 1
441 return dictionary
442
Chaoren Lin9070f532015-07-17 22:13:29 +0000443def target_is_android():
444 if not hasattr(target_is_android, 'result'):
445 triple = lldb.DBG.GetSelectedPlatform().GetTriple()
446 match = re.match(".*-.*-.*-android", triple)
447 target_is_android.result = match is not None
448 return target_is_android.result
449
Siva Chandra8af91662015-06-05 00:22:49 +0000450def android_device_api():
Chaoren Lin9070f532015-07-17 22:13:29 +0000451 if not hasattr(android_device_api, 'result'):
452 assert lldb.platform_url is not None
453 device_id = None
454 parsed_url = urlparse.urlparse(lldb.platform_url)
455 if parsed_url.scheme == "adb":
456 device_id = parsed_url.netloc.split(":")[0]
457 retcode, stdout, stderr = run_adb_command(
458 ["shell", "getprop", "ro.build.version.sdk"], device_id)
459 if retcode == 0:
460 android_device_api.result = int(stdout)
461 else:
462 raise LookupError(
463 ">>> Unable to determine the API level of the Android device.\n"
464 ">>> stdout:\n%s\n"
465 ">>> stderr:\n%s\n" % (stdout, stderr))
466 return android_device_api.result
Siva Chandra8af91662015-06-05 00:22:49 +0000467
Johnny Chena74bb0a2011-08-01 18:46:13 +0000468#
469# Decorators for categorizing test cases.
470#
471
472from functools import wraps
473def python_api_test(func):
474 """Decorate the item as a Python API only test."""
475 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
476 raise Exception("@python_api_test can only be used to decorate a test method")
477 @wraps(func)
478 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000479 if lldb.dont_do_python_api_test:
480 self.skipTest("python api tests")
Johnny Chena74bb0a2011-08-01 18:46:13 +0000481 return func(self, *args, **kwargs)
482
483 # Mark this function as such to separate them from lldb command line tests.
484 wrapper.__python_api_test__ = True
485 return wrapper
486
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +0000487def lldbmi_test(func):
488 """Decorate the item as a lldb-mi only test."""
489 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
490 raise Exception("@lldbmi_test can only be used to decorate a test method")
491 @wraps(func)
492 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000493 if lldb.dont_do_lldbmi_test:
494 self.skipTest("lldb-mi tests")
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +0000495 return func(self, *args, **kwargs)
496
497 # Mark this function as such to separate them from lldb command line tests.
498 wrapper.__lldbmi_test__ = True
499 return wrapper
500
Johnny Chena74bb0a2011-08-01 18:46:13 +0000501def benchmarks_test(func):
502 """Decorate the item as a benchmarks test."""
503 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
504 raise Exception("@benchmarks_test can only be used to decorate a test method")
505 @wraps(func)
506 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000507 if not lldb.just_do_benchmarks_test:
508 self.skipTest("benchmarks tests")
Johnny Chena74bb0a2011-08-01 18:46:13 +0000509 return func(self, *args, **kwargs)
510
511 # Mark this function as such to separate them from the regular tests.
512 wrapper.__benchmarks_test__ = True
513 return wrapper
514
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000515def no_debug_info_test(func):
516 """Decorate the item as a test what don't use any debug info. If this annotation is specified
517 then the test runner won't generate a separate test for each debug info format. """
518 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
519 raise Exception("@no_debug_info_test can only be used to decorate a test method")
520 @wraps(func)
521 def wrapper(self, *args, **kwargs):
522 return func(self, *args, **kwargs)
523
524 # Mark this function as such to separate them from the regular tests.
525 wrapper.__no_debug_info_test__ = True
526 return wrapper
527
Johnny Chenf1548d42012-04-06 00:56:05 +0000528def dsym_test(func):
529 """Decorate the item as a dsym test."""
530 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
531 raise Exception("@dsym_test can only be used to decorate a test method")
532 @wraps(func)
533 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000534 if lldb.dont_do_dsym_test:
535 self.skipTest("dsym tests")
Johnny Chenf1548d42012-04-06 00:56:05 +0000536 return func(self, *args, **kwargs)
537
538 # Mark this function as such to separate them from the regular tests.
539 wrapper.__dsym_test__ = True
540 return wrapper
541
542def dwarf_test(func):
543 """Decorate the item as a dwarf test."""
544 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
545 raise Exception("@dwarf_test can only be used to decorate a test method")
546 @wraps(func)
547 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000548 if lldb.dont_do_dwarf_test:
549 self.skipTest("dwarf tests")
Johnny Chenf1548d42012-04-06 00:56:05 +0000550 return func(self, *args, **kwargs)
551
552 # Mark this function as such to separate them from the regular tests.
553 wrapper.__dwarf_test__ = True
554 return wrapper
555
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +0000556def dwo_test(func):
557 """Decorate the item as a dwo test."""
558 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
559 raise Exception("@dwo_test can only be used to decorate a test method")
560 @wraps(func)
561 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000562 if lldb.dont_do_dwo_test:
563 self.skipTest("dwo tests")
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +0000564 return func(self, *args, **kwargs)
565
566 # Mark this function as such to separate them from the regular tests.
567 wrapper.__dwo_test__ = True
568 return wrapper
569
Todd Fialaa41d48c2014-04-28 04:49:40 +0000570def debugserver_test(func):
571 """Decorate the item as a debugserver test."""
572 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
573 raise Exception("@debugserver_test can only be used to decorate a test method")
574 @wraps(func)
575 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000576 if lldb.dont_do_debugserver_test:
577 self.skipTest("debugserver tests")
Todd Fialaa41d48c2014-04-28 04:49:40 +0000578 return func(self, *args, **kwargs)
579
580 # Mark this function as such to separate them from the regular tests.
581 wrapper.__debugserver_test__ = True
582 return wrapper
583
584def llgs_test(func):
Robert Flack8cc4cf12015-03-06 14:36:33 +0000585 """Decorate the item as a lldb-server test."""
Todd Fialaa41d48c2014-04-28 04:49:40 +0000586 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
587 raise Exception("@llgs_test can only be used to decorate a test method")
588 @wraps(func)
589 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000590 if lldb.dont_do_llgs_test:
591 self.skipTest("llgs tests")
Todd Fialaa41d48c2014-04-28 04:49:40 +0000592 return func(self, *args, **kwargs)
593
594 # Mark this function as such to separate them from the regular tests.
595 wrapper.__llgs_test__ = True
596 return wrapper
597
Daniel Maleae0f8f572013-08-26 23:57:52 +0000598def not_remote_testsuite_ready(func):
599 """Decorate the item as a test which is not ready yet for remote testsuite."""
600 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
601 raise Exception("@not_remote_testsuite_ready can only be used to decorate a test method")
602 @wraps(func)
603 def wrapper(self, *args, **kwargs):
Pavel Labathf882f6f2015-10-12 13:42:16 +0000604 if lldb.lldbtest_remote_sandbox or lldb.remote_platform:
605 self.skipTest("not ready for remote testsuite")
Daniel Maleae0f8f572013-08-26 23:57:52 +0000606 return func(self, *args, **kwargs)
607
608 # Mark this function as such to separate them from the regular tests.
609 wrapper.__not_ready_for_remote_testsuite_test__ = True
610 return wrapper
611
Ed Maste433790a2014-04-23 12:55:41 +0000612def expectedFailure(expected_fn, bugnumber=None):
613 def expectedFailure_impl(func):
614 @wraps(func)
615 def wrapper(*args, **kwargs):
Enrico Granata43f62132013-02-23 01:28:30 +0000616 from unittest2 import case
617 self = args[0]
Enrico Granata43f62132013-02-23 01:28:30 +0000618 try:
Ed Maste433790a2014-04-23 12:55:41 +0000619 func(*args, **kwargs)
Enrico Granata43f62132013-02-23 01:28:30 +0000620 except Exception:
Ed Maste433790a2014-04-23 12:55:41 +0000621 if expected_fn(self):
622 raise case._ExpectedFailure(sys.exc_info(), bugnumber)
Enrico Granata43f62132013-02-23 01:28:30 +0000623 else:
624 raise
Ed Maste433790a2014-04-23 12:55:41 +0000625 if expected_fn(self):
626 raise case._UnexpectedSuccess(sys.exc_info(), bugnumber)
627 return wrapper
Ying Chen464d1e12015-03-27 00:26:52 +0000628 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
629 # return decorator in this case, so it will be used to decorating original method
630 if callable(bugnumber):
631 return expectedFailure_impl(bugnumber)
632 else:
633 return expectedFailure_impl
Ed Maste433790a2014-04-23 12:55:41 +0000634
Ying Chen7091c2c2015-04-21 01:15:47 +0000635# provide a function to xfail on defined oslist, compiler version, and archs
636# if none is specified for any argument, that argument won't be checked and thus means for all
637# for example,
638# @expectedFailureAll, xfail for all platform/compiler/arch,
639# @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
640# @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000641def expectedFailureAll(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, triple=None, debug_info=None):
Ying Chen7091c2c2015-04-21 01:15:47 +0000642 def fn(self):
643 return ((oslist is None or self.getPlatform() in oslist) and
644 (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
Tamas Berghammercf6f92a2015-09-07 15:50:19 +0000645 self.expectedArch(archs) and
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000646 (triple is None or re.match(triple, lldb.DBG.GetSelectedPlatform().GetTriple())) and
647 (debug_info is None or self.debug_info in debug_info))
Ying Chen7091c2c2015-04-21 01:15:47 +0000648 return expectedFailure(fn, bugnumber)
649
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000650def expectedFailureDwarf(bugnumber=None):
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +0000651 return expectedFailureAll(bugnumber=bugnumber, debug_info="dwarf")
652
653def expectedFailureDwo(bugnumber=None):
654 return expectedFailureAll(bugnumber=bugnumber, debug_info="dwo")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000655
656def expectedFailureDsym(bugnumber=None):
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +0000657 return expectedFailureAll(bugnumber=bugnumber, debug_info="dsym")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000658
659def expectedFailureCompiler(compiler, compiler_version=None, bugnumber=None):
660 if compiler_version is None:
661 compiler_version=['=', None]
662 return expectedFailureAll(bugnumber=bugnumber, compiler=compiler, compiler_version=compiler_version)
663
Vince Harron8974ce22015-03-13 19:54:54 +0000664# to XFAIL a specific clang versions, try this
665# @expectedFailureClang('bugnumber', ['<=', '3.4'])
666def expectedFailureClang(bugnumber=None, compiler_version=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000667 return expectedFailureCompiler('clang', compiler_version, bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000668
669def expectedFailureGcc(bugnumber=None, compiler_version=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000670 return expectedFailureCompiler('gcc', compiler_version, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000671
Matt Kopec0de53f02013-03-15 19:10:12 +0000672def expectedFailureIcc(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000673 return expectedFailureCompiler('icc', None, bugnumber)
Matt Kopec0de53f02013-03-15 19:10:12 +0000674
Ed Maste433790a2014-04-23 12:55:41 +0000675def expectedFailureArch(arch, bugnumber=None):
676 def fn(self):
677 return arch in self.getArchitecture()
Ying Chen464d1e12015-03-27 00:26:52 +0000678 return expectedFailure(fn, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000679
Enrico Granatae6cedc12013-02-23 01:05:23 +0000680def expectedFailurei386(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000681 return expectedFailureArch('i386', bugnumber)
Johnny Chena33843f2011-12-22 21:14:31 +0000682
Matt Kopecee969f92013-09-26 23:30:59 +0000683def expectedFailurex86_64(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000684 return expectedFailureArch('x86_64', bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000685
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000686def expectedFailureOS(oslist, bugnumber=None, compilers=None, debug_info=None):
Ed Maste433790a2014-04-23 12:55:41 +0000687 def fn(self):
Robert Flack13c7ad92015-03-30 14:12:17 +0000688 return (self.getPlatform() in oslist and
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000689 self.expectedCompiler(compilers) and
690 (debug_info is None or self.debug_info in debug_info))
Ying Chen464d1e12015-03-27 00:26:52 +0000691 return expectedFailure(fn, bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000692
Chaoren Linf7160f32015-06-09 17:39:27 +0000693def expectedFailureHostOS(oslist, bugnumber=None, compilers=None):
694 def fn(self):
695 return (getHostPlatform() in oslist and
696 self.expectedCompiler(compilers))
697 return expectedFailure(fn, bugnumber)
698
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000699def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None):
Robert Flackefa49c22015-03-26 19:34:26 +0000700 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000701 return expectedFailureOS(getDarwinOSTriples(), bugnumber, compilers, debug_info=debug_info)
Matt Kopecee969f92013-09-26 23:30:59 +0000702
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000703def expectedFailureFreeBSD(bugnumber=None, compilers=None, debug_info=None):
704 return expectedFailureOS(['freebsd'], bugnumber, compilers, debug_info=debug_info)
Ed Maste24a7f7d2013-07-24 19:47:08 +0000705
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000706def expectedFailureLinux(bugnumber=None, compilers=None, debug_info=None):
707 return expectedFailureOS(['linux'], bugnumber, compilers, debug_info=debug_info)
Matt Kopece9ea0da2013-05-07 19:29:28 +0000708
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000709def expectedFailureWindows(bugnumber=None, compilers=None, debug_info=None):
710 return expectedFailureOS(['windows'], bugnumber, compilers, debug_info=debug_info)
Zachary Turner80c2c602014-12-09 19:28:00 +0000711
Chaoren Linf7160f32015-06-09 17:39:27 +0000712def expectedFailureHostWindows(bugnumber=None, compilers=None):
713 return expectedFailureHostOS(['windows'], bugnumber, compilers)
714
Pavel Labath090152b2015-08-20 11:37:19 +0000715def matchAndroid(api_levels=None, archs=None):
716 def match(self):
717 if not target_is_android():
718 return False
719 if archs is not None and self.getArchitecture() not in archs:
720 return False
721 if api_levels is not None and android_device_api() not in api_levels:
722 return False
723 return True
724 return match
725
726
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000727def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
Siva Chandra8af91662015-06-05 00:22:49 +0000728 """ Mark a test as xfail for Android.
729
730 Arguments:
731 bugnumber - The LLVM pr associated with the problem.
732 api_levels - A sequence of numbers specifying the Android API levels
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000733 for which a test is expected to fail. None means all API level.
734 arch - A sequence of architecture names specifying the architectures
735 for which a test is expected to fail. None means all architectures.
Siva Chandra8af91662015-06-05 00:22:49 +0000736 """
Pavel Labath090152b2015-08-20 11:37:19 +0000737 return expectedFailure(matchAndroid(api_levels, archs), bugnumber)
Pavel Labath674bc7b2015-05-29 14:54:46 +0000738
Vince Harron7ac3ea42015-06-26 15:13:21 +0000739# if the test passes on the first try, we're done (success)
740# if the test fails once, then passes on the second try, raise an ExpectedFailure
741# if the test fails twice in a row, re-throw the exception from the second test run
742def expectedFlakey(expected_fn, bugnumber=None):
743 def expectedFailure_impl(func):
744 @wraps(func)
745 def wrapper(*args, **kwargs):
746 from unittest2 import case
747 self = args[0]
748 try:
749 func(*args, **kwargs)
Ying Chen0a7202b2015-07-01 22:44:27 +0000750 # don't retry if the test case is already decorated with xfail or skip
751 except (case._ExpectedFailure, case.SkipTest, case._UnexpectedSuccess):
752 raise
Vince Harron7ac3ea42015-06-26 15:13:21 +0000753 except Exception:
754 if expected_fn(self):
Ying Chen0a7202b2015-07-01 22:44:27 +0000755 # before retry, run tearDown for previous run and setup for next
Vince Harron7ac3ea42015-06-26 15:13:21 +0000756 try:
Ying Chen0a7202b2015-07-01 22:44:27 +0000757 self.tearDown()
758 self.setUp()
Vince Harron7ac3ea42015-06-26 15:13:21 +0000759 func(*args, **kwargs)
760 except Exception:
761 # oh snap! two failures in a row, record a failure/error
762 raise
763 # record the expected failure
764 raise case._ExpectedFailure(sys.exc_info(), bugnumber)
765 else:
766 raise
767 return wrapper
768 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
769 # return decorator in this case, so it will be used to decorating original method
770 if callable(bugnumber):
771 return expectedFailure_impl(bugnumber)
772 else:
773 return expectedFailure_impl
774
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000775def expectedFlakeyDwarf(bugnumber=None):
776 def fn(self):
777 return self.debug_info == "dwarf"
778 return expectedFlakey(fn, bugnumber)
779
780def expectedFlakeyDsym(bugnumber=None):
781 def fn(self):
782 return self.debug_info == "dwarf"
783 return expectedFlakey(fn, bugnumber)
784
Vince Harron7ac3ea42015-06-26 15:13:21 +0000785def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
786 def fn(self):
787 return (self.getPlatform() in oslist and
788 self.expectedCompiler(compilers))
789 return expectedFlakey(fn, bugnumber)
790
791def expectedFlakeyDarwin(bugnumber=None, compilers=None):
792 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
793 return expectedFlakeyOS(getDarwinOSTriples(), bugnumber, compilers)
794
795def expectedFlakeyLinux(bugnumber=None, compilers=None):
796 return expectedFlakeyOS(['linux'], bugnumber, compilers)
797
798def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
799 return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
800
801def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
802 if compiler_version is None:
803 compiler_version=['=', None]
804 def fn(self):
805 return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
806 return expectedFlakey(fn, bugnumber)
807
808# @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
809def expectedFlakeyClang(bugnumber=None, compiler_version=None):
810 return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
811
812# @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
813def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
814 return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
815
Pavel Labath63a579c2015-09-07 12:15:27 +0000816def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
817 return expectedFlakey(matchAndroid(api_levels, archs), bugnumber)
818
Greg Clayton12514562013-12-05 22:22:32 +0000819def skipIfRemote(func):
820 """Decorate the item to skip tests if testing remotely."""
821 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
822 raise Exception("@skipIfRemote can only be used to decorate a test method")
823 @wraps(func)
824 def wrapper(*args, **kwargs):
825 from unittest2 import case
826 if lldb.remote_platform:
827 self = args[0]
828 self.skipTest("skip on remote platform")
829 else:
830 func(*args, **kwargs)
831 return wrapper
832
Siva Chandra4470f382015-06-17 22:32:27 +0000833def skipUnlessListedRemote(remote_list=None):
834 def myImpl(func):
835 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
836 raise Exception("@skipIfRemote can only be used to decorate a "
837 "test method")
838
839 @wraps(func)
840 def wrapper(*args, **kwargs):
841 if remote_list and lldb.remote_platform:
842 self = args[0]
843 triple = self.dbg.GetSelectedPlatform().GetTriple()
844 for r in remote_list:
845 if r in triple:
846 func(*args, **kwargs)
847 return
848 self.skipTest("skip on remote platform %s" % str(triple))
849 else:
850 func(*args, **kwargs)
851 return wrapper
852
853 return myImpl
854
Greg Clayton12514562013-12-05 22:22:32 +0000855def skipIfRemoteDueToDeadlock(func):
856 """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
857 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
858 raise Exception("@skipIfRemote can only be used to decorate a test method")
859 @wraps(func)
860 def wrapper(*args, **kwargs):
861 from unittest2 import case
862 if lldb.remote_platform:
863 self = args[0]
864 self.skipTest("skip on remote platform (deadlocks)")
865 else:
866 func(*args, **kwargs)
867 return wrapper
868
Enrico Granatab633e432014-10-06 21:37:06 +0000869def skipIfNoSBHeaders(func):
870 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
871 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Ed Maste59cca5d2014-10-07 01:57:52 +0000872 raise Exception("@skipIfNoSBHeaders can only be used to decorate a test method")
Enrico Granatab633e432014-10-06 21:37:06 +0000873 @wraps(func)
874 def wrapper(*args, **kwargs):
875 from unittest2 import case
876 self = args[0]
Shawn Best181b09b2014-11-08 00:04:04 +0000877 if sys.platform.startswith("darwin"):
878 header = os.path.join(self.lib_dir, 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
879 else:
880 header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
Enrico Granatab633e432014-10-06 21:37:06 +0000881 platform = sys.platform
Enrico Granatab633e432014-10-06 21:37:06 +0000882 if not os.path.exists(header):
883 self.skipTest("skip because LLDB.h header not found")
884 else:
885 func(*args, **kwargs)
886 return wrapper
887
Robert Flack13c7ad92015-03-30 14:12:17 +0000888def skipIfFreeBSD(func):
889 """Decorate the item to skip tests that should be skipped on FreeBSD."""
890 return skipIfPlatform(["freebsd"])(func)
Zachary Turnerc7826522014-08-13 17:44:53 +0000891
Greg Claytone0d0a762015-04-02 18:24:03 +0000892def getDarwinOSTriples():
893 return ['darwin', 'macosx', 'ios']
894
Daniel Maleab3d41a22013-07-09 00:08:01 +0000895def skipIfDarwin(func):
896 """Decorate the item to skip tests that should be skipped on Darwin."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000897 return skipIfPlatform(getDarwinOSTriples())(func)
Daniel Maleab3d41a22013-07-09 00:08:01 +0000898
Robert Flack13c7ad92015-03-30 14:12:17 +0000899def skipIfLinux(func):
900 """Decorate the item to skip tests that should be skipped on Linux."""
901 return skipIfPlatform(["linux"])(func)
902
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000903def skipUnlessHostLinux(func):
904 """Decorate the item to skip tests that should be skipped on any non Linux host."""
905 return skipUnlessHostPlatform(["linux"])(func)
906
Robert Flack13c7ad92015-03-30 14:12:17 +0000907def skipIfWindows(func):
908 """Decorate the item to skip tests that should be skipped on Windows."""
909 return skipIfPlatform(["windows"])(func)
910
Chaoren Line6eea5d2015-06-08 22:13:28 +0000911def skipIfHostWindows(func):
912 """Decorate the item to skip tests that should be skipped on Windows."""
913 return skipIfHostPlatform(["windows"])(func)
914
Adrian McCarthyd9dbae52015-09-16 18:17:11 +0000915def skipUnlessWindows(func):
916 """Decorate the item to skip tests that should be skipped on any non-Windows platform."""
917 return skipUnlessPlatform(["windows"])(func)
918
Robert Flack13c7ad92015-03-30 14:12:17 +0000919def skipUnlessDarwin(func):
920 """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000921 return skipUnlessPlatform(getDarwinOSTriples())(func)
Robert Flack13c7ad92015-03-30 14:12:17 +0000922
Ryan Brown57bee1e2015-09-14 22:45:11 +0000923def skipUnlessGoInstalled(func):
924 """Decorate the item to skip tests when no Go compiler is available."""
925 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
926 raise Exception("@skipIfGcc can only be used to decorate a test method")
927 @wraps(func)
928 def wrapper(*args, **kwargs):
929 from unittest2 import case
930 self = args[0]
931 compiler = self.getGoCompilerVersion()
932 if not compiler:
933 self.skipTest("skipping because go compiler not found")
934 else:
Todd Fialabe5dfc52015-10-06 19:15:56 +0000935 # Ensure the version is the minimum version supported by
Todd Fiala02c08d02015-10-06 22:14:33 +0000936 # the LLDB go support.
Todd Fialabe5dfc52015-10-06 19:15:56 +0000937 match_version = re.search(r"(\d+\.\d+(\.\d+)?)", compiler)
938 if not match_version:
939 # Couldn't determine version.
940 self.skipTest(
941 "skipping because go version could not be parsed "
942 "out of {}".format(compiler))
943 else:
944 from distutils.version import StrictVersion
Todd Fiala02c08d02015-10-06 22:14:33 +0000945 min_strict_version = StrictVersion("1.4.0")
Todd Fialabe5dfc52015-10-06 19:15:56 +0000946 compiler_strict_version = StrictVersion(match_version.group(1))
947 if compiler_strict_version < min_strict_version:
948 self.skipTest(
949 "skipping because available go version ({}) does "
Todd Fiala02c08d02015-10-06 22:14:33 +0000950 "not meet minimum required go version ({})".format(
Todd Fialabe5dfc52015-10-06 19:15:56 +0000951 compiler_strict_version,
952 min_strict_version))
Todd Fiala9f236802015-10-06 19:23:22 +0000953 func(*args, **kwargs)
Ryan Brown57bee1e2015-09-14 22:45:11 +0000954 return wrapper
955
Robert Flack068898c2015-04-09 18:07:58 +0000956def getPlatform():
Robert Flack6e1fd352015-05-15 12:39:33 +0000957 """Returns the target platform which the tests are running on."""
Robert Flack068898c2015-04-09 18:07:58 +0000958 platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
959 if platform.startswith('freebsd'):
960 platform = 'freebsd'
961 return platform
962
Robert Flack6e1fd352015-05-15 12:39:33 +0000963def getHostPlatform():
964 """Returns the host platform running the test suite."""
965 # Attempts to return a platform name matching a target Triple platform.
966 if sys.platform.startswith('linux'):
967 return 'linux'
968 elif sys.platform.startswith('win32'):
969 return 'windows'
970 elif sys.platform.startswith('darwin'):
971 return 'darwin'
972 elif sys.platform.startswith('freebsd'):
973 return 'freebsd'
974 else:
975 return sys.platform
976
Robert Flackfb2f6c62015-04-17 08:02:18 +0000977def platformIsDarwin():
978 """Returns true if the OS triple for the selected platform is any valid apple OS"""
979 return getPlatform() in getDarwinOSTriples()
980
Robert Flack6e1fd352015-05-15 12:39:33 +0000981def skipIfHostIncompatibleWithRemote(func):
982 """Decorate the item to skip tests if binaries built on this host are incompatible."""
983 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
984 raise Exception("@skipIfHostIncompatibleWithRemote can only be used to decorate a test method")
985 @wraps(func)
986 def wrapper(*args, **kwargs):
987 from unittest2 import case
988 self = args[0]
989 host_arch = self.getLldbArchitecture()
990 host_platform = getHostPlatform()
991 target_arch = self.getArchitecture()
Robert Flack4629c4b2015-05-15 18:54:32 +0000992 target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
Robert Flack6e1fd352015-05-15 12:39:33 +0000993 if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
994 self.skipTest("skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch))
995 elif target_platform != host_platform:
996 self.skipTest("skipping because target is %s but host is %s" % (target_platform, host_platform))
997 else:
998 func(*args, **kwargs)
999 return wrapper
1000
Chaoren Line6eea5d2015-06-08 22:13:28 +00001001def skipIfHostPlatform(oslist):
1002 """Decorate the item to skip tests if running on one of the listed host platforms."""
1003 return unittest2.skipIf(getHostPlatform() in oslist,
1004 "skip on %s" % (", ".join(oslist)))
1005
1006def skipUnlessHostPlatform(oslist):
1007 """Decorate the item to skip tests unless running on one of the listed host platforms."""
1008 return unittest2.skipUnless(getHostPlatform() in oslist,
1009 "requires on of %s" % (", ".join(oslist)))
1010
Zachary Turner793d9972015-08-14 23:29:24 +00001011def skipUnlessArch(archlist):
1012 """Decorate the item to skip tests unless running on one of the listed architectures."""
1013 def myImpl(func):
1014 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1015 raise Exception("@skipUnlessArch can only be used to decorate a test method")
1016
1017 @wraps(func)
1018 def wrapper(*args, **kwargs):
1019 self = args[0]
1020 if self.getArchitecture() not in archlist:
1021 self.skipTest("skipping for architecture %s (requires one of %s)" %
1022 (self.getArchitecture(), ", ".join(archlist)))
1023 else:
1024 func(*args, **kwargs)
1025 return wrapper
1026
1027 return myImpl
1028
Robert Flack13c7ad92015-03-30 14:12:17 +00001029def skipIfPlatform(oslist):
1030 """Decorate the item to skip tests if running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +00001031 return unittest2.skipIf(getPlatform() in oslist,
1032 "skip on %s" % (", ".join(oslist)))
Robert Flack13c7ad92015-03-30 14:12:17 +00001033
1034def skipUnlessPlatform(oslist):
1035 """Decorate the item to skip tests unless running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +00001036 return unittest2.skipUnless(getPlatform() in oslist,
1037 "requires on of %s" % (", ".join(oslist)))
Daniel Maleab3d41a22013-07-09 00:08:01 +00001038
Daniel Malea48359902013-05-14 20:48:54 +00001039def skipIfLinuxClang(func):
1040 """Decorate the item to skip tests that should be skipped if building on
1041 Linux with clang.
1042 """
1043 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1044 raise Exception("@skipIfLinuxClang can only be used to decorate a test method")
1045 @wraps(func)
1046 def wrapper(*args, **kwargs):
1047 from unittest2 import case
1048 self = args[0]
1049 compiler = self.getCompiler()
Vince Harronc8492672015-05-04 02:59:19 +00001050 platform = self.getPlatform()
1051 if "clang" in compiler and platform == "linux":
Daniel Malea48359902013-05-14 20:48:54 +00001052 self.skipTest("skipping because Clang is used on Linux")
1053 else:
1054 func(*args, **kwargs)
1055 return wrapper
1056
Ying Chen7091c2c2015-04-21 01:15:47 +00001057# provide a function to skip on defined oslist, compiler version, and archs
1058# if none is specified for any argument, that argument won't be checked and thus means for all
1059# for example,
1060# @skipIf, skip for all platform/compiler/arch,
1061# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
1062# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
1063
1064# TODO: refactor current code, to make skipIfxxx functions to call this function
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00001065def skipIf(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, debug_info=None):
Ying Chen7091c2c2015-04-21 01:15:47 +00001066 def fn(self):
1067 return ((oslist is None or self.getPlatform() in oslist) and
1068 (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00001069 self.expectedArch(archs) and
1070 (debug_info is None or self.debug_info in debug_info))
1071 return skipTestIfFn(fn, bugnumber, skipReason="skipping because os:%s compiler: %s %s arch: %s debug info: %s"%(oslist, compiler, compiler_version, archs, debug_info))
1072
1073def skipIfDebugInfo(bugnumber=None, debug_info=None):
1074 return skipIf(bugnumber=bugnumber, debug_info=debug_info)
1075
Greg Claytonedea2372015-10-07 20:01:13 +00001076def skipIfDWO(bugnumber=None):
1077 return skipIfDebugInfo(bugnumber, ["dwo"])
1078
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00001079def skipIfDwarf(bugnumber=None):
1080 return skipIfDebugInfo(bugnumber, ["dwarf"])
1081
1082def skipIfDsym(bugnumber=None):
1083 return skipIfDebugInfo(bugnumber, ["dsym"])
Ying Chen7091c2c2015-04-21 01:15:47 +00001084
1085def skipTestIfFn(expected_fn, bugnumber=None, skipReason=None):
1086 def skipTestIfFn_impl(func):
1087 @wraps(func)
1088 def wrapper(*args, **kwargs):
1089 from unittest2 import case
1090 self = args[0]
1091 if expected_fn(self):
1092 self.skipTest(skipReason)
1093 else:
1094 func(*args, **kwargs)
1095 return wrapper
1096 if callable(bugnumber):
1097 return skipTestIfFn_impl(bugnumber)
1098 else:
1099 return skipTestIfFn_impl
1100
Daniel Maleabe230792013-01-24 23:52:09 +00001101def skipIfGcc(func):
1102 """Decorate the item to skip tests that should be skipped if building with gcc ."""
1103 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Daniel Malea0aea0162013-02-27 17:29:46 +00001104 raise Exception("@skipIfGcc can only be used to decorate a test method")
Daniel Maleabe230792013-01-24 23:52:09 +00001105 @wraps(func)
1106 def wrapper(*args, **kwargs):
1107 from unittest2 import case
1108 self = args[0]
1109 compiler = self.getCompiler()
1110 if "gcc" in compiler:
1111 self.skipTest("skipping because gcc is the test compiler")
1112 else:
1113 func(*args, **kwargs)
1114 return wrapper
1115
Matt Kopec0de53f02013-03-15 19:10:12 +00001116def skipIfIcc(func):
1117 """Decorate the item to skip tests that should be skipped if building with icc ."""
1118 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1119 raise Exception("@skipIfIcc can only be used to decorate a test method")
1120 @wraps(func)
1121 def wrapper(*args, **kwargs):
1122 from unittest2 import case
1123 self = args[0]
1124 compiler = self.getCompiler()
1125 if "icc" in compiler:
1126 self.skipTest("skipping because icc is the test compiler")
1127 else:
1128 func(*args, **kwargs)
1129 return wrapper
1130
Daniel Malea55faa402013-05-02 21:44:31 +00001131def skipIfi386(func):
1132 """Decorate the item to skip tests that should be skipped if building 32-bit."""
1133 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1134 raise Exception("@skipIfi386 can only be used to decorate a test method")
1135 @wraps(func)
1136 def wrapper(*args, **kwargs):
1137 from unittest2 import case
1138 self = args[0]
1139 if "i386" == self.getArchitecture():
1140 self.skipTest("skipping because i386 is not a supported architecture")
1141 else:
1142 func(*args, **kwargs)
1143 return wrapper
1144
Pavel Labath090152b2015-08-20 11:37:19 +00001145def skipIfTargetAndroid(api_levels=None, archs=None):
Siva Chandra77f20fc2015-06-05 19:54:49 +00001146 """Decorator to skip tests when the target is Android.
1147
1148 Arguments:
1149 api_levels - The API levels for which the test should be skipped. If
1150 it is None, then the test will be skipped for all API levels.
Pavel Labath090152b2015-08-20 11:37:19 +00001151 arch - A sequence of architecture names specifying the architectures
1152 for which a test is skipped. None means all architectures.
Siva Chandra77f20fc2015-06-05 19:54:49 +00001153 """
1154 def myImpl(func):
1155 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1156 raise Exception("@skipIfTargetAndroid can only be used to "
1157 "decorate a test method")
1158 @wraps(func)
1159 def wrapper(*args, **kwargs):
1160 from unittest2 import case
1161 self = args[0]
Pavel Labath090152b2015-08-20 11:37:19 +00001162 if matchAndroid(api_levels, archs)(self):
1163 self.skipTest("skiped on Android target with API %d and architecture %s" %
1164 (android_device_api(), self.getArchitecture()))
Tamas Berghammer1253a812015-03-13 10:12:25 +00001165 func(*args, **kwargs)
Siva Chandra77f20fc2015-06-05 19:54:49 +00001166 return wrapper
1167 return myImpl
Tamas Berghammer1253a812015-03-13 10:12:25 +00001168
Ilia Kd9953052015-03-12 07:19:41 +00001169def skipUnlessCompilerRt(func):
1170 """Decorate the item to skip tests if testing remotely."""
1171 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1172 raise Exception("@skipUnless can only be used to decorate a test method")
1173 @wraps(func)
1174 def wrapper(*args, **kwargs):
1175 from unittest2 import case
1176 import os.path
1177 compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "projects", "compiler-rt")
1178 if not os.path.exists(compilerRtPath):
1179 self = args[0]
1180 self.skipTest("skip if compiler-rt not found")
1181 else:
1182 func(*args, **kwargs)
1183 return wrapper
Daniel Malea55faa402013-05-02 21:44:31 +00001184
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001185class _PlatformContext(object):
1186 """Value object class which contains platform-specific options."""
1187
1188 def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
1189 self.shlib_environment_var = shlib_environment_var
1190 self.shlib_prefix = shlib_prefix
1191 self.shlib_extension = shlib_extension
1192
1193
Johnny Chena74bb0a2011-08-01 18:46:13 +00001194class Base(unittest2.TestCase):
Johnny Chen8334dad2010-10-22 23:15:46 +00001195 """
Johnny Chena74bb0a2011-08-01 18:46:13 +00001196 Abstract base for performing lldb (see TestBase) or other generic tests (see
1197 BenchBase for one example). lldbtest.Base works with the test driver to
1198 accomplish things.
1199
Johnny Chen8334dad2010-10-22 23:15:46 +00001200 """
Enrico Granata5020f952012-10-24 21:42:49 +00001201
Enrico Granata19186272012-10-24 21:44:48 +00001202 # The concrete subclass should override this attribute.
1203 mydir = None
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001204
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001205 # Keep track of the old current working directory.
1206 oldcwd = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001207
Greg Clayton4570d3e2013-12-10 23:19:29 +00001208 @staticmethod
1209 def compute_mydir(test_file):
1210 '''Subclasses should call this function to correctly calculate the required "mydir" attribute as follows:
1211
1212 mydir = TestBase.compute_mydir(__file__)'''
1213 test_dir = os.path.dirname(test_file)
1214 return test_dir[len(os.environ["LLDB_TEST"])+1:]
1215
Johnny Chenfb4264c2011-08-01 19:50:58 +00001216 def TraceOn(self):
1217 """Returns True if we are in trace mode (tracing detailed test execution)."""
1218 return traceAlways
Greg Clayton4570d3e2013-12-10 23:19:29 +00001219
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001220 @classmethod
1221 def setUpClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001222 """
1223 Python unittest framework class setup fixture.
1224 Do current directory manipulation.
1225 """
Johnny Chenf02ec122010-07-03 20:41:42 +00001226 # Fail fast if 'mydir' attribute is not overridden.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001227 if not cls.mydir or len(cls.mydir) == 0:
Johnny Chenf02ec122010-07-03 20:41:42 +00001228 raise Exception("Subclasses must override the 'mydir' attribute.")
Enrico Granata7e137e32012-10-24 18:14:21 +00001229
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001230 # Save old working directory.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001231 cls.oldcwd = os.getcwd()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001232
1233 # Change current working directory if ${LLDB_TEST} is defined.
1234 # See also dotest.py which sets up ${LLDB_TEST}.
1235 if ("LLDB_TEST" in os.environ):
Vince Harron85d19652015-05-21 19:09:29 +00001236 full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001237 if traceAlways:
Vince Harron85d19652015-05-21 19:09:29 +00001238 print >> sys.stderr, "Change dir to:", full_dir
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001239 os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
1240
Vince Harron85d19652015-05-21 19:09:29 +00001241 if debug_confirm_directory_exclusivity:
Zachary Turnerb48b4042015-05-21 20:16:02 +00001242 import lock
Vince Harron85d19652015-05-21 19:09:29 +00001243 cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
1244 try:
1245 cls.dir_lock.try_acquire()
1246 # write the class that owns the lock into the lock file
1247 cls.dir_lock.handle.write(cls.__name__)
1248 except IOError as ioerror:
1249 # nothing else should have this directory lock
1250 # wait here until we get a lock
1251 cls.dir_lock.acquire()
1252 # read the previous owner from the lock file
1253 lock_id = cls.dir_lock.handle.read()
1254 print >> sys.stderr, "LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id)
1255 raise ioerror
1256
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001257 # Set platform context.
Robert Flackfb2f6c62015-04-17 08:02:18 +00001258 if platformIsDarwin():
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001259 cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
Robert Flackfb2f6c62015-04-17 08:02:18 +00001260 elif getPlatform() == "linux" or getPlatform() == "freebsd":
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001261 cls.platformContext = _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001262 else:
1263 cls.platformContext = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001264
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001265 @classmethod
1266 def tearDownClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001267 """
1268 Python unittest framework class teardown fixture.
1269 Do class-wide cleanup.
1270 """
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001271
Johnny Chen0fddfb22011-11-17 19:57:27 +00001272 if doCleanup and not lldb.skip_build_and_cleanup:
Johnny Chen707b3c92010-10-11 22:25:46 +00001273 # First, let's do the platform-specific cleanup.
Peter Collingbourne19f48d52011-06-20 19:06:20 +00001274 module = builder_module()
Zachary Turnerb1490b62015-08-26 19:44:56 +00001275 module.cleanup()
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001276
Johnny Chen707b3c92010-10-11 22:25:46 +00001277 # Subclass might have specific cleanup function defined.
1278 if getattr(cls, "classCleanup", None):
1279 if traceAlways:
1280 print >> sys.stderr, "Call class-specific cleanup function for class:", cls
1281 try:
1282 cls.classCleanup()
1283 except:
1284 exc_type, exc_value, exc_tb = sys.exc_info()
1285 traceback.print_exception(exc_type, exc_value, exc_tb)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001286
Vince Harron85d19652015-05-21 19:09:29 +00001287 if debug_confirm_directory_exclusivity:
1288 cls.dir_lock.release()
1289 del cls.dir_lock
1290
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001291 # Restore old working directory.
1292 if traceAlways:
Johnny Chen703dbd02010-09-30 17:06:24 +00001293 print >> sys.stderr, "Restore dir to:", cls.oldcwd
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001294 os.chdir(cls.oldcwd)
1295
Johnny Chena74bb0a2011-08-01 18:46:13 +00001296 @classmethod
1297 def skipLongRunningTest(cls):
1298 """
1299 By default, we skip long running test case.
1300 This can be overridden by passing '-l' to the test driver (dotest.py).
1301 """
1302 if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
1303 return False
1304 else:
1305 return True
Johnny Chened492022011-06-21 00:53:00 +00001306
Vince Harron6d3d0f12015-05-10 22:01:59 +00001307 def enableLogChannelsForCurrentTest(self):
1308 if len(lldbtest_config.channels) == 0:
1309 return
1310
1311 # if debug channels are specified in lldbtest_config.channels,
1312 # create a new set of log files for every test
1313 log_basename = self.getLogBasenameForCurrentTest()
1314
1315 # confirm that the file is writeable
1316 host_log_path = "{}-host.log".format(log_basename)
1317 open(host_log_path, 'w').close()
1318
1319 log_enable = "log enable -Tpn -f {} ".format(host_log_path)
1320 for channel_with_categories in lldbtest_config.channels:
1321 channel_then_categories = channel_with_categories.split(' ', 1)
1322 channel = channel_then_categories[0]
1323 if len(channel_then_categories) > 1:
1324 categories = channel_then_categories[1]
1325 else:
1326 categories = "default"
1327
1328 if channel == "gdb-remote":
1329 # communicate gdb-remote categories to debugserver
1330 os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
1331
1332 self.ci.HandleCommand(log_enable + channel_with_categories, self.res)
1333 if not self.res.Succeeded():
1334 raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
1335
1336 # Communicate log path name to debugserver & lldb-server
1337 server_log_path = "{}-server.log".format(log_basename)
1338 open(server_log_path, 'w').close()
1339 os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
1340
1341 # Communicate channels to lldb-server
1342 os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
1343
1344 if len(lldbtest_config.channels) == 0:
1345 return
1346
1347 def disableLogChannelsForCurrentTest(self):
1348 # close all log files that we opened
1349 for channel_and_categories in lldbtest_config.channels:
1350 # channel format - <channel-name> [<category0> [<category1> ...]]
1351 channel = channel_and_categories.split(' ', 1)[0]
1352 self.ci.HandleCommand("log disable " + channel, self.res)
1353 if not self.res.Succeeded():
1354 raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
1355
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001356 def setUp(self):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001357 """Fixture for unittest test case setup.
1358
1359 It works with the test driver to conditionally skip tests and does other
1360 initializations."""
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001361 #import traceback
1362 #traceback.print_stack()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001363
Daniel Malea9115f072013-08-06 15:02:32 +00001364 if "LIBCXX_PATH" in os.environ:
1365 self.libcxxPath = os.environ["LIBCXX_PATH"]
1366 else:
1367 self.libcxxPath = None
1368
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001369 if "LLDBMI_EXEC" in os.environ:
1370 self.lldbMiExec = os.environ["LLDBMI_EXEC"]
1371 else:
1372 self.lldbMiExec = None
1373 self.dont_do_lldbmi_test = True
Vince Harron790d95c2015-05-18 19:39:03 +00001374
Johnny Chenebe51722011-10-07 19:21:09 +00001375 # If we spawn an lldb process for test (via pexpect), do not load the
1376 # init file unless told otherwise.
1377 if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
1378 self.lldbOption = ""
1379 else:
1380 self.lldbOption = "--no-lldbinit"
Johnny Chenaaa82ff2011-08-02 22:54:37 +00001381
Johnny Chen985e7402011-08-01 21:13:26 +00001382 # Assign the test method name to self.testMethodName.
1383 #
1384 # For an example of the use of this attribute, look at test/types dir.
1385 # There are a bunch of test cases under test/types and we don't want the
1386 # module cacheing subsystem to be confused with executable name "a.out"
1387 # used for all the test cases.
1388 self.testMethodName = self._testMethodName
1389
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001390 # Python API only test is decorated with @python_api_test,
1391 # which also sets the "__python_api_test__" attribute of the
1392 # function object to True.
Johnny Chen4533dad2011-05-31 23:21:42 +00001393 try:
1394 if lldb.just_do_python_api_test:
1395 testMethod = getattr(self, self._testMethodName)
1396 if getattr(testMethod, "__python_api_test__", False):
1397 pass
1398 else:
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001399 self.skipTest("non python api test")
1400 except AttributeError:
1401 pass
1402
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001403 # lldb-mi only test is decorated with @lldbmi_test,
1404 # which also sets the "__lldbmi_test__" attribute of the
1405 # function object to True.
1406 try:
1407 if lldb.just_do_lldbmi_test:
1408 testMethod = getattr(self, self._testMethodName)
1409 if getattr(testMethod, "__lldbmi_test__", False):
1410 pass
1411 else:
1412 self.skipTest("non lldb-mi test")
1413 except AttributeError:
1414 pass
1415
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001416 # Benchmarks test is decorated with @benchmarks_test,
1417 # which also sets the "__benchmarks_test__" attribute of the
1418 # function object to True.
1419 try:
1420 if lldb.just_do_benchmarks_test:
1421 testMethod = getattr(self, self._testMethodName)
1422 if getattr(testMethod, "__benchmarks_test__", False):
1423 pass
1424 else:
1425 self.skipTest("non benchmarks test")
Johnny Chen4533dad2011-05-31 23:21:42 +00001426 except AttributeError:
1427 pass
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001428
Johnny Chen985e7402011-08-01 21:13:26 +00001429 # This is for the case of directly spawning 'lldb'/'gdb' and interacting
1430 # with it using pexpect.
1431 self.child = None
1432 self.child_prompt = "(lldb) "
1433 # If the child is interacting with the embedded script interpreter,
1434 # there are two exits required during tear down, first to quit the
1435 # embedded script interpreter and second to quit the lldb command
1436 # interpreter.
1437 self.child_in_script_interpreter = False
1438
Johnny Chenfb4264c2011-08-01 19:50:58 +00001439 # These are for customized teardown cleanup.
1440 self.dict = None
1441 self.doTearDownCleanup = False
1442 # And in rare cases where there are multiple teardown cleanups.
1443 self.dicts = []
1444 self.doTearDownCleanups = False
1445
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001446 # List of spawned subproces.Popen objects
1447 self.subprocesses = []
1448
Daniel Malea69207462013-06-05 21:07:02 +00001449 # List of forked process PIDs
1450 self.forkedProcessPids = []
1451
Johnny Chenfb4264c2011-08-01 19:50:58 +00001452 # Create a string buffer to record the session info, to be dumped into a
1453 # test case specific file if test failure is encountered.
Vince Harron1f160372015-05-21 18:51:20 +00001454 self.log_basename = self.getLogBasenameForCurrentTest()
Vince Harron35b17dc2015-05-21 18:20:21 +00001455
Vince Harron1f160372015-05-21 18:51:20 +00001456 session_file = "{}.log".format(self.log_basename)
Vince Harron35b17dc2015-05-21 18:20:21 +00001457 unbuffered = 0 # 0 is the constant for unbuffered
Vince Harron1f160372015-05-21 18:51:20 +00001458 self.session = open(session_file, "w", unbuffered)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001459
1460 # Optimistically set __errored__, __failed__, __expected__ to False
1461 # initially. If the test errored/failed, the session info
1462 # (self.session) is then dumped into a session specific file for
1463 # diagnosis.
Zachary Turnerb1490b62015-08-26 19:44:56 +00001464 self.__cleanup_errored__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001465 self.__errored__ = False
1466 self.__failed__ = False
1467 self.__expected__ = False
1468 # We are also interested in unexpected success.
1469 self.__unexpected__ = False
Johnny Chenf79b0762011-08-16 00:48:58 +00001470 # And skipped tests.
1471 self.__skipped__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001472
1473 # See addTearDownHook(self, hook) which allows the client to add a hook
1474 # function to be run during tearDown() time.
1475 self.hooks = []
1476
1477 # See HideStdout(self).
1478 self.sys_stdout_hidden = False
1479
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001480 if self.platformContext:
1481 # set environment variable names for finding shared libraries
1482 self.dylibPath = self.platformContext.shlib_environment_var
Daniel Malea179ff292012-11-26 21:21:11 +00001483
Vince Harron6d3d0f12015-05-10 22:01:59 +00001484 # Create the debugger instance if necessary.
1485 try:
1486 self.dbg = lldb.DBG
1487 except AttributeError:
1488 self.dbg = lldb.SBDebugger.Create()
1489
1490 if not self.dbg:
1491 raise Exception('Invalid debugger instance')
1492
1493 # Retrieve the associated command interpreter instance.
1494 self.ci = self.dbg.GetCommandInterpreter()
1495 if not self.ci:
1496 raise Exception('Could not get the command interpreter')
1497
1498 # And the result object.
1499 self.res = lldb.SBCommandReturnObject()
1500
1501 self.enableLogChannelsForCurrentTest()
1502
Johnny Chen2a808582011-10-19 16:48:07 +00001503 def runHooks(self, child=None, child_prompt=None, use_cmd_api=False):
Johnny Chena737ba52011-10-19 01:06:21 +00001504 """Perform the run hooks to bring lldb debugger to the desired state.
1505
Johnny Chen2a808582011-10-19 16:48:07 +00001506 By default, expect a pexpect spawned child and child prompt to be
1507 supplied (use_cmd_api=False). If use_cmd_api is true, ignore the child
1508 and child prompt and use self.runCmd() to run the hooks one by one.
1509
Johnny Chena737ba52011-10-19 01:06:21 +00001510 Note that child is a process spawned by pexpect.spawn(). If not, your
1511 test case is mostly likely going to fail.
1512
1513 See also dotest.py where lldb.runHooks are processed/populated.
1514 """
1515 if not lldb.runHooks:
1516 self.skipTest("No runhooks specified for lldb, skip the test")
Johnny Chen2a808582011-10-19 16:48:07 +00001517 if use_cmd_api:
1518 for hook in lldb.runhooks:
1519 self.runCmd(hook)
1520 else:
1521 if not child or not child_prompt:
1522 self.fail("Both child and child_prompt need to be defined.")
1523 for hook in lldb.runHooks:
1524 child.sendline(hook)
1525 child.expect_exact(child_prompt)
Johnny Chena737ba52011-10-19 01:06:21 +00001526
Daniel Malea249287a2013-02-19 16:08:57 +00001527 def setAsync(self, value):
1528 """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
1529 old_async = self.dbg.GetAsync()
1530 self.dbg.SetAsync(value)
1531 self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
1532
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001533 def cleanupSubprocesses(self):
1534 # Ensure any subprocesses are cleaned up
1535 for p in self.subprocesses:
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001536 p.terminate()
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001537 del p
1538 del self.subprocesses[:]
Daniel Malea69207462013-06-05 21:07:02 +00001539 # Ensure any forked processes are cleaned up
1540 for pid in self.forkedProcessPids:
1541 if os.path.exists("/proc/" + str(pid)):
1542 os.kill(pid, signal.SIGTERM)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001543
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001544 def spawnSubprocess(self, executable, args=[], install_remote=True):
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001545 """ Creates a subprocess.Popen object with the specified executable and arguments,
1546 saves it in self.subprocesses, and returns the object.
1547 NOTE: if using this function, ensure you also call:
1548
1549 self.addTearDownHook(self.cleanupSubprocesses)
1550
1551 otherwise the test suite will leak processes.
1552 """
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001553 proc = _RemoteProcess(install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001554 proc.launch(executable, args)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001555 self.subprocesses.append(proc)
1556 return proc
1557
Daniel Malea69207462013-06-05 21:07:02 +00001558 def forkSubprocess(self, executable, args=[]):
1559 """ Fork a subprocess with its own group ID.
1560 NOTE: if using this function, ensure you also call:
1561
1562 self.addTearDownHook(self.cleanupSubprocesses)
1563
1564 otherwise the test suite will leak processes.
1565 """
1566 child_pid = os.fork()
1567 if child_pid == 0:
1568 # If more I/O support is required, this can be beefed up.
1569 fd = os.open(os.devnull, os.O_RDWR)
Daniel Malea69207462013-06-05 21:07:02 +00001570 os.dup2(fd, 1)
1571 os.dup2(fd, 2)
1572 # This call causes the child to have its of group ID
1573 os.setpgid(0,0)
1574 os.execvp(executable, [executable] + args)
1575 # Give the child time to get through the execvp() call
1576 time.sleep(0.1)
1577 self.forkedProcessPids.append(child_pid)
1578 return child_pid
1579
Johnny Chenfb4264c2011-08-01 19:50:58 +00001580 def HideStdout(self):
1581 """Hide output to stdout from the user.
1582
1583 During test execution, there might be cases where we don't want to show the
1584 standard output to the user. For example,
1585
1586 self.runCmd(r'''sc print "\n\n\tHello!\n"''')
1587
1588 tests whether command abbreviation for 'script' works or not. There is no
1589 need to show the 'Hello' output to the user as long as the 'script' command
1590 succeeds and we are not in TraceOn() mode (see the '-t' option).
1591
1592 In this case, the test method calls self.HideStdout(self) to redirect the
1593 sys.stdout to a null device, and restores the sys.stdout upon teardown.
1594
1595 Note that you should only call this method at most once during a test case
1596 execution. Any subsequent call has no effect at all."""
1597 if self.sys_stdout_hidden:
1598 return
1599
1600 self.sys_stdout_hidden = True
1601 old_stdout = sys.stdout
1602 sys.stdout = open(os.devnull, 'w')
1603 def restore_stdout():
1604 sys.stdout = old_stdout
1605 self.addTearDownHook(restore_stdout)
1606
1607 # =======================================================================
1608 # Methods for customized teardown cleanups as well as execution of hooks.
1609 # =======================================================================
1610
1611 def setTearDownCleanup(self, dictionary=None):
1612 """Register a cleanup action at tearDown() time with a dictinary"""
1613 self.dict = dictionary
1614 self.doTearDownCleanup = True
1615
1616 def addTearDownCleanup(self, dictionary):
1617 """Add a cleanup action at tearDown() time with a dictinary"""
1618 self.dicts.append(dictionary)
1619 self.doTearDownCleanups = True
1620
1621 def addTearDownHook(self, hook):
1622 """
1623 Add a function to be run during tearDown() time.
1624
1625 Hooks are executed in a first come first serve manner.
1626 """
1627 if callable(hook):
1628 with recording(self, traceAlways) as sbuf:
1629 print >> sbuf, "Adding tearDown hook:", getsource_if_available(hook)
1630 self.hooks.append(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001631
1632 return self
Johnny Chenfb4264c2011-08-01 19:50:58 +00001633
Jim Inghamda3a3862014-10-16 23:02:14 +00001634 def deletePexpectChild(self):
Johnny Chen985e7402011-08-01 21:13:26 +00001635 # This is for the case of directly spawning 'lldb' and interacting with it
1636 # using pexpect.
Johnny Chen985e7402011-08-01 21:13:26 +00001637 if self.child and self.child.isalive():
Zachary Turner9ef307b2014-07-22 16:19:29 +00001638 import pexpect
Johnny Chen985e7402011-08-01 21:13:26 +00001639 with recording(self, traceAlways) as sbuf:
1640 print >> sbuf, "tearing down the child process...."
Johnny Chen985e7402011-08-01 21:13:26 +00001641 try:
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001642 if self.child_in_script_interpreter:
1643 self.child.sendline('quit()')
1644 self.child.expect_exact(self.child_prompt)
1645 self.child.sendline('settings set interpreter.prompt-on-quit false')
1646 self.child.sendline('quit')
Johnny Chen985e7402011-08-01 21:13:26 +00001647 self.child.expect(pexpect.EOF)
Ilia K47448c22015-02-11 21:41:58 +00001648 except (ValueError, pexpect.ExceptionPexpect):
1649 # child is already terminated
1650 pass
1651 except OSError as exception:
1652 import errno
1653 if exception.errno != errno.EIO:
1654 # unexpected error
1655 raise
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001656 # child is already terminated
Johnny Chen985e7402011-08-01 21:13:26 +00001657 pass
Shawn Besteb3e9052014-11-06 17:52:15 +00001658 finally:
1659 # Give it one final blow to make sure the child is terminated.
1660 self.child.close()
Jim Inghamda3a3862014-10-16 23:02:14 +00001661
1662 def tearDown(self):
1663 """Fixture for unittest test case teardown."""
1664 #import traceback
1665 #traceback.print_stack()
1666
1667 self.deletePexpectChild()
1668
Johnny Chenfb4264c2011-08-01 19:50:58 +00001669 # Check and run any hook functions.
1670 for hook in reversed(self.hooks):
1671 with recording(self, traceAlways) as sbuf:
1672 print >> sbuf, "Executing tearDown hook:", getsource_if_available(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001673 import inspect
1674 hook_argc = len(inspect.getargspec(hook).args)
Enrico Granata6e0566c2014-11-17 19:00:20 +00001675 if hook_argc == 0 or getattr(hook,'im_self',None):
Enrico Granataab0e8312014-11-05 21:31:57 +00001676 hook()
1677 elif hook_argc == 1:
1678 hook(self)
1679 else:
1680 hook() # try the plain call and hope it works
Johnny Chenfb4264c2011-08-01 19:50:58 +00001681
1682 del self.hooks
1683
1684 # Perform registered teardown cleanup.
1685 if doCleanup and self.doTearDownCleanup:
Johnny Chen0fddfb22011-11-17 19:57:27 +00001686 self.cleanup(dictionary=self.dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001687
1688 # In rare cases where there are multiple teardown cleanups added.
1689 if doCleanup and self.doTearDownCleanups:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001690 if self.dicts:
1691 for dict in reversed(self.dicts):
Johnny Chen0fddfb22011-11-17 19:57:27 +00001692 self.cleanup(dictionary=dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001693
Vince Harron9753dd92015-05-10 15:22:09 +00001694 self.disableLogChannelsForCurrentTest()
1695
Johnny Chenfb4264c2011-08-01 19:50:58 +00001696 # =========================================================
1697 # Various callbacks to allow introspection of test progress
1698 # =========================================================
1699
1700 def markError(self):
1701 """Callback invoked when an error (unexpected exception) errored."""
1702 self.__errored__ = True
1703 with recording(self, False) as sbuf:
1704 # False because there's no need to write "ERROR" to the stderr twice.
1705 # Once by the Python unittest framework, and a second time by us.
1706 print >> sbuf, "ERROR"
1707
Zachary Turnerb1490b62015-08-26 19:44:56 +00001708 def markCleanupError(self):
1709 """Callback invoked when an error occurs while a test is cleaning up."""
1710 self.__cleanup_errored__ = True
1711 with recording(self, False) as sbuf:
1712 # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
1713 # Once by the Python unittest framework, and a second time by us.
1714 print >> sbuf, "CLEANUP_ERROR"
1715
Johnny Chenfb4264c2011-08-01 19:50:58 +00001716 def markFailure(self):
1717 """Callback invoked when a failure (test assertion failure) occurred."""
1718 self.__failed__ = True
1719 with recording(self, False) as sbuf:
1720 # False because there's no need to write "FAIL" to the stderr twice.
1721 # Once by the Python unittest framework, and a second time by us.
1722 print >> sbuf, "FAIL"
1723
Enrico Granatae6cedc12013-02-23 01:05:23 +00001724 def markExpectedFailure(self,err,bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001725 """Callback invoked when an expected failure/error occurred."""
1726 self.__expected__ = True
1727 with recording(self, False) as sbuf:
1728 # False because there's no need to write "expected failure" to the
1729 # stderr twice.
1730 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001731 if bugnumber == None:
1732 print >> sbuf, "expected failure"
1733 else:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001734 print >> sbuf, "expected failure (problem id:" + str(bugnumber) + ")"
Johnny Chenfb4264c2011-08-01 19:50:58 +00001735
Johnny Chenc5cc6252011-08-15 23:09:08 +00001736 def markSkippedTest(self):
1737 """Callback invoked when a test is skipped."""
1738 self.__skipped__ = True
1739 with recording(self, False) as sbuf:
1740 # False because there's no need to write "skipped test" to the
1741 # stderr twice.
1742 # Once by the Python unittest framework, and a second time by us.
1743 print >> sbuf, "skipped test"
1744
Enrico Granatae6cedc12013-02-23 01:05:23 +00001745 def markUnexpectedSuccess(self, bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001746 """Callback invoked when an unexpected success occurred."""
1747 self.__unexpected__ = True
1748 with recording(self, False) as sbuf:
1749 # False because there's no need to write "unexpected success" to the
1750 # stderr twice.
1751 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001752 if bugnumber == None:
1753 print >> sbuf, "unexpected success"
1754 else:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001755 print >> sbuf, "unexpected success (problem id:" + str(bugnumber) + ")"
Johnny Chenfb4264c2011-08-01 19:50:58 +00001756
Greg Clayton70995582015-01-07 22:25:50 +00001757 def getRerunArgs(self):
1758 return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
Vince Harron9753dd92015-05-10 15:22:09 +00001759
1760 def getLogBasenameForCurrentTest(self, prefix=None):
1761 """
1762 returns a partial path that can be used as the beginning of the name of multiple
1763 log files pertaining to this test
1764
1765 <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
1766 """
1767 dname = os.path.join(os.environ["LLDB_TEST"],
1768 os.environ["LLDB_SESSION_DIRNAME"])
1769 if not os.path.isdir(dname):
1770 os.mkdir(dname)
1771
1772 compiler = self.getCompiler()
1773
1774 if compiler[1] == ':':
1775 compiler = compiler[2:]
Chaoren Lin636a0e32015-07-17 21:40:11 +00001776 if os.path.altsep is not None:
1777 compiler = compiler.replace(os.path.altsep, os.path.sep)
Vince Harron9753dd92015-05-10 15:22:09 +00001778
Vince Harron19e300f2015-05-12 00:50:54 +00001779 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
Vince Harron9753dd92015-05-10 15:22:09 +00001780 if len(fname) > 200:
Vince Harron19e300f2015-05-12 00:50:54 +00001781 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
Vince Harron9753dd92015-05-10 15:22:09 +00001782
1783 if prefix is not None:
1784 fname = "{}-{}".format(prefix, fname)
1785
1786 return os.path.join(dname, fname)
1787
Johnny Chenfb4264c2011-08-01 19:50:58 +00001788 def dumpSessionInfo(self):
1789 """
1790 Dump the debugger interactions leading to a test error/failure. This
1791 allows for more convenient postmortem analysis.
1792
1793 See also LLDBTestResult (dotest.py) which is a singlton class derived
1794 from TextTestResult and overwrites addError, addFailure, and
1795 addExpectedFailure methods to allow us to to mark the test instance as
1796 such.
1797 """
1798
1799 # We are here because self.tearDown() detected that this test instance
1800 # either errored or failed. The lldb.test_result singleton contains
1801 # two lists (erros and failures) which get populated by the unittest
1802 # framework. Look over there for stack trace information.
1803 #
1804 # The lists contain 2-tuples of TestCase instances and strings holding
1805 # formatted tracebacks.
1806 #
1807 # See http://docs.python.org/library/unittest.html#unittest.TestResult.
Vince Harron9753dd92015-05-10 15:22:09 +00001808
Vince Harron35b17dc2015-05-21 18:20:21 +00001809 # output tracebacks into session
Vince Harron9753dd92015-05-10 15:22:09 +00001810 pairs = []
Johnny Chenfb4264c2011-08-01 19:50:58 +00001811 if self.__errored__:
1812 pairs = lldb.test_result.errors
1813 prefix = 'Error'
Zachary Turner14181db2015-09-11 21:27:37 +00001814 elif self.__cleanup_errored__:
Zachary Turnerb1490b62015-08-26 19:44:56 +00001815 pairs = lldb.test_result.cleanup_errors
1816 prefix = 'CleanupError'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001817 elif self.__failed__:
1818 pairs = lldb.test_result.failures
1819 prefix = 'Failure'
1820 elif self.__expected__:
1821 pairs = lldb.test_result.expectedFailures
1822 prefix = 'ExpectedFailure'
Johnny Chenc5cc6252011-08-15 23:09:08 +00001823 elif self.__skipped__:
1824 prefix = 'SkippedTest'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001825 elif self.__unexpected__:
Vince Harron35b17dc2015-05-21 18:20:21 +00001826 prefix = 'UnexpectedSuccess'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001827 else:
Vince Harron35b17dc2015-05-21 18:20:21 +00001828 prefix = 'Success'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001829
Johnny Chenc5cc6252011-08-15 23:09:08 +00001830 if not self.__unexpected__ and not self.__skipped__:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001831 for test, traceback in pairs:
1832 if test is self:
1833 print >> self.session, traceback
1834
Vince Harron35b17dc2015-05-21 18:20:21 +00001835 # put footer (timestamp/rerun instructions) into session
Johnny Chen8082a002011-08-11 00:16:28 +00001836 testMethod = getattr(self, self._testMethodName)
1837 if getattr(testMethod, "__benchmarks_test__", False):
1838 benchmarks = True
1839 else:
1840 benchmarks = False
1841
Vince Harron35b17dc2015-05-21 18:20:21 +00001842 import datetime
1843 print >> self.session, "Session info generated @", datetime.datetime.now().ctime()
1844 print >> self.session, "To rerun this test, issue the following command from the 'test' directory:\n"
1845 print >> self.session, "./dotest.py %s -v %s %s" % (self.getRunOptions(),
1846 ('+b' if benchmarks else '-t'),
1847 self.getRerunArgs())
1848 self.session.close()
1849 del self.session
1850
1851 # process the log files
Vince Harron1f160372015-05-21 18:51:20 +00001852 log_files_for_this_test = glob.glob(self.log_basename + "*")
Vince Harron35b17dc2015-05-21 18:20:21 +00001853
1854 if prefix != 'Success' or lldbtest_config.log_success:
1855 # keep all log files, rename them to include prefix
1856 dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1857 for src in log_files_for_this_test:
Zachary Turner306278f2015-05-26 20:26:29 +00001858 if os.path.isfile(src):
1859 dst = src.replace(self.log_basename, dst_log_basename)
1860 if os.name == "nt" and os.path.isfile(dst):
1861 # On Windows, renaming a -> b will throw an exception if b exists. On non-Windows platforms
1862 # it silently replaces the destination. Ultimately this means that atomic renames are not
1863 # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
1864 # destination first if it already exists.
1865 os.remove(dst)
Zachary Turner5de068b2015-05-26 19:52:24 +00001866
Zachary Turner306278f2015-05-26 20:26:29 +00001867 os.rename(src, dst)
Vince Harron35b17dc2015-05-21 18:20:21 +00001868 else:
1869 # success! (and we don't want log files) delete log files
1870 for log_file in log_files_for_this_test:
Adrian McCarthya7292042015-09-04 20:48:48 +00001871 try:
1872 os.unlink(log_file)
1873 except:
1874 # We've seen consistent unlink failures on Windows, perhaps because the
1875 # just-created log file is being scanned by anti-virus. Empirically, this
1876 # sleep-and-retry approach allows tests to succeed much more reliably.
1877 # Attempts to figure out exactly what process was still holding a file handle
1878 # have failed because running instrumentation like Process Monitor seems to
1879 # slow things down enough that the problem becomes much less consistent.
1880 time.sleep(0.5)
1881 os.unlink(log_file)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001882
1883 # ====================================================
1884 # Config. methods supported through a plugin interface
1885 # (enables reading of the current test configuration)
1886 # ====================================================
1887
1888 def getArchitecture(self):
1889 """Returns the architecture in effect the test suite is running with."""
1890 module = builder_module()
Ed Maste0f434e62015-04-06 15:50:48 +00001891 arch = module.getArchitecture()
1892 if arch == 'amd64':
1893 arch = 'x86_64'
1894 return arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00001895
Vince Harron02613762015-05-04 00:17:53 +00001896 def getLldbArchitecture(self):
1897 """Returns the architecture of the lldb binary."""
1898 if not hasattr(self, 'lldbArchitecture'):
1899
1900 # spawn local process
1901 command = [
Vince Harron790d95c2015-05-18 19:39:03 +00001902 lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001903 "-o",
Vince Harron790d95c2015-05-18 19:39:03 +00001904 "file " + lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001905 "-o",
1906 "quit"
1907 ]
1908
1909 output = check_output(command)
1910 str = output.decode("utf-8");
1911
1912 for line in str.splitlines():
1913 m = re.search("Current executable set to '.*' \\((.*)\\)\\.", line)
1914 if m:
1915 self.lldbArchitecture = m.group(1)
1916 break
1917
1918 return self.lldbArchitecture
1919
Johnny Chenfb4264c2011-08-01 19:50:58 +00001920 def getCompiler(self):
1921 """Returns the compiler in effect the test suite is running with."""
1922 module = builder_module()
1923 return module.getCompiler()
1924
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001925 def getCompilerBinary(self):
1926 """Returns the compiler binary the test suite is running with."""
1927 return self.getCompiler().split()[0]
1928
Daniel Malea0aea0162013-02-27 17:29:46 +00001929 def getCompilerVersion(self):
1930 """ Returns a string that represents the compiler version.
1931 Supports: llvm, clang.
1932 """
1933 from lldbutil import which
1934 version = 'unknown'
1935
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001936 compiler = self.getCompilerBinary()
Zachary Turner9ef307b2014-07-22 16:19:29 +00001937 version_output = system([[which(compiler), "-v"]])[1]
Daniel Malea0aea0162013-02-27 17:29:46 +00001938 for line in version_output.split(os.linesep):
Greg Clayton2a844b72013-03-06 02:34:51 +00001939 m = re.search('version ([0-9\.]+)', line)
Daniel Malea0aea0162013-02-27 17:29:46 +00001940 if m:
1941 version = m.group(1)
1942 return version
1943
Ryan Brown57bee1e2015-09-14 22:45:11 +00001944 def getGoCompilerVersion(self):
1945 """ Returns a string that represents the go compiler version, or None if go is not found.
1946 """
1947 compiler = which("go")
1948 if compiler:
1949 version_output = system([[compiler, "version"]])[0]
1950 for line in version_output.split(os.linesep):
1951 m = re.search('go version (devel|go\\S+)', line)
1952 if m:
1953 return m.group(1)
1954 return None
1955
Greg Claytone0d0a762015-04-02 18:24:03 +00001956 def platformIsDarwin(self):
1957 """Returns true if the OS triple for the selected platform is any valid apple OS"""
Robert Flackfb2f6c62015-04-17 08:02:18 +00001958 return platformIsDarwin()
Vince Harron20952cc2015-04-03 01:00:06 +00001959
Robert Flack13c7ad92015-03-30 14:12:17 +00001960 def getPlatform(self):
Robert Flackfb2f6c62015-04-17 08:02:18 +00001961 """Returns the target platform the test suite is running on."""
Robert Flack068898c2015-04-09 18:07:58 +00001962 return getPlatform()
Robert Flack13c7ad92015-03-30 14:12:17 +00001963
Daniel Maleaadaaec92013-08-06 20:51:41 +00001964 def isIntelCompiler(self):
1965 """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1966 return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1967
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001968 def expectedCompilerVersion(self, compiler_version):
1969 """Returns True iff compiler_version[1] matches the current compiler version.
1970 Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1971 Any operator other than the following defaults to an equality test:
1972 '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1973 """
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001974 if (compiler_version == None):
1975 return True
1976 operator = str(compiler_version[0])
1977 version = compiler_version[1]
1978
1979 if (version == None):
1980 return True
1981 if (operator == '>'):
1982 return self.getCompilerVersion() > version
1983 if (operator == '>=' or operator == '=>'):
1984 return self.getCompilerVersion() >= version
1985 if (operator == '<'):
1986 return self.getCompilerVersion() < version
1987 if (operator == '<=' or operator == '=<'):
1988 return self.getCompilerVersion() <= version
1989 if (operator == '!=' or operator == '!' or operator == 'not'):
1990 return str(version) not in str(self.getCompilerVersion())
1991 return str(version) in str(self.getCompilerVersion())
1992
1993 def expectedCompiler(self, compilers):
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001994 """Returns True iff any element of compilers is a sub-string of the current compiler."""
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001995 if (compilers == None):
1996 return True
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001997
1998 for compiler in compilers:
1999 if compiler in self.getCompiler():
2000 return True
2001
2002 return False
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00002003
Ying Chen7091c2c2015-04-21 01:15:47 +00002004 def expectedArch(self, archs):
2005 """Returns True iff any element of archs is a sub-string of the current architecture."""
2006 if (archs == None):
2007 return True
2008
2009 for arch in archs:
2010 if arch in self.getArchitecture():
2011 return True
2012
2013 return False
2014
Johnny Chenfb4264c2011-08-01 19:50:58 +00002015 def getRunOptions(self):
2016 """Command line option for -A and -C to run this test again, called from
2017 self.dumpSessionInfo()."""
2018 arch = self.getArchitecture()
2019 comp = self.getCompiler()
Johnny Chenb7bdd102011-08-24 19:48:51 +00002020 if arch:
2021 option_str = "-A " + arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00002022 else:
Johnny Chenb7bdd102011-08-24 19:48:51 +00002023 option_str = ""
2024 if comp:
Johnny Chen531c0852012-03-16 20:44:00 +00002025 option_str += " -C " + comp
Johnny Chenb7bdd102011-08-24 19:48:51 +00002026 return option_str
Johnny Chenfb4264c2011-08-01 19:50:58 +00002027
2028 # ==================================================
2029 # Build methods supported through a plugin interface
2030 # ==================================================
2031
Ed Mastec97323e2014-04-01 18:47:58 +00002032 def getstdlibFlag(self):
2033 """ Returns the proper -stdlib flag, or empty if not required."""
Robert Flack4629c4b2015-05-15 18:54:32 +00002034 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Ed Mastec97323e2014-04-01 18:47:58 +00002035 stdlibflag = "-stdlib=libc++"
2036 else:
2037 stdlibflag = ""
2038 return stdlibflag
2039
Matt Kopec7663b3a2013-09-25 17:44:00 +00002040 def getstdFlag(self):
2041 """ Returns the proper stdflag. """
Daniel Malea55faa402013-05-02 21:44:31 +00002042 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
Daniel Malea0b7c6112013-05-06 19:31:31 +00002043 stdflag = "-std=c++0x"
Daniel Malea55faa402013-05-02 21:44:31 +00002044 else:
2045 stdflag = "-std=c++11"
Matt Kopec7663b3a2013-09-25 17:44:00 +00002046 return stdflag
2047
2048 def buildDriver(self, sources, exe_name):
2049 """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
2050 or LLDB.framework).
2051 """
2052
2053 stdflag = self.getstdFlag()
Ed Mastec97323e2014-04-01 18:47:58 +00002054 stdlibflag = self.getstdlibFlag()
Daniel Malea55faa402013-05-02 21:44:31 +00002055
2056 if sys.platform.startswith("darwin"):
2057 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
2058 d = {'CXX_SOURCES' : sources,
2059 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00002060 'CFLAGS_EXTRAS' : "%s %s" % (stdflag, stdlibflag),
Daniel Malea55faa402013-05-02 21:44:31 +00002061 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
Stefanus Du Toit04004442013-07-30 19:19:49 +00002062 'LD_EXTRAS' : "%s -Wl,-rpath,%s" % (dsym, self.lib_dir),
Daniel Malea55faa402013-05-02 21:44:31 +00002063 }
Ed Maste372c24d2013-07-25 21:02:34 +00002064 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 +00002065 d = {'CXX_SOURCES' : sources,
Daniel Malea55faa402013-05-02 21:44:31 +00002066 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00002067 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
Daniel Malea55faa402013-05-02 21:44:31 +00002068 'LD_EXTRAS' : "-L%s -llldb" % self.lib_dir}
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00002069 elif sys.platform.startswith('win'):
2070 d = {'CXX_SOURCES' : sources,
2071 'EXE' : exe_name,
2072 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2073 'LD_EXTRAS' : "-L%s -lliblldb" % self.implib_dir}
Daniel Malea55faa402013-05-02 21:44:31 +00002074 if self.TraceOn():
2075 print "Building LLDB Driver (%s) from sources %s" % (exe_name, sources)
2076
2077 self.buildDefault(dictionary=d)
2078
Matt Kopec7663b3a2013-09-25 17:44:00 +00002079 def buildLibrary(self, sources, lib_name):
2080 """Platform specific way to build a default library. """
2081
2082 stdflag = self.getstdFlag()
2083
Robert Flack4629c4b2015-05-15 18:54:32 +00002084 if self.platformIsDarwin():
Matt Kopec7663b3a2013-09-25 17:44:00 +00002085 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
2086 d = {'DYLIB_CXX_SOURCES' : sources,
2087 'DYLIB_NAME' : lib_name,
2088 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
2089 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
2090 'LD_EXTRAS' : "%s -Wl,-rpath,%s -dynamiclib" % (dsym, self.lib_dir),
2091 }
Robert Flack4629c4b2015-05-15 18:54:32 +00002092 elif self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux' or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
Matt Kopec7663b3a2013-09-25 17:44:00 +00002093 d = {'DYLIB_CXX_SOURCES' : sources,
2094 'DYLIB_NAME' : lib_name,
2095 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2096 'LD_EXTRAS' : "-shared -L%s -llldb" % self.lib_dir}
Robert Flack4629c4b2015-05-15 18:54:32 +00002097 elif self.getPlatform() == 'windows':
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00002098 d = {'DYLIB_CXX_SOURCES' : sources,
2099 'DYLIB_NAME' : lib_name,
2100 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2101 'LD_EXTRAS' : "-shared -l%s\liblldb.lib" % self.implib_dir}
Matt Kopec7663b3a2013-09-25 17:44:00 +00002102 if self.TraceOn():
2103 print "Building LLDB Library (%s) from sources %s" % (lib_name, sources)
2104
2105 self.buildDefault(dictionary=d)
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002106
Daniel Malea55faa402013-05-02 21:44:31 +00002107 def buildProgram(self, sources, exe_name):
2108 """ Platform specific way to build an executable from C/C++ sources. """
2109 d = {'CXX_SOURCES' : sources,
2110 'EXE' : exe_name}
2111 self.buildDefault(dictionary=d)
2112
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002113 def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002114 """Platform specific way to build the default binaries."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002115 if lldb.skip_build_and_cleanup:
2116 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002117 module = builder_module()
Chaoren Line9bbabc2015-07-18 00:37:55 +00002118 if target_is_android():
2119 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002120 if not module.buildDefault(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002121 raise Exception("Don't know how to build default binary")
2122
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002123 def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002124 """Platform specific way to build binaries with dsym info."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002125 if lldb.skip_build_and_cleanup:
2126 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002127 module = builder_module()
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002128 if not module.buildDsym(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002129 raise Exception("Don't know how to build binary with dsym")
2130
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002131 def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002132 """Platform specific way to build binaries with dwarf maps."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002133 if lldb.skip_build_and_cleanup:
2134 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002135 module = builder_module()
Chaoren Lin9070f532015-07-17 22:13:29 +00002136 if target_is_android():
Chaoren Line9bbabc2015-07-18 00:37:55 +00002137 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002138 if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002139 raise Exception("Don't know how to build binary with dwarf")
Johnny Chena74bb0a2011-08-01 18:46:13 +00002140
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +00002141 def buildDwo(self, architecture=None, compiler=None, dictionary=None, clean=True):
2142 """Platform specific way to build binaries with dwarf maps."""
2143 if lldb.skip_build_and_cleanup:
2144 return
2145 module = builder_module()
2146 if target_is_android():
2147 dictionary = append_android_envs(dictionary)
2148 if not module.buildDwo(self, architecture, compiler, dictionary, clean):
2149 raise Exception("Don't know how to build binary with dwo")
2150
Ryan Brown57bee1e2015-09-14 22:45:11 +00002151 def buildGo(self):
2152 """Build the default go binary.
2153 """
2154 system([[which('go'), 'build -gcflags "-N -l" -o a.out main.go']])
2155
Oleksiy Vyalov49b71c62015-01-22 20:03:21 +00002156 def signBinary(self, binary_path):
2157 if sys.platform.startswith("darwin"):
2158 codesign_cmd = "codesign --force --sign lldb_codesign %s" % (binary_path)
2159 call(codesign_cmd, shell=True)
2160
Kuba Breckabeed8212014-09-04 01:03:18 +00002161 def findBuiltClang(self):
2162 """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
2163 paths_to_try = [
2164 "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
2165 "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
2166 "llvm-build/Release/x86_64/Release/bin/clang",
2167 "llvm-build/Debug/x86_64/Debug/bin/clang",
2168 ]
2169 lldb_root_path = os.path.join(os.path.dirname(__file__), "..")
2170 for p in paths_to_try:
2171 path = os.path.join(lldb_root_path, p)
2172 if os.path.exists(path):
2173 return path
Ilia Kd9953052015-03-12 07:19:41 +00002174
2175 # Tries to find clang at the same folder as the lldb
Vince Harron790d95c2015-05-18 19:39:03 +00002176 path = os.path.join(os.path.dirname(lldbtest_config.lldbExec), "clang")
Ilia Kd9953052015-03-12 07:19:41 +00002177 if os.path.exists(path):
2178 return path
Kuba Breckabeed8212014-09-04 01:03:18 +00002179
2180 return os.environ["CC"]
2181
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002182 def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False):
Andrew Kaylor93132f52013-05-28 23:04:25 +00002183 """ Returns a dictionary (which can be provided to build* functions above) which
2184 contains OS-specific build flags.
2185 """
2186 cflags = ""
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002187 ldflags = ""
Daniel Malea9115f072013-08-06 15:02:32 +00002188
2189 # On Mac OS X, unless specifically requested to use libstdc++, use libc++
Robert Flack4629c4b2015-05-15 18:54:32 +00002190 if not use_libstdcxx and self.platformIsDarwin():
Daniel Malea9115f072013-08-06 15:02:32 +00002191 use_libcxx = True
2192
2193 if use_libcxx and self.libcxxPath:
2194 cflags += "-stdlib=libc++ "
2195 if self.libcxxPath:
2196 libcxxInclude = os.path.join(self.libcxxPath, "include")
2197 libcxxLib = os.path.join(self.libcxxPath, "lib")
2198 if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
2199 cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (libcxxInclude, libcxxLib, libcxxLib)
2200
Andrew Kaylor93132f52013-05-28 23:04:25 +00002201 if use_cpp11:
2202 cflags += "-std="
2203 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2204 cflags += "c++0x"
2205 else:
2206 cflags += "c++11"
Robert Flack4629c4b2015-05-15 18:54:32 +00002207 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Andrew Kaylor93132f52013-05-28 23:04:25 +00002208 cflags += " -stdlib=libc++"
2209 elif "clang" in self.getCompiler():
2210 cflags += " -stdlib=libstdc++"
2211
Andrew Kaylor93132f52013-05-28 23:04:25 +00002212 return {'CFLAGS_EXTRAS' : cflags,
2213 'LD_EXTRAS' : ldflags,
2214 }
2215
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002216 def cleanup(self, dictionary=None):
2217 """Platform specific way to do cleanup after build."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002218 if lldb.skip_build_and_cleanup:
2219 return
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002220 module = builder_module()
2221 if not module.cleanup(self, dictionary):
Johnny Chen0fddfb22011-11-17 19:57:27 +00002222 raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002223
Daniel Malea55faa402013-05-02 21:44:31 +00002224 def getLLDBLibraryEnvVal(self):
2225 """ Returns the path that the OS-specific library search environment variable
2226 (self.dylibPath) should be set to in order for a program to find the LLDB
2227 library. If an environment variable named self.dylibPath is already set,
2228 the new path is appended to it and returned.
2229 """
2230 existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
2231 if existing_library_path:
2232 return "%s:%s" % (existing_library_path, self.lib_dir)
2233 elif sys.platform.startswith("darwin"):
2234 return os.path.join(self.lib_dir, 'LLDB.framework')
2235 else:
2236 return self.lib_dir
Johnny Chena74bb0a2011-08-01 18:46:13 +00002237
Ed Maste437f8f62013-09-09 14:04:04 +00002238 def getLibcPlusPlusLibs(self):
Robert Flackfa5ad652015-05-13 20:17:34 +00002239 if self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux':
Ed Maste437f8f62013-09-09 14:04:04 +00002240 return ['libc++.so.1']
2241 else:
2242 return ['libc++.1.dylib','libc++abi.dylib']
2243
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002244# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
2245# We change the test methods to create a new test method for each test for each debug info we are
2246# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
2247# the new test method we remove the old method at the same time.
2248class LLDBTestCaseFactory(type):
2249 def __new__(cls, name, bases, attrs):
2250 newattrs = {}
2251 for attrname, attrvalue in attrs.iteritems():
2252 if attrname.startswith("test") and not getattr(attrvalue, "__no_debug_info_test__", False):
2253 @dsym_test
2254 def dsym_test_method(self, attrvalue=attrvalue):
2255 self.debug_info = "dsym"
2256 return attrvalue(self)
2257 dsym_method_name = attrname + "_dsym"
2258 dsym_test_method.__name__ = dsym_method_name
2259 newattrs[dsym_method_name] = dsym_test_method
2260
2261 @dwarf_test
2262 def dwarf_test_method(self, attrvalue=attrvalue):
2263 self.debug_info = "dwarf"
2264 return attrvalue(self)
2265 dwarf_method_name = attrname + "_dwarf"
2266 dwarf_test_method.__name__ = dwarf_method_name
2267 newattrs[dwarf_method_name] = dwarf_test_method
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +00002268
2269 @dwo_test
2270 def dwo_test_method(self, attrvalue=attrvalue):
2271 self.debug_info = "dwo"
2272 return attrvalue(self)
2273 dwo_method_name = attrname + "_dwo"
2274 dwo_test_method.__name__ = dwo_method_name
2275 newattrs[dwo_method_name] = dwo_test_method
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002276 else:
2277 newattrs[attrname] = attrvalue
2278 return super(LLDBTestCaseFactory, cls).__new__(cls, name, bases, newattrs)
2279
Johnny Chena74bb0a2011-08-01 18:46:13 +00002280class TestBase(Base):
2281 """
2282 This abstract base class is meant to be subclassed. It provides default
2283 implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
2284 among other things.
2285
2286 Important things for test class writers:
2287
2288 - Overwrite the mydir class attribute, otherwise your test class won't
2289 run. It specifies the relative directory to the top level 'test' so
2290 the test harness can change to the correct working directory before
2291 running your test.
2292
2293 - The setUp method sets up things to facilitate subsequent interactions
2294 with the debugger as part of the test. These include:
2295 - populate the test method name
2296 - create/get a debugger set with synchronous mode (self.dbg)
2297 - get the command interpreter from with the debugger (self.ci)
2298 - create a result object for use with the command interpreter
2299 (self.res)
2300 - plus other stuffs
2301
2302 - The tearDown method tries to perform some necessary cleanup on behalf
2303 of the test to return the debugger to a good state for the next test.
2304 These include:
2305 - execute any tearDown hooks registered by the test method with
2306 TestBase.addTearDownHook(); examples can be found in
2307 settings/TestSettings.py
2308 - kill the inferior process associated with each target, if any,
2309 and, then delete the target from the debugger's target list
2310 - perform build cleanup before running the next test method in the
2311 same test class; examples of registering for this service can be
2312 found in types/TestIntegerTypes.py with the call:
2313 - self.setTearDownCleanup(dictionary=d)
2314
2315 - Similarly setUpClass and tearDownClass perform classwise setup and
2316 teardown fixtures. The tearDownClass method invokes a default build
2317 cleanup for the entire test class; also, subclasses can implement the
2318 classmethod classCleanup(cls) to perform special class cleanup action.
2319
2320 - The instance methods runCmd and expect are used heavily by existing
2321 test cases to send a command to the command interpreter and to perform
2322 string/pattern matching on the output of such command execution. The
2323 expect method also provides a mode to peform string/pattern matching
2324 without running a command.
2325
2326 - The build methods buildDefault, buildDsym, and buildDwarf are used to
2327 build the binaries used during a particular test scenario. A plugin
2328 should be provided for the sys.platform running the test suite. The
2329 Mac OS X implementation is located in plugins/darwin.py.
2330 """
2331
2332 # Maximum allowed attempts when launching the inferior process.
2333 # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
2334 maxLaunchCount = 3;
2335
2336 # Time to wait before the next launching attempt in second(s).
2337 # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
2338 timeWaitNextLaunch = 1.0;
2339
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002340 # Setup the metaclass for this class to change the list of the test methods when a new class is loaded
2341 __metaclass__ = LLDBTestCaseFactory
2342
Johnny Chena74bb0a2011-08-01 18:46:13 +00002343 def doDelay(self):
2344 """See option -w of dotest.py."""
2345 if ("LLDB_WAIT_BETWEEN_TEST_CASES" in os.environ and
2346 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] == 'YES'):
2347 waitTime = 1.0
2348 if "LLDB_TIME_WAIT_BETWEEN_TEST_CASES" in os.environ:
2349 waitTime = float(os.environ["LLDB_TIME_WAIT_BETWEEN_TEST_CASES"])
2350 time.sleep(waitTime)
2351
Enrico Granata165f8af2012-09-21 19:10:53 +00002352 # Returns the list of categories to which this test case belongs
2353 # by default, look for a ".categories" file, and read its contents
2354 # if no such file exists, traverse the hierarchy - we guarantee
2355 # a .categories to exist at the top level directory so we do not end up
2356 # looping endlessly - subclasses are free to define their own categories
2357 # in whatever way makes sense to them
2358 def getCategories(self):
2359 import inspect
2360 import os.path
2361 folder = inspect.getfile(self.__class__)
2362 folder = os.path.dirname(folder)
2363 while folder != '/':
2364 categories_file_name = os.path.join(folder,".categories")
2365 if os.path.exists(categories_file_name):
2366 categories_file = open(categories_file_name,'r')
2367 categories = categories_file.readline()
2368 categories_file.close()
2369 categories = str.replace(categories,'\n','')
2370 categories = str.replace(categories,'\r','')
2371 return categories.split(',')
2372 else:
2373 folder = os.path.dirname(folder)
2374 continue
2375
Johnny Chena74bb0a2011-08-01 18:46:13 +00002376 def setUp(self):
2377 #import traceback
2378 #traceback.print_stack()
2379
2380 # Works with the test driver to conditionally skip tests via decorators.
2381 Base.setUp(self)
2382
Johnny Chena74bb0a2011-08-01 18:46:13 +00002383 try:
2384 if lldb.blacklist:
2385 className = self.__class__.__name__
2386 classAndMethodName = "%s.%s" % (className, self._testMethodName)
2387 if className in lldb.blacklist:
2388 self.skipTest(lldb.blacklist.get(className))
2389 elif classAndMethodName in lldb.blacklist:
2390 self.skipTest(lldb.blacklist.get(classAndMethodName))
2391 except AttributeError:
2392 pass
2393
Johnny Chened492022011-06-21 00:53:00 +00002394 # Insert some delay between successive test cases if specified.
2395 self.doDelay()
Johnny Chen0ed37c92010-10-07 02:04:14 +00002396
Johnny Chenf2b70232010-08-25 18:49:48 +00002397 if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
2398 self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
2399
Johnny Chen430eb762010-10-19 16:00:42 +00002400 if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
Johnny Chen4921b112010-11-29 20:20:34 +00002401 self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
Johnny Chenf2b70232010-08-25 18:49:48 +00002402
Daniel Maleae0f8f572013-08-26 23:57:52 +00002403 #
2404 # Warning: MAJOR HACK AHEAD!
2405 # If we are running testsuite remotely (by checking lldb.lldbtest_remote_sandbox),
2406 # redefine the self.dbg.CreateTarget(filename) method to execute a "file filename"
2407 # command, instead. See also runCmd() where it decorates the "file filename" call
2408 # with additional functionality when running testsuite remotely.
2409 #
2410 if lldb.lldbtest_remote_sandbox:
2411 def DecoratedCreateTarget(arg):
2412 self.runCmd("file %s" % arg)
2413 target = self.dbg.GetSelectedTarget()
2414 #
Greg Claytonc6947512013-12-13 19:18:59 +00002415 # SBtarget.LaunchSimple () currently not working for remote platform?
Daniel Maleae0f8f572013-08-26 23:57:52 +00002416 # johnny @ 04/23/2012
2417 #
2418 def DecoratedLaunchSimple(argv, envp, wd):
2419 self.runCmd("run")
2420 return target.GetProcess()
2421 target.LaunchSimple = DecoratedLaunchSimple
2422
2423 return target
2424 self.dbg.CreateTarget = DecoratedCreateTarget
2425 if self.TraceOn():
2426 print "self.dbg.Create is redefined to:\n%s" % getsource_if_available(DecoratedCreateTarget)
2427
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002428 # We want our debugger to be synchronous.
2429 self.dbg.SetAsync(False)
2430
2431 # Retrieve the associated command interpreter instance.
2432 self.ci = self.dbg.GetCommandInterpreter()
2433 if not self.ci:
2434 raise Exception('Could not get the command interpreter')
2435
2436 # And the result object.
2437 self.res = lldb.SBCommandReturnObject()
2438
Johnny Chen44d24972012-04-16 18:55:15 +00002439 # Run global pre-flight code, if defined via the config file.
2440 if lldb.pre_flight:
2441 lldb.pre_flight(self)
2442
Enrico Granatabd0998a2015-10-02 22:53:32 +00002443 if lldb.remote_platform and lldb.remote_platform_working_dir:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00002444 remote_test_dir = lldbutil.join_remote_paths(
2445 lldb.remote_platform_working_dir,
2446 self.getArchitecture(),
2447 str(self.test_number),
2448 self.mydir)
Greg Claytonfb909312013-11-23 01:58:15 +00002449 error = lldb.remote_platform.MakeDirectory(remote_test_dir, 0700)
2450 if error.Success():
Greg Claytonfb909312013-11-23 01:58:15 +00002451 lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
Tamas Berghammerf2addf82015-10-07 12:38:29 +00002452
Tamas Berghammer11db2d32015-10-07 14:52:16 +00002453 # This function removes all files from the current working directory while leaving
2454 # the directories in place. The cleaup is required to reduce the disk space required
2455 # by the test suit while leaving the directories untached is neccessary because
2456 # sub-directories might belong to an other test
2457 def clean_working_directory():
Tamas Berghammerf2addf82015-10-07 12:38:29 +00002458 # TODO: Make it working on Windows when we need it for remote debugging support
Tamas Berghammer11db2d32015-10-07 14:52:16 +00002459 # TODO: Replace the heuristic to remove the files with a logic what collects the
2460 # list of files we have to remove during test runs.
2461 shell_cmd = lldb.SBPlatformShellCommand("rm %s/*" % remote_test_dir)
Tamas Berghammerf2addf82015-10-07 12:38:29 +00002462 lldb.remote_platform.Run(shell_cmd)
Tamas Berghammer11db2d32015-10-07 14:52:16 +00002463 self.addTearDownHook(clean_working_directory)
Greg Claytonfb909312013-11-23 01:58:15 +00002464 else:
2465 print "error: making remote directory '%s': %s" % (remote_test_dir, error)
2466
Greg Clayton35c91342014-11-17 18:40:27 +00002467 def registerSharedLibrariesWithTarget(self, target, shlibs):
2468 '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
2469
2470 Any modules in the target that have their remote install file specification set will
2471 get uploaded to the remote host. This function registers the local copies of the
2472 shared libraries with the target and sets their remote install locations so they will
2473 be uploaded when the target is run.
2474 '''
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00002475 if not shlibs or not self.platformContext:
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002476 return None
Greg Clayton35c91342014-11-17 18:40:27 +00002477
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002478 shlib_environment_var = self.platformContext.shlib_environment_var
2479 shlib_prefix = self.platformContext.shlib_prefix
2480 shlib_extension = '.' + self.platformContext.shlib_extension
2481
2482 working_dir = self.get_process_working_directory()
2483 environment = ['%s=%s' % (shlib_environment_var, working_dir)]
2484 # Add any shared libraries to our target if remote so they get
2485 # uploaded into the working directory on the remote side
2486 for name in shlibs:
2487 # The path can be a full path to a shared library, or a make file name like "Foo" for
2488 # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
2489 # basename like "libFoo.so". So figure out which one it is and resolve the local copy
2490 # of the shared library accordingly
2491 if os.path.exists(name):
2492 local_shlib_path = name # name is the full path to the local shared library
2493 else:
2494 # Check relative names
2495 local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
2496 if not os.path.exists(local_shlib_path):
2497 local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
Greg Clayton35c91342014-11-17 18:40:27 +00002498 if not os.path.exists(local_shlib_path):
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002499 local_shlib_path = os.path.join(os.getcwd(), name)
Greg Clayton35c91342014-11-17 18:40:27 +00002500
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002501 # Make sure we found the local shared library in the above code
2502 self.assertTrue(os.path.exists(local_shlib_path))
2503
2504 # Add the shared library to our target
2505 shlib_module = target.AddModule(local_shlib_path, None, None, None)
2506 if lldb.remote_platform:
Greg Clayton35c91342014-11-17 18:40:27 +00002507 # We must set the remote install location if we want the shared library
2508 # to get uploaded to the remote target
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00002509 remote_shlib_path = lldbutil.append_to_process_working_directory(os.path.basename(local_shlib_path))
Greg Clayton35c91342014-11-17 18:40:27 +00002510 shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002511
2512 return environment
2513
Enrico Granata44818162012-10-24 01:23:57 +00002514 # utility methods that tests can use to access the current objects
2515 def target(self):
2516 if not self.dbg:
2517 raise Exception('Invalid debugger instance')
2518 return self.dbg.GetSelectedTarget()
2519
2520 def process(self):
2521 if not self.dbg:
2522 raise Exception('Invalid debugger instance')
2523 return self.dbg.GetSelectedTarget().GetProcess()
2524
2525 def thread(self):
2526 if not self.dbg:
2527 raise Exception('Invalid debugger instance')
2528 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2529
2530 def frame(self):
2531 if not self.dbg:
2532 raise Exception('Invalid debugger instance')
2533 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
2534
Greg Claytonc6947512013-12-13 19:18:59 +00002535 def get_process_working_directory(self):
2536 '''Get the working directory that should be used when launching processes for local or remote processes.'''
2537 if lldb.remote_platform:
2538 # Remote tests set the platform working directory up in TestBase.setUp()
2539 return lldb.remote_platform.GetWorkingDirectory()
2540 else:
2541 # local tests change directory into each test subdirectory
2542 return os.getcwd()
2543
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002544 def tearDown(self):
Johnny Chen7d1d7532010-09-02 21:23:12 +00002545 #import traceback
2546 #traceback.print_stack()
2547
Adrian McCarthy6ecdbc82015-10-15 22:39:55 +00002548 # Ensure all the references to SB objects have gone away so that we can
2549 # be sure that all test-specific resources have been freed before we
2550 # attempt to delete the targets.
2551 gc.collect()
2552
Johnny Chen3794ad92011-06-15 21:24:24 +00002553 # Delete the target(s) from the debugger as a general cleanup step.
2554 # This includes terminating the process for each target, if any.
2555 # We'd like to reuse the debugger for our next test without incurring
2556 # the initialization overhead.
2557 targets = []
2558 for target in self.dbg:
2559 if target:
2560 targets.append(target)
2561 process = target.GetProcess()
2562 if process:
2563 rc = self.invoke(process, "Kill")
2564 self.assertTrue(rc.Success(), PROCESS_KILLED)
2565 for target in targets:
2566 self.dbg.DeleteTarget(target)
Johnny Chen6ca006c2010-08-16 21:28:10 +00002567
Johnny Chen44d24972012-04-16 18:55:15 +00002568 # Run global post-flight code, if defined via the config file.
2569 if lldb.post_flight:
2570 lldb.post_flight(self)
2571
Zachary Turner65fe1eb2015-03-26 16:43:25 +00002572 # Do this last, to make sure it's in reverse order from how we setup.
2573 Base.tearDown(self)
2574
Zachary Turner95812042015-03-26 18:54:21 +00002575 # This must be the last statement, otherwise teardown hooks or other
2576 # lines might depend on this still being active.
2577 del self.dbg
2578
Johnny Chen86268e42011-09-30 21:48:35 +00002579 def switch_to_thread_with_stop_reason(self, stop_reason):
2580 """
2581 Run the 'thread list' command, and select the thread with stop reason as
2582 'stop_reason'. If no such thread exists, no select action is done.
2583 """
2584 from lldbutil import stop_reason_to_str
2585 self.runCmd('thread list')
2586 output = self.res.GetOutput()
2587 thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
2588 stop_reason_to_str(stop_reason))
2589 for line in output.splitlines():
2590 matched = thread_line_pattern.match(line)
2591 if matched:
2592 self.runCmd('thread select %s' % matched.group(1))
2593
Enrico Granata7594f142013-06-17 22:51:50 +00002594 def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
Johnny Chen27f212d2010-08-19 23:26:59 +00002595 """
2596 Ask the command interpreter to handle the command and then check its
2597 return status.
2598 """
2599 # Fail fast if 'cmd' is not meaningful.
2600 if not cmd or len(cmd) == 0:
2601 raise Exception("Bad 'cmd' parameter encountered")
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002602
Johnny Chen8d55a342010-08-31 17:42:54 +00002603 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002604
Daniel Maleae0f8f572013-08-26 23:57:52 +00002605 # This is an opportunity to insert the 'platform target-install' command if we are told so
2606 # via the settig of lldb.lldbtest_remote_sandbox.
2607 if cmd.startswith("target create "):
2608 cmd = cmd.replace("target create ", "file ")
2609 if cmd.startswith("file ") and lldb.lldbtest_remote_sandbox:
2610 with recording(self, trace) as sbuf:
2611 the_rest = cmd.split("file ")[1]
2612 # Split the rest of the command line.
2613 atoms = the_rest.split()
2614 #
2615 # NOTE: This assumes that the options, if any, follow the file command,
2616 # instead of follow the specified target.
2617 #
2618 target = atoms[-1]
2619 # Now let's get the absolute pathname of our target.
2620 abs_target = os.path.abspath(target)
2621 print >> sbuf, "Found a file command, target (with absolute pathname)=%s" % abs_target
2622 fpath, fname = os.path.split(abs_target)
2623 parent_dir = os.path.split(fpath)[0]
2624 platform_target_install_command = 'platform target-install %s %s' % (fpath, lldb.lldbtest_remote_sandbox)
2625 print >> sbuf, "Insert this command to be run first: %s" % platform_target_install_command
2626 self.ci.HandleCommand(platform_target_install_command, self.res)
2627 # And this is the file command we want to execute, instead.
2628 #
2629 # Warning: SIDE EFFECT AHEAD!!!
2630 # Populate the remote executable pathname into the lldb namespace,
2631 # so that test cases can grab this thing out of the namespace.
2632 #
2633 lldb.lldbtest_remote_sandboxed_executable = abs_target.replace(parent_dir, lldb.lldbtest_remote_sandbox)
2634 cmd = "file -P %s %s %s" % (lldb.lldbtest_remote_sandboxed_executable, the_rest.replace(target, ''), abs_target)
2635 print >> sbuf, "And this is the replaced file command: %s" % cmd
2636
Johnny Chen63dfb272010-09-01 00:15:19 +00002637 running = (cmd.startswith("run") or cmd.startswith("process launch"))
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002638
Johnny Chen63dfb272010-09-01 00:15:19 +00002639 for i in range(self.maxLaunchCount if running else 1):
Enrico Granata7594f142013-06-17 22:51:50 +00002640 self.ci.HandleCommand(cmd, self.res, inHistory)
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002641
Johnny Chen150c3cc2010-10-15 01:18:29 +00002642 with recording(self, trace) as sbuf:
2643 print >> sbuf, "runCmd:", cmd
Johnny Chenab254f52010-10-15 16:13:00 +00002644 if not check:
Johnny Chen27b107b2010-10-15 18:52:22 +00002645 print >> sbuf, "check of return status not required"
Johnny Chenf2b70232010-08-25 18:49:48 +00002646 if self.res.Succeeded():
Johnny Chen150c3cc2010-10-15 01:18:29 +00002647 print >> sbuf, "output:", self.res.GetOutput()
Johnny Chenf2b70232010-08-25 18:49:48 +00002648 else:
Johnny Chen150c3cc2010-10-15 01:18:29 +00002649 print >> sbuf, "runCmd failed!"
2650 print >> sbuf, self.res.GetError()
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002651
Johnny Chenff3d01d2010-08-20 21:03:09 +00002652 if self.res.Succeeded():
Johnny Chenf2b70232010-08-25 18:49:48 +00002653 break
Johnny Chen150c3cc2010-10-15 01:18:29 +00002654 elif running:
Johnny Chencf7f74e2011-01-19 02:02:08 +00002655 # For process launch, wait some time before possible next try.
2656 time.sleep(self.timeWaitNextLaunch)
Johnny Chen552d6712012-08-01 19:56:04 +00002657 with recording(self, trace) as sbuf:
Johnny Chen150c3cc2010-10-15 01:18:29 +00002658 print >> sbuf, "Command '" + cmd + "' failed!"
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002659
Johnny Chen27f212d2010-08-19 23:26:59 +00002660 if check:
Sean Callanan05834cd2015-07-01 23:56:30 +00002661 self.assertTrue(self.res.Succeeded(),
2662 msg if msg else CMD_MSG(cmd))
Johnny Chen27f212d2010-08-19 23:26:59 +00002663
Jim Ingham63dfc722012-09-22 00:05:11 +00002664 def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
2665 """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2666
2667 Otherwise, all the arguments have the same meanings as for the expect function"""
2668
2669 trace = (True if traceAlways else trace)
2670
2671 if exe:
2672 # First run the command. If we are expecting error, set check=False.
2673 # Pass the assert message along since it provides more semantic info.
2674 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
2675
2676 # Then compare the output against expected strings.
2677 output = self.res.GetError() if error else self.res.GetOutput()
2678
2679 # If error is True, the API client expects the command to fail!
2680 if error:
2681 self.assertFalse(self.res.Succeeded(),
2682 "Command '" + str + "' is expected to fail!")
2683 else:
2684 # No execution required, just compare str against the golden input.
2685 output = str
2686 with recording(self, trace) as sbuf:
2687 print >> sbuf, "looking at:", output
2688
2689 # The heading says either "Expecting" or "Not expecting".
2690 heading = "Expecting" if matching else "Not expecting"
2691
2692 for pattern in patterns:
2693 # Match Objects always have a boolean value of True.
2694 match_object = re.search(pattern, output)
2695 matched = bool(match_object)
2696 with recording(self, trace) as sbuf:
2697 print >> sbuf, "%s pattern: %s" % (heading, pattern)
2698 print >> sbuf, "Matched" if matched else "Not matched"
2699 if matched:
2700 break
2701
2702 self.assertTrue(matched if matching else not matched,
2703 msg if msg else EXP_MSG(str, exe))
2704
2705 return match_object
2706
Enrico Granata7594f142013-06-17 22:51:50 +00002707 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 +00002708 """
2709 Similar to runCmd; with additional expect style output matching ability.
2710
2711 Ask the command interpreter to handle the command and then check its
2712 return status. The 'msg' parameter specifies an informational assert
2713 message. We expect the output from running the command to start with
Johnny Chenea88e942010-09-21 21:08:53 +00002714 'startstr', matches the substrings contained in 'substrs', and regexp
2715 matches the patterns contained in 'patterns'.
Johnny Chenb3307862010-09-17 22:28:51 +00002716
2717 If the keyword argument error is set to True, it signifies that the API
2718 client is expecting the command to fail. In this case, the error stream
Johnny Chenaa902922010-09-17 22:45:27 +00002719 from running the command is retrieved and compared against the golden
Johnny Chenb3307862010-09-17 22:28:51 +00002720 input, instead.
Johnny Chenea88e942010-09-21 21:08:53 +00002721
2722 If the keyword argument matching is set to False, it signifies that the API
2723 client is expecting the output of the command not to match the golden
2724 input.
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002725
2726 Finally, the required argument 'str' represents the lldb command to be
2727 sent to the command interpreter. In case the keyword argument 'exe' is
2728 set to False, the 'str' is treated as a string to be matched/not-matched
2729 against the golden input.
Johnny Chen27f212d2010-08-19 23:26:59 +00002730 """
Johnny Chen8d55a342010-08-31 17:42:54 +00002731 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002732
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002733 if exe:
2734 # First run the command. If we are expecting error, set check=False.
Johnny Chen62d4f862010-10-28 21:10:32 +00002735 # Pass the assert message along since it provides more semantic info.
Enrico Granata7594f142013-06-17 22:51:50 +00002736 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error, inHistory=inHistory)
Johnny Chen27f212d2010-08-19 23:26:59 +00002737
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002738 # Then compare the output against expected strings.
2739 output = self.res.GetError() if error else self.res.GetOutput()
Johnny Chenb3307862010-09-17 22:28:51 +00002740
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002741 # If error is True, the API client expects the command to fail!
2742 if error:
2743 self.assertFalse(self.res.Succeeded(),
2744 "Command '" + str + "' is expected to fail!")
2745 else:
2746 # No execution required, just compare str against the golden input.
Enrico Granatabc08ab42012-10-23 00:09:02 +00002747 if isinstance(str,lldb.SBCommandReturnObject):
2748 output = str.GetOutput()
2749 else:
2750 output = str
Johnny Chen150c3cc2010-10-15 01:18:29 +00002751 with recording(self, trace) as sbuf:
2752 print >> sbuf, "looking at:", output
Johnny Chenb3307862010-09-17 22:28:51 +00002753
Johnny Chenea88e942010-09-21 21:08:53 +00002754 # The heading says either "Expecting" or "Not expecting".
Johnny Chen150c3cc2010-10-15 01:18:29 +00002755 heading = "Expecting" if matching else "Not expecting"
Johnny Chenea88e942010-09-21 21:08:53 +00002756
2757 # Start from the startstr, if specified.
2758 # If there's no startstr, set the initial state appropriately.
2759 matched = output.startswith(startstr) if startstr else (True if matching else False)
Johnny Chenb145bba2010-08-20 18:25:15 +00002760
Johnny Chen150c3cc2010-10-15 01:18:29 +00002761 if startstr:
2762 with recording(self, trace) as sbuf:
2763 print >> sbuf, "%s start string: %s" % (heading, startstr)
2764 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenb145bba2010-08-20 18:25:15 +00002765
Johnny Chen86268e42011-09-30 21:48:35 +00002766 # Look for endstr, if specified.
2767 keepgoing = matched if matching else not matched
2768 if endstr:
2769 matched = output.endswith(endstr)
2770 with recording(self, trace) as sbuf:
2771 print >> sbuf, "%s end string: %s" % (heading, endstr)
2772 print >> sbuf, "Matched" if matched else "Not matched"
2773
Johnny Chenea88e942010-09-21 21:08:53 +00002774 # Look for sub strings, if specified.
2775 keepgoing = matched if matching else not matched
2776 if substrs and keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002777 for str in substrs:
Johnny Chenb052f6c2010-09-23 23:35:28 +00002778 matched = output.find(str) != -1
Johnny Chen150c3cc2010-10-15 01:18:29 +00002779 with recording(self, trace) as sbuf:
2780 print >> sbuf, "%s sub string: %s" % (heading, str)
2781 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenea88e942010-09-21 21:08:53 +00002782 keepgoing = matched if matching else not matched
2783 if not keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002784 break
2785
Johnny Chenea88e942010-09-21 21:08:53 +00002786 # Search for regular expression patterns, if specified.
2787 keepgoing = matched if matching else not matched
2788 if patterns and keepgoing:
2789 for pattern in patterns:
2790 # Match Objects always have a boolean value of True.
2791 matched = bool(re.search(pattern, output))
Johnny Chen150c3cc2010-10-15 01:18:29 +00002792 with recording(self, trace) as sbuf:
2793 print >> sbuf, "%s pattern: %s" % (heading, pattern)
2794 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenea88e942010-09-21 21:08:53 +00002795 keepgoing = matched if matching else not matched
2796 if not keepgoing:
2797 break
Johnny Chenea88e942010-09-21 21:08:53 +00002798
2799 self.assertTrue(matched if matching else not matched,
Johnny Chenc0c67f22010-11-09 18:42:22 +00002800 msg if msg else EXP_MSG(str, exe))
Johnny Chen27f212d2010-08-19 23:26:59 +00002801
Johnny Chenf3c59232010-08-25 22:52:45 +00002802 def invoke(self, obj, name, trace=False):
Johnny Chen61703c92010-08-25 22:56:10 +00002803 """Use reflection to call a method dynamically with no argument."""
Johnny Chen8d55a342010-08-31 17:42:54 +00002804 trace = (True if traceAlways else trace)
Johnny Chenf3c59232010-08-25 22:52:45 +00002805
2806 method = getattr(obj, name)
2807 import inspect
2808 self.assertTrue(inspect.ismethod(method),
2809 name + "is a method name of object: " + str(obj))
2810 result = method()
Johnny Chen150c3cc2010-10-15 01:18:29 +00002811 with recording(self, trace) as sbuf:
2812 print >> sbuf, str(method) + ":", result
Johnny Chenf3c59232010-08-25 22:52:45 +00002813 return result
Johnny Chen827edff2010-08-27 00:15:48 +00002814
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002815 def build(self, architecture=None, compiler=None, dictionary=None, clean=True):
2816 """Platform specific way to build the default binaries."""
2817 if lldb.skip_build_and_cleanup:
2818 return
2819 module = builder_module()
2820 if target_is_android():
2821 dictionary = append_android_envs(dictionary)
2822 if self.debug_info is None:
2823 return self.buildDefault(architecture, compiler, dictionary, clean)
2824 elif self.debug_info == "dsym":
2825 return self.buildDsym(architecture, compiler, dictionary, clean)
2826 elif self.debug_info == "dwarf":
2827 return self.buildDwarf(architecture, compiler, dictionary, clean)
Tamas Berghammer4c0c7a72015-10-07 10:02:17 +00002828 elif self.debug_info == "dwo":
2829 return self.buildDwo(architecture, compiler, dictionary, clean)
2830 else:
2831 self.fail("Can't build for debug info: %s" % self.debug_info)
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002832
Johnny Chenf359cf22011-05-27 23:36:52 +00002833 # =================================================
2834 # Misc. helper methods for debugging test execution
2835 # =================================================
2836
Johnny Chen56b92a72011-07-11 19:15:11 +00002837 def DebugSBValue(self, val):
Johnny Chen8d55a342010-08-31 17:42:54 +00002838 """Debug print a SBValue object, if traceAlways is True."""
Johnny Chende90f1d2011-04-27 17:43:07 +00002839 from lldbutil import value_type_to_str
Johnny Chen87bb5892010-11-03 21:37:58 +00002840
Johnny Chen8d55a342010-08-31 17:42:54 +00002841 if not traceAlways:
Johnny Chen827edff2010-08-27 00:15:48 +00002842 return
2843
2844 err = sys.stderr
2845 err.write(val.GetName() + ":\n")
Johnny Chen86268e42011-09-30 21:48:35 +00002846 err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n')
2847 err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n')
2848 err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n')
2849 err.write('\t' + "Value -> " + str(val.GetValue()) + '\n')
2850 err.write('\t' + "ValueAsUnsigned -> " + str(val.GetValueAsUnsigned())+ '\n')
2851 err.write('\t' + "ValueType -> " + value_type_to_str(val.GetValueType()) + '\n')
2852 err.write('\t' + "Summary -> " + str(val.GetSummary()) + '\n')
2853 err.write('\t' + "IsPointerType -> " + str(val.TypeIsPointerType()) + '\n')
2854 err.write('\t' + "Location -> " + val.GetLocation() + '\n')
Johnny Chen827edff2010-08-27 00:15:48 +00002855
Johnny Chen36c5eb12011-08-05 20:17:27 +00002856 def DebugSBType(self, type):
2857 """Debug print a SBType object, if traceAlways is True."""
2858 if not traceAlways:
2859 return
2860
2861 err = sys.stderr
2862 err.write(type.GetName() + ":\n")
2863 err.write('\t' + "ByteSize -> " + str(type.GetByteSize()) + '\n')
2864 err.write('\t' + "IsPointerType -> " + str(type.IsPointerType()) + '\n')
2865 err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
2866
Johnny Chenb877f1e2011-03-12 01:18:19 +00002867 def DebugPExpect(self, child):
2868 """Debug the spwaned pexpect object."""
2869 if not traceAlways:
2870 return
2871
2872 print child
Filipe Cabecinhas0eec15a2012-06-20 10:13:40 +00002873
2874 @classmethod
2875 def RemoveTempFile(cls, file):
2876 if os.path.exists(file):
2877 os.remove(file)