blob: 5463c573c55856668a5aefb9a0dfce197b05bfa5 [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
Vince Harron9753dd92015-05-10 15:22:09 +000035import glob
Johnny Chen90312a82010-09-21 22:34:45 +000036import os, sys, traceback
Enrico Granata7e137e32012-10-24 18:14:21 +000037import os.path
Johnny Chenea88e942010-09-21 21:08:53 +000038import re
Daniel Malea69207462013-06-05 21:07:02 +000039import signal
Johnny Chen8952a2d2010-08-30 21:35:00 +000040from subprocess import *
Johnny Chen150c3cc2010-10-15 01:18:29 +000041import StringIO
Johnny Chenf2b70232010-08-25 18:49:48 +000042import time
Johnny Chena33a93c2010-08-30 23:08:52 +000043import types
Johnny Chen73258832010-08-05 23:42:46 +000044import unittest2
Johnny Chenbf6ffa32010-07-03 03:41:59 +000045import lldb
Vince Harron9753dd92015-05-10 15:22:09 +000046import lldbtest_config
Chaoren Lin3e2bdb42015-05-11 17:53:39 +000047import lldbutil
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +000048from _pyio import __metaclass__
Johnny Chenbf6ffa32010-07-03 03:41:59 +000049
Siva Chandra8af91662015-06-05 00:22:49 +000050if sys.version_info.major < 3:
51 import urlparse
52else:
53 import urllib.parse as urlparse
54
Vince Harron85d19652015-05-21 19:09:29 +000055# dosep.py starts lots and lots of dotest instances
56# This option helps you find if two (or more) dotest instances are using the same
57# directory at the same time
58# Enable it to cause test failures and stderr messages if dotest instances try to run in
59# the same directory simultaneously
60# it is disabled by default because it litters the test directories with ".dirlock" files
61debug_confirm_directory_exclusivity = False
62
Johnny Chen707b3c92010-10-11 22:25:46 +000063# See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
Johnny Chend2047fa2011-01-19 18:18:47 +000064# LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' options.
Johnny Chen707b3c92010-10-11 22:25:46 +000065
66# By default, traceAlways is False.
Johnny Chen8d55a342010-08-31 17:42:54 +000067if "LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"]=="YES":
68 traceAlways = True
69else:
70 traceAlways = False
71
Johnny Chen707b3c92010-10-11 22:25:46 +000072# By default, doCleanup is True.
73if "LLDB_DO_CLEANUP" in os.environ and os.environ["LLDB_DO_CLEANUP"]=="NO":
74 doCleanup = False
75else:
76 doCleanup = True
77
Johnny Chen8d55a342010-08-31 17:42:54 +000078
Johnny Chen00778092010-08-09 22:01:17 +000079#
80# Some commonly used assert messages.
81#
82
Johnny Chenaa902922010-09-17 22:45:27 +000083COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"
84
Johnny Chen00778092010-08-09 22:01:17 +000085CURRENT_EXECUTABLE_SET = "Current executable set successfully"
86
Johnny Chen7d1d7532010-09-02 21:23:12 +000087PROCESS_IS_VALID = "Process is valid"
88
89PROCESS_KILLED = "Process is killed successfully"
90
Johnny Chend5f66fc2010-12-23 01:12:19 +000091PROCESS_EXITED = "Process exited successfully"
92
93PROCESS_STOPPED = "Process status should be stopped"
94
Sean Callanan05834cd2015-07-01 23:56:30 +000095RUN_SUCCEEDED = "Process is launched successfully"
Johnny Chen00778092010-08-09 22:01:17 +000096
Johnny Chen17941842010-08-09 23:44:24 +000097RUN_COMPLETED = "Process exited successfully"
Johnny Chen00778092010-08-09 22:01:17 +000098
Johnny Chen67af43f2010-10-05 19:27:32 +000099BACKTRACE_DISPLAYED_CORRECTLY = "Backtrace displayed correctly"
100
Johnny Chen17941842010-08-09 23:44:24 +0000101BREAKPOINT_CREATED = "Breakpoint created successfully"
102
Johnny Chenf10af382010-12-04 00:07:24 +0000103BREAKPOINT_STATE_CORRECT = "Breakpoint state is correct"
104
Johnny Chene76896c2010-08-17 21:33:31 +0000105BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
106
Johnny Chen17941842010-08-09 23:44:24 +0000107BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
Johnny Chen00778092010-08-09 22:01:17 +0000108
Johnny Chen703dbd02010-09-30 17:06:24 +0000109BREAKPOINT_HIT_TWICE = "Breakpoint resolved with hit cout = 2"
110
Johnny Chen164f1e12010-10-15 18:07:09 +0000111BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3"
112
Greg Clayton5db6b792012-10-24 18:24:14 +0000113MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."
114
Johnny Chen89109ed12011-06-27 20:05:23 +0000115OBJECT_PRINTED_CORRECTLY = "Object printed correctly"
116
Johnny Chen5b3a3572010-12-09 18:22:12 +0000117SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"
118
Johnny Chenc70b02a2010-09-22 23:00:20 +0000119STEP_OUT_SUCCEEDED = "Thread step-out succeeded"
120
Johnny Chen1691a162011-04-15 16:44:48 +0000121STOPPED_DUE_TO_EXC_BAD_ACCESS = "Process should be stopped due to bad access exception"
122
Ashok Thirumurthib4e51342013-05-17 15:35:15 +0000123STOPPED_DUE_TO_ASSERT = "Process should be stopped due to an assertion"
124
Johnny Chen5d6c4642010-11-10 23:46:38 +0000125STOPPED_DUE_TO_BREAKPOINT = "Process should be stopped due to breakpoint"
Johnny Chende0338b2010-11-10 20:20:06 +0000126
Johnny Chen5d6c4642010-11-10 23:46:38 +0000127STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS = "%s, %s" % (
128 STOPPED_DUE_TO_BREAKPOINT, "instead, the actual stop reason is: '%s'")
Johnny Chen00778092010-08-09 22:01:17 +0000129
Johnny Chen2e431ce2010-10-20 18:38:48 +0000130STOPPED_DUE_TO_BREAKPOINT_CONDITION = "Stopped due to breakpoint condition"
131
Johnny Chen0a3d1ca2010-12-13 21:49:58 +0000132STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT = "Stopped due to breakpoint and ignore count"
133
Johnny Chenc066ab42010-10-14 01:22:03 +0000134STOPPED_DUE_TO_SIGNAL = "Process state is stopped due to signal"
135
Johnny Chen00778092010-08-09 22:01:17 +0000136STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
137
Johnny Chenf68cc122011-09-15 21:09:59 +0000138STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"
139
Johnny Chen3c884a02010-08-24 22:07:56 +0000140DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
141
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000142VALID_BREAKPOINT = "Got a valid breakpoint"
143
Johnny Chen5bfb8ee2010-10-22 18:10:25 +0000144VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location"
145
Johnny Chen7209d84f2011-05-06 23:26:12 +0000146VALID_COMMAND_INTERPRETER = "Got a valid command interpreter"
147
Johnny Chen5ee88192010-08-27 23:47:36 +0000148VALID_FILESPEC = "Got a valid filespec"
149
Johnny Chen025d1b82010-12-08 01:25:21 +0000150VALID_MODULE = "Got a valid module"
151
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000152VALID_PROCESS = "Got a valid process"
153
Johnny Chen025d1b82010-12-08 01:25:21 +0000154VALID_SYMBOL = "Got a valid symbol"
155
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000156VALID_TARGET = "Got a valid target"
157
Matthew Gardinerc928de32014-10-22 07:22:56 +0000158VALID_PLATFORM = "Got a valid platform"
159
Johnny Chen15f247a2012-02-03 20:43:00 +0000160VALID_TYPE = "Got a valid type"
161
Johnny Chen5819ab42011-07-15 22:28:10 +0000162VALID_VARIABLE = "Got a valid variable"
163
Johnny Chen981463d2010-08-25 19:00:04 +0000164VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
Johnny Chen00778092010-08-09 22:01:17 +0000165
Johnny Chenf68cc122011-09-15 21:09:59 +0000166WATCHPOINT_CREATED = "Watchpoint created successfully"
Johnny Chen5fca8ca2010-08-26 20:04:17 +0000167
Sean Callanan05834cd2015-07-01 23:56:30 +0000168def CMD_MSG(str):
169 '''A generic "Command '%s' returns successfully" message generator.'''
170 return "Command '%s' returns successfully" % str
Johnny Chenc0c67f22010-11-09 18:42:22 +0000171
Johnny Chen3bc8ae42012-03-15 19:10:00 +0000172def COMPLETION_MSG(str_before, str_after):
Johnny Chen98aceb02012-01-20 23:02:51 +0000173 '''A generic message generator for the completion mechanism.'''
174 return "'%s' successfully completes to '%s'" % (str_before, str_after)
175
Johnny Chenc0c67f22010-11-09 18:42:22 +0000176def EXP_MSG(str, exe):
Johnny Chenaacf92e2011-05-31 22:16:51 +0000177 '''A generic "'%s' returns expected result" message generator if exe.
178 Otherwise, it generates "'%s' matches expected result" message.'''
Johnny Chenc0c67f22010-11-09 18:42:22 +0000179 return "'%s' %s expected result" % (str, 'returns' if exe else 'matches')
Johnny Chen17941842010-08-09 23:44:24 +0000180
Johnny Chen3343f042010-10-19 19:11:38 +0000181def SETTING_MSG(setting):
Johnny Chenaacf92e2011-05-31 22:16:51 +0000182 '''A generic "Value of setting '%s' is correct" message generator.'''
Johnny Chen3343f042010-10-19 19:11:38 +0000183 return "Value of setting '%s' is correct" % setting
184
Johnny Chen27c41232010-08-26 21:49:29 +0000185def EnvArray():
Johnny Chenaacf92e2011-05-31 22:16:51 +0000186 """Returns an env variable array from the os.environ map object."""
Johnny Chen27c41232010-08-26 21:49:29 +0000187 return map(lambda k,v: k+"="+v, os.environ.keys(), os.environ.values())
188
Johnny Chen47ceb032010-10-11 23:52:19 +0000189def line_number(filename, string_to_match):
190 """Helper function to return the line number of the first matched string."""
191 with open(filename, 'r') as f:
192 for i, line in enumerate(f):
193 if line.find(string_to_match) != -1:
194 # Found our match.
Johnny Chencd9b7772010-10-12 00:09:25 +0000195 return i+1
Johnny Chen1691a162011-04-15 16:44:48 +0000196 raise Exception("Unable to find '%s' within file %s" % (string_to_match, filename))
Johnny Chen47ceb032010-10-11 23:52:19 +0000197
Johnny Chen67af43f2010-10-05 19:27:32 +0000198def pointer_size():
199 """Return the pointer size of the host system."""
200 import ctypes
201 a_pointer = ctypes.c_void_p(0xffff)
202 return 8 * ctypes.sizeof(a_pointer)
203
Johnny Chen57816732012-02-09 02:01:59 +0000204def is_exe(fpath):
205 """Returns true if fpath is an executable."""
206 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
207
208def which(program):
209 """Returns the full path to a program; None otherwise."""
210 fpath, fname = os.path.split(program)
211 if fpath:
212 if is_exe(program):
213 return program
214 else:
215 for path in os.environ["PATH"].split(os.pathsep):
216 exe_file = os.path.join(path, program)
217 if is_exe(exe_file):
218 return exe_file
219 return None
220
Johnny Chen150c3cc2010-10-15 01:18:29 +0000221class recording(StringIO.StringIO):
222 """
223 A nice little context manager for recording the debugger interactions into
224 our session object. If trace flag is ON, it also emits the interactions
225 into the stderr.
226 """
227 def __init__(self, test, trace):
Johnny Chen690fcef2010-10-15 23:55:05 +0000228 """Create a StringIO instance; record the session obj and trace flag."""
Johnny Chen150c3cc2010-10-15 01:18:29 +0000229 StringIO.StringIO.__init__(self)
Johnny Chen0241f142011-08-16 22:06:17 +0000230 # The test might not have undergone the 'setUp(self)' phase yet, so that
231 # the attribute 'session' might not even exist yet.
Johnny Chenbfcf37f2011-08-16 17:06:45 +0000232 self.session = getattr(test, "session", None) if test else None
Johnny Chen150c3cc2010-10-15 01:18:29 +0000233 self.trace = trace
234
235 def __enter__(self):
236 """
237 Context management protocol on entry to the body of the with statement.
238 Just return the StringIO object.
239 """
240 return self
241
242 def __exit__(self, type, value, tb):
243 """
244 Context management protocol on exit from the body of the with statement.
245 If trace is ON, it emits the recordings into stderr. Always add the
246 recordings to our session object. And close the StringIO object, too.
247 """
248 if self.trace:
Johnny Chen690fcef2010-10-15 23:55:05 +0000249 print >> sys.stderr, self.getvalue()
250 if self.session:
251 print >> self.session, self.getvalue()
Johnny Chen150c3cc2010-10-15 01:18:29 +0000252 self.close()
253
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000254class _BaseProcess(object):
255 __metaclass__ = abc.ABCMeta
256
257 @abc.abstractproperty
258 def pid(self):
259 """Returns process PID if has been launched already."""
260
261 @abc.abstractmethod
262 def launch(self, executable, args):
263 """Launches new process with given executable and args."""
264
265 @abc.abstractmethod
266 def terminate(self):
267 """Terminates previously launched process.."""
268
269class _LocalProcess(_BaseProcess):
270
271 def __init__(self, trace_on):
272 self._proc = None
273 self._trace_on = trace_on
Ilia K725abcb2015-04-15 13:35:49 +0000274 self._delayafterterminate = 0.1
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000275
276 @property
277 def pid(self):
278 return self._proc.pid
279
280 def launch(self, executable, args):
281 self._proc = Popen([executable] + args,
282 stdout = open(os.devnull) if not self._trace_on else None,
283 stdin = PIPE)
284
285 def terminate(self):
286 if self._proc.poll() == None:
Ilia K725abcb2015-04-15 13:35:49 +0000287 # Terminate _proc like it does the pexpect
Adrian McCarthy137d7ba2015-07-07 14:47:34 +0000288 signals_to_try = [sig for sig in ['SIGHUP', 'SIGCONT', 'SIGINT'] if sig in dir(signal)]
289 for sig in signals_to_try:
290 try:
291 self._proc.send_signal(getattr(signal, sig))
292 time.sleep(self._delayafterterminate)
293 if self._proc.poll() != None:
294 return
295 except ValueError:
296 pass # Windows says SIGINT is not a valid signal to send
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000297 self._proc.terminate()
Ilia K725abcb2015-04-15 13:35:49 +0000298 time.sleep(self._delayafterterminate)
299 if self._proc.poll() != None:
300 return
301 self._proc.kill()
302 time.sleep(self._delayafterterminate)
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000303
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000304 def poll(self):
305 return self._proc.poll()
306
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000307class _RemoteProcess(_BaseProcess):
308
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000309 def __init__(self, install_remote):
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000310 self._pid = None
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000311 self._install_remote = install_remote
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000312
313 @property
314 def pid(self):
315 return self._pid
316
317 def launch(self, executable, args):
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000318 if self._install_remote:
319 src_path = executable
Chaoren Lin5d76b1b2015-06-06 00:25:50 +0000320 dst_path = lldbutil.append_to_process_working_directory(os.path.basename(executable))
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000321
322 dst_file_spec = lldb.SBFileSpec(dst_path, False)
323 err = lldb.remote_platform.Install(lldb.SBFileSpec(src_path, True), dst_file_spec)
324 if err.Fail():
325 raise Exception("remote_platform.Install('%s', '%s') failed: %s" % (src_path, dst_path, err))
326 else:
327 dst_path = executable
328 dst_file_spec = lldb.SBFileSpec(executable, False)
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000329
330 launch_info = lldb.SBLaunchInfo(args)
331 launch_info.SetExecutableFile(dst_file_spec, True)
Chaoren Lin3e2bdb42015-05-11 17:53:39 +0000332 launch_info.SetWorkingDirectory(lldb.remote_platform.GetWorkingDirectory())
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000333
334 # Redirect stdout and stderr to /dev/null
335 launch_info.AddSuppressFileAction(1, False, True)
336 launch_info.AddSuppressFileAction(2, False, True)
337
338 err = lldb.remote_platform.Launch(launch_info)
339 if err.Fail():
340 raise Exception("remote_platform.Launch('%s', '%s') failed: %s" % (dst_path, args, err))
341 self._pid = launch_info.GetProcessID()
342
343 def terminate(self):
Tamas Berghammer04f51d12015-03-11 13:51:07 +0000344 lldb.remote_platform.Kill(self._pid)
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +0000345
Johnny Chen690fcef2010-10-15 23:55:05 +0000346# From 2.7's subprocess.check_output() convenience function.
Johnny Chenac77f3b2011-03-23 20:28:59 +0000347# Return a tuple (stdoutdata, stderrdata).
Zachary Turner9ef307b2014-07-22 16:19:29 +0000348def system(commands, **kwargs):
Johnny Chen8eb14a92011-11-16 22:44:28 +0000349 r"""Run an os command with arguments and return its output as a byte string.
Johnny Chen690fcef2010-10-15 23:55:05 +0000350
351 If the exit code was non-zero it raises a CalledProcessError. The
352 CalledProcessError object will have the return code in the returncode
353 attribute and output in the output attribute.
354
355 The arguments are the same as for the Popen constructor. Example:
356
357 >>> check_output(["ls", "-l", "/dev/null"])
358 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
359
360 The stdout argument is not allowed as it is used internally.
361 To capture standard error in the result, use stderr=STDOUT.
362
363 >>> check_output(["/bin/sh", "-c",
364 ... "ls -l non_existent_file ; exit 0"],
365 ... stderr=STDOUT)
366 'ls: non_existent_file: No such file or directory\n'
367 """
368
369 # Assign the sender object to variable 'test' and remove it from kwargs.
370 test = kwargs.pop('sender', None)
371
Zachary Turner9ef307b2014-07-22 16:19:29 +0000372 # [['make', 'clean', 'foo'], ['make', 'foo']] -> ['make clean foo', 'make foo']
373 commandList = [' '.join(x) for x in commands]
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000374 output = ""
375 error = ""
376 for shellCommand in commandList:
377 if 'stdout' in kwargs:
378 raise ValueError('stdout argument not allowed, it will be overridden.')
379 if 'shell' in kwargs and kwargs['shell']==False:
380 raise ValueError('shell=False not allowed')
381 process = Popen(shellCommand, stdout=PIPE, stderr=PIPE, shell=True, **kwargs)
382 pid = process.pid
383 this_output, this_error = process.communicate()
384 retcode = process.poll()
Zachary Turner9ef307b2014-07-22 16:19:29 +0000385
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000386 # Enable trace on failure return while tracking down FreeBSD buildbot issues
387 trace = traceAlways
388 if not trace and retcode and sys.platform.startswith("freebsd"):
389 trace = True
Johnny Chen690fcef2010-10-15 23:55:05 +0000390
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000391 with recording(test, trace) as sbuf:
392 print >> sbuf
393 print >> sbuf, "os command:", shellCommand
394 print >> sbuf, "with pid:", pid
Adrian McCarthy1d574332015-04-03 17:10:30 +0000395 print >> sbuf, "stdout:", this_output
396 print >> sbuf, "stderr:", this_error
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000397 print >> sbuf, "retcode:", retcode
398 print >> sbuf
Ed Maste6e496332014-08-05 20:33:17 +0000399
Zachary Turner65fe1eb2015-03-26 16:43:25 +0000400 if retcode:
401 cmd = kwargs.get("args")
402 if cmd is None:
403 cmd = shellCommand
404 raise CalledProcessError(retcode, cmd)
405 output = output + this_output
406 error = error + this_error
Johnny Chenac77f3b2011-03-23 20:28:59 +0000407 return (output, error)
Johnny Chen690fcef2010-10-15 23:55:05 +0000408
Johnny Chenab9c1dd2010-11-01 20:35:01 +0000409def getsource_if_available(obj):
410 """
411 Return the text of the source code for an object if available. Otherwise,
412 a print representation is returned.
413 """
414 import inspect
415 try:
416 return inspect.getsource(obj)
417 except:
418 return repr(obj)
419
Peter Collingbourne19f48d52011-06-20 19:06:20 +0000420def builder_module():
Ed Maste4d90f0f2013-07-25 13:24:34 +0000421 if sys.platform.startswith("freebsd"):
422 return __import__("builder_freebsd")
Peter Collingbourne19f48d52011-06-20 19:06:20 +0000423 return __import__("builder_" + sys.platform)
424
Siva Chandra8af91662015-06-05 00:22:49 +0000425def run_adb_command(cmd, device_id):
426 device_id_args = []
427 if device_id:
428 device_id_args = ["-s", device_id]
429 full_cmd = ["adb"] + device_id_args + cmd
430 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE)
431 stdout, stderr = p.communicate()
432 return p.returncode, stdout, stderr
433
Chaoren Line9bbabc2015-07-18 00:37:55 +0000434def append_android_envs(dictionary):
435 if dictionary is None:
436 dictionary = {}
437 dictionary["OS"] = "Android"
438 if android_device_api() >= 16:
439 dictionary["PIE"] = 1
440 return dictionary
441
Chaoren Lin9070f532015-07-17 22:13:29 +0000442def target_is_android():
443 if not hasattr(target_is_android, 'result'):
444 triple = lldb.DBG.GetSelectedPlatform().GetTriple()
445 match = re.match(".*-.*-.*-android", triple)
446 target_is_android.result = match is not None
447 return target_is_android.result
448
Siva Chandra8af91662015-06-05 00:22:49 +0000449def android_device_api():
Chaoren Lin9070f532015-07-17 22:13:29 +0000450 if not hasattr(android_device_api, 'result'):
451 assert lldb.platform_url is not None
452 device_id = None
453 parsed_url = urlparse.urlparse(lldb.platform_url)
454 if parsed_url.scheme == "adb":
455 device_id = parsed_url.netloc.split(":")[0]
456 retcode, stdout, stderr = run_adb_command(
457 ["shell", "getprop", "ro.build.version.sdk"], device_id)
458 if retcode == 0:
459 android_device_api.result = int(stdout)
460 else:
461 raise LookupError(
462 ">>> Unable to determine the API level of the Android device.\n"
463 ">>> stdout:\n%s\n"
464 ">>> stderr:\n%s\n" % (stdout, stderr))
465 return android_device_api.result
Siva Chandra8af91662015-06-05 00:22:49 +0000466
Johnny Chena74bb0a2011-08-01 18:46:13 +0000467#
468# Decorators for categorizing test cases.
469#
470
471from functools import wraps
472def python_api_test(func):
473 """Decorate the item as a Python API only test."""
474 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
475 raise Exception("@python_api_test can only be used to decorate a test method")
476 @wraps(func)
477 def wrapper(self, *args, **kwargs):
478 try:
479 if lldb.dont_do_python_api_test:
480 self.skipTest("python api tests")
481 except AttributeError:
482 pass
483 return func(self, *args, **kwargs)
484
485 # Mark this function as such to separate them from lldb command line tests.
486 wrapper.__python_api_test__ = True
487 return wrapper
488
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +0000489def lldbmi_test(func):
490 """Decorate the item as a lldb-mi only test."""
491 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
492 raise Exception("@lldbmi_test can only be used to decorate a test method")
493 @wraps(func)
494 def wrapper(self, *args, **kwargs):
495 try:
496 if lldb.dont_do_lldbmi_test:
497 self.skipTest("lldb-mi tests")
498 except AttributeError:
499 pass
500 return func(self, *args, **kwargs)
501
502 # Mark this function as such to separate them from lldb command line tests.
503 wrapper.__lldbmi_test__ = True
504 return wrapper
505
Johnny Chena74bb0a2011-08-01 18:46:13 +0000506def benchmarks_test(func):
507 """Decorate the item as a benchmarks test."""
508 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
509 raise Exception("@benchmarks_test can only be used to decorate a test method")
510 @wraps(func)
511 def wrapper(self, *args, **kwargs):
512 try:
513 if not lldb.just_do_benchmarks_test:
514 self.skipTest("benchmarks tests")
515 except AttributeError:
516 pass
517 return func(self, *args, **kwargs)
518
519 # Mark this function as such to separate them from the regular tests.
520 wrapper.__benchmarks_test__ = True
521 return wrapper
522
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000523def no_debug_info_test(func):
524 """Decorate the item as a test what don't use any debug info. If this annotation is specified
525 then the test runner won't generate a separate test for each debug info format. """
526 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
527 raise Exception("@no_debug_info_test can only be used to decorate a test method")
528 @wraps(func)
529 def wrapper(self, *args, **kwargs):
530 return func(self, *args, **kwargs)
531
532 # Mark this function as such to separate them from the regular tests.
533 wrapper.__no_debug_info_test__ = True
534 return wrapper
535
Johnny Chenf1548d42012-04-06 00:56:05 +0000536def dsym_test(func):
537 """Decorate the item as a dsym test."""
538 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
539 raise Exception("@dsym_test can only be used to decorate a test method")
540 @wraps(func)
541 def wrapper(self, *args, **kwargs):
542 try:
543 if lldb.dont_do_dsym_test:
544 self.skipTest("dsym tests")
545 except AttributeError:
546 pass
547 return func(self, *args, **kwargs)
548
549 # Mark this function as such to separate them from the regular tests.
550 wrapper.__dsym_test__ = True
551 return wrapper
552
553def dwarf_test(func):
554 """Decorate the item as a dwarf test."""
555 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
556 raise Exception("@dwarf_test can only be used to decorate a test method")
557 @wraps(func)
558 def wrapper(self, *args, **kwargs):
559 try:
560 if lldb.dont_do_dwarf_test:
561 self.skipTest("dwarf tests")
562 except AttributeError:
563 pass
564 return func(self, *args, **kwargs)
565
566 # Mark this function as such to separate them from the regular tests.
567 wrapper.__dwarf_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):
576 try:
577 if lldb.dont_do_debugserver_test:
578 self.skipTest("debugserver tests")
579 except AttributeError:
580 pass
581 return func(self, *args, **kwargs)
582
583 # Mark this function as such to separate them from the regular tests.
584 wrapper.__debugserver_test__ = True
585 return wrapper
586
587def llgs_test(func):
Robert Flack8cc4cf12015-03-06 14:36:33 +0000588 """Decorate the item as a lldb-server test."""
Todd Fialaa41d48c2014-04-28 04:49:40 +0000589 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
590 raise Exception("@llgs_test can only be used to decorate a test method")
591 @wraps(func)
592 def wrapper(self, *args, **kwargs):
593 try:
594 if lldb.dont_do_llgs_test:
595 self.skipTest("llgs tests")
596 except AttributeError:
597 pass
598 return func(self, *args, **kwargs)
599
600 # Mark this function as such to separate them from the regular tests.
601 wrapper.__llgs_test__ = True
602 return wrapper
603
Daniel Maleae0f8f572013-08-26 23:57:52 +0000604def not_remote_testsuite_ready(func):
605 """Decorate the item as a test which is not ready yet for remote testsuite."""
606 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
607 raise Exception("@not_remote_testsuite_ready can only be used to decorate a test method")
608 @wraps(func)
609 def wrapper(self, *args, **kwargs):
610 try:
Tamas Berghammer3e0ecb22015-03-25 15:13:28 +0000611 if lldb.lldbtest_remote_sandbox or lldb.remote_platform:
Daniel Maleae0f8f572013-08-26 23:57:52 +0000612 self.skipTest("not ready for remote testsuite")
613 except AttributeError:
614 pass
615 return func(self, *args, **kwargs)
616
617 # Mark this function as such to separate them from the regular tests.
618 wrapper.__not_ready_for_remote_testsuite_test__ = True
619 return wrapper
620
Ed Maste433790a2014-04-23 12:55:41 +0000621def expectedFailure(expected_fn, bugnumber=None):
622 def expectedFailure_impl(func):
623 @wraps(func)
624 def wrapper(*args, **kwargs):
Enrico Granata43f62132013-02-23 01:28:30 +0000625 from unittest2 import case
626 self = args[0]
Enrico Granata43f62132013-02-23 01:28:30 +0000627 try:
Ed Maste433790a2014-04-23 12:55:41 +0000628 func(*args, **kwargs)
Enrico Granata43f62132013-02-23 01:28:30 +0000629 except Exception:
Ed Maste433790a2014-04-23 12:55:41 +0000630 if expected_fn(self):
631 raise case._ExpectedFailure(sys.exc_info(), bugnumber)
Enrico Granata43f62132013-02-23 01:28:30 +0000632 else:
633 raise
Ed Maste433790a2014-04-23 12:55:41 +0000634 if expected_fn(self):
635 raise case._UnexpectedSuccess(sys.exc_info(), bugnumber)
636 return wrapper
Ying Chen464d1e12015-03-27 00:26:52 +0000637 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
638 # return decorator in this case, so it will be used to decorating original method
639 if callable(bugnumber):
640 return expectedFailure_impl(bugnumber)
641 else:
642 return expectedFailure_impl
Ed Maste433790a2014-04-23 12:55:41 +0000643
Ying Chen7091c2c2015-04-21 01:15:47 +0000644# provide a function to xfail on defined oslist, compiler version, and archs
645# if none is specified for any argument, that argument won't be checked and thus means for all
646# for example,
647# @expectedFailureAll, xfail for all platform/compiler/arch,
648# @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
649# @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000650def expectedFailureAll(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, triple=None, debug_info=None):
Ying Chen7091c2c2015-04-21 01:15:47 +0000651 def fn(self):
652 return ((oslist is None or self.getPlatform() in oslist) and
653 (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
Tamas Berghammercf6f92a2015-09-07 15:50:19 +0000654 self.expectedArch(archs) and
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000655 (triple is None or re.match(triple, lldb.DBG.GetSelectedPlatform().GetTriple())) and
656 (debug_info is None or self.debug_info in debug_info))
Ying Chen7091c2c2015-04-21 01:15:47 +0000657 return expectedFailure(fn, bugnumber)
658
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000659def expectedFailureDwarf(bugnumber=None):
660 return expectedFailureAll(bugnumber==bugnumber, debug_info="dwarf")
661
662def expectedFailureDsym(bugnumber=None):
663 return expectedFailureAll(bugnumber==bugnumber, debug_info="dsym")
664
665def expectedFailureCompiler(compiler, compiler_version=None, bugnumber=None):
666 if compiler_version is None:
667 compiler_version=['=', None]
668 return expectedFailureAll(bugnumber=bugnumber, compiler=compiler, compiler_version=compiler_version)
669
Vince Harron8974ce22015-03-13 19:54:54 +0000670# to XFAIL a specific clang versions, try this
671# @expectedFailureClang('bugnumber', ['<=', '3.4'])
672def expectedFailureClang(bugnumber=None, compiler_version=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000673 return expectedFailureCompiler('clang', compiler_version, bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000674
675def expectedFailureGcc(bugnumber=None, compiler_version=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000676 return expectedFailureCompiler('gcc', compiler_version, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000677
Matt Kopec0de53f02013-03-15 19:10:12 +0000678def expectedFailureIcc(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000679 return expectedFailureCompiler('icc', None, bugnumber)
Matt Kopec0de53f02013-03-15 19:10:12 +0000680
Ed Maste433790a2014-04-23 12:55:41 +0000681def expectedFailureArch(arch, bugnumber=None):
682 def fn(self):
683 return arch in self.getArchitecture()
Ying Chen464d1e12015-03-27 00:26:52 +0000684 return expectedFailure(fn, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000685
Enrico Granatae6cedc12013-02-23 01:05:23 +0000686def expectedFailurei386(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000687 return expectedFailureArch('i386', bugnumber)
Johnny Chena33843f2011-12-22 21:14:31 +0000688
Matt Kopecee969f92013-09-26 23:30:59 +0000689def expectedFailurex86_64(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000690 return expectedFailureArch('x86_64', bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000691
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000692def expectedFailureOS(oslist, bugnumber=None, compilers=None, debug_info=None):
Ed Maste433790a2014-04-23 12:55:41 +0000693 def fn(self):
Robert Flack13c7ad92015-03-30 14:12:17 +0000694 return (self.getPlatform() in oslist and
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000695 self.expectedCompiler(compilers) and
696 (debug_info is None or self.debug_info in debug_info))
Ying Chen464d1e12015-03-27 00:26:52 +0000697 return expectedFailure(fn, bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000698
Chaoren Linf7160f32015-06-09 17:39:27 +0000699def expectedFailureHostOS(oslist, bugnumber=None, compilers=None):
700 def fn(self):
701 return (getHostPlatform() in oslist and
702 self.expectedCompiler(compilers))
703 return expectedFailure(fn, bugnumber)
704
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000705def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None):
Robert Flackefa49c22015-03-26 19:34:26 +0000706 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000707 return expectedFailureOS(getDarwinOSTriples(), bugnumber, compilers, debug_info=debug_info)
Matt Kopecee969f92013-09-26 23:30:59 +0000708
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000709def expectedFailureFreeBSD(bugnumber=None, compilers=None, debug_info=None):
710 return expectedFailureOS(['freebsd'], bugnumber, compilers, debug_info=debug_info)
Ed Maste24a7f7d2013-07-24 19:47:08 +0000711
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000712def expectedFailureLinux(bugnumber=None, compilers=None, debug_info=None):
713 return expectedFailureOS(['linux'], bugnumber, compilers, debug_info=debug_info)
Matt Kopece9ea0da2013-05-07 19:29:28 +0000714
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000715def expectedFailureWindows(bugnumber=None, compilers=None, debug_info=None):
716 return expectedFailureOS(['windows'], bugnumber, compilers, debug_info=debug_info)
Zachary Turner80c2c602014-12-09 19:28:00 +0000717
Chaoren Linf7160f32015-06-09 17:39:27 +0000718def expectedFailureHostWindows(bugnumber=None, compilers=None):
719 return expectedFailureHostOS(['windows'], bugnumber, compilers)
720
Pavel Labath090152b2015-08-20 11:37:19 +0000721def matchAndroid(api_levels=None, archs=None):
722 def match(self):
723 if not target_is_android():
724 return False
725 if archs is not None and self.getArchitecture() not in archs:
726 return False
727 if api_levels is not None and android_device_api() not in api_levels:
728 return False
729 return True
730 return match
731
732
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000733def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
Siva Chandra8af91662015-06-05 00:22:49 +0000734 """ Mark a test as xfail for Android.
735
736 Arguments:
737 bugnumber - The LLVM pr associated with the problem.
738 api_levels - A sequence of numbers specifying the Android API levels
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000739 for which a test is expected to fail. None means all API level.
740 arch - A sequence of architecture names specifying the architectures
741 for which a test is expected to fail. None means all architectures.
Siva Chandra8af91662015-06-05 00:22:49 +0000742 """
Pavel Labath090152b2015-08-20 11:37:19 +0000743 return expectedFailure(matchAndroid(api_levels, archs), bugnumber)
Pavel Labath674bc7b2015-05-29 14:54:46 +0000744
Vince Harron7ac3ea42015-06-26 15:13:21 +0000745# if the test passes on the first try, we're done (success)
746# if the test fails once, then passes on the second try, raise an ExpectedFailure
747# if the test fails twice in a row, re-throw the exception from the second test run
748def expectedFlakey(expected_fn, bugnumber=None):
749 def expectedFailure_impl(func):
750 @wraps(func)
751 def wrapper(*args, **kwargs):
752 from unittest2 import case
753 self = args[0]
754 try:
755 func(*args, **kwargs)
Ying Chen0a7202b2015-07-01 22:44:27 +0000756 # don't retry if the test case is already decorated with xfail or skip
757 except (case._ExpectedFailure, case.SkipTest, case._UnexpectedSuccess):
758 raise
Vince Harron7ac3ea42015-06-26 15:13:21 +0000759 except Exception:
760 if expected_fn(self):
Ying Chen0a7202b2015-07-01 22:44:27 +0000761 # before retry, run tearDown for previous run and setup for next
Vince Harron7ac3ea42015-06-26 15:13:21 +0000762 try:
Ying Chen0a7202b2015-07-01 22:44:27 +0000763 self.tearDown()
764 self.setUp()
Vince Harron7ac3ea42015-06-26 15:13:21 +0000765 func(*args, **kwargs)
766 except Exception:
767 # oh snap! two failures in a row, record a failure/error
768 raise
769 # record the expected failure
770 raise case._ExpectedFailure(sys.exc_info(), bugnumber)
771 else:
772 raise
773 return wrapper
774 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
775 # return decorator in this case, so it will be used to decorating original method
776 if callable(bugnumber):
777 return expectedFailure_impl(bugnumber)
778 else:
779 return expectedFailure_impl
780
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000781def expectedFlakeyDwarf(bugnumber=None):
782 def fn(self):
783 return self.debug_info == "dwarf"
784 return expectedFlakey(fn, bugnumber)
785
786def expectedFlakeyDsym(bugnumber=None):
787 def fn(self):
788 return self.debug_info == "dwarf"
789 return expectedFlakey(fn, bugnumber)
790
Vince Harron7ac3ea42015-06-26 15:13:21 +0000791def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
792 def fn(self):
793 return (self.getPlatform() in oslist and
794 self.expectedCompiler(compilers))
795 return expectedFlakey(fn, bugnumber)
796
797def expectedFlakeyDarwin(bugnumber=None, compilers=None):
798 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
799 return expectedFlakeyOS(getDarwinOSTriples(), bugnumber, compilers)
800
801def expectedFlakeyLinux(bugnumber=None, compilers=None):
802 return expectedFlakeyOS(['linux'], bugnumber, compilers)
803
804def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
805 return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
806
807def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
808 if compiler_version is None:
809 compiler_version=['=', None]
810 def fn(self):
811 return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
812 return expectedFlakey(fn, bugnumber)
813
814# @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
815def expectedFlakeyClang(bugnumber=None, compiler_version=None):
816 return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
817
818# @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
819def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
820 return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
821
Pavel Labath63a579c2015-09-07 12:15:27 +0000822def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
823 return expectedFlakey(matchAndroid(api_levels, archs), bugnumber)
824
Greg Clayton12514562013-12-05 22:22:32 +0000825def skipIfRemote(func):
826 """Decorate the item to skip tests if testing remotely."""
827 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
828 raise Exception("@skipIfRemote can only be used to decorate a test method")
829 @wraps(func)
830 def wrapper(*args, **kwargs):
831 from unittest2 import case
832 if lldb.remote_platform:
833 self = args[0]
834 self.skipTest("skip on remote platform")
835 else:
836 func(*args, **kwargs)
837 return wrapper
838
Siva Chandra4470f382015-06-17 22:32:27 +0000839def skipUnlessListedRemote(remote_list=None):
840 def myImpl(func):
841 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
842 raise Exception("@skipIfRemote can only be used to decorate a "
843 "test method")
844
845 @wraps(func)
846 def wrapper(*args, **kwargs):
847 if remote_list and lldb.remote_platform:
848 self = args[0]
849 triple = self.dbg.GetSelectedPlatform().GetTriple()
850 for r in remote_list:
851 if r in triple:
852 func(*args, **kwargs)
853 return
854 self.skipTest("skip on remote platform %s" % str(triple))
855 else:
856 func(*args, **kwargs)
857 return wrapper
858
859 return myImpl
860
Greg Clayton12514562013-12-05 22:22:32 +0000861def skipIfRemoteDueToDeadlock(func):
862 """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
863 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
864 raise Exception("@skipIfRemote can only be used to decorate a test method")
865 @wraps(func)
866 def wrapper(*args, **kwargs):
867 from unittest2 import case
868 if lldb.remote_platform:
869 self = args[0]
870 self.skipTest("skip on remote platform (deadlocks)")
871 else:
872 func(*args, **kwargs)
873 return wrapper
874
Enrico Granatab633e432014-10-06 21:37:06 +0000875def skipIfNoSBHeaders(func):
876 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
877 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Ed Maste59cca5d2014-10-07 01:57:52 +0000878 raise Exception("@skipIfNoSBHeaders can only be used to decorate a test method")
Enrico Granatab633e432014-10-06 21:37:06 +0000879 @wraps(func)
880 def wrapper(*args, **kwargs):
881 from unittest2 import case
882 self = args[0]
Shawn Best181b09b2014-11-08 00:04:04 +0000883 if sys.platform.startswith("darwin"):
884 header = os.path.join(self.lib_dir, 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
885 else:
886 header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
Enrico Granatab633e432014-10-06 21:37:06 +0000887 platform = sys.platform
Enrico Granatab633e432014-10-06 21:37:06 +0000888 if not os.path.exists(header):
889 self.skipTest("skip because LLDB.h header not found")
890 else:
891 func(*args, **kwargs)
892 return wrapper
893
Robert Flack13c7ad92015-03-30 14:12:17 +0000894def skipIfFreeBSD(func):
895 """Decorate the item to skip tests that should be skipped on FreeBSD."""
896 return skipIfPlatform(["freebsd"])(func)
Zachary Turnerc7826522014-08-13 17:44:53 +0000897
Greg Claytone0d0a762015-04-02 18:24:03 +0000898def getDarwinOSTriples():
899 return ['darwin', 'macosx', 'ios']
900
Daniel Maleab3d41a22013-07-09 00:08:01 +0000901def skipIfDarwin(func):
902 """Decorate the item to skip tests that should be skipped on Darwin."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000903 return skipIfPlatform(getDarwinOSTriples())(func)
Daniel Maleab3d41a22013-07-09 00:08:01 +0000904
Robert Flack13c7ad92015-03-30 14:12:17 +0000905def skipIfLinux(func):
906 """Decorate the item to skip tests that should be skipped on Linux."""
907 return skipIfPlatform(["linux"])(func)
908
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000909def skipUnlessHostLinux(func):
910 """Decorate the item to skip tests that should be skipped on any non Linux host."""
911 return skipUnlessHostPlatform(["linux"])(func)
912
Robert Flack13c7ad92015-03-30 14:12:17 +0000913def skipIfWindows(func):
914 """Decorate the item to skip tests that should be skipped on Windows."""
915 return skipIfPlatform(["windows"])(func)
916
Chaoren Line6eea5d2015-06-08 22:13:28 +0000917def skipIfHostWindows(func):
918 """Decorate the item to skip tests that should be skipped on Windows."""
919 return skipIfHostPlatform(["windows"])(func)
920
Adrian McCarthyd9dbae52015-09-16 18:17:11 +0000921def skipUnlessWindows(func):
922 """Decorate the item to skip tests that should be skipped on any non-Windows platform."""
923 return skipUnlessPlatform(["windows"])(func)
924
Robert Flack13c7ad92015-03-30 14:12:17 +0000925def skipUnlessDarwin(func):
926 """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000927 return skipUnlessPlatform(getDarwinOSTriples())(func)
Robert Flack13c7ad92015-03-30 14:12:17 +0000928
Ryan Brown57bee1e2015-09-14 22:45:11 +0000929def skipUnlessGoInstalled(func):
930 """Decorate the item to skip tests when no Go compiler is available."""
931 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
932 raise Exception("@skipIfGcc can only be used to decorate a test method")
933 @wraps(func)
934 def wrapper(*args, **kwargs):
935 from unittest2 import case
936 self = args[0]
937 compiler = self.getGoCompilerVersion()
938 if not compiler:
939 self.skipTest("skipping because go compiler not found")
940 else:
941 func(*args, **kwargs)
942 return wrapper
943
Robert Flack068898c2015-04-09 18:07:58 +0000944def getPlatform():
Robert Flack6e1fd352015-05-15 12:39:33 +0000945 """Returns the target platform which the tests are running on."""
Robert Flack068898c2015-04-09 18:07:58 +0000946 platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
947 if platform.startswith('freebsd'):
948 platform = 'freebsd'
949 return platform
950
Robert Flack6e1fd352015-05-15 12:39:33 +0000951def getHostPlatform():
952 """Returns the host platform running the test suite."""
953 # Attempts to return a platform name matching a target Triple platform.
954 if sys.platform.startswith('linux'):
955 return 'linux'
956 elif sys.platform.startswith('win32'):
957 return 'windows'
958 elif sys.platform.startswith('darwin'):
959 return 'darwin'
960 elif sys.platform.startswith('freebsd'):
961 return 'freebsd'
962 else:
963 return sys.platform
964
Robert Flackfb2f6c62015-04-17 08:02:18 +0000965def platformIsDarwin():
966 """Returns true if the OS triple for the selected platform is any valid apple OS"""
967 return getPlatform() in getDarwinOSTriples()
968
Robert Flack6e1fd352015-05-15 12:39:33 +0000969def skipIfHostIncompatibleWithRemote(func):
970 """Decorate the item to skip tests if binaries built on this host are incompatible."""
971 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
972 raise Exception("@skipIfHostIncompatibleWithRemote can only be used to decorate a test method")
973 @wraps(func)
974 def wrapper(*args, **kwargs):
975 from unittest2 import case
976 self = args[0]
977 host_arch = self.getLldbArchitecture()
978 host_platform = getHostPlatform()
979 target_arch = self.getArchitecture()
Robert Flack4629c4b2015-05-15 18:54:32 +0000980 target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
Robert Flack6e1fd352015-05-15 12:39:33 +0000981 if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
982 self.skipTest("skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch))
983 elif target_platform != host_platform:
984 self.skipTest("skipping because target is %s but host is %s" % (target_platform, host_platform))
985 else:
986 func(*args, **kwargs)
987 return wrapper
988
Chaoren Line6eea5d2015-06-08 22:13:28 +0000989def skipIfHostPlatform(oslist):
990 """Decorate the item to skip tests if running on one of the listed host platforms."""
991 return unittest2.skipIf(getHostPlatform() in oslist,
992 "skip on %s" % (", ".join(oslist)))
993
994def skipUnlessHostPlatform(oslist):
995 """Decorate the item to skip tests unless running on one of the listed host platforms."""
996 return unittest2.skipUnless(getHostPlatform() in oslist,
997 "requires on of %s" % (", ".join(oslist)))
998
Zachary Turner793d9972015-08-14 23:29:24 +0000999def skipUnlessArch(archlist):
1000 """Decorate the item to skip tests unless running on one of the listed architectures."""
1001 def myImpl(func):
1002 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1003 raise Exception("@skipUnlessArch can only be used to decorate a test method")
1004
1005 @wraps(func)
1006 def wrapper(*args, **kwargs):
1007 self = args[0]
1008 if self.getArchitecture() not in archlist:
1009 self.skipTest("skipping for architecture %s (requires one of %s)" %
1010 (self.getArchitecture(), ", ".join(archlist)))
1011 else:
1012 func(*args, **kwargs)
1013 return wrapper
1014
1015 return myImpl
1016
Robert Flack13c7ad92015-03-30 14:12:17 +00001017def skipIfPlatform(oslist):
1018 """Decorate the item to skip tests if running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +00001019 return unittest2.skipIf(getPlatform() in oslist,
1020 "skip on %s" % (", ".join(oslist)))
Robert Flack13c7ad92015-03-30 14:12:17 +00001021
1022def skipUnlessPlatform(oslist):
1023 """Decorate the item to skip tests unless running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +00001024 return unittest2.skipUnless(getPlatform() in oslist,
1025 "requires on of %s" % (", ".join(oslist)))
Daniel Maleab3d41a22013-07-09 00:08:01 +00001026
Daniel Malea48359902013-05-14 20:48:54 +00001027def skipIfLinuxClang(func):
1028 """Decorate the item to skip tests that should be skipped if building on
1029 Linux with clang.
1030 """
1031 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1032 raise Exception("@skipIfLinuxClang can only be used to decorate a test method")
1033 @wraps(func)
1034 def wrapper(*args, **kwargs):
1035 from unittest2 import case
1036 self = args[0]
1037 compiler = self.getCompiler()
Vince Harronc8492672015-05-04 02:59:19 +00001038 platform = self.getPlatform()
1039 if "clang" in compiler and platform == "linux":
Daniel Malea48359902013-05-14 20:48:54 +00001040 self.skipTest("skipping because Clang is used on Linux")
1041 else:
1042 func(*args, **kwargs)
1043 return wrapper
1044
Ying Chen7091c2c2015-04-21 01:15:47 +00001045# provide a function to skip on defined oslist, compiler version, and archs
1046# if none is specified for any argument, that argument won't be checked and thus means for all
1047# for example,
1048# @skipIf, skip for all platform/compiler/arch,
1049# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
1050# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
1051
1052# TODO: refactor current code, to make skipIfxxx functions to call this function
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00001053def skipIf(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, debug_info=None):
Ying Chen7091c2c2015-04-21 01:15:47 +00001054 def fn(self):
1055 return ((oslist is None or self.getPlatform() in oslist) and
1056 (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00001057 self.expectedArch(archs) and
1058 (debug_info is None or self.debug_info in debug_info))
1059 return skipTestIfFn(fn, bugnumber, skipReason="skipping because os:%s compiler: %s %s arch: %s debug info: %s"%(oslist, compiler, compiler_version, archs, debug_info))
1060
1061def skipIfDebugInfo(bugnumber=None, debug_info=None):
1062 return skipIf(bugnumber=bugnumber, debug_info=debug_info)
1063
1064def skipIfDwarf(bugnumber=None):
1065 return skipIfDebugInfo(bugnumber, ["dwarf"])
1066
1067def skipIfDsym(bugnumber=None):
1068 return skipIfDebugInfo(bugnumber, ["dsym"])
Ying Chen7091c2c2015-04-21 01:15:47 +00001069
1070def skipTestIfFn(expected_fn, bugnumber=None, skipReason=None):
1071 def skipTestIfFn_impl(func):
1072 @wraps(func)
1073 def wrapper(*args, **kwargs):
1074 from unittest2 import case
1075 self = args[0]
1076 if expected_fn(self):
1077 self.skipTest(skipReason)
1078 else:
1079 func(*args, **kwargs)
1080 return wrapper
1081 if callable(bugnumber):
1082 return skipTestIfFn_impl(bugnumber)
1083 else:
1084 return skipTestIfFn_impl
1085
Daniel Maleabe230792013-01-24 23:52:09 +00001086def skipIfGcc(func):
1087 """Decorate the item to skip tests that should be skipped if building with gcc ."""
1088 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Daniel Malea0aea0162013-02-27 17:29:46 +00001089 raise Exception("@skipIfGcc can only be used to decorate a test method")
Daniel Maleabe230792013-01-24 23:52:09 +00001090 @wraps(func)
1091 def wrapper(*args, **kwargs):
1092 from unittest2 import case
1093 self = args[0]
1094 compiler = self.getCompiler()
1095 if "gcc" in compiler:
1096 self.skipTest("skipping because gcc is the test compiler")
1097 else:
1098 func(*args, **kwargs)
1099 return wrapper
1100
Matt Kopec0de53f02013-03-15 19:10:12 +00001101def skipIfIcc(func):
1102 """Decorate the item to skip tests that should be skipped if building with icc ."""
1103 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1104 raise Exception("@skipIfIcc can only be used to decorate a test method")
1105 @wraps(func)
1106 def wrapper(*args, **kwargs):
1107 from unittest2 import case
1108 self = args[0]
1109 compiler = self.getCompiler()
1110 if "icc" in compiler:
1111 self.skipTest("skipping because icc is the test compiler")
1112 else:
1113 func(*args, **kwargs)
1114 return wrapper
1115
Daniel Malea55faa402013-05-02 21:44:31 +00001116def skipIfi386(func):
1117 """Decorate the item to skip tests that should be skipped if building 32-bit."""
1118 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1119 raise Exception("@skipIfi386 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 if "i386" == self.getArchitecture():
1125 self.skipTest("skipping because i386 is not a supported architecture")
1126 else:
1127 func(*args, **kwargs)
1128 return wrapper
1129
Pavel Labath090152b2015-08-20 11:37:19 +00001130def skipIfTargetAndroid(api_levels=None, archs=None):
Siva Chandra77f20fc2015-06-05 19:54:49 +00001131 """Decorator to skip tests when the target is Android.
1132
1133 Arguments:
1134 api_levels - The API levels for which the test should be skipped. If
1135 it is None, then the test will be skipped for all API levels.
Pavel Labath090152b2015-08-20 11:37:19 +00001136 arch - A sequence of architecture names specifying the architectures
1137 for which a test is skipped. None means all architectures.
Siva Chandra77f20fc2015-06-05 19:54:49 +00001138 """
1139 def myImpl(func):
1140 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1141 raise Exception("@skipIfTargetAndroid can only be used to "
1142 "decorate a test method")
1143 @wraps(func)
1144 def wrapper(*args, **kwargs):
1145 from unittest2 import case
1146 self = args[0]
Pavel Labath090152b2015-08-20 11:37:19 +00001147 if matchAndroid(api_levels, archs)(self):
1148 self.skipTest("skiped on Android target with API %d and architecture %s" %
1149 (android_device_api(), self.getArchitecture()))
Tamas Berghammer1253a812015-03-13 10:12:25 +00001150 func(*args, **kwargs)
Siva Chandra77f20fc2015-06-05 19:54:49 +00001151 return wrapper
1152 return myImpl
Tamas Berghammer1253a812015-03-13 10:12:25 +00001153
Ilia Kd9953052015-03-12 07:19:41 +00001154def skipUnlessCompilerRt(func):
1155 """Decorate the item to skip tests if testing remotely."""
1156 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1157 raise Exception("@skipUnless can only be used to decorate a test method")
1158 @wraps(func)
1159 def wrapper(*args, **kwargs):
1160 from unittest2 import case
1161 import os.path
1162 compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "projects", "compiler-rt")
1163 if not os.path.exists(compilerRtPath):
1164 self = args[0]
1165 self.skipTest("skip if compiler-rt not found")
1166 else:
1167 func(*args, **kwargs)
1168 return wrapper
Daniel Malea55faa402013-05-02 21:44:31 +00001169
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001170class _PlatformContext(object):
1171 """Value object class which contains platform-specific options."""
1172
1173 def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
1174 self.shlib_environment_var = shlib_environment_var
1175 self.shlib_prefix = shlib_prefix
1176 self.shlib_extension = shlib_extension
1177
1178
Johnny Chena74bb0a2011-08-01 18:46:13 +00001179class Base(unittest2.TestCase):
Johnny Chen8334dad2010-10-22 23:15:46 +00001180 """
Johnny Chena74bb0a2011-08-01 18:46:13 +00001181 Abstract base for performing lldb (see TestBase) or other generic tests (see
1182 BenchBase for one example). lldbtest.Base works with the test driver to
1183 accomplish things.
1184
Johnny Chen8334dad2010-10-22 23:15:46 +00001185 """
Enrico Granata5020f952012-10-24 21:42:49 +00001186
Enrico Granata19186272012-10-24 21:44:48 +00001187 # The concrete subclass should override this attribute.
1188 mydir = None
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001189
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001190 # Keep track of the old current working directory.
1191 oldcwd = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001192
Greg Clayton4570d3e2013-12-10 23:19:29 +00001193 @staticmethod
1194 def compute_mydir(test_file):
1195 '''Subclasses should call this function to correctly calculate the required "mydir" attribute as follows:
1196
1197 mydir = TestBase.compute_mydir(__file__)'''
1198 test_dir = os.path.dirname(test_file)
1199 return test_dir[len(os.environ["LLDB_TEST"])+1:]
1200
Johnny Chenfb4264c2011-08-01 19:50:58 +00001201 def TraceOn(self):
1202 """Returns True if we are in trace mode (tracing detailed test execution)."""
1203 return traceAlways
Greg Clayton4570d3e2013-12-10 23:19:29 +00001204
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001205 @classmethod
1206 def setUpClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001207 """
1208 Python unittest framework class setup fixture.
1209 Do current directory manipulation.
1210 """
Johnny Chenf02ec122010-07-03 20:41:42 +00001211 # Fail fast if 'mydir' attribute is not overridden.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001212 if not cls.mydir or len(cls.mydir) == 0:
Johnny Chenf02ec122010-07-03 20:41:42 +00001213 raise Exception("Subclasses must override the 'mydir' attribute.")
Enrico Granata7e137e32012-10-24 18:14:21 +00001214
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001215 # Save old working directory.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001216 cls.oldcwd = os.getcwd()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001217
1218 # Change current working directory if ${LLDB_TEST} is defined.
1219 # See also dotest.py which sets up ${LLDB_TEST}.
1220 if ("LLDB_TEST" in os.environ):
Vince Harron85d19652015-05-21 19:09:29 +00001221 full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001222 if traceAlways:
Vince Harron85d19652015-05-21 19:09:29 +00001223 print >> sys.stderr, "Change dir to:", full_dir
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001224 os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
1225
Vince Harron85d19652015-05-21 19:09:29 +00001226 if debug_confirm_directory_exclusivity:
Zachary Turnerb48b4042015-05-21 20:16:02 +00001227 import lock
Vince Harron85d19652015-05-21 19:09:29 +00001228 cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
1229 try:
1230 cls.dir_lock.try_acquire()
1231 # write the class that owns the lock into the lock file
1232 cls.dir_lock.handle.write(cls.__name__)
1233 except IOError as ioerror:
1234 # nothing else should have this directory lock
1235 # wait here until we get a lock
1236 cls.dir_lock.acquire()
1237 # read the previous owner from the lock file
1238 lock_id = cls.dir_lock.handle.read()
1239 print >> sys.stderr, "LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id)
1240 raise ioerror
1241
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001242 # Set platform context.
Robert Flackfb2f6c62015-04-17 08:02:18 +00001243 if platformIsDarwin():
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001244 cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
Robert Flackfb2f6c62015-04-17 08:02:18 +00001245 elif getPlatform() == "linux" or getPlatform() == "freebsd":
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001246 cls.platformContext = _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001247 else:
1248 cls.platformContext = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001249
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001250 @classmethod
1251 def tearDownClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001252 """
1253 Python unittest framework class teardown fixture.
1254 Do class-wide cleanup.
1255 """
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001256
Johnny Chen0fddfb22011-11-17 19:57:27 +00001257 if doCleanup and not lldb.skip_build_and_cleanup:
Johnny Chen707b3c92010-10-11 22:25:46 +00001258 # First, let's do the platform-specific cleanup.
Peter Collingbourne19f48d52011-06-20 19:06:20 +00001259 module = builder_module()
Zachary Turnerb1490b62015-08-26 19:44:56 +00001260 module.cleanup()
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001261
Johnny Chen707b3c92010-10-11 22:25:46 +00001262 # Subclass might have specific cleanup function defined.
1263 if getattr(cls, "classCleanup", None):
1264 if traceAlways:
1265 print >> sys.stderr, "Call class-specific cleanup function for class:", cls
1266 try:
1267 cls.classCleanup()
1268 except:
1269 exc_type, exc_value, exc_tb = sys.exc_info()
1270 traceback.print_exception(exc_type, exc_value, exc_tb)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001271
Vince Harron85d19652015-05-21 19:09:29 +00001272 if debug_confirm_directory_exclusivity:
1273 cls.dir_lock.release()
1274 del cls.dir_lock
1275
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001276 # Restore old working directory.
1277 if traceAlways:
Johnny Chen703dbd02010-09-30 17:06:24 +00001278 print >> sys.stderr, "Restore dir to:", cls.oldcwd
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001279 os.chdir(cls.oldcwd)
1280
Johnny Chena74bb0a2011-08-01 18:46:13 +00001281 @classmethod
1282 def skipLongRunningTest(cls):
1283 """
1284 By default, we skip long running test case.
1285 This can be overridden by passing '-l' to the test driver (dotest.py).
1286 """
1287 if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
1288 return False
1289 else:
1290 return True
Johnny Chened492022011-06-21 00:53:00 +00001291
Vince Harron6d3d0f12015-05-10 22:01:59 +00001292 def enableLogChannelsForCurrentTest(self):
1293 if len(lldbtest_config.channels) == 0:
1294 return
1295
1296 # if debug channels are specified in lldbtest_config.channels,
1297 # create a new set of log files for every test
1298 log_basename = self.getLogBasenameForCurrentTest()
1299
1300 # confirm that the file is writeable
1301 host_log_path = "{}-host.log".format(log_basename)
1302 open(host_log_path, 'w').close()
1303
1304 log_enable = "log enable -Tpn -f {} ".format(host_log_path)
1305 for channel_with_categories in lldbtest_config.channels:
1306 channel_then_categories = channel_with_categories.split(' ', 1)
1307 channel = channel_then_categories[0]
1308 if len(channel_then_categories) > 1:
1309 categories = channel_then_categories[1]
1310 else:
1311 categories = "default"
1312
1313 if channel == "gdb-remote":
1314 # communicate gdb-remote categories to debugserver
1315 os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
1316
1317 self.ci.HandleCommand(log_enable + channel_with_categories, self.res)
1318 if not self.res.Succeeded():
1319 raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
1320
1321 # Communicate log path name to debugserver & lldb-server
1322 server_log_path = "{}-server.log".format(log_basename)
1323 open(server_log_path, 'w').close()
1324 os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
1325
1326 # Communicate channels to lldb-server
1327 os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
1328
1329 if len(lldbtest_config.channels) == 0:
1330 return
1331
1332 def disableLogChannelsForCurrentTest(self):
1333 # close all log files that we opened
1334 for channel_and_categories in lldbtest_config.channels:
1335 # channel format - <channel-name> [<category0> [<category1> ...]]
1336 channel = channel_and_categories.split(' ', 1)[0]
1337 self.ci.HandleCommand("log disable " + channel, self.res)
1338 if not self.res.Succeeded():
1339 raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
1340
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001341 def setUp(self):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001342 """Fixture for unittest test case setup.
1343
1344 It works with the test driver to conditionally skip tests and does other
1345 initializations."""
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001346 #import traceback
1347 #traceback.print_stack()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001348
Daniel Malea9115f072013-08-06 15:02:32 +00001349 if "LIBCXX_PATH" in os.environ:
1350 self.libcxxPath = os.environ["LIBCXX_PATH"]
1351 else:
1352 self.libcxxPath = None
1353
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001354 if "LLDBMI_EXEC" in os.environ:
1355 self.lldbMiExec = os.environ["LLDBMI_EXEC"]
1356 else:
1357 self.lldbMiExec = None
1358 self.dont_do_lldbmi_test = True
Vince Harron790d95c2015-05-18 19:39:03 +00001359
Johnny Chenebe51722011-10-07 19:21:09 +00001360 # If we spawn an lldb process for test (via pexpect), do not load the
1361 # init file unless told otherwise.
1362 if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
1363 self.lldbOption = ""
1364 else:
1365 self.lldbOption = "--no-lldbinit"
Johnny Chenaaa82ff2011-08-02 22:54:37 +00001366
Johnny Chen985e7402011-08-01 21:13:26 +00001367 # Assign the test method name to self.testMethodName.
1368 #
1369 # For an example of the use of this attribute, look at test/types dir.
1370 # There are a bunch of test cases under test/types and we don't want the
1371 # module cacheing subsystem to be confused with executable name "a.out"
1372 # used for all the test cases.
1373 self.testMethodName = self._testMethodName
1374
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001375 # Python API only test is decorated with @python_api_test,
1376 # which also sets the "__python_api_test__" attribute of the
1377 # function object to True.
Johnny Chen4533dad2011-05-31 23:21:42 +00001378 try:
1379 if lldb.just_do_python_api_test:
1380 testMethod = getattr(self, self._testMethodName)
1381 if getattr(testMethod, "__python_api_test__", False):
1382 pass
1383 else:
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001384 self.skipTest("non python api test")
1385 except AttributeError:
1386 pass
1387
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001388 # lldb-mi only test is decorated with @lldbmi_test,
1389 # which also sets the "__lldbmi_test__" attribute of the
1390 # function object to True.
1391 try:
1392 if lldb.just_do_lldbmi_test:
1393 testMethod = getattr(self, self._testMethodName)
1394 if getattr(testMethod, "__lldbmi_test__", False):
1395 pass
1396 else:
1397 self.skipTest("non lldb-mi test")
1398 except AttributeError:
1399 pass
1400
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001401 # Benchmarks test is decorated with @benchmarks_test,
1402 # which also sets the "__benchmarks_test__" attribute of the
1403 # function object to True.
1404 try:
1405 if lldb.just_do_benchmarks_test:
1406 testMethod = getattr(self, self._testMethodName)
1407 if getattr(testMethod, "__benchmarks_test__", False):
1408 pass
1409 else:
1410 self.skipTest("non benchmarks test")
Johnny Chen4533dad2011-05-31 23:21:42 +00001411 except AttributeError:
1412 pass
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001413
Johnny Chen985e7402011-08-01 21:13:26 +00001414 # This is for the case of directly spawning 'lldb'/'gdb' and interacting
1415 # with it using pexpect.
1416 self.child = None
1417 self.child_prompt = "(lldb) "
1418 # If the child is interacting with the embedded script interpreter,
1419 # there are two exits required during tear down, first to quit the
1420 # embedded script interpreter and second to quit the lldb command
1421 # interpreter.
1422 self.child_in_script_interpreter = False
1423
Johnny Chenfb4264c2011-08-01 19:50:58 +00001424 # These are for customized teardown cleanup.
1425 self.dict = None
1426 self.doTearDownCleanup = False
1427 # And in rare cases where there are multiple teardown cleanups.
1428 self.dicts = []
1429 self.doTearDownCleanups = False
1430
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001431 # List of spawned subproces.Popen objects
1432 self.subprocesses = []
1433
Daniel Malea69207462013-06-05 21:07:02 +00001434 # List of forked process PIDs
1435 self.forkedProcessPids = []
1436
Johnny Chenfb4264c2011-08-01 19:50:58 +00001437 # Create a string buffer to record the session info, to be dumped into a
1438 # test case specific file if test failure is encountered.
Vince Harron1f160372015-05-21 18:51:20 +00001439 self.log_basename = self.getLogBasenameForCurrentTest()
Vince Harron35b17dc2015-05-21 18:20:21 +00001440
Vince Harron1f160372015-05-21 18:51:20 +00001441 session_file = "{}.log".format(self.log_basename)
Vince Harron35b17dc2015-05-21 18:20:21 +00001442 unbuffered = 0 # 0 is the constant for unbuffered
Vince Harron1f160372015-05-21 18:51:20 +00001443 self.session = open(session_file, "w", unbuffered)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001444
1445 # Optimistically set __errored__, __failed__, __expected__ to False
1446 # initially. If the test errored/failed, the session info
1447 # (self.session) is then dumped into a session specific file for
1448 # diagnosis.
Zachary Turnerb1490b62015-08-26 19:44:56 +00001449 self.__cleanup_errored__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001450 self.__errored__ = False
1451 self.__failed__ = False
1452 self.__expected__ = False
1453 # We are also interested in unexpected success.
1454 self.__unexpected__ = False
Johnny Chenf79b0762011-08-16 00:48:58 +00001455 # And skipped tests.
1456 self.__skipped__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001457
1458 # See addTearDownHook(self, hook) which allows the client to add a hook
1459 # function to be run during tearDown() time.
1460 self.hooks = []
1461
1462 # See HideStdout(self).
1463 self.sys_stdout_hidden = False
1464
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001465 if self.platformContext:
1466 # set environment variable names for finding shared libraries
1467 self.dylibPath = self.platformContext.shlib_environment_var
Daniel Malea179ff292012-11-26 21:21:11 +00001468
Vince Harron6d3d0f12015-05-10 22:01:59 +00001469 # Create the debugger instance if necessary.
1470 try:
1471 self.dbg = lldb.DBG
1472 except AttributeError:
1473 self.dbg = lldb.SBDebugger.Create()
1474
1475 if not self.dbg:
1476 raise Exception('Invalid debugger instance')
1477
1478 # Retrieve the associated command interpreter instance.
1479 self.ci = self.dbg.GetCommandInterpreter()
1480 if not self.ci:
1481 raise Exception('Could not get the command interpreter')
1482
1483 # And the result object.
1484 self.res = lldb.SBCommandReturnObject()
1485
1486 self.enableLogChannelsForCurrentTest()
1487
Johnny Chen2a808582011-10-19 16:48:07 +00001488 def runHooks(self, child=None, child_prompt=None, use_cmd_api=False):
Johnny Chena737ba52011-10-19 01:06:21 +00001489 """Perform the run hooks to bring lldb debugger to the desired state.
1490
Johnny Chen2a808582011-10-19 16:48:07 +00001491 By default, expect a pexpect spawned child and child prompt to be
1492 supplied (use_cmd_api=False). If use_cmd_api is true, ignore the child
1493 and child prompt and use self.runCmd() to run the hooks one by one.
1494
Johnny Chena737ba52011-10-19 01:06:21 +00001495 Note that child is a process spawned by pexpect.spawn(). If not, your
1496 test case is mostly likely going to fail.
1497
1498 See also dotest.py where lldb.runHooks are processed/populated.
1499 """
1500 if not lldb.runHooks:
1501 self.skipTest("No runhooks specified for lldb, skip the test")
Johnny Chen2a808582011-10-19 16:48:07 +00001502 if use_cmd_api:
1503 for hook in lldb.runhooks:
1504 self.runCmd(hook)
1505 else:
1506 if not child or not child_prompt:
1507 self.fail("Both child and child_prompt need to be defined.")
1508 for hook in lldb.runHooks:
1509 child.sendline(hook)
1510 child.expect_exact(child_prompt)
Johnny Chena737ba52011-10-19 01:06:21 +00001511
Daniel Malea249287a2013-02-19 16:08:57 +00001512 def setAsync(self, value):
1513 """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
1514 old_async = self.dbg.GetAsync()
1515 self.dbg.SetAsync(value)
1516 self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
1517
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001518 def cleanupSubprocesses(self):
1519 # Ensure any subprocesses are cleaned up
1520 for p in self.subprocesses:
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001521 p.terminate()
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001522 del p
1523 del self.subprocesses[:]
Daniel Malea69207462013-06-05 21:07:02 +00001524 # Ensure any forked processes are cleaned up
1525 for pid in self.forkedProcessPids:
1526 if os.path.exists("/proc/" + str(pid)):
1527 os.kill(pid, signal.SIGTERM)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001528
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001529 def spawnSubprocess(self, executable, args=[], install_remote=True):
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001530 """ Creates a subprocess.Popen object with the specified executable and arguments,
1531 saves it in self.subprocesses, and returns the object.
1532 NOTE: if using this function, ensure you also call:
1533
1534 self.addTearDownHook(self.cleanupSubprocesses)
1535
1536 otherwise the test suite will leak processes.
1537 """
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001538 proc = _RemoteProcess(install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001539 proc.launch(executable, args)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001540 self.subprocesses.append(proc)
1541 return proc
1542
Daniel Malea69207462013-06-05 21:07:02 +00001543 def forkSubprocess(self, executable, args=[]):
1544 """ Fork a subprocess with its own group ID.
1545 NOTE: if using this function, ensure you also call:
1546
1547 self.addTearDownHook(self.cleanupSubprocesses)
1548
1549 otherwise the test suite will leak processes.
1550 """
1551 child_pid = os.fork()
1552 if child_pid == 0:
1553 # If more I/O support is required, this can be beefed up.
1554 fd = os.open(os.devnull, os.O_RDWR)
Daniel Malea69207462013-06-05 21:07:02 +00001555 os.dup2(fd, 1)
1556 os.dup2(fd, 2)
1557 # This call causes the child to have its of group ID
1558 os.setpgid(0,0)
1559 os.execvp(executable, [executable] + args)
1560 # Give the child time to get through the execvp() call
1561 time.sleep(0.1)
1562 self.forkedProcessPids.append(child_pid)
1563 return child_pid
1564
Johnny Chenfb4264c2011-08-01 19:50:58 +00001565 def HideStdout(self):
1566 """Hide output to stdout from the user.
1567
1568 During test execution, there might be cases where we don't want to show the
1569 standard output to the user. For example,
1570
1571 self.runCmd(r'''sc print "\n\n\tHello!\n"''')
1572
1573 tests whether command abbreviation for 'script' works or not. There is no
1574 need to show the 'Hello' output to the user as long as the 'script' command
1575 succeeds and we are not in TraceOn() mode (see the '-t' option).
1576
1577 In this case, the test method calls self.HideStdout(self) to redirect the
1578 sys.stdout to a null device, and restores the sys.stdout upon teardown.
1579
1580 Note that you should only call this method at most once during a test case
1581 execution. Any subsequent call has no effect at all."""
1582 if self.sys_stdout_hidden:
1583 return
1584
1585 self.sys_stdout_hidden = True
1586 old_stdout = sys.stdout
1587 sys.stdout = open(os.devnull, 'w')
1588 def restore_stdout():
1589 sys.stdout = old_stdout
1590 self.addTearDownHook(restore_stdout)
1591
1592 # =======================================================================
1593 # Methods for customized teardown cleanups as well as execution of hooks.
1594 # =======================================================================
1595
1596 def setTearDownCleanup(self, dictionary=None):
1597 """Register a cleanup action at tearDown() time with a dictinary"""
1598 self.dict = dictionary
1599 self.doTearDownCleanup = True
1600
1601 def addTearDownCleanup(self, dictionary):
1602 """Add a cleanup action at tearDown() time with a dictinary"""
1603 self.dicts.append(dictionary)
1604 self.doTearDownCleanups = True
1605
1606 def addTearDownHook(self, hook):
1607 """
1608 Add a function to be run during tearDown() time.
1609
1610 Hooks are executed in a first come first serve manner.
1611 """
1612 if callable(hook):
1613 with recording(self, traceAlways) as sbuf:
1614 print >> sbuf, "Adding tearDown hook:", getsource_if_available(hook)
1615 self.hooks.append(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001616
1617 return self
Johnny Chenfb4264c2011-08-01 19:50:58 +00001618
Jim Inghamda3a3862014-10-16 23:02:14 +00001619 def deletePexpectChild(self):
Johnny Chen985e7402011-08-01 21:13:26 +00001620 # This is for the case of directly spawning 'lldb' and interacting with it
1621 # using pexpect.
Johnny Chen985e7402011-08-01 21:13:26 +00001622 if self.child and self.child.isalive():
Zachary Turner9ef307b2014-07-22 16:19:29 +00001623 import pexpect
Johnny Chen985e7402011-08-01 21:13:26 +00001624 with recording(self, traceAlways) as sbuf:
1625 print >> sbuf, "tearing down the child process...."
Johnny Chen985e7402011-08-01 21:13:26 +00001626 try:
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001627 if self.child_in_script_interpreter:
1628 self.child.sendline('quit()')
1629 self.child.expect_exact(self.child_prompt)
1630 self.child.sendline('settings set interpreter.prompt-on-quit false')
1631 self.child.sendline('quit')
Johnny Chen985e7402011-08-01 21:13:26 +00001632 self.child.expect(pexpect.EOF)
Ilia K47448c22015-02-11 21:41:58 +00001633 except (ValueError, pexpect.ExceptionPexpect):
1634 # child is already terminated
1635 pass
1636 except OSError as exception:
1637 import errno
1638 if exception.errno != errno.EIO:
1639 # unexpected error
1640 raise
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001641 # child is already terminated
Johnny Chen985e7402011-08-01 21:13:26 +00001642 pass
Shawn Besteb3e9052014-11-06 17:52:15 +00001643 finally:
1644 # Give it one final blow to make sure the child is terminated.
1645 self.child.close()
Jim Inghamda3a3862014-10-16 23:02:14 +00001646
1647 def tearDown(self):
1648 """Fixture for unittest test case teardown."""
1649 #import traceback
1650 #traceback.print_stack()
1651
1652 self.deletePexpectChild()
1653
Johnny Chenfb4264c2011-08-01 19:50:58 +00001654 # Check and run any hook functions.
1655 for hook in reversed(self.hooks):
1656 with recording(self, traceAlways) as sbuf:
1657 print >> sbuf, "Executing tearDown hook:", getsource_if_available(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001658 import inspect
1659 hook_argc = len(inspect.getargspec(hook).args)
Enrico Granata6e0566c2014-11-17 19:00:20 +00001660 if hook_argc == 0 or getattr(hook,'im_self',None):
Enrico Granataab0e8312014-11-05 21:31:57 +00001661 hook()
1662 elif hook_argc == 1:
1663 hook(self)
1664 else:
1665 hook() # try the plain call and hope it works
Johnny Chenfb4264c2011-08-01 19:50:58 +00001666
1667 del self.hooks
1668
1669 # Perform registered teardown cleanup.
1670 if doCleanup and self.doTearDownCleanup:
Johnny Chen0fddfb22011-11-17 19:57:27 +00001671 self.cleanup(dictionary=self.dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001672
1673 # In rare cases where there are multiple teardown cleanups added.
1674 if doCleanup and self.doTearDownCleanups:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001675 if self.dicts:
1676 for dict in reversed(self.dicts):
Johnny Chen0fddfb22011-11-17 19:57:27 +00001677 self.cleanup(dictionary=dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001678
Vince Harron9753dd92015-05-10 15:22:09 +00001679 self.disableLogChannelsForCurrentTest()
1680
Johnny Chenfb4264c2011-08-01 19:50:58 +00001681 # =========================================================
1682 # Various callbacks to allow introspection of test progress
1683 # =========================================================
1684
1685 def markError(self):
1686 """Callback invoked when an error (unexpected exception) errored."""
1687 self.__errored__ = True
1688 with recording(self, False) as sbuf:
1689 # False because there's no need to write "ERROR" to the stderr twice.
1690 # Once by the Python unittest framework, and a second time by us.
1691 print >> sbuf, "ERROR"
1692
Zachary Turnerb1490b62015-08-26 19:44:56 +00001693 def markCleanupError(self):
1694 """Callback invoked when an error occurs while a test is cleaning up."""
1695 self.__cleanup_errored__ = True
1696 with recording(self, False) as sbuf:
1697 # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
1698 # Once by the Python unittest framework, and a second time by us.
1699 print >> sbuf, "CLEANUP_ERROR"
1700
Johnny Chenfb4264c2011-08-01 19:50:58 +00001701 def markFailure(self):
1702 """Callback invoked when a failure (test assertion failure) occurred."""
1703 self.__failed__ = True
1704 with recording(self, False) as sbuf:
1705 # False because there's no need to write "FAIL" to the stderr twice.
1706 # Once by the Python unittest framework, and a second time by us.
1707 print >> sbuf, "FAIL"
1708
Enrico Granatae6cedc12013-02-23 01:05:23 +00001709 def markExpectedFailure(self,err,bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001710 """Callback invoked when an expected failure/error occurred."""
1711 self.__expected__ = True
1712 with recording(self, False) as sbuf:
1713 # False because there's no need to write "expected failure" to the
1714 # stderr twice.
1715 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001716 if bugnumber == None:
1717 print >> sbuf, "expected failure"
1718 else:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001719 print >> sbuf, "expected failure (problem id:" + str(bugnumber) + ")"
Johnny Chenfb4264c2011-08-01 19:50:58 +00001720
Johnny Chenc5cc6252011-08-15 23:09:08 +00001721 def markSkippedTest(self):
1722 """Callback invoked when a test is skipped."""
1723 self.__skipped__ = True
1724 with recording(self, False) as sbuf:
1725 # False because there's no need to write "skipped test" to the
1726 # stderr twice.
1727 # Once by the Python unittest framework, and a second time by us.
1728 print >> sbuf, "skipped test"
1729
Enrico Granatae6cedc12013-02-23 01:05:23 +00001730 def markUnexpectedSuccess(self, bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001731 """Callback invoked when an unexpected success occurred."""
1732 self.__unexpected__ = True
1733 with recording(self, False) as sbuf:
1734 # False because there's no need to write "unexpected success" to the
1735 # stderr twice.
1736 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001737 if bugnumber == None:
1738 print >> sbuf, "unexpected success"
1739 else:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001740 print >> sbuf, "unexpected success (problem id:" + str(bugnumber) + ")"
Johnny Chenfb4264c2011-08-01 19:50:58 +00001741
Greg Clayton70995582015-01-07 22:25:50 +00001742 def getRerunArgs(self):
1743 return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
Vince Harron9753dd92015-05-10 15:22:09 +00001744
1745 def getLogBasenameForCurrentTest(self, prefix=None):
1746 """
1747 returns a partial path that can be used as the beginning of the name of multiple
1748 log files pertaining to this test
1749
1750 <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
1751 """
1752 dname = os.path.join(os.environ["LLDB_TEST"],
1753 os.environ["LLDB_SESSION_DIRNAME"])
1754 if not os.path.isdir(dname):
1755 os.mkdir(dname)
1756
1757 compiler = self.getCompiler()
1758
1759 if compiler[1] == ':':
1760 compiler = compiler[2:]
Chaoren Lin636a0e32015-07-17 21:40:11 +00001761 if os.path.altsep is not None:
1762 compiler = compiler.replace(os.path.altsep, os.path.sep)
Vince Harron9753dd92015-05-10 15:22:09 +00001763
Vince Harron19e300f2015-05-12 00:50:54 +00001764 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
Vince Harron9753dd92015-05-10 15:22:09 +00001765 if len(fname) > 200:
Vince Harron19e300f2015-05-12 00:50:54 +00001766 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
Vince Harron9753dd92015-05-10 15:22:09 +00001767
1768 if prefix is not None:
1769 fname = "{}-{}".format(prefix, fname)
1770
1771 return os.path.join(dname, fname)
1772
Johnny Chenfb4264c2011-08-01 19:50:58 +00001773 def dumpSessionInfo(self):
1774 """
1775 Dump the debugger interactions leading to a test error/failure. This
1776 allows for more convenient postmortem analysis.
1777
1778 See also LLDBTestResult (dotest.py) which is a singlton class derived
1779 from TextTestResult and overwrites addError, addFailure, and
1780 addExpectedFailure methods to allow us to to mark the test instance as
1781 such.
1782 """
1783
1784 # We are here because self.tearDown() detected that this test instance
1785 # either errored or failed. The lldb.test_result singleton contains
1786 # two lists (erros and failures) which get populated by the unittest
1787 # framework. Look over there for stack trace information.
1788 #
1789 # The lists contain 2-tuples of TestCase instances and strings holding
1790 # formatted tracebacks.
1791 #
1792 # See http://docs.python.org/library/unittest.html#unittest.TestResult.
Vince Harron9753dd92015-05-10 15:22:09 +00001793
Vince Harron35b17dc2015-05-21 18:20:21 +00001794 # output tracebacks into session
Vince Harron9753dd92015-05-10 15:22:09 +00001795 pairs = []
Johnny Chenfb4264c2011-08-01 19:50:58 +00001796 if self.__errored__:
1797 pairs = lldb.test_result.errors
1798 prefix = 'Error'
Zachary Turner14181db2015-09-11 21:27:37 +00001799 elif self.__cleanup_errored__:
Zachary Turnerb1490b62015-08-26 19:44:56 +00001800 pairs = lldb.test_result.cleanup_errors
1801 prefix = 'CleanupError'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001802 elif self.__failed__:
1803 pairs = lldb.test_result.failures
1804 prefix = 'Failure'
1805 elif self.__expected__:
1806 pairs = lldb.test_result.expectedFailures
1807 prefix = 'ExpectedFailure'
Johnny Chenc5cc6252011-08-15 23:09:08 +00001808 elif self.__skipped__:
1809 prefix = 'SkippedTest'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001810 elif self.__unexpected__:
Vince Harron35b17dc2015-05-21 18:20:21 +00001811 prefix = 'UnexpectedSuccess'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001812 else:
Vince Harron35b17dc2015-05-21 18:20:21 +00001813 prefix = 'Success'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001814
Johnny Chenc5cc6252011-08-15 23:09:08 +00001815 if not self.__unexpected__ and not self.__skipped__:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001816 for test, traceback in pairs:
1817 if test is self:
1818 print >> self.session, traceback
1819
Vince Harron35b17dc2015-05-21 18:20:21 +00001820 # put footer (timestamp/rerun instructions) into session
Johnny Chen8082a002011-08-11 00:16:28 +00001821 testMethod = getattr(self, self._testMethodName)
1822 if getattr(testMethod, "__benchmarks_test__", False):
1823 benchmarks = True
1824 else:
1825 benchmarks = False
1826
Vince Harron35b17dc2015-05-21 18:20:21 +00001827 import datetime
1828 print >> self.session, "Session info generated @", datetime.datetime.now().ctime()
1829 print >> self.session, "To rerun this test, issue the following command from the 'test' directory:\n"
1830 print >> self.session, "./dotest.py %s -v %s %s" % (self.getRunOptions(),
1831 ('+b' if benchmarks else '-t'),
1832 self.getRerunArgs())
1833 self.session.close()
1834 del self.session
1835
1836 # process the log files
Vince Harron1f160372015-05-21 18:51:20 +00001837 log_files_for_this_test = glob.glob(self.log_basename + "*")
Vince Harron35b17dc2015-05-21 18:20:21 +00001838
1839 if prefix != 'Success' or lldbtest_config.log_success:
1840 # keep all log files, rename them to include prefix
1841 dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1842 for src in log_files_for_this_test:
Zachary Turner306278f2015-05-26 20:26:29 +00001843 if os.path.isfile(src):
1844 dst = src.replace(self.log_basename, dst_log_basename)
1845 if os.name == "nt" and os.path.isfile(dst):
1846 # On Windows, renaming a -> b will throw an exception if b exists. On non-Windows platforms
1847 # it silently replaces the destination. Ultimately this means that atomic renames are not
1848 # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
1849 # destination first if it already exists.
1850 os.remove(dst)
Zachary Turner5de068b2015-05-26 19:52:24 +00001851
Zachary Turner306278f2015-05-26 20:26:29 +00001852 os.rename(src, dst)
Vince Harron35b17dc2015-05-21 18:20:21 +00001853 else:
1854 # success! (and we don't want log files) delete log files
1855 for log_file in log_files_for_this_test:
Adrian McCarthya7292042015-09-04 20:48:48 +00001856 try:
1857 os.unlink(log_file)
1858 except:
1859 # We've seen consistent unlink failures on Windows, perhaps because the
1860 # just-created log file is being scanned by anti-virus. Empirically, this
1861 # sleep-and-retry approach allows tests to succeed much more reliably.
1862 # Attempts to figure out exactly what process was still holding a file handle
1863 # have failed because running instrumentation like Process Monitor seems to
1864 # slow things down enough that the problem becomes much less consistent.
1865 time.sleep(0.5)
1866 os.unlink(log_file)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001867
1868 # ====================================================
1869 # Config. methods supported through a plugin interface
1870 # (enables reading of the current test configuration)
1871 # ====================================================
1872
1873 def getArchitecture(self):
1874 """Returns the architecture in effect the test suite is running with."""
1875 module = builder_module()
Ed Maste0f434e62015-04-06 15:50:48 +00001876 arch = module.getArchitecture()
1877 if arch == 'amd64':
1878 arch = 'x86_64'
1879 return arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00001880
Vince Harron02613762015-05-04 00:17:53 +00001881 def getLldbArchitecture(self):
1882 """Returns the architecture of the lldb binary."""
1883 if not hasattr(self, 'lldbArchitecture'):
1884
1885 # spawn local process
1886 command = [
Vince Harron790d95c2015-05-18 19:39:03 +00001887 lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001888 "-o",
Vince Harron790d95c2015-05-18 19:39:03 +00001889 "file " + lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001890 "-o",
1891 "quit"
1892 ]
1893
1894 output = check_output(command)
1895 str = output.decode("utf-8");
1896
1897 for line in str.splitlines():
1898 m = re.search("Current executable set to '.*' \\((.*)\\)\\.", line)
1899 if m:
1900 self.lldbArchitecture = m.group(1)
1901 break
1902
1903 return self.lldbArchitecture
1904
Johnny Chenfb4264c2011-08-01 19:50:58 +00001905 def getCompiler(self):
1906 """Returns the compiler in effect the test suite is running with."""
1907 module = builder_module()
1908 return module.getCompiler()
1909
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001910 def getCompilerBinary(self):
1911 """Returns the compiler binary the test suite is running with."""
1912 return self.getCompiler().split()[0]
1913
Daniel Malea0aea0162013-02-27 17:29:46 +00001914 def getCompilerVersion(self):
1915 """ Returns a string that represents the compiler version.
1916 Supports: llvm, clang.
1917 """
1918 from lldbutil import which
1919 version = 'unknown'
1920
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001921 compiler = self.getCompilerBinary()
Zachary Turner9ef307b2014-07-22 16:19:29 +00001922 version_output = system([[which(compiler), "-v"]])[1]
Daniel Malea0aea0162013-02-27 17:29:46 +00001923 for line in version_output.split(os.linesep):
Greg Clayton2a844b72013-03-06 02:34:51 +00001924 m = re.search('version ([0-9\.]+)', line)
Daniel Malea0aea0162013-02-27 17:29:46 +00001925 if m:
1926 version = m.group(1)
1927 return version
1928
Ryan Brown57bee1e2015-09-14 22:45:11 +00001929 def getGoCompilerVersion(self):
1930 """ Returns a string that represents the go compiler version, or None if go is not found.
1931 """
1932 compiler = which("go")
1933 if compiler:
1934 version_output = system([[compiler, "version"]])[0]
1935 for line in version_output.split(os.linesep):
1936 m = re.search('go version (devel|go\\S+)', line)
1937 if m:
1938 return m.group(1)
1939 return None
1940
Greg Claytone0d0a762015-04-02 18:24:03 +00001941 def platformIsDarwin(self):
1942 """Returns true if the OS triple for the selected platform is any valid apple OS"""
Robert Flackfb2f6c62015-04-17 08:02:18 +00001943 return platformIsDarwin()
Vince Harron20952cc2015-04-03 01:00:06 +00001944
Robert Flack13c7ad92015-03-30 14:12:17 +00001945 def getPlatform(self):
Robert Flackfb2f6c62015-04-17 08:02:18 +00001946 """Returns the target platform the test suite is running on."""
Robert Flack068898c2015-04-09 18:07:58 +00001947 return getPlatform()
Robert Flack13c7ad92015-03-30 14:12:17 +00001948
Daniel Maleaadaaec92013-08-06 20:51:41 +00001949 def isIntelCompiler(self):
1950 """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1951 return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1952
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001953 def expectedCompilerVersion(self, compiler_version):
1954 """Returns True iff compiler_version[1] matches the current compiler version.
1955 Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1956 Any operator other than the following defaults to an equality test:
1957 '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1958 """
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001959 if (compiler_version == None):
1960 return True
1961 operator = str(compiler_version[0])
1962 version = compiler_version[1]
1963
1964 if (version == None):
1965 return True
1966 if (operator == '>'):
1967 return self.getCompilerVersion() > version
1968 if (operator == '>=' or operator == '=>'):
1969 return self.getCompilerVersion() >= version
1970 if (operator == '<'):
1971 return self.getCompilerVersion() < version
1972 if (operator == '<=' or operator == '=<'):
1973 return self.getCompilerVersion() <= version
1974 if (operator == '!=' or operator == '!' or operator == 'not'):
1975 return str(version) not in str(self.getCompilerVersion())
1976 return str(version) in str(self.getCompilerVersion())
1977
1978 def expectedCompiler(self, compilers):
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001979 """Returns True iff any element of compilers is a sub-string of the current compiler."""
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001980 if (compilers == None):
1981 return True
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001982
1983 for compiler in compilers:
1984 if compiler in self.getCompiler():
1985 return True
1986
1987 return False
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001988
Ying Chen7091c2c2015-04-21 01:15:47 +00001989 def expectedArch(self, archs):
1990 """Returns True iff any element of archs is a sub-string of the current architecture."""
1991 if (archs == None):
1992 return True
1993
1994 for arch in archs:
1995 if arch in self.getArchitecture():
1996 return True
1997
1998 return False
1999
Johnny Chenfb4264c2011-08-01 19:50:58 +00002000 def getRunOptions(self):
2001 """Command line option for -A and -C to run this test again, called from
2002 self.dumpSessionInfo()."""
2003 arch = self.getArchitecture()
2004 comp = self.getCompiler()
Johnny Chenb7bdd102011-08-24 19:48:51 +00002005 if arch:
2006 option_str = "-A " + arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00002007 else:
Johnny Chenb7bdd102011-08-24 19:48:51 +00002008 option_str = ""
2009 if comp:
Johnny Chen531c0852012-03-16 20:44:00 +00002010 option_str += " -C " + comp
Johnny Chenb7bdd102011-08-24 19:48:51 +00002011 return option_str
Johnny Chenfb4264c2011-08-01 19:50:58 +00002012
2013 # ==================================================
2014 # Build methods supported through a plugin interface
2015 # ==================================================
2016
Ed Mastec97323e2014-04-01 18:47:58 +00002017 def getstdlibFlag(self):
2018 """ Returns the proper -stdlib flag, or empty if not required."""
Robert Flack4629c4b2015-05-15 18:54:32 +00002019 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Ed Mastec97323e2014-04-01 18:47:58 +00002020 stdlibflag = "-stdlib=libc++"
2021 else:
2022 stdlibflag = ""
2023 return stdlibflag
2024
Matt Kopec7663b3a2013-09-25 17:44:00 +00002025 def getstdFlag(self):
2026 """ Returns the proper stdflag. """
Daniel Malea55faa402013-05-02 21:44:31 +00002027 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
Daniel Malea0b7c6112013-05-06 19:31:31 +00002028 stdflag = "-std=c++0x"
Daniel Malea55faa402013-05-02 21:44:31 +00002029 else:
2030 stdflag = "-std=c++11"
Matt Kopec7663b3a2013-09-25 17:44:00 +00002031 return stdflag
2032
2033 def buildDriver(self, sources, exe_name):
2034 """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
2035 or LLDB.framework).
2036 """
2037
2038 stdflag = self.getstdFlag()
Ed Mastec97323e2014-04-01 18:47:58 +00002039 stdlibflag = self.getstdlibFlag()
Daniel Malea55faa402013-05-02 21:44:31 +00002040
2041 if sys.platform.startswith("darwin"):
2042 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
2043 d = {'CXX_SOURCES' : sources,
2044 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00002045 'CFLAGS_EXTRAS' : "%s %s" % (stdflag, stdlibflag),
Daniel Malea55faa402013-05-02 21:44:31 +00002046 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
Stefanus Du Toit04004442013-07-30 19:19:49 +00002047 'LD_EXTRAS' : "%s -Wl,-rpath,%s" % (dsym, self.lib_dir),
Daniel Malea55faa402013-05-02 21:44:31 +00002048 }
Ed Maste372c24d2013-07-25 21:02:34 +00002049 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 +00002050 d = {'CXX_SOURCES' : sources,
Daniel Malea55faa402013-05-02 21:44:31 +00002051 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00002052 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
Daniel Malea55faa402013-05-02 21:44:31 +00002053 'LD_EXTRAS' : "-L%s -llldb" % self.lib_dir}
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00002054 elif sys.platform.startswith('win'):
2055 d = {'CXX_SOURCES' : sources,
2056 'EXE' : exe_name,
2057 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2058 'LD_EXTRAS' : "-L%s -lliblldb" % self.implib_dir}
Daniel Malea55faa402013-05-02 21:44:31 +00002059 if self.TraceOn():
2060 print "Building LLDB Driver (%s) from sources %s" % (exe_name, sources)
2061
2062 self.buildDefault(dictionary=d)
2063
Matt Kopec7663b3a2013-09-25 17:44:00 +00002064 def buildLibrary(self, sources, lib_name):
2065 """Platform specific way to build a default library. """
2066
2067 stdflag = self.getstdFlag()
2068
Robert Flack4629c4b2015-05-15 18:54:32 +00002069 if self.platformIsDarwin():
Matt Kopec7663b3a2013-09-25 17:44:00 +00002070 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
2071 d = {'DYLIB_CXX_SOURCES' : sources,
2072 'DYLIB_NAME' : lib_name,
2073 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
2074 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
2075 'LD_EXTRAS' : "%s -Wl,-rpath,%s -dynamiclib" % (dsym, self.lib_dir),
2076 }
Robert Flack4629c4b2015-05-15 18:54:32 +00002077 elif self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux' or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
Matt Kopec7663b3a2013-09-25 17:44:00 +00002078 d = {'DYLIB_CXX_SOURCES' : sources,
2079 'DYLIB_NAME' : lib_name,
2080 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2081 'LD_EXTRAS' : "-shared -L%s -llldb" % self.lib_dir}
Robert Flack4629c4b2015-05-15 18:54:32 +00002082 elif self.getPlatform() == 'windows':
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00002083 d = {'DYLIB_CXX_SOURCES' : sources,
2084 'DYLIB_NAME' : lib_name,
2085 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2086 'LD_EXTRAS' : "-shared -l%s\liblldb.lib" % self.implib_dir}
Matt Kopec7663b3a2013-09-25 17:44:00 +00002087 if self.TraceOn():
2088 print "Building LLDB Library (%s) from sources %s" % (lib_name, sources)
2089
2090 self.buildDefault(dictionary=d)
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002091
Daniel Malea55faa402013-05-02 21:44:31 +00002092 def buildProgram(self, sources, exe_name):
2093 """ Platform specific way to build an executable from C/C++ sources. """
2094 d = {'CXX_SOURCES' : sources,
2095 'EXE' : exe_name}
2096 self.buildDefault(dictionary=d)
2097
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002098 def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002099 """Platform specific way to build the default binaries."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002100 if lldb.skip_build_and_cleanup:
2101 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002102 module = builder_module()
Chaoren Line9bbabc2015-07-18 00:37:55 +00002103 if target_is_android():
2104 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002105 if not module.buildDefault(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002106 raise Exception("Don't know how to build default binary")
2107
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002108 def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002109 """Platform specific way to build binaries with dsym info."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002110 if lldb.skip_build_and_cleanup:
2111 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002112 module = builder_module()
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002113 if not module.buildDsym(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002114 raise Exception("Don't know how to build binary with dsym")
2115
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002116 def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002117 """Platform specific way to build binaries with dwarf maps."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002118 if lldb.skip_build_and_cleanup:
2119 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002120 module = builder_module()
Chaoren Lin9070f532015-07-17 22:13:29 +00002121 if target_is_android():
Chaoren Line9bbabc2015-07-18 00:37:55 +00002122 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002123 if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002124 raise Exception("Don't know how to build binary with dwarf")
Johnny Chena74bb0a2011-08-01 18:46:13 +00002125
Ryan Brown57bee1e2015-09-14 22:45:11 +00002126 def buildGo(self):
2127 """Build the default go binary.
2128 """
2129 system([[which('go'), 'build -gcflags "-N -l" -o a.out main.go']])
2130
Oleksiy Vyalov49b71c62015-01-22 20:03:21 +00002131 def signBinary(self, binary_path):
2132 if sys.platform.startswith("darwin"):
2133 codesign_cmd = "codesign --force --sign lldb_codesign %s" % (binary_path)
2134 call(codesign_cmd, shell=True)
2135
Kuba Breckabeed8212014-09-04 01:03:18 +00002136 def findBuiltClang(self):
2137 """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
2138 paths_to_try = [
2139 "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
2140 "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
2141 "llvm-build/Release/x86_64/Release/bin/clang",
2142 "llvm-build/Debug/x86_64/Debug/bin/clang",
2143 ]
2144 lldb_root_path = os.path.join(os.path.dirname(__file__), "..")
2145 for p in paths_to_try:
2146 path = os.path.join(lldb_root_path, p)
2147 if os.path.exists(path):
2148 return path
Ilia Kd9953052015-03-12 07:19:41 +00002149
2150 # Tries to find clang at the same folder as the lldb
Vince Harron790d95c2015-05-18 19:39:03 +00002151 path = os.path.join(os.path.dirname(lldbtest_config.lldbExec), "clang")
Ilia Kd9953052015-03-12 07:19:41 +00002152 if os.path.exists(path):
2153 return path
Kuba Breckabeed8212014-09-04 01:03:18 +00002154
2155 return os.environ["CC"]
2156
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002157 def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False):
Andrew Kaylor93132f52013-05-28 23:04:25 +00002158 """ Returns a dictionary (which can be provided to build* functions above) which
2159 contains OS-specific build flags.
2160 """
2161 cflags = ""
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002162 ldflags = ""
Daniel Malea9115f072013-08-06 15:02:32 +00002163
2164 # On Mac OS X, unless specifically requested to use libstdc++, use libc++
Robert Flack4629c4b2015-05-15 18:54:32 +00002165 if not use_libstdcxx and self.platformIsDarwin():
Daniel Malea9115f072013-08-06 15:02:32 +00002166 use_libcxx = True
2167
2168 if use_libcxx and self.libcxxPath:
2169 cflags += "-stdlib=libc++ "
2170 if self.libcxxPath:
2171 libcxxInclude = os.path.join(self.libcxxPath, "include")
2172 libcxxLib = os.path.join(self.libcxxPath, "lib")
2173 if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
2174 cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (libcxxInclude, libcxxLib, libcxxLib)
2175
Andrew Kaylor93132f52013-05-28 23:04:25 +00002176 if use_cpp11:
2177 cflags += "-std="
2178 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2179 cflags += "c++0x"
2180 else:
2181 cflags += "c++11"
Robert Flack4629c4b2015-05-15 18:54:32 +00002182 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Andrew Kaylor93132f52013-05-28 23:04:25 +00002183 cflags += " -stdlib=libc++"
2184 elif "clang" in self.getCompiler():
2185 cflags += " -stdlib=libstdc++"
2186
Andrew Kaylor93132f52013-05-28 23:04:25 +00002187 return {'CFLAGS_EXTRAS' : cflags,
2188 'LD_EXTRAS' : ldflags,
2189 }
2190
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002191 def cleanup(self, dictionary=None):
2192 """Platform specific way to do cleanup after build."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002193 if lldb.skip_build_and_cleanup:
2194 return
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002195 module = builder_module()
2196 if not module.cleanup(self, dictionary):
Johnny Chen0fddfb22011-11-17 19:57:27 +00002197 raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002198
Daniel Malea55faa402013-05-02 21:44:31 +00002199 def getLLDBLibraryEnvVal(self):
2200 """ Returns the path that the OS-specific library search environment variable
2201 (self.dylibPath) should be set to in order for a program to find the LLDB
2202 library. If an environment variable named self.dylibPath is already set,
2203 the new path is appended to it and returned.
2204 """
2205 existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
2206 if existing_library_path:
2207 return "%s:%s" % (existing_library_path, self.lib_dir)
2208 elif sys.platform.startswith("darwin"):
2209 return os.path.join(self.lib_dir, 'LLDB.framework')
2210 else:
2211 return self.lib_dir
Johnny Chena74bb0a2011-08-01 18:46:13 +00002212
Ed Maste437f8f62013-09-09 14:04:04 +00002213 def getLibcPlusPlusLibs(self):
Robert Flackfa5ad652015-05-13 20:17:34 +00002214 if self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux':
Ed Maste437f8f62013-09-09 14:04:04 +00002215 return ['libc++.so.1']
2216 else:
2217 return ['libc++.1.dylib','libc++abi.dylib']
2218
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002219# Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
2220# We change the test methods to create a new test method for each test for each debug info we are
2221# testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
2222# the new test method we remove the old method at the same time.
2223class LLDBTestCaseFactory(type):
2224 def __new__(cls, name, bases, attrs):
2225 newattrs = {}
2226 for attrname, attrvalue in attrs.iteritems():
2227 if attrname.startswith("test") and not getattr(attrvalue, "__no_debug_info_test__", False):
2228 @dsym_test
2229 def dsym_test_method(self, attrvalue=attrvalue):
2230 self.debug_info = "dsym"
2231 return attrvalue(self)
2232 dsym_method_name = attrname + "_dsym"
2233 dsym_test_method.__name__ = dsym_method_name
2234 newattrs[dsym_method_name] = dsym_test_method
2235
2236 @dwarf_test
2237 def dwarf_test_method(self, attrvalue=attrvalue):
2238 self.debug_info = "dwarf"
2239 return attrvalue(self)
2240 dwarf_method_name = attrname + "_dwarf"
2241 dwarf_test_method.__name__ = dwarf_method_name
2242 newattrs[dwarf_method_name] = dwarf_test_method
2243 else:
2244 newattrs[attrname] = attrvalue
2245 return super(LLDBTestCaseFactory, cls).__new__(cls, name, bases, newattrs)
2246
Johnny Chena74bb0a2011-08-01 18:46:13 +00002247class TestBase(Base):
2248 """
2249 This abstract base class is meant to be subclassed. It provides default
2250 implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
2251 among other things.
2252
2253 Important things for test class writers:
2254
2255 - Overwrite the mydir class attribute, otherwise your test class won't
2256 run. It specifies the relative directory to the top level 'test' so
2257 the test harness can change to the correct working directory before
2258 running your test.
2259
2260 - The setUp method sets up things to facilitate subsequent interactions
2261 with the debugger as part of the test. These include:
2262 - populate the test method name
2263 - create/get a debugger set with synchronous mode (self.dbg)
2264 - get the command interpreter from with the debugger (self.ci)
2265 - create a result object for use with the command interpreter
2266 (self.res)
2267 - plus other stuffs
2268
2269 - The tearDown method tries to perform some necessary cleanup on behalf
2270 of the test to return the debugger to a good state for the next test.
2271 These include:
2272 - execute any tearDown hooks registered by the test method with
2273 TestBase.addTearDownHook(); examples can be found in
2274 settings/TestSettings.py
2275 - kill the inferior process associated with each target, if any,
2276 and, then delete the target from the debugger's target list
2277 - perform build cleanup before running the next test method in the
2278 same test class; examples of registering for this service can be
2279 found in types/TestIntegerTypes.py with the call:
2280 - self.setTearDownCleanup(dictionary=d)
2281
2282 - Similarly setUpClass and tearDownClass perform classwise setup and
2283 teardown fixtures. The tearDownClass method invokes a default build
2284 cleanup for the entire test class; also, subclasses can implement the
2285 classmethod classCleanup(cls) to perform special class cleanup action.
2286
2287 - The instance methods runCmd and expect are used heavily by existing
2288 test cases to send a command to the command interpreter and to perform
2289 string/pattern matching on the output of such command execution. The
2290 expect method also provides a mode to peform string/pattern matching
2291 without running a command.
2292
2293 - The build methods buildDefault, buildDsym, and buildDwarf are used to
2294 build the binaries used during a particular test scenario. A plugin
2295 should be provided for the sys.platform running the test suite. The
2296 Mac OS X implementation is located in plugins/darwin.py.
2297 """
2298
2299 # Maximum allowed attempts when launching the inferior process.
2300 # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
2301 maxLaunchCount = 3;
2302
2303 # Time to wait before the next launching attempt in second(s).
2304 # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
2305 timeWaitNextLaunch = 1.0;
2306
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002307 # Setup the metaclass for this class to change the list of the test methods when a new class is loaded
2308 __metaclass__ = LLDBTestCaseFactory
2309
Johnny Chena74bb0a2011-08-01 18:46:13 +00002310 def doDelay(self):
2311 """See option -w of dotest.py."""
2312 if ("LLDB_WAIT_BETWEEN_TEST_CASES" in os.environ and
2313 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] == 'YES'):
2314 waitTime = 1.0
2315 if "LLDB_TIME_WAIT_BETWEEN_TEST_CASES" in os.environ:
2316 waitTime = float(os.environ["LLDB_TIME_WAIT_BETWEEN_TEST_CASES"])
2317 time.sleep(waitTime)
2318
Enrico Granata165f8af2012-09-21 19:10:53 +00002319 # Returns the list of categories to which this test case belongs
2320 # by default, look for a ".categories" file, and read its contents
2321 # if no such file exists, traverse the hierarchy - we guarantee
2322 # a .categories to exist at the top level directory so we do not end up
2323 # looping endlessly - subclasses are free to define their own categories
2324 # in whatever way makes sense to them
2325 def getCategories(self):
2326 import inspect
2327 import os.path
2328 folder = inspect.getfile(self.__class__)
2329 folder = os.path.dirname(folder)
2330 while folder != '/':
2331 categories_file_name = os.path.join(folder,".categories")
2332 if os.path.exists(categories_file_name):
2333 categories_file = open(categories_file_name,'r')
2334 categories = categories_file.readline()
2335 categories_file.close()
2336 categories = str.replace(categories,'\n','')
2337 categories = str.replace(categories,'\r','')
2338 return categories.split(',')
2339 else:
2340 folder = os.path.dirname(folder)
2341 continue
2342
Johnny Chena74bb0a2011-08-01 18:46:13 +00002343 def setUp(self):
2344 #import traceback
2345 #traceback.print_stack()
2346
2347 # Works with the test driver to conditionally skip tests via decorators.
2348 Base.setUp(self)
2349
Johnny Chena74bb0a2011-08-01 18:46:13 +00002350 try:
2351 if lldb.blacklist:
2352 className = self.__class__.__name__
2353 classAndMethodName = "%s.%s" % (className, self._testMethodName)
2354 if className in lldb.blacklist:
2355 self.skipTest(lldb.blacklist.get(className))
2356 elif classAndMethodName in lldb.blacklist:
2357 self.skipTest(lldb.blacklist.get(classAndMethodName))
2358 except AttributeError:
2359 pass
2360
Johnny Chened492022011-06-21 00:53:00 +00002361 # Insert some delay between successive test cases if specified.
2362 self.doDelay()
Johnny Chen0ed37c92010-10-07 02:04:14 +00002363
Johnny Chenf2b70232010-08-25 18:49:48 +00002364 if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
2365 self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
2366
Johnny Chen430eb762010-10-19 16:00:42 +00002367 if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
Johnny Chen4921b112010-11-29 20:20:34 +00002368 self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
Johnny Chenf2b70232010-08-25 18:49:48 +00002369
Daniel Maleae0f8f572013-08-26 23:57:52 +00002370 #
2371 # Warning: MAJOR HACK AHEAD!
2372 # If we are running testsuite remotely (by checking lldb.lldbtest_remote_sandbox),
2373 # redefine the self.dbg.CreateTarget(filename) method to execute a "file filename"
2374 # command, instead. See also runCmd() where it decorates the "file filename" call
2375 # with additional functionality when running testsuite remotely.
2376 #
2377 if lldb.lldbtest_remote_sandbox:
2378 def DecoratedCreateTarget(arg):
2379 self.runCmd("file %s" % arg)
2380 target = self.dbg.GetSelectedTarget()
2381 #
Greg Claytonc6947512013-12-13 19:18:59 +00002382 # SBtarget.LaunchSimple () currently not working for remote platform?
Daniel Maleae0f8f572013-08-26 23:57:52 +00002383 # johnny @ 04/23/2012
2384 #
2385 def DecoratedLaunchSimple(argv, envp, wd):
2386 self.runCmd("run")
2387 return target.GetProcess()
2388 target.LaunchSimple = DecoratedLaunchSimple
2389
2390 return target
2391 self.dbg.CreateTarget = DecoratedCreateTarget
2392 if self.TraceOn():
2393 print "self.dbg.Create is redefined to:\n%s" % getsource_if_available(DecoratedCreateTarget)
2394
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002395 # We want our debugger to be synchronous.
2396 self.dbg.SetAsync(False)
2397
2398 # Retrieve the associated command interpreter instance.
2399 self.ci = self.dbg.GetCommandInterpreter()
2400 if not self.ci:
2401 raise Exception('Could not get the command interpreter')
2402
2403 # And the result object.
2404 self.res = lldb.SBCommandReturnObject()
2405
Johnny Chen44d24972012-04-16 18:55:15 +00002406 # Run global pre-flight code, if defined via the config file.
2407 if lldb.pre_flight:
2408 lldb.pre_flight(self)
2409
Enrico Granatabd0998a2015-10-02 22:53:32 +00002410 if lldb.remote_platform and lldb.remote_platform_working_dir:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00002411 remote_test_dir = lldbutil.join_remote_paths(
2412 lldb.remote_platform_working_dir,
2413 self.getArchitecture(),
2414 str(self.test_number),
2415 self.mydir)
Greg Claytonfb909312013-11-23 01:58:15 +00002416 error = lldb.remote_platform.MakeDirectory(remote_test_dir, 0700)
2417 if error.Success():
Greg Claytonfb909312013-11-23 01:58:15 +00002418 lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
2419 else:
2420 print "error: making remote directory '%s': %s" % (remote_test_dir, error)
2421
Greg Clayton35c91342014-11-17 18:40:27 +00002422 def registerSharedLibrariesWithTarget(self, target, shlibs):
2423 '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
2424
2425 Any modules in the target that have their remote install file specification set will
2426 get uploaded to the remote host. This function registers the local copies of the
2427 shared libraries with the target and sets their remote install locations so they will
2428 be uploaded when the target is run.
2429 '''
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00002430 if not shlibs or not self.platformContext:
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002431 return None
Greg Clayton35c91342014-11-17 18:40:27 +00002432
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002433 shlib_environment_var = self.platformContext.shlib_environment_var
2434 shlib_prefix = self.platformContext.shlib_prefix
2435 shlib_extension = '.' + self.platformContext.shlib_extension
2436
2437 working_dir = self.get_process_working_directory()
2438 environment = ['%s=%s' % (shlib_environment_var, working_dir)]
2439 # Add any shared libraries to our target if remote so they get
2440 # uploaded into the working directory on the remote side
2441 for name in shlibs:
2442 # The path can be a full path to a shared library, or a make file name like "Foo" for
2443 # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
2444 # basename like "libFoo.so". So figure out which one it is and resolve the local copy
2445 # of the shared library accordingly
2446 if os.path.exists(name):
2447 local_shlib_path = name # name is the full path to the local shared library
2448 else:
2449 # Check relative names
2450 local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
2451 if not os.path.exists(local_shlib_path):
2452 local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
Greg Clayton35c91342014-11-17 18:40:27 +00002453 if not os.path.exists(local_shlib_path):
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002454 local_shlib_path = os.path.join(os.getcwd(), name)
Greg Clayton35c91342014-11-17 18:40:27 +00002455
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002456 # Make sure we found the local shared library in the above code
2457 self.assertTrue(os.path.exists(local_shlib_path))
2458
2459 # Add the shared library to our target
2460 shlib_module = target.AddModule(local_shlib_path, None, None, None)
2461 if lldb.remote_platform:
Greg Clayton35c91342014-11-17 18:40:27 +00002462 # We must set the remote install location if we want the shared library
2463 # to get uploaded to the remote target
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00002464 remote_shlib_path = lldbutil.append_to_process_working_directory(os.path.basename(local_shlib_path))
Greg Clayton35c91342014-11-17 18:40:27 +00002465 shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002466
2467 return environment
2468
Enrico Granata44818162012-10-24 01:23:57 +00002469 # utility methods that tests can use to access the current objects
2470 def target(self):
2471 if not self.dbg:
2472 raise Exception('Invalid debugger instance')
2473 return self.dbg.GetSelectedTarget()
2474
2475 def process(self):
2476 if not self.dbg:
2477 raise Exception('Invalid debugger instance')
2478 return self.dbg.GetSelectedTarget().GetProcess()
2479
2480 def thread(self):
2481 if not self.dbg:
2482 raise Exception('Invalid debugger instance')
2483 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2484
2485 def frame(self):
2486 if not self.dbg:
2487 raise Exception('Invalid debugger instance')
2488 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
2489
Greg Claytonc6947512013-12-13 19:18:59 +00002490 def get_process_working_directory(self):
2491 '''Get the working directory that should be used when launching processes for local or remote processes.'''
2492 if lldb.remote_platform:
2493 # Remote tests set the platform working directory up in TestBase.setUp()
2494 return lldb.remote_platform.GetWorkingDirectory()
2495 else:
2496 # local tests change directory into each test subdirectory
2497 return os.getcwd()
2498
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002499 def tearDown(self):
Johnny Chen7d1d7532010-09-02 21:23:12 +00002500 #import traceback
2501 #traceback.print_stack()
2502
Johnny Chen3794ad92011-06-15 21:24:24 +00002503 # Delete the target(s) from the debugger as a general cleanup step.
2504 # This includes terminating the process for each target, if any.
2505 # We'd like to reuse the debugger for our next test without incurring
2506 # the initialization overhead.
2507 targets = []
2508 for target in self.dbg:
2509 if target:
2510 targets.append(target)
2511 process = target.GetProcess()
2512 if process:
2513 rc = self.invoke(process, "Kill")
2514 self.assertTrue(rc.Success(), PROCESS_KILLED)
2515 for target in targets:
2516 self.dbg.DeleteTarget(target)
Johnny Chen6ca006c2010-08-16 21:28:10 +00002517
Johnny Chen44d24972012-04-16 18:55:15 +00002518 # Run global post-flight code, if defined via the config file.
2519 if lldb.post_flight:
2520 lldb.post_flight(self)
2521
Zachary Turner65fe1eb2015-03-26 16:43:25 +00002522 # Do this last, to make sure it's in reverse order from how we setup.
2523 Base.tearDown(self)
2524
Zachary Turner95812042015-03-26 18:54:21 +00002525 # This must be the last statement, otherwise teardown hooks or other
2526 # lines might depend on this still being active.
2527 del self.dbg
2528
Johnny Chen86268e42011-09-30 21:48:35 +00002529 def switch_to_thread_with_stop_reason(self, stop_reason):
2530 """
2531 Run the 'thread list' command, and select the thread with stop reason as
2532 'stop_reason'. If no such thread exists, no select action is done.
2533 """
2534 from lldbutil import stop_reason_to_str
2535 self.runCmd('thread list')
2536 output = self.res.GetOutput()
2537 thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
2538 stop_reason_to_str(stop_reason))
2539 for line in output.splitlines():
2540 matched = thread_line_pattern.match(line)
2541 if matched:
2542 self.runCmd('thread select %s' % matched.group(1))
2543
Enrico Granata7594f142013-06-17 22:51:50 +00002544 def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
Johnny Chen27f212d2010-08-19 23:26:59 +00002545 """
2546 Ask the command interpreter to handle the command and then check its
2547 return status.
2548 """
2549 # Fail fast if 'cmd' is not meaningful.
2550 if not cmd or len(cmd) == 0:
2551 raise Exception("Bad 'cmd' parameter encountered")
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002552
Johnny Chen8d55a342010-08-31 17:42:54 +00002553 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002554
Daniel Maleae0f8f572013-08-26 23:57:52 +00002555 # This is an opportunity to insert the 'platform target-install' command if we are told so
2556 # via the settig of lldb.lldbtest_remote_sandbox.
2557 if cmd.startswith("target create "):
2558 cmd = cmd.replace("target create ", "file ")
2559 if cmd.startswith("file ") and lldb.lldbtest_remote_sandbox:
2560 with recording(self, trace) as sbuf:
2561 the_rest = cmd.split("file ")[1]
2562 # Split the rest of the command line.
2563 atoms = the_rest.split()
2564 #
2565 # NOTE: This assumes that the options, if any, follow the file command,
2566 # instead of follow the specified target.
2567 #
2568 target = atoms[-1]
2569 # Now let's get the absolute pathname of our target.
2570 abs_target = os.path.abspath(target)
2571 print >> sbuf, "Found a file command, target (with absolute pathname)=%s" % abs_target
2572 fpath, fname = os.path.split(abs_target)
2573 parent_dir = os.path.split(fpath)[0]
2574 platform_target_install_command = 'platform target-install %s %s' % (fpath, lldb.lldbtest_remote_sandbox)
2575 print >> sbuf, "Insert this command to be run first: %s" % platform_target_install_command
2576 self.ci.HandleCommand(platform_target_install_command, self.res)
2577 # And this is the file command we want to execute, instead.
2578 #
2579 # Warning: SIDE EFFECT AHEAD!!!
2580 # Populate the remote executable pathname into the lldb namespace,
2581 # so that test cases can grab this thing out of the namespace.
2582 #
2583 lldb.lldbtest_remote_sandboxed_executable = abs_target.replace(parent_dir, lldb.lldbtest_remote_sandbox)
2584 cmd = "file -P %s %s %s" % (lldb.lldbtest_remote_sandboxed_executable, the_rest.replace(target, ''), abs_target)
2585 print >> sbuf, "And this is the replaced file command: %s" % cmd
2586
Johnny Chen63dfb272010-09-01 00:15:19 +00002587 running = (cmd.startswith("run") or cmd.startswith("process launch"))
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002588
Johnny Chen63dfb272010-09-01 00:15:19 +00002589 for i in range(self.maxLaunchCount if running else 1):
Enrico Granata7594f142013-06-17 22:51:50 +00002590 self.ci.HandleCommand(cmd, self.res, inHistory)
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002591
Johnny Chen150c3cc2010-10-15 01:18:29 +00002592 with recording(self, trace) as sbuf:
2593 print >> sbuf, "runCmd:", cmd
Johnny Chenab254f52010-10-15 16:13:00 +00002594 if not check:
Johnny Chen27b107b2010-10-15 18:52:22 +00002595 print >> sbuf, "check of return status not required"
Johnny Chenf2b70232010-08-25 18:49:48 +00002596 if self.res.Succeeded():
Johnny Chen150c3cc2010-10-15 01:18:29 +00002597 print >> sbuf, "output:", self.res.GetOutput()
Johnny Chenf2b70232010-08-25 18:49:48 +00002598 else:
Johnny Chen150c3cc2010-10-15 01:18:29 +00002599 print >> sbuf, "runCmd failed!"
2600 print >> sbuf, self.res.GetError()
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002601
Johnny Chenff3d01d2010-08-20 21:03:09 +00002602 if self.res.Succeeded():
Johnny Chenf2b70232010-08-25 18:49:48 +00002603 break
Johnny Chen150c3cc2010-10-15 01:18:29 +00002604 elif running:
Johnny Chencf7f74e2011-01-19 02:02:08 +00002605 # For process launch, wait some time before possible next try.
2606 time.sleep(self.timeWaitNextLaunch)
Johnny Chen552d6712012-08-01 19:56:04 +00002607 with recording(self, trace) as sbuf:
Johnny Chen150c3cc2010-10-15 01:18:29 +00002608 print >> sbuf, "Command '" + cmd + "' failed!"
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002609
Johnny Chen27f212d2010-08-19 23:26:59 +00002610 if check:
Sean Callanan05834cd2015-07-01 23:56:30 +00002611 self.assertTrue(self.res.Succeeded(),
2612 msg if msg else CMD_MSG(cmd))
Johnny Chen27f212d2010-08-19 23:26:59 +00002613
Jim Ingham63dfc722012-09-22 00:05:11 +00002614 def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
2615 """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2616
2617 Otherwise, all the arguments have the same meanings as for the expect function"""
2618
2619 trace = (True if traceAlways else trace)
2620
2621 if exe:
2622 # First run the command. If we are expecting error, set check=False.
2623 # Pass the assert message along since it provides more semantic info.
2624 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
2625
2626 # Then compare the output against expected strings.
2627 output = self.res.GetError() if error else self.res.GetOutput()
2628
2629 # If error is True, the API client expects the command to fail!
2630 if error:
2631 self.assertFalse(self.res.Succeeded(),
2632 "Command '" + str + "' is expected to fail!")
2633 else:
2634 # No execution required, just compare str against the golden input.
2635 output = str
2636 with recording(self, trace) as sbuf:
2637 print >> sbuf, "looking at:", output
2638
2639 # The heading says either "Expecting" or "Not expecting".
2640 heading = "Expecting" if matching else "Not expecting"
2641
2642 for pattern in patterns:
2643 # Match Objects always have a boolean value of True.
2644 match_object = re.search(pattern, output)
2645 matched = bool(match_object)
2646 with recording(self, trace) as sbuf:
2647 print >> sbuf, "%s pattern: %s" % (heading, pattern)
2648 print >> sbuf, "Matched" if matched else "Not matched"
2649 if matched:
2650 break
2651
2652 self.assertTrue(matched if matching else not matched,
2653 msg if msg else EXP_MSG(str, exe))
2654
2655 return match_object
2656
Enrico Granata7594f142013-06-17 22:51:50 +00002657 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 +00002658 """
2659 Similar to runCmd; with additional expect style output matching ability.
2660
2661 Ask the command interpreter to handle the command and then check its
2662 return status. The 'msg' parameter specifies an informational assert
2663 message. We expect the output from running the command to start with
Johnny Chenea88e942010-09-21 21:08:53 +00002664 'startstr', matches the substrings contained in 'substrs', and regexp
2665 matches the patterns contained in 'patterns'.
Johnny Chenb3307862010-09-17 22:28:51 +00002666
2667 If the keyword argument error is set to True, it signifies that the API
2668 client is expecting the command to fail. In this case, the error stream
Johnny Chenaa902922010-09-17 22:45:27 +00002669 from running the command is retrieved and compared against the golden
Johnny Chenb3307862010-09-17 22:28:51 +00002670 input, instead.
Johnny Chenea88e942010-09-21 21:08:53 +00002671
2672 If the keyword argument matching is set to False, it signifies that the API
2673 client is expecting the output of the command not to match the golden
2674 input.
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002675
2676 Finally, the required argument 'str' represents the lldb command to be
2677 sent to the command interpreter. In case the keyword argument 'exe' is
2678 set to False, the 'str' is treated as a string to be matched/not-matched
2679 against the golden input.
Johnny Chen27f212d2010-08-19 23:26:59 +00002680 """
Johnny Chen8d55a342010-08-31 17:42:54 +00002681 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002682
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002683 if exe:
2684 # First run the command. If we are expecting error, set check=False.
Johnny Chen62d4f862010-10-28 21:10:32 +00002685 # Pass the assert message along since it provides more semantic info.
Enrico Granata7594f142013-06-17 22:51:50 +00002686 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error, inHistory=inHistory)
Johnny Chen27f212d2010-08-19 23:26:59 +00002687
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002688 # Then compare the output against expected strings.
2689 output = self.res.GetError() if error else self.res.GetOutput()
Johnny Chenb3307862010-09-17 22:28:51 +00002690
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002691 # If error is True, the API client expects the command to fail!
2692 if error:
2693 self.assertFalse(self.res.Succeeded(),
2694 "Command '" + str + "' is expected to fail!")
2695 else:
2696 # No execution required, just compare str against the golden input.
Enrico Granatabc08ab42012-10-23 00:09:02 +00002697 if isinstance(str,lldb.SBCommandReturnObject):
2698 output = str.GetOutput()
2699 else:
2700 output = str
Johnny Chen150c3cc2010-10-15 01:18:29 +00002701 with recording(self, trace) as sbuf:
2702 print >> sbuf, "looking at:", output
Johnny Chenb3307862010-09-17 22:28:51 +00002703
Johnny Chenea88e942010-09-21 21:08:53 +00002704 # The heading says either "Expecting" or "Not expecting".
Johnny Chen150c3cc2010-10-15 01:18:29 +00002705 heading = "Expecting" if matching else "Not expecting"
Johnny Chenea88e942010-09-21 21:08:53 +00002706
2707 # Start from the startstr, if specified.
2708 # If there's no startstr, set the initial state appropriately.
2709 matched = output.startswith(startstr) if startstr else (True if matching else False)
Johnny Chenb145bba2010-08-20 18:25:15 +00002710
Johnny Chen150c3cc2010-10-15 01:18:29 +00002711 if startstr:
2712 with recording(self, trace) as sbuf:
2713 print >> sbuf, "%s start string: %s" % (heading, startstr)
2714 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenb145bba2010-08-20 18:25:15 +00002715
Johnny Chen86268e42011-09-30 21:48:35 +00002716 # Look for endstr, if specified.
2717 keepgoing = matched if matching else not matched
2718 if endstr:
2719 matched = output.endswith(endstr)
2720 with recording(self, trace) as sbuf:
2721 print >> sbuf, "%s end string: %s" % (heading, endstr)
2722 print >> sbuf, "Matched" if matched else "Not matched"
2723
Johnny Chenea88e942010-09-21 21:08:53 +00002724 # Look for sub strings, if specified.
2725 keepgoing = matched if matching else not matched
2726 if substrs and keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002727 for str in substrs:
Johnny Chenb052f6c2010-09-23 23:35:28 +00002728 matched = output.find(str) != -1
Johnny Chen150c3cc2010-10-15 01:18:29 +00002729 with recording(self, trace) as sbuf:
2730 print >> sbuf, "%s sub string: %s" % (heading, str)
2731 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenea88e942010-09-21 21:08:53 +00002732 keepgoing = matched if matching else not matched
2733 if not keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002734 break
2735
Johnny Chenea88e942010-09-21 21:08:53 +00002736 # Search for regular expression patterns, if specified.
2737 keepgoing = matched if matching else not matched
2738 if patterns and keepgoing:
2739 for pattern in patterns:
2740 # Match Objects always have a boolean value of True.
2741 matched = bool(re.search(pattern, output))
Johnny Chen150c3cc2010-10-15 01:18:29 +00002742 with recording(self, trace) as sbuf:
2743 print >> sbuf, "%s pattern: %s" % (heading, pattern)
2744 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenea88e942010-09-21 21:08:53 +00002745 keepgoing = matched if matching else not matched
2746 if not keepgoing:
2747 break
Johnny Chenea88e942010-09-21 21:08:53 +00002748
2749 self.assertTrue(matched if matching else not matched,
Johnny Chenc0c67f22010-11-09 18:42:22 +00002750 msg if msg else EXP_MSG(str, exe))
Johnny Chen27f212d2010-08-19 23:26:59 +00002751
Johnny Chenf3c59232010-08-25 22:52:45 +00002752 def invoke(self, obj, name, trace=False):
Johnny Chen61703c92010-08-25 22:56:10 +00002753 """Use reflection to call a method dynamically with no argument."""
Johnny Chen8d55a342010-08-31 17:42:54 +00002754 trace = (True if traceAlways else trace)
Johnny Chenf3c59232010-08-25 22:52:45 +00002755
2756 method = getattr(obj, name)
2757 import inspect
2758 self.assertTrue(inspect.ismethod(method),
2759 name + "is a method name of object: " + str(obj))
2760 result = method()
Johnny Chen150c3cc2010-10-15 01:18:29 +00002761 with recording(self, trace) as sbuf:
2762 print >> sbuf, str(method) + ":", result
Johnny Chenf3c59232010-08-25 22:52:45 +00002763 return result
Johnny Chen827edff2010-08-27 00:15:48 +00002764
Tamas Berghammerc8fd1302015-09-30 10:12:40 +00002765 def build(self, architecture=None, compiler=None, dictionary=None, clean=True):
2766 """Platform specific way to build the default binaries."""
2767 if lldb.skip_build_and_cleanup:
2768 return
2769 module = builder_module()
2770 if target_is_android():
2771 dictionary = append_android_envs(dictionary)
2772 if self.debug_info is None:
2773 return self.buildDefault(architecture, compiler, dictionary, clean)
2774 elif self.debug_info == "dsym":
2775 return self.buildDsym(architecture, compiler, dictionary, clean)
2776 elif self.debug_info == "dwarf":
2777 return self.buildDwarf(architecture, compiler, dictionary, clean)
2778
Johnny Chenf359cf22011-05-27 23:36:52 +00002779 # =================================================
2780 # Misc. helper methods for debugging test execution
2781 # =================================================
2782
Johnny Chen56b92a72011-07-11 19:15:11 +00002783 def DebugSBValue(self, val):
Johnny Chen8d55a342010-08-31 17:42:54 +00002784 """Debug print a SBValue object, if traceAlways is True."""
Johnny Chende90f1d2011-04-27 17:43:07 +00002785 from lldbutil import value_type_to_str
Johnny Chen87bb5892010-11-03 21:37:58 +00002786
Johnny Chen8d55a342010-08-31 17:42:54 +00002787 if not traceAlways:
Johnny Chen827edff2010-08-27 00:15:48 +00002788 return
2789
2790 err = sys.stderr
2791 err.write(val.GetName() + ":\n")
Johnny Chen86268e42011-09-30 21:48:35 +00002792 err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n')
2793 err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n')
2794 err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n')
2795 err.write('\t' + "Value -> " + str(val.GetValue()) + '\n')
2796 err.write('\t' + "ValueAsUnsigned -> " + str(val.GetValueAsUnsigned())+ '\n')
2797 err.write('\t' + "ValueType -> " + value_type_to_str(val.GetValueType()) + '\n')
2798 err.write('\t' + "Summary -> " + str(val.GetSummary()) + '\n')
2799 err.write('\t' + "IsPointerType -> " + str(val.TypeIsPointerType()) + '\n')
2800 err.write('\t' + "Location -> " + val.GetLocation() + '\n')
Johnny Chen827edff2010-08-27 00:15:48 +00002801
Johnny Chen36c5eb12011-08-05 20:17:27 +00002802 def DebugSBType(self, type):
2803 """Debug print a SBType object, if traceAlways is True."""
2804 if not traceAlways:
2805 return
2806
2807 err = sys.stderr
2808 err.write(type.GetName() + ":\n")
2809 err.write('\t' + "ByteSize -> " + str(type.GetByteSize()) + '\n')
2810 err.write('\t' + "IsPointerType -> " + str(type.IsPointerType()) + '\n')
2811 err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
2812
Johnny Chenb877f1e2011-03-12 01:18:19 +00002813 def DebugPExpect(self, child):
2814 """Debug the spwaned pexpect object."""
2815 if not traceAlways:
2816 return
2817
2818 print child
Filipe Cabecinhas0eec15a2012-06-20 10:13:40 +00002819
2820 @classmethod
2821 def RemoveTempFile(cls, file):
2822 if os.path.exists(file):
2823 os.remove(file)