blob: a22a3db827f84b0bf44a84f964487750a715cab5 [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
Johnny Chenf1548d42012-04-06 00:56:05 +0000523def dsym_test(func):
524 """Decorate the item as a dsym test."""
525 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
526 raise Exception("@dsym_test can only be used to decorate a test method")
527 @wraps(func)
528 def wrapper(self, *args, **kwargs):
529 try:
530 if lldb.dont_do_dsym_test:
531 self.skipTest("dsym tests")
532 except AttributeError:
533 pass
534 return func(self, *args, **kwargs)
535
536 # Mark this function as such to separate them from the regular tests.
537 wrapper.__dsym_test__ = True
538 return wrapper
539
540def dwarf_test(func):
541 """Decorate the item as a dwarf test."""
542 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
543 raise Exception("@dwarf_test can only be used to decorate a test method")
544 @wraps(func)
545 def wrapper(self, *args, **kwargs):
546 try:
547 if lldb.dont_do_dwarf_test:
548 self.skipTest("dwarf tests")
549 except AttributeError:
550 pass
551 return func(self, *args, **kwargs)
552
553 # Mark this function as such to separate them from the regular tests.
554 wrapper.__dwarf_test__ = True
555 return wrapper
556
Todd Fialaa41d48c2014-04-28 04:49:40 +0000557def debugserver_test(func):
558 """Decorate the item as a debugserver test."""
559 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
560 raise Exception("@debugserver_test can only be used to decorate a test method")
561 @wraps(func)
562 def wrapper(self, *args, **kwargs):
563 try:
564 if lldb.dont_do_debugserver_test:
565 self.skipTest("debugserver tests")
566 except AttributeError:
567 pass
568 return func(self, *args, **kwargs)
569
570 # Mark this function as such to separate them from the regular tests.
571 wrapper.__debugserver_test__ = True
572 return wrapper
573
574def llgs_test(func):
Robert Flack8cc4cf12015-03-06 14:36:33 +0000575 """Decorate the item as a lldb-server test."""
Todd Fialaa41d48c2014-04-28 04:49:40 +0000576 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
577 raise Exception("@llgs_test can only be used to decorate a test method")
578 @wraps(func)
579 def wrapper(self, *args, **kwargs):
580 try:
581 if lldb.dont_do_llgs_test:
582 self.skipTest("llgs tests")
583 except AttributeError:
584 pass
585 return func(self, *args, **kwargs)
586
587 # Mark this function as such to separate them from the regular tests.
588 wrapper.__llgs_test__ = True
589 return wrapper
590
Daniel Maleae0f8f572013-08-26 23:57:52 +0000591def not_remote_testsuite_ready(func):
592 """Decorate the item as a test which is not ready yet for remote testsuite."""
593 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
594 raise Exception("@not_remote_testsuite_ready can only be used to decorate a test method")
595 @wraps(func)
596 def wrapper(self, *args, **kwargs):
597 try:
Tamas Berghammer3e0ecb22015-03-25 15:13:28 +0000598 if lldb.lldbtest_remote_sandbox or lldb.remote_platform:
Daniel Maleae0f8f572013-08-26 23:57:52 +0000599 self.skipTest("not ready for remote testsuite")
600 except AttributeError:
601 pass
602 return func(self, *args, **kwargs)
603
604 # Mark this function as such to separate them from the regular tests.
605 wrapper.__not_ready_for_remote_testsuite_test__ = True
606 return wrapper
607
Ed Maste433790a2014-04-23 12:55:41 +0000608def expectedFailure(expected_fn, bugnumber=None):
609 def expectedFailure_impl(func):
610 @wraps(func)
611 def wrapper(*args, **kwargs):
Enrico Granata43f62132013-02-23 01:28:30 +0000612 from unittest2 import case
613 self = args[0]
Enrico Granata43f62132013-02-23 01:28:30 +0000614 try:
Ed Maste433790a2014-04-23 12:55:41 +0000615 func(*args, **kwargs)
Enrico Granata43f62132013-02-23 01:28:30 +0000616 except Exception:
Ed Maste433790a2014-04-23 12:55:41 +0000617 if expected_fn(self):
618 raise case._ExpectedFailure(sys.exc_info(), bugnumber)
Enrico Granata43f62132013-02-23 01:28:30 +0000619 else:
620 raise
Ed Maste433790a2014-04-23 12:55:41 +0000621 if expected_fn(self):
622 raise case._UnexpectedSuccess(sys.exc_info(), bugnumber)
623 return wrapper
Ying Chen464d1e12015-03-27 00:26:52 +0000624 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
625 # return decorator in this case, so it will be used to decorating original method
626 if callable(bugnumber):
627 return expectedFailure_impl(bugnumber)
628 else:
629 return expectedFailure_impl
Ed Maste433790a2014-04-23 12:55:41 +0000630
631def expectedFailureCompiler(compiler, compiler_version=None, bugnumber=None):
632 if compiler_version is None:
633 compiler_version=['=', None]
634 def fn(self):
635 return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
Ying Chen464d1e12015-03-27 00:26:52 +0000636 return expectedFailure(fn, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000637
Ying Chen7091c2c2015-04-21 01:15:47 +0000638# provide a function to xfail on defined oslist, compiler version, and archs
639# if none is specified for any argument, that argument won't be checked and thus means for all
640# for example,
641# @expectedFailureAll, xfail for all platform/compiler/arch,
642# @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
643# @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
644def expectedFailureAll(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None):
645 def fn(self):
646 return ((oslist is None or self.getPlatform() in oslist) and
647 (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
648 self.expectedArch(archs))
649 return expectedFailure(fn, bugnumber)
650
Vince Harron8974ce22015-03-13 19:54:54 +0000651# to XFAIL a specific clang versions, try this
652# @expectedFailureClang('bugnumber', ['<=', '3.4'])
653def expectedFailureClang(bugnumber=None, compiler_version=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000654 return expectedFailureCompiler('clang', compiler_version, bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000655
656def expectedFailureGcc(bugnumber=None, compiler_version=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000657 return expectedFailureCompiler('gcc', compiler_version, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000658
Matt Kopec0de53f02013-03-15 19:10:12 +0000659def expectedFailureIcc(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000660 return expectedFailureCompiler('icc', None, bugnumber)
Matt Kopec0de53f02013-03-15 19:10:12 +0000661
Ed Maste433790a2014-04-23 12:55:41 +0000662def expectedFailureArch(arch, bugnumber=None):
663 def fn(self):
664 return arch in self.getArchitecture()
Ying Chen464d1e12015-03-27 00:26:52 +0000665 return expectedFailure(fn, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000666
Enrico Granatae6cedc12013-02-23 01:05:23 +0000667def expectedFailurei386(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000668 return expectedFailureArch('i386', bugnumber)
Johnny Chena33843f2011-12-22 21:14:31 +0000669
Matt Kopecee969f92013-09-26 23:30:59 +0000670def expectedFailurex86_64(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000671 return expectedFailureArch('x86_64', bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000672
Robert Flackefa49c22015-03-26 19:34:26 +0000673def expectedFailureOS(oslist, bugnumber=None, compilers=None):
Ed Maste433790a2014-04-23 12:55:41 +0000674 def fn(self):
Robert Flack13c7ad92015-03-30 14:12:17 +0000675 return (self.getPlatform() in oslist and
Robert Flackefa49c22015-03-26 19:34:26 +0000676 self.expectedCompiler(compilers))
Ying Chen464d1e12015-03-27 00:26:52 +0000677 return expectedFailure(fn, bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000678
Chaoren Linf7160f32015-06-09 17:39:27 +0000679def expectedFailureHostOS(oslist, bugnumber=None, compilers=None):
680 def fn(self):
681 return (getHostPlatform() in oslist and
682 self.expectedCompiler(compilers))
683 return expectedFailure(fn, bugnumber)
684
Ed Maste433790a2014-04-23 12:55:41 +0000685def expectedFailureDarwin(bugnumber=None, compilers=None):
Robert Flackefa49c22015-03-26 19:34:26 +0000686 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
Greg Claytone0d0a762015-04-02 18:24:03 +0000687 return expectedFailureOS(getDarwinOSTriples(), bugnumber, compilers)
Matt Kopecee969f92013-09-26 23:30:59 +0000688
Ed Maste24a7f7d2013-07-24 19:47:08 +0000689def expectedFailureFreeBSD(bugnumber=None, compilers=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000690 return expectedFailureOS(['freebsd'], bugnumber, compilers)
Ed Maste24a7f7d2013-07-24 19:47:08 +0000691
Ashok Thirumurthic97a6082013-05-17 20:15:07 +0000692def expectedFailureLinux(bugnumber=None, compilers=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000693 return expectedFailureOS(['linux'], bugnumber, compilers)
Matt Kopece9ea0da2013-05-07 19:29:28 +0000694
Zachary Turner80c2c602014-12-09 19:28:00 +0000695def expectedFailureWindows(bugnumber=None, compilers=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000696 return expectedFailureOS(['windows'], bugnumber, compilers)
Zachary Turner80c2c602014-12-09 19:28:00 +0000697
Chaoren Linf7160f32015-06-09 17:39:27 +0000698def expectedFailureHostWindows(bugnumber=None, compilers=None):
699 return expectedFailureHostOS(['windows'], bugnumber, compilers)
700
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000701def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
Siva Chandra8af91662015-06-05 00:22:49 +0000702 """ Mark a test as xfail for Android.
703
704 Arguments:
705 bugnumber - The LLVM pr associated with the problem.
706 api_levels - A sequence of numbers specifying the Android API levels
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000707 for which a test is expected to fail. None means all API level.
708 arch - A sequence of architecture names specifying the architectures
709 for which a test is expected to fail. None means all architectures.
Siva Chandra8af91662015-06-05 00:22:49 +0000710 """
Pavel Labath674bc7b2015-05-29 14:54:46 +0000711 def fn(self):
Chaoren Lin9070f532015-07-17 22:13:29 +0000712 if target_is_android():
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000713 if archs is not None and self.getArchitecture() not in archs:
714 return False
715 if api_levels is not None and android_device_api() not in api_levels:
716 return False
717 return True
Siva Chandra8af91662015-06-05 00:22:49 +0000718
Pavel Labath674bc7b2015-05-29 14:54:46 +0000719 return expectedFailure(fn, bugnumber)
720
Vince Harron7ac3ea42015-06-26 15:13:21 +0000721# if the test passes on the first try, we're done (success)
722# if the test fails once, then passes on the second try, raise an ExpectedFailure
723# if the test fails twice in a row, re-throw the exception from the second test run
724def expectedFlakey(expected_fn, bugnumber=None):
725 def expectedFailure_impl(func):
726 @wraps(func)
727 def wrapper(*args, **kwargs):
728 from unittest2 import case
729 self = args[0]
730 try:
731 func(*args, **kwargs)
Ying Chen0a7202b2015-07-01 22:44:27 +0000732 # don't retry if the test case is already decorated with xfail or skip
733 except (case._ExpectedFailure, case.SkipTest, case._UnexpectedSuccess):
734 raise
Vince Harron7ac3ea42015-06-26 15:13:21 +0000735 except Exception:
736 if expected_fn(self):
Ying Chen0a7202b2015-07-01 22:44:27 +0000737 # before retry, run tearDown for previous run and setup for next
Vince Harron7ac3ea42015-06-26 15:13:21 +0000738 try:
Ying Chen0a7202b2015-07-01 22:44:27 +0000739 self.tearDown()
740 self.setUp()
Vince Harron7ac3ea42015-06-26 15:13:21 +0000741 func(*args, **kwargs)
742 except Exception:
743 # oh snap! two failures in a row, record a failure/error
744 raise
745 # record the expected failure
746 raise case._ExpectedFailure(sys.exc_info(), bugnumber)
747 else:
748 raise
749 return wrapper
750 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
751 # return decorator in this case, so it will be used to decorating original method
752 if callable(bugnumber):
753 return expectedFailure_impl(bugnumber)
754 else:
755 return expectedFailure_impl
756
757def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
758 def fn(self):
759 return (self.getPlatform() in oslist and
760 self.expectedCompiler(compilers))
761 return expectedFlakey(fn, bugnumber)
762
763def expectedFlakeyDarwin(bugnumber=None, compilers=None):
764 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
765 return expectedFlakeyOS(getDarwinOSTriples(), bugnumber, compilers)
766
767def expectedFlakeyLinux(bugnumber=None, compilers=None):
768 return expectedFlakeyOS(['linux'], bugnumber, compilers)
769
770def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
771 return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
772
773def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
774 if compiler_version is None:
775 compiler_version=['=', None]
776 def fn(self):
777 return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
778 return expectedFlakey(fn, bugnumber)
779
780# @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
781def expectedFlakeyClang(bugnumber=None, compiler_version=None):
782 return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
783
784# @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
785def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
786 return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
787
Greg Clayton12514562013-12-05 22:22:32 +0000788def skipIfRemote(func):
789 """Decorate the item to skip tests if testing remotely."""
790 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
791 raise Exception("@skipIfRemote can only be used to decorate a test method")
792 @wraps(func)
793 def wrapper(*args, **kwargs):
794 from unittest2 import case
795 if lldb.remote_platform:
796 self = args[0]
797 self.skipTest("skip on remote platform")
798 else:
799 func(*args, **kwargs)
800 return wrapper
801
Siva Chandra4470f382015-06-17 22:32:27 +0000802def skipUnlessListedRemote(remote_list=None):
803 def myImpl(func):
804 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
805 raise Exception("@skipIfRemote can only be used to decorate a "
806 "test method")
807
808 @wraps(func)
809 def wrapper(*args, **kwargs):
810 if remote_list and lldb.remote_platform:
811 self = args[0]
812 triple = self.dbg.GetSelectedPlatform().GetTriple()
813 for r in remote_list:
814 if r in triple:
815 func(*args, **kwargs)
816 return
817 self.skipTest("skip on remote platform %s" % str(triple))
818 else:
819 func(*args, **kwargs)
820 return wrapper
821
822 return myImpl
823
Greg Clayton12514562013-12-05 22:22:32 +0000824def skipIfRemoteDueToDeadlock(func):
825 """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
826 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
827 raise Exception("@skipIfRemote can only be used to decorate a test method")
828 @wraps(func)
829 def wrapper(*args, **kwargs):
830 from unittest2 import case
831 if lldb.remote_platform:
832 self = args[0]
833 self.skipTest("skip on remote platform (deadlocks)")
834 else:
835 func(*args, **kwargs)
836 return wrapper
837
Enrico Granatab633e432014-10-06 21:37:06 +0000838def skipIfNoSBHeaders(func):
839 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
840 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Ed Maste59cca5d2014-10-07 01:57:52 +0000841 raise Exception("@skipIfNoSBHeaders can only be used to decorate a test method")
Enrico Granatab633e432014-10-06 21:37:06 +0000842 @wraps(func)
843 def wrapper(*args, **kwargs):
844 from unittest2 import case
845 self = args[0]
Shawn Best181b09b2014-11-08 00:04:04 +0000846 if sys.platform.startswith("darwin"):
847 header = os.path.join(self.lib_dir, 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
848 else:
849 header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
Enrico Granatab633e432014-10-06 21:37:06 +0000850 platform = sys.platform
Enrico Granatab633e432014-10-06 21:37:06 +0000851 if not os.path.exists(header):
852 self.skipTest("skip because LLDB.h header not found")
853 else:
854 func(*args, **kwargs)
855 return wrapper
856
Robert Flack13c7ad92015-03-30 14:12:17 +0000857def skipIfFreeBSD(func):
858 """Decorate the item to skip tests that should be skipped on FreeBSD."""
859 return skipIfPlatform(["freebsd"])(func)
Zachary Turnerc7826522014-08-13 17:44:53 +0000860
Greg Claytone0d0a762015-04-02 18:24:03 +0000861def getDarwinOSTriples():
862 return ['darwin', 'macosx', 'ios']
863
Daniel Maleab3d41a22013-07-09 00:08:01 +0000864def skipIfDarwin(func):
865 """Decorate the item to skip tests that should be skipped on Darwin."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000866 return skipIfPlatform(getDarwinOSTriples())(func)
Daniel Maleab3d41a22013-07-09 00:08:01 +0000867
Robert Flack13c7ad92015-03-30 14:12:17 +0000868def skipIfLinux(func):
869 """Decorate the item to skip tests that should be skipped on Linux."""
870 return skipIfPlatform(["linux"])(func)
871
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000872def skipUnlessHostLinux(func):
873 """Decorate the item to skip tests that should be skipped on any non Linux host."""
874 return skipUnlessHostPlatform(["linux"])(func)
875
Robert Flack13c7ad92015-03-30 14:12:17 +0000876def skipIfWindows(func):
877 """Decorate the item to skip tests that should be skipped on Windows."""
878 return skipIfPlatform(["windows"])(func)
879
Chaoren Line6eea5d2015-06-08 22:13:28 +0000880def skipIfHostWindows(func):
881 """Decorate the item to skip tests that should be skipped on Windows."""
882 return skipIfHostPlatform(["windows"])(func)
883
Robert Flack13c7ad92015-03-30 14:12:17 +0000884def skipUnlessDarwin(func):
885 """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000886 return skipUnlessPlatform(getDarwinOSTriples())(func)
Robert Flack13c7ad92015-03-30 14:12:17 +0000887
Robert Flack068898c2015-04-09 18:07:58 +0000888def getPlatform():
Robert Flack6e1fd352015-05-15 12:39:33 +0000889 """Returns the target platform which the tests are running on."""
Robert Flack068898c2015-04-09 18:07:58 +0000890 platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
891 if platform.startswith('freebsd'):
892 platform = 'freebsd'
893 return platform
894
Robert Flack6e1fd352015-05-15 12:39:33 +0000895def getHostPlatform():
896 """Returns the host platform running the test suite."""
897 # Attempts to return a platform name matching a target Triple platform.
898 if sys.platform.startswith('linux'):
899 return 'linux'
900 elif sys.platform.startswith('win32'):
901 return 'windows'
902 elif sys.platform.startswith('darwin'):
903 return 'darwin'
904 elif sys.platform.startswith('freebsd'):
905 return 'freebsd'
906 else:
907 return sys.platform
908
Robert Flackfb2f6c62015-04-17 08:02:18 +0000909def platformIsDarwin():
910 """Returns true if the OS triple for the selected platform is any valid apple OS"""
911 return getPlatform() in getDarwinOSTriples()
912
Robert Flack6e1fd352015-05-15 12:39:33 +0000913def skipIfHostIncompatibleWithRemote(func):
914 """Decorate the item to skip tests if binaries built on this host are incompatible."""
915 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
916 raise Exception("@skipIfHostIncompatibleWithRemote can only be used to decorate a test method")
917 @wraps(func)
918 def wrapper(*args, **kwargs):
919 from unittest2 import case
920 self = args[0]
921 host_arch = self.getLldbArchitecture()
922 host_platform = getHostPlatform()
923 target_arch = self.getArchitecture()
Robert Flack4629c4b2015-05-15 18:54:32 +0000924 target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
Robert Flack6e1fd352015-05-15 12:39:33 +0000925 if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
926 self.skipTest("skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch))
927 elif target_platform != host_platform:
928 self.skipTest("skipping because target is %s but host is %s" % (target_platform, host_platform))
929 else:
930 func(*args, **kwargs)
931 return wrapper
932
Chaoren Line6eea5d2015-06-08 22:13:28 +0000933def skipIfHostPlatform(oslist):
934 """Decorate the item to skip tests if running on one of the listed host platforms."""
935 return unittest2.skipIf(getHostPlatform() in oslist,
936 "skip on %s" % (", ".join(oslist)))
937
938def skipUnlessHostPlatform(oslist):
939 """Decorate the item to skip tests unless running on one of the listed host platforms."""
940 return unittest2.skipUnless(getHostPlatform() in oslist,
941 "requires on of %s" % (", ".join(oslist)))
942
Zachary Turner793d9972015-08-14 23:29:24 +0000943def skipUnlessArch(archlist):
944 """Decorate the item to skip tests unless running on one of the listed architectures."""
945 def myImpl(func):
946 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
947 raise Exception("@skipUnlessArch can only be used to decorate a test method")
948
949 @wraps(func)
950 def wrapper(*args, **kwargs):
951 self = args[0]
952 if self.getArchitecture() not in archlist:
953 self.skipTest("skipping for architecture %s (requires one of %s)" %
954 (self.getArchitecture(), ", ".join(archlist)))
955 else:
956 func(*args, **kwargs)
957 return wrapper
958
959 return myImpl
960
Robert Flack13c7ad92015-03-30 14:12:17 +0000961def skipIfPlatform(oslist):
962 """Decorate the item to skip tests if running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +0000963 return unittest2.skipIf(getPlatform() in oslist,
964 "skip on %s" % (", ".join(oslist)))
Robert Flack13c7ad92015-03-30 14:12:17 +0000965
966def skipUnlessPlatform(oslist):
967 """Decorate the item to skip tests unless running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +0000968 return unittest2.skipUnless(getPlatform() in oslist,
969 "requires on of %s" % (", ".join(oslist)))
Daniel Maleab3d41a22013-07-09 00:08:01 +0000970
Daniel Malea48359902013-05-14 20:48:54 +0000971def skipIfLinuxClang(func):
972 """Decorate the item to skip tests that should be skipped if building on
973 Linux with clang.
974 """
975 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
976 raise Exception("@skipIfLinuxClang can only be used to decorate a test method")
977 @wraps(func)
978 def wrapper(*args, **kwargs):
979 from unittest2 import case
980 self = args[0]
981 compiler = self.getCompiler()
Vince Harronc8492672015-05-04 02:59:19 +0000982 platform = self.getPlatform()
983 if "clang" in compiler and platform == "linux":
Daniel Malea48359902013-05-14 20:48:54 +0000984 self.skipTest("skipping because Clang is used on Linux")
985 else:
986 func(*args, **kwargs)
987 return wrapper
988
Ying Chen7091c2c2015-04-21 01:15:47 +0000989# provide a function to skip on defined oslist, compiler version, and archs
990# if none is specified for any argument, that argument won't be checked and thus means for all
991# for example,
992# @skipIf, skip for all platform/compiler/arch,
993# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
994# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
995
996# TODO: refactor current code, to make skipIfxxx functions to call this function
997def skipIf(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None):
998 def fn(self):
999 return ((oslist is None or self.getPlatform() in oslist) and
1000 (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
1001 self.expectedArch(archs))
1002 return skipTestIfFn(fn, bugnumber, skipReason="skipping because os:%s compiler: %s %s arch: %s"%(oslist, compiler, compiler_version, archs))
1003
1004def skipTestIfFn(expected_fn, bugnumber=None, skipReason=None):
1005 def skipTestIfFn_impl(func):
1006 @wraps(func)
1007 def wrapper(*args, **kwargs):
1008 from unittest2 import case
1009 self = args[0]
1010 if expected_fn(self):
1011 self.skipTest(skipReason)
1012 else:
1013 func(*args, **kwargs)
1014 return wrapper
1015 if callable(bugnumber):
1016 return skipTestIfFn_impl(bugnumber)
1017 else:
1018 return skipTestIfFn_impl
1019
Daniel Maleabe230792013-01-24 23:52:09 +00001020def skipIfGcc(func):
1021 """Decorate the item to skip tests that should be skipped if building with gcc ."""
1022 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Daniel Malea0aea0162013-02-27 17:29:46 +00001023 raise Exception("@skipIfGcc can only be used to decorate a test method")
Daniel Maleabe230792013-01-24 23:52:09 +00001024 @wraps(func)
1025 def wrapper(*args, **kwargs):
1026 from unittest2 import case
1027 self = args[0]
1028 compiler = self.getCompiler()
1029 if "gcc" in compiler:
1030 self.skipTest("skipping because gcc is the test compiler")
1031 else:
1032 func(*args, **kwargs)
1033 return wrapper
1034
Matt Kopec0de53f02013-03-15 19:10:12 +00001035def skipIfIcc(func):
1036 """Decorate the item to skip tests that should be skipped if building with icc ."""
1037 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1038 raise Exception("@skipIfIcc can only be used to decorate a test method")
1039 @wraps(func)
1040 def wrapper(*args, **kwargs):
1041 from unittest2 import case
1042 self = args[0]
1043 compiler = self.getCompiler()
1044 if "icc" in compiler:
1045 self.skipTest("skipping because icc is the test compiler")
1046 else:
1047 func(*args, **kwargs)
1048 return wrapper
1049
Daniel Malea55faa402013-05-02 21:44:31 +00001050def skipIfi386(func):
1051 """Decorate the item to skip tests that should be skipped if building 32-bit."""
1052 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1053 raise Exception("@skipIfi386 can only be used to decorate a test method")
1054 @wraps(func)
1055 def wrapper(*args, **kwargs):
1056 from unittest2 import case
1057 self = args[0]
1058 if "i386" == self.getArchitecture():
1059 self.skipTest("skipping because i386 is not a supported architecture")
1060 else:
1061 func(*args, **kwargs)
1062 return wrapper
1063
Siva Chandra77f20fc2015-06-05 19:54:49 +00001064def skipIfTargetAndroid(api_levels=None):
1065 """Decorator to skip tests when the target is Android.
1066
1067 Arguments:
1068 api_levels - The API levels for which the test should be skipped. If
1069 it is None, then the test will be skipped for all API levels.
1070 """
1071 def myImpl(func):
1072 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1073 raise Exception("@skipIfTargetAndroid can only be used to "
1074 "decorate a test method")
1075 @wraps(func)
1076 def wrapper(*args, **kwargs):
1077 from unittest2 import case
1078 self = args[0]
Chaoren Lin9070f532015-07-17 22:13:29 +00001079 if target_is_android():
Siva Chandra77f20fc2015-06-05 19:54:49 +00001080 if api_levels:
1081 device_api = android_device_api()
1082 if device_api and (device_api in api_levels):
1083 self.skipTest(
1084 "skip on Android target with API %d" % device_api)
1085 else:
1086 self.skipTest("skip on Android target")
Tamas Berghammer1253a812015-03-13 10:12:25 +00001087 func(*args, **kwargs)
Siva Chandra77f20fc2015-06-05 19:54:49 +00001088 return wrapper
1089 return myImpl
Tamas Berghammer1253a812015-03-13 10:12:25 +00001090
Ilia Kd9953052015-03-12 07:19:41 +00001091def skipUnlessCompilerRt(func):
1092 """Decorate the item to skip tests if testing remotely."""
1093 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1094 raise Exception("@skipUnless can only be used to decorate a test method")
1095 @wraps(func)
1096 def wrapper(*args, **kwargs):
1097 from unittest2 import case
1098 import os.path
1099 compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "projects", "compiler-rt")
1100 if not os.path.exists(compilerRtPath):
1101 self = args[0]
1102 self.skipTest("skip if compiler-rt not found")
1103 else:
1104 func(*args, **kwargs)
1105 return wrapper
Daniel Malea55faa402013-05-02 21:44:31 +00001106
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001107class _PlatformContext(object):
1108 """Value object class which contains platform-specific options."""
1109
1110 def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
1111 self.shlib_environment_var = shlib_environment_var
1112 self.shlib_prefix = shlib_prefix
1113 self.shlib_extension = shlib_extension
1114
1115
Johnny Chena74bb0a2011-08-01 18:46:13 +00001116class Base(unittest2.TestCase):
Johnny Chen8334dad2010-10-22 23:15:46 +00001117 """
Johnny Chena74bb0a2011-08-01 18:46:13 +00001118 Abstract base for performing lldb (see TestBase) or other generic tests (see
1119 BenchBase for one example). lldbtest.Base works with the test driver to
1120 accomplish things.
1121
Johnny Chen8334dad2010-10-22 23:15:46 +00001122 """
Enrico Granata5020f952012-10-24 21:42:49 +00001123
Enrico Granata19186272012-10-24 21:44:48 +00001124 # The concrete subclass should override this attribute.
1125 mydir = None
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001126
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001127 # Keep track of the old current working directory.
1128 oldcwd = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001129
Greg Clayton4570d3e2013-12-10 23:19:29 +00001130 @staticmethod
1131 def compute_mydir(test_file):
1132 '''Subclasses should call this function to correctly calculate the required "mydir" attribute as follows:
1133
1134 mydir = TestBase.compute_mydir(__file__)'''
1135 test_dir = os.path.dirname(test_file)
1136 return test_dir[len(os.environ["LLDB_TEST"])+1:]
1137
Johnny Chenfb4264c2011-08-01 19:50:58 +00001138 def TraceOn(self):
1139 """Returns True if we are in trace mode (tracing detailed test execution)."""
1140 return traceAlways
Greg Clayton4570d3e2013-12-10 23:19:29 +00001141
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001142 @classmethod
1143 def setUpClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001144 """
1145 Python unittest framework class setup fixture.
1146 Do current directory manipulation.
1147 """
Johnny Chenf02ec122010-07-03 20:41:42 +00001148 # Fail fast if 'mydir' attribute is not overridden.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001149 if not cls.mydir or len(cls.mydir) == 0:
Johnny Chenf02ec122010-07-03 20:41:42 +00001150 raise Exception("Subclasses must override the 'mydir' attribute.")
Enrico Granata7e137e32012-10-24 18:14:21 +00001151
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001152 # Save old working directory.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001153 cls.oldcwd = os.getcwd()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001154
1155 # Change current working directory if ${LLDB_TEST} is defined.
1156 # See also dotest.py which sets up ${LLDB_TEST}.
1157 if ("LLDB_TEST" in os.environ):
Vince Harron85d19652015-05-21 19:09:29 +00001158 full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001159 if traceAlways:
Vince Harron85d19652015-05-21 19:09:29 +00001160 print >> sys.stderr, "Change dir to:", full_dir
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001161 os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
1162
Vince Harron85d19652015-05-21 19:09:29 +00001163 if debug_confirm_directory_exclusivity:
Zachary Turnerb48b4042015-05-21 20:16:02 +00001164 import lock
Vince Harron85d19652015-05-21 19:09:29 +00001165 cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
1166 try:
1167 cls.dir_lock.try_acquire()
1168 # write the class that owns the lock into the lock file
1169 cls.dir_lock.handle.write(cls.__name__)
1170 except IOError as ioerror:
1171 # nothing else should have this directory lock
1172 # wait here until we get a lock
1173 cls.dir_lock.acquire()
1174 # read the previous owner from the lock file
1175 lock_id = cls.dir_lock.handle.read()
1176 print >> sys.stderr, "LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id)
1177 raise ioerror
1178
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001179 # Set platform context.
Robert Flackfb2f6c62015-04-17 08:02:18 +00001180 if platformIsDarwin():
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001181 cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
Robert Flackfb2f6c62015-04-17 08:02:18 +00001182 elif getPlatform() == "linux" or getPlatform() == "freebsd":
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001183 cls.platformContext = _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001184 else:
1185 cls.platformContext = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001186
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001187 @classmethod
1188 def tearDownClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001189 """
1190 Python unittest framework class teardown fixture.
1191 Do class-wide cleanup.
1192 """
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001193
Johnny Chen0fddfb22011-11-17 19:57:27 +00001194 if doCleanup and not lldb.skip_build_and_cleanup:
Johnny Chen707b3c92010-10-11 22:25:46 +00001195 # First, let's do the platform-specific cleanup.
Peter Collingbourne19f48d52011-06-20 19:06:20 +00001196 module = builder_module()
Johnny Chen707b3c92010-10-11 22:25:46 +00001197 if not module.cleanup():
1198 raise Exception("Don't know how to do cleanup")
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001199
Johnny Chen707b3c92010-10-11 22:25:46 +00001200 # Subclass might have specific cleanup function defined.
1201 if getattr(cls, "classCleanup", None):
1202 if traceAlways:
1203 print >> sys.stderr, "Call class-specific cleanup function for class:", cls
1204 try:
1205 cls.classCleanup()
1206 except:
1207 exc_type, exc_value, exc_tb = sys.exc_info()
1208 traceback.print_exception(exc_type, exc_value, exc_tb)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001209
Vince Harron85d19652015-05-21 19:09:29 +00001210 if debug_confirm_directory_exclusivity:
1211 cls.dir_lock.release()
1212 del cls.dir_lock
1213
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001214 # Restore old working directory.
1215 if traceAlways:
Johnny Chen703dbd02010-09-30 17:06:24 +00001216 print >> sys.stderr, "Restore dir to:", cls.oldcwd
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001217 os.chdir(cls.oldcwd)
1218
Johnny Chena74bb0a2011-08-01 18:46:13 +00001219 @classmethod
1220 def skipLongRunningTest(cls):
1221 """
1222 By default, we skip long running test case.
1223 This can be overridden by passing '-l' to the test driver (dotest.py).
1224 """
1225 if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
1226 return False
1227 else:
1228 return True
Johnny Chened492022011-06-21 00:53:00 +00001229
Vince Harron6d3d0f12015-05-10 22:01:59 +00001230 def enableLogChannelsForCurrentTest(self):
1231 if len(lldbtest_config.channels) == 0:
1232 return
1233
1234 # if debug channels are specified in lldbtest_config.channels,
1235 # create a new set of log files for every test
1236 log_basename = self.getLogBasenameForCurrentTest()
1237
1238 # confirm that the file is writeable
1239 host_log_path = "{}-host.log".format(log_basename)
1240 open(host_log_path, 'w').close()
1241
1242 log_enable = "log enable -Tpn -f {} ".format(host_log_path)
1243 for channel_with_categories in lldbtest_config.channels:
1244 channel_then_categories = channel_with_categories.split(' ', 1)
1245 channel = channel_then_categories[0]
1246 if len(channel_then_categories) > 1:
1247 categories = channel_then_categories[1]
1248 else:
1249 categories = "default"
1250
1251 if channel == "gdb-remote":
1252 # communicate gdb-remote categories to debugserver
1253 os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
1254
1255 self.ci.HandleCommand(log_enable + channel_with_categories, self.res)
1256 if not self.res.Succeeded():
1257 raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
1258
1259 # Communicate log path name to debugserver & lldb-server
1260 server_log_path = "{}-server.log".format(log_basename)
1261 open(server_log_path, 'w').close()
1262 os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
1263
1264 # Communicate channels to lldb-server
1265 os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
1266
1267 if len(lldbtest_config.channels) == 0:
1268 return
1269
1270 def disableLogChannelsForCurrentTest(self):
1271 # close all log files that we opened
1272 for channel_and_categories in lldbtest_config.channels:
1273 # channel format - <channel-name> [<category0> [<category1> ...]]
1274 channel = channel_and_categories.split(' ', 1)[0]
1275 self.ci.HandleCommand("log disable " + channel, self.res)
1276 if not self.res.Succeeded():
1277 raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
1278
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001279 def setUp(self):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001280 """Fixture for unittest test case setup.
1281
1282 It works with the test driver to conditionally skip tests and does other
1283 initializations."""
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001284 #import traceback
1285 #traceback.print_stack()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001286
Daniel Malea9115f072013-08-06 15:02:32 +00001287 if "LIBCXX_PATH" in os.environ:
1288 self.libcxxPath = os.environ["LIBCXX_PATH"]
1289 else:
1290 self.libcxxPath = None
1291
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001292 if "LLDBMI_EXEC" in os.environ:
1293 self.lldbMiExec = os.environ["LLDBMI_EXEC"]
1294 else:
1295 self.lldbMiExec = None
1296 self.dont_do_lldbmi_test = True
Vince Harron790d95c2015-05-18 19:39:03 +00001297
Johnny Chenebe51722011-10-07 19:21:09 +00001298 # If we spawn an lldb process for test (via pexpect), do not load the
1299 # init file unless told otherwise.
1300 if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
1301 self.lldbOption = ""
1302 else:
1303 self.lldbOption = "--no-lldbinit"
Johnny Chenaaa82ff2011-08-02 22:54:37 +00001304
Johnny Chen985e7402011-08-01 21:13:26 +00001305 # Assign the test method name to self.testMethodName.
1306 #
1307 # For an example of the use of this attribute, look at test/types dir.
1308 # There are a bunch of test cases under test/types and we don't want the
1309 # module cacheing subsystem to be confused with executable name "a.out"
1310 # used for all the test cases.
1311 self.testMethodName = self._testMethodName
1312
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001313 # Python API only test is decorated with @python_api_test,
1314 # which also sets the "__python_api_test__" attribute of the
1315 # function object to True.
Johnny Chen4533dad2011-05-31 23:21:42 +00001316 try:
1317 if lldb.just_do_python_api_test:
1318 testMethod = getattr(self, self._testMethodName)
1319 if getattr(testMethod, "__python_api_test__", False):
1320 pass
1321 else:
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001322 self.skipTest("non python api test")
1323 except AttributeError:
1324 pass
1325
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001326 # lldb-mi only test is decorated with @lldbmi_test,
1327 # which also sets the "__lldbmi_test__" attribute of the
1328 # function object to True.
1329 try:
1330 if lldb.just_do_lldbmi_test:
1331 testMethod = getattr(self, self._testMethodName)
1332 if getattr(testMethod, "__lldbmi_test__", False):
1333 pass
1334 else:
1335 self.skipTest("non lldb-mi test")
1336 except AttributeError:
1337 pass
1338
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001339 # Benchmarks test is decorated with @benchmarks_test,
1340 # which also sets the "__benchmarks_test__" attribute of the
1341 # function object to True.
1342 try:
1343 if lldb.just_do_benchmarks_test:
1344 testMethod = getattr(self, self._testMethodName)
1345 if getattr(testMethod, "__benchmarks_test__", False):
1346 pass
1347 else:
1348 self.skipTest("non benchmarks test")
Johnny Chen4533dad2011-05-31 23:21:42 +00001349 except AttributeError:
1350 pass
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001351
Johnny Chen985e7402011-08-01 21:13:26 +00001352 # This is for the case of directly spawning 'lldb'/'gdb' and interacting
1353 # with it using pexpect.
1354 self.child = None
1355 self.child_prompt = "(lldb) "
1356 # If the child is interacting with the embedded script interpreter,
1357 # there are two exits required during tear down, first to quit the
1358 # embedded script interpreter and second to quit the lldb command
1359 # interpreter.
1360 self.child_in_script_interpreter = False
1361
Johnny Chenfb4264c2011-08-01 19:50:58 +00001362 # These are for customized teardown cleanup.
1363 self.dict = None
1364 self.doTearDownCleanup = False
1365 # And in rare cases where there are multiple teardown cleanups.
1366 self.dicts = []
1367 self.doTearDownCleanups = False
1368
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001369 # List of spawned subproces.Popen objects
1370 self.subprocesses = []
1371
Daniel Malea69207462013-06-05 21:07:02 +00001372 # List of forked process PIDs
1373 self.forkedProcessPids = []
1374
Johnny Chenfb4264c2011-08-01 19:50:58 +00001375 # Create a string buffer to record the session info, to be dumped into a
1376 # test case specific file if test failure is encountered.
Vince Harron1f160372015-05-21 18:51:20 +00001377 self.log_basename = self.getLogBasenameForCurrentTest()
Vince Harron35b17dc2015-05-21 18:20:21 +00001378
Vince Harron1f160372015-05-21 18:51:20 +00001379 session_file = "{}.log".format(self.log_basename)
Vince Harron35b17dc2015-05-21 18:20:21 +00001380 unbuffered = 0 # 0 is the constant for unbuffered
Vince Harron1f160372015-05-21 18:51:20 +00001381 self.session = open(session_file, "w", unbuffered)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001382
1383 # Optimistically set __errored__, __failed__, __expected__ to False
1384 # initially. If the test errored/failed, the session info
1385 # (self.session) is then dumped into a session specific file for
1386 # diagnosis.
1387 self.__errored__ = False
1388 self.__failed__ = False
1389 self.__expected__ = False
1390 # We are also interested in unexpected success.
1391 self.__unexpected__ = False
Johnny Chenf79b0762011-08-16 00:48:58 +00001392 # And skipped tests.
1393 self.__skipped__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001394
1395 # See addTearDownHook(self, hook) which allows the client to add a hook
1396 # function to be run during tearDown() time.
1397 self.hooks = []
1398
1399 # See HideStdout(self).
1400 self.sys_stdout_hidden = False
1401
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001402 if self.platformContext:
1403 # set environment variable names for finding shared libraries
1404 self.dylibPath = self.platformContext.shlib_environment_var
Daniel Malea179ff292012-11-26 21:21:11 +00001405
Vince Harron6d3d0f12015-05-10 22:01:59 +00001406 # Create the debugger instance if necessary.
1407 try:
1408 self.dbg = lldb.DBG
1409 except AttributeError:
1410 self.dbg = lldb.SBDebugger.Create()
1411
1412 if not self.dbg:
1413 raise Exception('Invalid debugger instance')
1414
1415 # Retrieve the associated command interpreter instance.
1416 self.ci = self.dbg.GetCommandInterpreter()
1417 if not self.ci:
1418 raise Exception('Could not get the command interpreter')
1419
1420 # And the result object.
1421 self.res = lldb.SBCommandReturnObject()
1422
1423 self.enableLogChannelsForCurrentTest()
1424
Johnny Chen2a808582011-10-19 16:48:07 +00001425 def runHooks(self, child=None, child_prompt=None, use_cmd_api=False):
Johnny Chena737ba52011-10-19 01:06:21 +00001426 """Perform the run hooks to bring lldb debugger to the desired state.
1427
Johnny Chen2a808582011-10-19 16:48:07 +00001428 By default, expect a pexpect spawned child and child prompt to be
1429 supplied (use_cmd_api=False). If use_cmd_api is true, ignore the child
1430 and child prompt and use self.runCmd() to run the hooks one by one.
1431
Johnny Chena737ba52011-10-19 01:06:21 +00001432 Note that child is a process spawned by pexpect.spawn(). If not, your
1433 test case is mostly likely going to fail.
1434
1435 See also dotest.py where lldb.runHooks are processed/populated.
1436 """
1437 if not lldb.runHooks:
1438 self.skipTest("No runhooks specified for lldb, skip the test")
Johnny Chen2a808582011-10-19 16:48:07 +00001439 if use_cmd_api:
1440 for hook in lldb.runhooks:
1441 self.runCmd(hook)
1442 else:
1443 if not child or not child_prompt:
1444 self.fail("Both child and child_prompt need to be defined.")
1445 for hook in lldb.runHooks:
1446 child.sendline(hook)
1447 child.expect_exact(child_prompt)
Johnny Chena737ba52011-10-19 01:06:21 +00001448
Daniel Malea249287a2013-02-19 16:08:57 +00001449 def setAsync(self, value):
1450 """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
1451 old_async = self.dbg.GetAsync()
1452 self.dbg.SetAsync(value)
1453 self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
1454
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001455 def cleanupSubprocesses(self):
1456 # Ensure any subprocesses are cleaned up
1457 for p in self.subprocesses:
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001458 p.terminate()
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001459 del p
1460 del self.subprocesses[:]
Daniel Malea69207462013-06-05 21:07:02 +00001461 # Ensure any forked processes are cleaned up
1462 for pid in self.forkedProcessPids:
1463 if os.path.exists("/proc/" + str(pid)):
1464 os.kill(pid, signal.SIGTERM)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001465
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001466 def spawnSubprocess(self, executable, args=[], install_remote=True):
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001467 """ Creates a subprocess.Popen object with the specified executable and arguments,
1468 saves it in self.subprocesses, and returns the object.
1469 NOTE: if using this function, ensure you also call:
1470
1471 self.addTearDownHook(self.cleanupSubprocesses)
1472
1473 otherwise the test suite will leak processes.
1474 """
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001475 proc = _RemoteProcess(install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001476 proc.launch(executable, args)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001477 self.subprocesses.append(proc)
1478 return proc
1479
Daniel Malea69207462013-06-05 21:07:02 +00001480 def forkSubprocess(self, executable, args=[]):
1481 """ Fork a subprocess with its own group ID.
1482 NOTE: if using this function, ensure you also call:
1483
1484 self.addTearDownHook(self.cleanupSubprocesses)
1485
1486 otherwise the test suite will leak processes.
1487 """
1488 child_pid = os.fork()
1489 if child_pid == 0:
1490 # If more I/O support is required, this can be beefed up.
1491 fd = os.open(os.devnull, os.O_RDWR)
Daniel Malea69207462013-06-05 21:07:02 +00001492 os.dup2(fd, 1)
1493 os.dup2(fd, 2)
1494 # This call causes the child to have its of group ID
1495 os.setpgid(0,0)
1496 os.execvp(executable, [executable] + args)
1497 # Give the child time to get through the execvp() call
1498 time.sleep(0.1)
1499 self.forkedProcessPids.append(child_pid)
1500 return child_pid
1501
Johnny Chenfb4264c2011-08-01 19:50:58 +00001502 def HideStdout(self):
1503 """Hide output to stdout from the user.
1504
1505 During test execution, there might be cases where we don't want to show the
1506 standard output to the user. For example,
1507
1508 self.runCmd(r'''sc print "\n\n\tHello!\n"''')
1509
1510 tests whether command abbreviation for 'script' works or not. There is no
1511 need to show the 'Hello' output to the user as long as the 'script' command
1512 succeeds and we are not in TraceOn() mode (see the '-t' option).
1513
1514 In this case, the test method calls self.HideStdout(self) to redirect the
1515 sys.stdout to a null device, and restores the sys.stdout upon teardown.
1516
1517 Note that you should only call this method at most once during a test case
1518 execution. Any subsequent call has no effect at all."""
1519 if self.sys_stdout_hidden:
1520 return
1521
1522 self.sys_stdout_hidden = True
1523 old_stdout = sys.stdout
1524 sys.stdout = open(os.devnull, 'w')
1525 def restore_stdout():
1526 sys.stdout = old_stdout
1527 self.addTearDownHook(restore_stdout)
1528
1529 # =======================================================================
1530 # Methods for customized teardown cleanups as well as execution of hooks.
1531 # =======================================================================
1532
1533 def setTearDownCleanup(self, dictionary=None):
1534 """Register a cleanup action at tearDown() time with a dictinary"""
1535 self.dict = dictionary
1536 self.doTearDownCleanup = True
1537
1538 def addTearDownCleanup(self, dictionary):
1539 """Add a cleanup action at tearDown() time with a dictinary"""
1540 self.dicts.append(dictionary)
1541 self.doTearDownCleanups = True
1542
1543 def addTearDownHook(self, hook):
1544 """
1545 Add a function to be run during tearDown() time.
1546
1547 Hooks are executed in a first come first serve manner.
1548 """
1549 if callable(hook):
1550 with recording(self, traceAlways) as sbuf:
1551 print >> sbuf, "Adding tearDown hook:", getsource_if_available(hook)
1552 self.hooks.append(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001553
1554 return self
Johnny Chenfb4264c2011-08-01 19:50:58 +00001555
Jim Inghamda3a3862014-10-16 23:02:14 +00001556 def deletePexpectChild(self):
Johnny Chen985e7402011-08-01 21:13:26 +00001557 # This is for the case of directly spawning 'lldb' and interacting with it
1558 # using pexpect.
Johnny Chen985e7402011-08-01 21:13:26 +00001559 if self.child and self.child.isalive():
Zachary Turner9ef307b2014-07-22 16:19:29 +00001560 import pexpect
Johnny Chen985e7402011-08-01 21:13:26 +00001561 with recording(self, traceAlways) as sbuf:
1562 print >> sbuf, "tearing down the child process...."
Johnny Chen985e7402011-08-01 21:13:26 +00001563 try:
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001564 if self.child_in_script_interpreter:
1565 self.child.sendline('quit()')
1566 self.child.expect_exact(self.child_prompt)
1567 self.child.sendline('settings set interpreter.prompt-on-quit false')
1568 self.child.sendline('quit')
Johnny Chen985e7402011-08-01 21:13:26 +00001569 self.child.expect(pexpect.EOF)
Ilia K47448c22015-02-11 21:41:58 +00001570 except (ValueError, pexpect.ExceptionPexpect):
1571 # child is already terminated
1572 pass
1573 except OSError as exception:
1574 import errno
1575 if exception.errno != errno.EIO:
1576 # unexpected error
1577 raise
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001578 # child is already terminated
Johnny Chen985e7402011-08-01 21:13:26 +00001579 pass
Shawn Besteb3e9052014-11-06 17:52:15 +00001580 finally:
1581 # Give it one final blow to make sure the child is terminated.
1582 self.child.close()
Jim Inghamda3a3862014-10-16 23:02:14 +00001583
1584 def tearDown(self):
1585 """Fixture for unittest test case teardown."""
1586 #import traceback
1587 #traceback.print_stack()
1588
1589 self.deletePexpectChild()
1590
Johnny Chenfb4264c2011-08-01 19:50:58 +00001591 # Check and run any hook functions.
1592 for hook in reversed(self.hooks):
1593 with recording(self, traceAlways) as sbuf:
1594 print >> sbuf, "Executing tearDown hook:", getsource_if_available(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001595 import inspect
1596 hook_argc = len(inspect.getargspec(hook).args)
Enrico Granata6e0566c2014-11-17 19:00:20 +00001597 if hook_argc == 0 or getattr(hook,'im_self',None):
Enrico Granataab0e8312014-11-05 21:31:57 +00001598 hook()
1599 elif hook_argc == 1:
1600 hook(self)
1601 else:
1602 hook() # try the plain call and hope it works
Johnny Chenfb4264c2011-08-01 19:50:58 +00001603
1604 del self.hooks
1605
1606 # Perform registered teardown cleanup.
1607 if doCleanup and self.doTearDownCleanup:
Johnny Chen0fddfb22011-11-17 19:57:27 +00001608 self.cleanup(dictionary=self.dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001609
1610 # In rare cases where there are multiple teardown cleanups added.
1611 if doCleanup and self.doTearDownCleanups:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001612 if self.dicts:
1613 for dict in reversed(self.dicts):
Johnny Chen0fddfb22011-11-17 19:57:27 +00001614 self.cleanup(dictionary=dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001615
Vince Harron9753dd92015-05-10 15:22:09 +00001616 self.disableLogChannelsForCurrentTest()
1617
Johnny Chenfb4264c2011-08-01 19:50:58 +00001618 # Decide whether to dump the session info.
1619 self.dumpSessionInfo()
1620
1621 # =========================================================
1622 # Various callbacks to allow introspection of test progress
1623 # =========================================================
1624
1625 def markError(self):
1626 """Callback invoked when an error (unexpected exception) errored."""
1627 self.__errored__ = True
1628 with recording(self, False) as sbuf:
1629 # False because there's no need to write "ERROR" to the stderr twice.
1630 # Once by the Python unittest framework, and a second time by us.
1631 print >> sbuf, "ERROR"
1632
1633 def markFailure(self):
1634 """Callback invoked when a failure (test assertion failure) occurred."""
1635 self.__failed__ = True
1636 with recording(self, False) as sbuf:
1637 # False because there's no need to write "FAIL" to the stderr twice.
1638 # Once by the Python unittest framework, and a second time by us.
1639 print >> sbuf, "FAIL"
1640
Enrico Granatae6cedc12013-02-23 01:05:23 +00001641 def markExpectedFailure(self,err,bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001642 """Callback invoked when an expected failure/error occurred."""
1643 self.__expected__ = True
1644 with recording(self, False) as sbuf:
1645 # False because there's no need to write "expected failure" to the
1646 # stderr twice.
1647 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001648 if bugnumber == None:
1649 print >> sbuf, "expected failure"
1650 else:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001651 print >> sbuf, "expected failure (problem id:" + str(bugnumber) + ")"
Johnny Chenfb4264c2011-08-01 19:50:58 +00001652
Johnny Chenc5cc6252011-08-15 23:09:08 +00001653 def markSkippedTest(self):
1654 """Callback invoked when a test is skipped."""
1655 self.__skipped__ = True
1656 with recording(self, False) as sbuf:
1657 # False because there's no need to write "skipped test" to the
1658 # stderr twice.
1659 # Once by the Python unittest framework, and a second time by us.
1660 print >> sbuf, "skipped test"
1661
Enrico Granatae6cedc12013-02-23 01:05:23 +00001662 def markUnexpectedSuccess(self, bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001663 """Callback invoked when an unexpected success occurred."""
1664 self.__unexpected__ = True
1665 with recording(self, False) as sbuf:
1666 # False because there's no need to write "unexpected success" to the
1667 # stderr twice.
1668 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001669 if bugnumber == None:
1670 print >> sbuf, "unexpected success"
1671 else:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001672 print >> sbuf, "unexpected success (problem id:" + str(bugnumber) + ")"
Johnny Chenfb4264c2011-08-01 19:50:58 +00001673
Greg Clayton70995582015-01-07 22:25:50 +00001674 def getRerunArgs(self):
1675 return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
Vince Harron9753dd92015-05-10 15:22:09 +00001676
1677 def getLogBasenameForCurrentTest(self, prefix=None):
1678 """
1679 returns a partial path that can be used as the beginning of the name of multiple
1680 log files pertaining to this test
1681
1682 <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
1683 """
1684 dname = os.path.join(os.environ["LLDB_TEST"],
1685 os.environ["LLDB_SESSION_DIRNAME"])
1686 if not os.path.isdir(dname):
1687 os.mkdir(dname)
1688
1689 compiler = self.getCompiler()
1690
1691 if compiler[1] == ':':
1692 compiler = compiler[2:]
Chaoren Lin636a0e32015-07-17 21:40:11 +00001693 if os.path.altsep is not None:
1694 compiler = compiler.replace(os.path.altsep, os.path.sep)
Vince Harron9753dd92015-05-10 15:22:09 +00001695
Vince Harron19e300f2015-05-12 00:50:54 +00001696 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
Vince Harron9753dd92015-05-10 15:22:09 +00001697 if len(fname) > 200:
Vince Harron19e300f2015-05-12 00:50:54 +00001698 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
Vince Harron9753dd92015-05-10 15:22:09 +00001699
1700 if prefix is not None:
1701 fname = "{}-{}".format(prefix, fname)
1702
1703 return os.path.join(dname, fname)
1704
Johnny Chenfb4264c2011-08-01 19:50:58 +00001705 def dumpSessionInfo(self):
1706 """
1707 Dump the debugger interactions leading to a test error/failure. This
1708 allows for more convenient postmortem analysis.
1709
1710 See also LLDBTestResult (dotest.py) which is a singlton class derived
1711 from TextTestResult and overwrites addError, addFailure, and
1712 addExpectedFailure methods to allow us to to mark the test instance as
1713 such.
1714 """
1715
1716 # We are here because self.tearDown() detected that this test instance
1717 # either errored or failed. The lldb.test_result singleton contains
1718 # two lists (erros and failures) which get populated by the unittest
1719 # framework. Look over there for stack trace information.
1720 #
1721 # The lists contain 2-tuples of TestCase instances and strings holding
1722 # formatted tracebacks.
1723 #
1724 # See http://docs.python.org/library/unittest.html#unittest.TestResult.
Vince Harron9753dd92015-05-10 15:22:09 +00001725
Vince Harron35b17dc2015-05-21 18:20:21 +00001726 # output tracebacks into session
Vince Harron9753dd92015-05-10 15:22:09 +00001727 pairs = []
Johnny Chenfb4264c2011-08-01 19:50:58 +00001728 if self.__errored__:
1729 pairs = lldb.test_result.errors
1730 prefix = 'Error'
1731 elif self.__failed__:
1732 pairs = lldb.test_result.failures
1733 prefix = 'Failure'
1734 elif self.__expected__:
1735 pairs = lldb.test_result.expectedFailures
1736 prefix = 'ExpectedFailure'
Johnny Chenc5cc6252011-08-15 23:09:08 +00001737 elif self.__skipped__:
1738 prefix = 'SkippedTest'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001739 elif self.__unexpected__:
Vince Harron35b17dc2015-05-21 18:20:21 +00001740 prefix = 'UnexpectedSuccess'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001741 else:
Vince Harron35b17dc2015-05-21 18:20:21 +00001742 prefix = 'Success'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001743
Johnny Chenc5cc6252011-08-15 23:09:08 +00001744 if not self.__unexpected__ and not self.__skipped__:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001745 for test, traceback in pairs:
1746 if test is self:
1747 print >> self.session, traceback
1748
Vince Harron35b17dc2015-05-21 18:20:21 +00001749 # put footer (timestamp/rerun instructions) into session
Johnny Chen8082a002011-08-11 00:16:28 +00001750 testMethod = getattr(self, self._testMethodName)
1751 if getattr(testMethod, "__benchmarks_test__", False):
1752 benchmarks = True
1753 else:
1754 benchmarks = False
1755
Vince Harron35b17dc2015-05-21 18:20:21 +00001756 import datetime
1757 print >> self.session, "Session info generated @", datetime.datetime.now().ctime()
1758 print >> self.session, "To rerun this test, issue the following command from the 'test' directory:\n"
1759 print >> self.session, "./dotest.py %s -v %s %s" % (self.getRunOptions(),
1760 ('+b' if benchmarks else '-t'),
1761 self.getRerunArgs())
1762 self.session.close()
1763 del self.session
1764
1765 # process the log files
Vince Harron1f160372015-05-21 18:51:20 +00001766 log_files_for_this_test = glob.glob(self.log_basename + "*")
Vince Harron35b17dc2015-05-21 18:20:21 +00001767
1768 if prefix != 'Success' or lldbtest_config.log_success:
1769 # keep all log files, rename them to include prefix
1770 dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1771 for src in log_files_for_this_test:
Zachary Turner306278f2015-05-26 20:26:29 +00001772 if os.path.isfile(src):
1773 dst = src.replace(self.log_basename, dst_log_basename)
1774 if os.name == "nt" and os.path.isfile(dst):
1775 # On Windows, renaming a -> b will throw an exception if b exists. On non-Windows platforms
1776 # it silently replaces the destination. Ultimately this means that atomic renames are not
1777 # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
1778 # destination first if it already exists.
1779 os.remove(dst)
Zachary Turner5de068b2015-05-26 19:52:24 +00001780
Zachary Turner306278f2015-05-26 20:26:29 +00001781 os.rename(src, dst)
Vince Harron35b17dc2015-05-21 18:20:21 +00001782 else:
1783 # success! (and we don't want log files) delete log files
1784 for log_file in log_files_for_this_test:
1785 os.unlink(log_file)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001786
1787 # ====================================================
1788 # Config. methods supported through a plugin interface
1789 # (enables reading of the current test configuration)
1790 # ====================================================
1791
1792 def getArchitecture(self):
1793 """Returns the architecture in effect the test suite is running with."""
1794 module = builder_module()
Ed Maste0f434e62015-04-06 15:50:48 +00001795 arch = module.getArchitecture()
1796 if arch == 'amd64':
1797 arch = 'x86_64'
1798 return arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00001799
Vince Harron02613762015-05-04 00:17:53 +00001800 def getLldbArchitecture(self):
1801 """Returns the architecture of the lldb binary."""
1802 if not hasattr(self, 'lldbArchitecture'):
1803
1804 # spawn local process
1805 command = [
Vince Harron790d95c2015-05-18 19:39:03 +00001806 lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001807 "-o",
Vince Harron790d95c2015-05-18 19:39:03 +00001808 "file " + lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001809 "-o",
1810 "quit"
1811 ]
1812
1813 output = check_output(command)
1814 str = output.decode("utf-8");
1815
1816 for line in str.splitlines():
1817 m = re.search("Current executable set to '.*' \\((.*)\\)\\.", line)
1818 if m:
1819 self.lldbArchitecture = m.group(1)
1820 break
1821
1822 return self.lldbArchitecture
1823
Johnny Chenfb4264c2011-08-01 19:50:58 +00001824 def getCompiler(self):
1825 """Returns the compiler in effect the test suite is running with."""
1826 module = builder_module()
1827 return module.getCompiler()
1828
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001829 def getCompilerBinary(self):
1830 """Returns the compiler binary the test suite is running with."""
1831 return self.getCompiler().split()[0]
1832
Daniel Malea0aea0162013-02-27 17:29:46 +00001833 def getCompilerVersion(self):
1834 """ Returns a string that represents the compiler version.
1835 Supports: llvm, clang.
1836 """
1837 from lldbutil import which
1838 version = 'unknown'
1839
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001840 compiler = self.getCompilerBinary()
Zachary Turner9ef307b2014-07-22 16:19:29 +00001841 version_output = system([[which(compiler), "-v"]])[1]
Daniel Malea0aea0162013-02-27 17:29:46 +00001842 for line in version_output.split(os.linesep):
Greg Clayton2a844b72013-03-06 02:34:51 +00001843 m = re.search('version ([0-9\.]+)', line)
Daniel Malea0aea0162013-02-27 17:29:46 +00001844 if m:
1845 version = m.group(1)
1846 return version
1847
Greg Claytone0d0a762015-04-02 18:24:03 +00001848 def platformIsDarwin(self):
1849 """Returns true if the OS triple for the selected platform is any valid apple OS"""
Robert Flackfb2f6c62015-04-17 08:02:18 +00001850 return platformIsDarwin()
Vince Harron20952cc2015-04-03 01:00:06 +00001851
Robert Flack13c7ad92015-03-30 14:12:17 +00001852 def getPlatform(self):
Robert Flackfb2f6c62015-04-17 08:02:18 +00001853 """Returns the target platform the test suite is running on."""
Robert Flack068898c2015-04-09 18:07:58 +00001854 return getPlatform()
Robert Flack13c7ad92015-03-30 14:12:17 +00001855
Daniel Maleaadaaec92013-08-06 20:51:41 +00001856 def isIntelCompiler(self):
1857 """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1858 return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1859
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001860 def expectedCompilerVersion(self, compiler_version):
1861 """Returns True iff compiler_version[1] matches the current compiler version.
1862 Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1863 Any operator other than the following defaults to an equality test:
1864 '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1865 """
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001866 if (compiler_version == None):
1867 return True
1868 operator = str(compiler_version[0])
1869 version = compiler_version[1]
1870
1871 if (version == None):
1872 return True
1873 if (operator == '>'):
1874 return self.getCompilerVersion() > version
1875 if (operator == '>=' or operator == '=>'):
1876 return self.getCompilerVersion() >= version
1877 if (operator == '<'):
1878 return self.getCompilerVersion() < version
1879 if (operator == '<=' or operator == '=<'):
1880 return self.getCompilerVersion() <= version
1881 if (operator == '!=' or operator == '!' or operator == 'not'):
1882 return str(version) not in str(self.getCompilerVersion())
1883 return str(version) in str(self.getCompilerVersion())
1884
1885 def expectedCompiler(self, compilers):
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001886 """Returns True iff any element of compilers is a sub-string of the current compiler."""
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001887 if (compilers == None):
1888 return True
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001889
1890 for compiler in compilers:
1891 if compiler in self.getCompiler():
1892 return True
1893
1894 return False
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001895
Ying Chen7091c2c2015-04-21 01:15:47 +00001896 def expectedArch(self, archs):
1897 """Returns True iff any element of archs is a sub-string of the current architecture."""
1898 if (archs == None):
1899 return True
1900
1901 for arch in archs:
1902 if arch in self.getArchitecture():
1903 return True
1904
1905 return False
1906
Johnny Chenfb4264c2011-08-01 19:50:58 +00001907 def getRunOptions(self):
1908 """Command line option for -A and -C to run this test again, called from
1909 self.dumpSessionInfo()."""
1910 arch = self.getArchitecture()
1911 comp = self.getCompiler()
Johnny Chenb7bdd102011-08-24 19:48:51 +00001912 if arch:
1913 option_str = "-A " + arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00001914 else:
Johnny Chenb7bdd102011-08-24 19:48:51 +00001915 option_str = ""
1916 if comp:
Johnny Chen531c0852012-03-16 20:44:00 +00001917 option_str += " -C " + comp
Johnny Chenb7bdd102011-08-24 19:48:51 +00001918 return option_str
Johnny Chenfb4264c2011-08-01 19:50:58 +00001919
1920 # ==================================================
1921 # Build methods supported through a plugin interface
1922 # ==================================================
1923
Ed Mastec97323e2014-04-01 18:47:58 +00001924 def getstdlibFlag(self):
1925 """ Returns the proper -stdlib flag, or empty if not required."""
Robert Flack4629c4b2015-05-15 18:54:32 +00001926 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Ed Mastec97323e2014-04-01 18:47:58 +00001927 stdlibflag = "-stdlib=libc++"
1928 else:
1929 stdlibflag = ""
1930 return stdlibflag
1931
Matt Kopec7663b3a2013-09-25 17:44:00 +00001932 def getstdFlag(self):
1933 """ Returns the proper stdflag. """
Daniel Malea55faa402013-05-02 21:44:31 +00001934 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
Daniel Malea0b7c6112013-05-06 19:31:31 +00001935 stdflag = "-std=c++0x"
Daniel Malea55faa402013-05-02 21:44:31 +00001936 else:
1937 stdflag = "-std=c++11"
Matt Kopec7663b3a2013-09-25 17:44:00 +00001938 return stdflag
1939
1940 def buildDriver(self, sources, exe_name):
1941 """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
1942 or LLDB.framework).
1943 """
1944
1945 stdflag = self.getstdFlag()
Ed Mastec97323e2014-04-01 18:47:58 +00001946 stdlibflag = self.getstdlibFlag()
Daniel Malea55faa402013-05-02 21:44:31 +00001947
1948 if sys.platform.startswith("darwin"):
1949 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
1950 d = {'CXX_SOURCES' : sources,
1951 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00001952 'CFLAGS_EXTRAS' : "%s %s" % (stdflag, stdlibflag),
Daniel Malea55faa402013-05-02 21:44:31 +00001953 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
Stefanus Du Toit04004442013-07-30 19:19:49 +00001954 'LD_EXTRAS' : "%s -Wl,-rpath,%s" % (dsym, self.lib_dir),
Daniel Malea55faa402013-05-02 21:44:31 +00001955 }
Ed Maste372c24d2013-07-25 21:02:34 +00001956 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 +00001957 d = {'CXX_SOURCES' : sources,
Daniel Malea55faa402013-05-02 21:44:31 +00001958 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00001959 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
Daniel Malea55faa402013-05-02 21:44:31 +00001960 'LD_EXTRAS' : "-L%s -llldb" % self.lib_dir}
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00001961 elif sys.platform.startswith('win'):
1962 d = {'CXX_SOURCES' : sources,
1963 'EXE' : exe_name,
1964 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1965 'LD_EXTRAS' : "-L%s -lliblldb" % self.implib_dir}
Daniel Malea55faa402013-05-02 21:44:31 +00001966 if self.TraceOn():
1967 print "Building LLDB Driver (%s) from sources %s" % (exe_name, sources)
1968
1969 self.buildDefault(dictionary=d)
1970
Matt Kopec7663b3a2013-09-25 17:44:00 +00001971 def buildLibrary(self, sources, lib_name):
1972 """Platform specific way to build a default library. """
1973
1974 stdflag = self.getstdFlag()
1975
Robert Flack4629c4b2015-05-15 18:54:32 +00001976 if self.platformIsDarwin():
Matt Kopec7663b3a2013-09-25 17:44:00 +00001977 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
1978 d = {'DYLIB_CXX_SOURCES' : sources,
1979 'DYLIB_NAME' : lib_name,
1980 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
1981 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
1982 'LD_EXTRAS' : "%s -Wl,-rpath,%s -dynamiclib" % (dsym, self.lib_dir),
1983 }
Robert Flack4629c4b2015-05-15 18:54:32 +00001984 elif self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux' or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
Matt Kopec7663b3a2013-09-25 17:44:00 +00001985 d = {'DYLIB_CXX_SOURCES' : sources,
1986 'DYLIB_NAME' : lib_name,
1987 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1988 'LD_EXTRAS' : "-shared -L%s -llldb" % self.lib_dir}
Robert Flack4629c4b2015-05-15 18:54:32 +00001989 elif self.getPlatform() == 'windows':
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00001990 d = {'DYLIB_CXX_SOURCES' : sources,
1991 'DYLIB_NAME' : lib_name,
1992 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1993 'LD_EXTRAS' : "-shared -l%s\liblldb.lib" % self.implib_dir}
Matt Kopec7663b3a2013-09-25 17:44:00 +00001994 if self.TraceOn():
1995 print "Building LLDB Library (%s) from sources %s" % (lib_name, sources)
1996
1997 self.buildDefault(dictionary=d)
1998
Daniel Malea55faa402013-05-02 21:44:31 +00001999 def buildProgram(self, sources, exe_name):
2000 """ Platform specific way to build an executable from C/C++ sources. """
2001 d = {'CXX_SOURCES' : sources,
2002 'EXE' : exe_name}
2003 self.buildDefault(dictionary=d)
2004
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002005 def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002006 """Platform specific way to build the default binaries."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002007 if lldb.skip_build_and_cleanup:
2008 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002009 module = builder_module()
Chaoren Line9bbabc2015-07-18 00:37:55 +00002010 if target_is_android():
2011 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002012 if not module.buildDefault(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002013 raise Exception("Don't know how to build default binary")
2014
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002015 def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002016 """Platform specific way to build binaries with dsym info."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002017 if lldb.skip_build_and_cleanup:
2018 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002019 module = builder_module()
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002020 if not module.buildDsym(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002021 raise Exception("Don't know how to build binary with dsym")
2022
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002023 def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002024 """Platform specific way to build binaries with dwarf maps."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002025 if lldb.skip_build_and_cleanup:
2026 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002027 module = builder_module()
Chaoren Lin9070f532015-07-17 22:13:29 +00002028 if target_is_android():
Chaoren Line9bbabc2015-07-18 00:37:55 +00002029 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002030 if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002031 raise Exception("Don't know how to build binary with dwarf")
Johnny Chena74bb0a2011-08-01 18:46:13 +00002032
Oleksiy Vyalov49b71c62015-01-22 20:03:21 +00002033 def signBinary(self, binary_path):
2034 if sys.platform.startswith("darwin"):
2035 codesign_cmd = "codesign --force --sign lldb_codesign %s" % (binary_path)
2036 call(codesign_cmd, shell=True)
2037
Kuba Breckabeed8212014-09-04 01:03:18 +00002038 def findBuiltClang(self):
2039 """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
2040 paths_to_try = [
2041 "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
2042 "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
2043 "llvm-build/Release/x86_64/Release/bin/clang",
2044 "llvm-build/Debug/x86_64/Debug/bin/clang",
2045 ]
2046 lldb_root_path = os.path.join(os.path.dirname(__file__), "..")
2047 for p in paths_to_try:
2048 path = os.path.join(lldb_root_path, p)
2049 if os.path.exists(path):
2050 return path
Ilia Kd9953052015-03-12 07:19:41 +00002051
2052 # Tries to find clang at the same folder as the lldb
Vince Harron790d95c2015-05-18 19:39:03 +00002053 path = os.path.join(os.path.dirname(lldbtest_config.lldbExec), "clang")
Ilia Kd9953052015-03-12 07:19:41 +00002054 if os.path.exists(path):
2055 return path
Kuba Breckabeed8212014-09-04 01:03:18 +00002056
2057 return os.environ["CC"]
2058
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002059 def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False):
Andrew Kaylor93132f52013-05-28 23:04:25 +00002060 """ Returns a dictionary (which can be provided to build* functions above) which
2061 contains OS-specific build flags.
2062 """
2063 cflags = ""
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002064 ldflags = ""
Daniel Malea9115f072013-08-06 15:02:32 +00002065
2066 # On Mac OS X, unless specifically requested to use libstdc++, use libc++
Robert Flack4629c4b2015-05-15 18:54:32 +00002067 if not use_libstdcxx and self.platformIsDarwin():
Daniel Malea9115f072013-08-06 15:02:32 +00002068 use_libcxx = True
2069
2070 if use_libcxx and self.libcxxPath:
2071 cflags += "-stdlib=libc++ "
2072 if self.libcxxPath:
2073 libcxxInclude = os.path.join(self.libcxxPath, "include")
2074 libcxxLib = os.path.join(self.libcxxPath, "lib")
2075 if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
2076 cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (libcxxInclude, libcxxLib, libcxxLib)
2077
Andrew Kaylor93132f52013-05-28 23:04:25 +00002078 if use_cpp11:
2079 cflags += "-std="
2080 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2081 cflags += "c++0x"
2082 else:
2083 cflags += "c++11"
Robert Flack4629c4b2015-05-15 18:54:32 +00002084 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Andrew Kaylor93132f52013-05-28 23:04:25 +00002085 cflags += " -stdlib=libc++"
2086 elif "clang" in self.getCompiler():
2087 cflags += " -stdlib=libstdc++"
2088
Andrew Kaylor93132f52013-05-28 23:04:25 +00002089 return {'CFLAGS_EXTRAS' : cflags,
2090 'LD_EXTRAS' : ldflags,
2091 }
2092
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002093 def cleanup(self, dictionary=None):
2094 """Platform specific way to do cleanup after build."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002095 if lldb.skip_build_and_cleanup:
2096 return
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002097 module = builder_module()
2098 if not module.cleanup(self, dictionary):
Johnny Chen0fddfb22011-11-17 19:57:27 +00002099 raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002100
Daniel Malea55faa402013-05-02 21:44:31 +00002101 def getLLDBLibraryEnvVal(self):
2102 """ Returns the path that the OS-specific library search environment variable
2103 (self.dylibPath) should be set to in order for a program to find the LLDB
2104 library. If an environment variable named self.dylibPath is already set,
2105 the new path is appended to it and returned.
2106 """
2107 existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
2108 if existing_library_path:
2109 return "%s:%s" % (existing_library_path, self.lib_dir)
2110 elif sys.platform.startswith("darwin"):
2111 return os.path.join(self.lib_dir, 'LLDB.framework')
2112 else:
2113 return self.lib_dir
Johnny Chena74bb0a2011-08-01 18:46:13 +00002114
Ed Maste437f8f62013-09-09 14:04:04 +00002115 def getLibcPlusPlusLibs(self):
Robert Flackfa5ad652015-05-13 20:17:34 +00002116 if self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux':
Ed Maste437f8f62013-09-09 14:04:04 +00002117 return ['libc++.so.1']
2118 else:
2119 return ['libc++.1.dylib','libc++abi.dylib']
2120
Johnny Chena74bb0a2011-08-01 18:46:13 +00002121class TestBase(Base):
2122 """
2123 This abstract base class is meant to be subclassed. It provides default
2124 implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
2125 among other things.
2126
2127 Important things for test class writers:
2128
2129 - Overwrite the mydir class attribute, otherwise your test class won't
2130 run. It specifies the relative directory to the top level 'test' so
2131 the test harness can change to the correct working directory before
2132 running your test.
2133
2134 - The setUp method sets up things to facilitate subsequent interactions
2135 with the debugger as part of the test. These include:
2136 - populate the test method name
2137 - create/get a debugger set with synchronous mode (self.dbg)
2138 - get the command interpreter from with the debugger (self.ci)
2139 - create a result object for use with the command interpreter
2140 (self.res)
2141 - plus other stuffs
2142
2143 - The tearDown method tries to perform some necessary cleanup on behalf
2144 of the test to return the debugger to a good state for the next test.
2145 These include:
2146 - execute any tearDown hooks registered by the test method with
2147 TestBase.addTearDownHook(); examples can be found in
2148 settings/TestSettings.py
2149 - kill the inferior process associated with each target, if any,
2150 and, then delete the target from the debugger's target list
2151 - perform build cleanup before running the next test method in the
2152 same test class; examples of registering for this service can be
2153 found in types/TestIntegerTypes.py with the call:
2154 - self.setTearDownCleanup(dictionary=d)
2155
2156 - Similarly setUpClass and tearDownClass perform classwise setup and
2157 teardown fixtures. The tearDownClass method invokes a default build
2158 cleanup for the entire test class; also, subclasses can implement the
2159 classmethod classCleanup(cls) to perform special class cleanup action.
2160
2161 - The instance methods runCmd and expect are used heavily by existing
2162 test cases to send a command to the command interpreter and to perform
2163 string/pattern matching on the output of such command execution. The
2164 expect method also provides a mode to peform string/pattern matching
2165 without running a command.
2166
2167 - The build methods buildDefault, buildDsym, and buildDwarf are used to
2168 build the binaries used during a particular test scenario. A plugin
2169 should be provided for the sys.platform running the test suite. The
2170 Mac OS X implementation is located in plugins/darwin.py.
2171 """
2172
2173 # Maximum allowed attempts when launching the inferior process.
2174 # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
2175 maxLaunchCount = 3;
2176
2177 # Time to wait before the next launching attempt in second(s).
2178 # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
2179 timeWaitNextLaunch = 1.0;
2180
2181 def doDelay(self):
2182 """See option -w of dotest.py."""
2183 if ("LLDB_WAIT_BETWEEN_TEST_CASES" in os.environ and
2184 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] == 'YES'):
2185 waitTime = 1.0
2186 if "LLDB_TIME_WAIT_BETWEEN_TEST_CASES" in os.environ:
2187 waitTime = float(os.environ["LLDB_TIME_WAIT_BETWEEN_TEST_CASES"])
2188 time.sleep(waitTime)
2189
Enrico Granata165f8af2012-09-21 19:10:53 +00002190 # Returns the list of categories to which this test case belongs
2191 # by default, look for a ".categories" file, and read its contents
2192 # if no such file exists, traverse the hierarchy - we guarantee
2193 # a .categories to exist at the top level directory so we do not end up
2194 # looping endlessly - subclasses are free to define their own categories
2195 # in whatever way makes sense to them
2196 def getCategories(self):
2197 import inspect
2198 import os.path
2199 folder = inspect.getfile(self.__class__)
2200 folder = os.path.dirname(folder)
2201 while folder != '/':
2202 categories_file_name = os.path.join(folder,".categories")
2203 if os.path.exists(categories_file_name):
2204 categories_file = open(categories_file_name,'r')
2205 categories = categories_file.readline()
2206 categories_file.close()
2207 categories = str.replace(categories,'\n','')
2208 categories = str.replace(categories,'\r','')
2209 return categories.split(',')
2210 else:
2211 folder = os.path.dirname(folder)
2212 continue
2213
Johnny Chena74bb0a2011-08-01 18:46:13 +00002214 def setUp(self):
2215 #import traceback
2216 #traceback.print_stack()
2217
2218 # Works with the test driver to conditionally skip tests via decorators.
2219 Base.setUp(self)
2220
Johnny Chena74bb0a2011-08-01 18:46:13 +00002221 try:
2222 if lldb.blacklist:
2223 className = self.__class__.__name__
2224 classAndMethodName = "%s.%s" % (className, self._testMethodName)
2225 if className in lldb.blacklist:
2226 self.skipTest(lldb.blacklist.get(className))
2227 elif classAndMethodName in lldb.blacklist:
2228 self.skipTest(lldb.blacklist.get(classAndMethodName))
2229 except AttributeError:
2230 pass
2231
Johnny Chened492022011-06-21 00:53:00 +00002232 # Insert some delay between successive test cases if specified.
2233 self.doDelay()
Johnny Chen0ed37c92010-10-07 02:04:14 +00002234
Johnny Chenf2b70232010-08-25 18:49:48 +00002235 if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
2236 self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
2237
Johnny Chen430eb762010-10-19 16:00:42 +00002238 if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
Johnny Chen4921b112010-11-29 20:20:34 +00002239 self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
Johnny Chenf2b70232010-08-25 18:49:48 +00002240
Daniel Maleae0f8f572013-08-26 23:57:52 +00002241 #
2242 # Warning: MAJOR HACK AHEAD!
2243 # If we are running testsuite remotely (by checking lldb.lldbtest_remote_sandbox),
2244 # redefine the self.dbg.CreateTarget(filename) method to execute a "file filename"
2245 # command, instead. See also runCmd() where it decorates the "file filename" call
2246 # with additional functionality when running testsuite remotely.
2247 #
2248 if lldb.lldbtest_remote_sandbox:
2249 def DecoratedCreateTarget(arg):
2250 self.runCmd("file %s" % arg)
2251 target = self.dbg.GetSelectedTarget()
2252 #
Greg Claytonc6947512013-12-13 19:18:59 +00002253 # SBtarget.LaunchSimple () currently not working for remote platform?
Daniel Maleae0f8f572013-08-26 23:57:52 +00002254 # johnny @ 04/23/2012
2255 #
2256 def DecoratedLaunchSimple(argv, envp, wd):
2257 self.runCmd("run")
2258 return target.GetProcess()
2259 target.LaunchSimple = DecoratedLaunchSimple
2260
2261 return target
2262 self.dbg.CreateTarget = DecoratedCreateTarget
2263 if self.TraceOn():
2264 print "self.dbg.Create is redefined to:\n%s" % getsource_if_available(DecoratedCreateTarget)
2265
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002266 # We want our debugger to be synchronous.
2267 self.dbg.SetAsync(False)
2268
2269 # Retrieve the associated command interpreter instance.
2270 self.ci = self.dbg.GetCommandInterpreter()
2271 if not self.ci:
2272 raise Exception('Could not get the command interpreter')
2273
2274 # And the result object.
2275 self.res = lldb.SBCommandReturnObject()
2276
Johnny Chen44d24972012-04-16 18:55:15 +00002277 # Run global pre-flight code, if defined via the config file.
2278 if lldb.pre_flight:
2279 lldb.pre_flight(self)
2280
Greg Claytonfb909312013-11-23 01:58:15 +00002281 if lldb.remote_platform:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00002282 remote_test_dir = lldbutil.join_remote_paths(
2283 lldb.remote_platform_working_dir,
2284 self.getArchitecture(),
2285 str(self.test_number),
2286 self.mydir)
Greg Claytonfb909312013-11-23 01:58:15 +00002287 error = lldb.remote_platform.MakeDirectory(remote_test_dir, 0700)
2288 if error.Success():
Greg Claytonfb909312013-11-23 01:58:15 +00002289 lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
2290 else:
2291 print "error: making remote directory '%s': %s" % (remote_test_dir, error)
2292
Greg Clayton35c91342014-11-17 18:40:27 +00002293 def registerSharedLibrariesWithTarget(self, target, shlibs):
2294 '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
2295
2296 Any modules in the target that have their remote install file specification set will
2297 get uploaded to the remote host. This function registers the local copies of the
2298 shared libraries with the target and sets their remote install locations so they will
2299 be uploaded when the target is run.
2300 '''
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00002301 if not shlibs or not self.platformContext:
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002302 return None
Greg Clayton35c91342014-11-17 18:40:27 +00002303
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002304 shlib_environment_var = self.platformContext.shlib_environment_var
2305 shlib_prefix = self.platformContext.shlib_prefix
2306 shlib_extension = '.' + self.platformContext.shlib_extension
2307
2308 working_dir = self.get_process_working_directory()
2309 environment = ['%s=%s' % (shlib_environment_var, working_dir)]
2310 # Add any shared libraries to our target if remote so they get
2311 # uploaded into the working directory on the remote side
2312 for name in shlibs:
2313 # The path can be a full path to a shared library, or a make file name like "Foo" for
2314 # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
2315 # basename like "libFoo.so". So figure out which one it is and resolve the local copy
2316 # of the shared library accordingly
2317 if os.path.exists(name):
2318 local_shlib_path = name # name is the full path to the local shared library
2319 else:
2320 # Check relative names
2321 local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
2322 if not os.path.exists(local_shlib_path):
2323 local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
Greg Clayton35c91342014-11-17 18:40:27 +00002324 if not os.path.exists(local_shlib_path):
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002325 local_shlib_path = os.path.join(os.getcwd(), name)
Greg Clayton35c91342014-11-17 18:40:27 +00002326
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002327 # Make sure we found the local shared library in the above code
2328 self.assertTrue(os.path.exists(local_shlib_path))
2329
2330 # Add the shared library to our target
2331 shlib_module = target.AddModule(local_shlib_path, None, None, None)
2332 if lldb.remote_platform:
Greg Clayton35c91342014-11-17 18:40:27 +00002333 # We must set the remote install location if we want the shared library
2334 # to get uploaded to the remote target
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00002335 remote_shlib_path = lldbutil.append_to_process_working_directory(os.path.basename(local_shlib_path))
Greg Clayton35c91342014-11-17 18:40:27 +00002336 shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002337
2338 return environment
2339
Enrico Granata44818162012-10-24 01:23:57 +00002340 # utility methods that tests can use to access the current objects
2341 def target(self):
2342 if not self.dbg:
2343 raise Exception('Invalid debugger instance')
2344 return self.dbg.GetSelectedTarget()
2345
2346 def process(self):
2347 if not self.dbg:
2348 raise Exception('Invalid debugger instance')
2349 return self.dbg.GetSelectedTarget().GetProcess()
2350
2351 def thread(self):
2352 if not self.dbg:
2353 raise Exception('Invalid debugger instance')
2354 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2355
2356 def frame(self):
2357 if not self.dbg:
2358 raise Exception('Invalid debugger instance')
2359 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
2360
Greg Claytonc6947512013-12-13 19:18:59 +00002361 def get_process_working_directory(self):
2362 '''Get the working directory that should be used when launching processes for local or remote processes.'''
2363 if lldb.remote_platform:
2364 # Remote tests set the platform working directory up in TestBase.setUp()
2365 return lldb.remote_platform.GetWorkingDirectory()
2366 else:
2367 # local tests change directory into each test subdirectory
2368 return os.getcwd()
2369
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002370 def tearDown(self):
Johnny Chen7d1d7532010-09-02 21:23:12 +00002371 #import traceback
2372 #traceback.print_stack()
2373
Johnny Chen3794ad92011-06-15 21:24:24 +00002374 # Delete the target(s) from the debugger as a general cleanup step.
2375 # This includes terminating the process for each target, if any.
2376 # We'd like to reuse the debugger for our next test without incurring
2377 # the initialization overhead.
2378 targets = []
2379 for target in self.dbg:
2380 if target:
2381 targets.append(target)
2382 process = target.GetProcess()
2383 if process:
2384 rc = self.invoke(process, "Kill")
2385 self.assertTrue(rc.Success(), PROCESS_KILLED)
2386 for target in targets:
2387 self.dbg.DeleteTarget(target)
Johnny Chen6ca006c2010-08-16 21:28:10 +00002388
Johnny Chen44d24972012-04-16 18:55:15 +00002389 # Run global post-flight code, if defined via the config file.
2390 if lldb.post_flight:
2391 lldb.post_flight(self)
2392
Zachary Turner65fe1eb2015-03-26 16:43:25 +00002393 # Do this last, to make sure it's in reverse order from how we setup.
2394 Base.tearDown(self)
2395
Zachary Turner95812042015-03-26 18:54:21 +00002396 # This must be the last statement, otherwise teardown hooks or other
2397 # lines might depend on this still being active.
2398 del self.dbg
2399
Johnny Chen86268e42011-09-30 21:48:35 +00002400 def switch_to_thread_with_stop_reason(self, stop_reason):
2401 """
2402 Run the 'thread list' command, and select the thread with stop reason as
2403 'stop_reason'. If no such thread exists, no select action is done.
2404 """
2405 from lldbutil import stop_reason_to_str
2406 self.runCmd('thread list')
2407 output = self.res.GetOutput()
2408 thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
2409 stop_reason_to_str(stop_reason))
2410 for line in output.splitlines():
2411 matched = thread_line_pattern.match(line)
2412 if matched:
2413 self.runCmd('thread select %s' % matched.group(1))
2414
Enrico Granata7594f142013-06-17 22:51:50 +00002415 def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
Johnny Chen27f212d2010-08-19 23:26:59 +00002416 """
2417 Ask the command interpreter to handle the command and then check its
2418 return status.
2419 """
2420 # Fail fast if 'cmd' is not meaningful.
2421 if not cmd or len(cmd) == 0:
2422 raise Exception("Bad 'cmd' parameter encountered")
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002423
Johnny Chen8d55a342010-08-31 17:42:54 +00002424 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002425
Daniel Maleae0f8f572013-08-26 23:57:52 +00002426 # This is an opportunity to insert the 'platform target-install' command if we are told so
2427 # via the settig of lldb.lldbtest_remote_sandbox.
2428 if cmd.startswith("target create "):
2429 cmd = cmd.replace("target create ", "file ")
2430 if cmd.startswith("file ") and lldb.lldbtest_remote_sandbox:
2431 with recording(self, trace) as sbuf:
2432 the_rest = cmd.split("file ")[1]
2433 # Split the rest of the command line.
2434 atoms = the_rest.split()
2435 #
2436 # NOTE: This assumes that the options, if any, follow the file command,
2437 # instead of follow the specified target.
2438 #
2439 target = atoms[-1]
2440 # Now let's get the absolute pathname of our target.
2441 abs_target = os.path.abspath(target)
2442 print >> sbuf, "Found a file command, target (with absolute pathname)=%s" % abs_target
2443 fpath, fname = os.path.split(abs_target)
2444 parent_dir = os.path.split(fpath)[0]
2445 platform_target_install_command = 'platform target-install %s %s' % (fpath, lldb.lldbtest_remote_sandbox)
2446 print >> sbuf, "Insert this command to be run first: %s" % platform_target_install_command
2447 self.ci.HandleCommand(platform_target_install_command, self.res)
2448 # And this is the file command we want to execute, instead.
2449 #
2450 # Warning: SIDE EFFECT AHEAD!!!
2451 # Populate the remote executable pathname into the lldb namespace,
2452 # so that test cases can grab this thing out of the namespace.
2453 #
2454 lldb.lldbtest_remote_sandboxed_executable = abs_target.replace(parent_dir, lldb.lldbtest_remote_sandbox)
2455 cmd = "file -P %s %s %s" % (lldb.lldbtest_remote_sandboxed_executable, the_rest.replace(target, ''), abs_target)
2456 print >> sbuf, "And this is the replaced file command: %s" % cmd
2457
Johnny Chen63dfb272010-09-01 00:15:19 +00002458 running = (cmd.startswith("run") or cmd.startswith("process launch"))
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002459
Johnny Chen63dfb272010-09-01 00:15:19 +00002460 for i in range(self.maxLaunchCount if running else 1):
Enrico Granata7594f142013-06-17 22:51:50 +00002461 self.ci.HandleCommand(cmd, self.res, inHistory)
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002462
Johnny Chen150c3cc2010-10-15 01:18:29 +00002463 with recording(self, trace) as sbuf:
2464 print >> sbuf, "runCmd:", cmd
Johnny Chenab254f52010-10-15 16:13:00 +00002465 if not check:
Johnny Chen27b107b2010-10-15 18:52:22 +00002466 print >> sbuf, "check of return status not required"
Johnny Chenf2b70232010-08-25 18:49:48 +00002467 if self.res.Succeeded():
Johnny Chen150c3cc2010-10-15 01:18:29 +00002468 print >> sbuf, "output:", self.res.GetOutput()
Johnny Chenf2b70232010-08-25 18:49:48 +00002469 else:
Johnny Chen150c3cc2010-10-15 01:18:29 +00002470 print >> sbuf, "runCmd failed!"
2471 print >> sbuf, self.res.GetError()
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002472
Johnny Chenff3d01d2010-08-20 21:03:09 +00002473 if self.res.Succeeded():
Johnny Chenf2b70232010-08-25 18:49:48 +00002474 break
Johnny Chen150c3cc2010-10-15 01:18:29 +00002475 elif running:
Johnny Chencf7f74e2011-01-19 02:02:08 +00002476 # For process launch, wait some time before possible next try.
2477 time.sleep(self.timeWaitNextLaunch)
Johnny Chen552d6712012-08-01 19:56:04 +00002478 with recording(self, trace) as sbuf:
Johnny Chen150c3cc2010-10-15 01:18:29 +00002479 print >> sbuf, "Command '" + cmd + "' failed!"
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002480
Johnny Chen27f212d2010-08-19 23:26:59 +00002481 if check:
Sean Callanan05834cd2015-07-01 23:56:30 +00002482 self.assertTrue(self.res.Succeeded(),
2483 msg if msg else CMD_MSG(cmd))
Johnny Chen27f212d2010-08-19 23:26:59 +00002484
Jim Ingham63dfc722012-09-22 00:05:11 +00002485 def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
2486 """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2487
2488 Otherwise, all the arguments have the same meanings as for the expect function"""
2489
2490 trace = (True if traceAlways else trace)
2491
2492 if exe:
2493 # First run the command. If we are expecting error, set check=False.
2494 # Pass the assert message along since it provides more semantic info.
2495 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
2496
2497 # Then compare the output against expected strings.
2498 output = self.res.GetError() if error else self.res.GetOutput()
2499
2500 # If error is True, the API client expects the command to fail!
2501 if error:
2502 self.assertFalse(self.res.Succeeded(),
2503 "Command '" + str + "' is expected to fail!")
2504 else:
2505 # No execution required, just compare str against the golden input.
2506 output = str
2507 with recording(self, trace) as sbuf:
2508 print >> sbuf, "looking at:", output
2509
2510 # The heading says either "Expecting" or "Not expecting".
2511 heading = "Expecting" if matching else "Not expecting"
2512
2513 for pattern in patterns:
2514 # Match Objects always have a boolean value of True.
2515 match_object = re.search(pattern, output)
2516 matched = bool(match_object)
2517 with recording(self, trace) as sbuf:
2518 print >> sbuf, "%s pattern: %s" % (heading, pattern)
2519 print >> sbuf, "Matched" if matched else "Not matched"
2520 if matched:
2521 break
2522
2523 self.assertTrue(matched if matching else not matched,
2524 msg if msg else EXP_MSG(str, exe))
2525
2526 return match_object
2527
Enrico Granata7594f142013-06-17 22:51:50 +00002528 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 +00002529 """
2530 Similar to runCmd; with additional expect style output matching ability.
2531
2532 Ask the command interpreter to handle the command and then check its
2533 return status. The 'msg' parameter specifies an informational assert
2534 message. We expect the output from running the command to start with
Johnny Chenea88e942010-09-21 21:08:53 +00002535 'startstr', matches the substrings contained in 'substrs', and regexp
2536 matches the patterns contained in 'patterns'.
Johnny Chenb3307862010-09-17 22:28:51 +00002537
2538 If the keyword argument error is set to True, it signifies that the API
2539 client is expecting the command to fail. In this case, the error stream
Johnny Chenaa902922010-09-17 22:45:27 +00002540 from running the command is retrieved and compared against the golden
Johnny Chenb3307862010-09-17 22:28:51 +00002541 input, instead.
Johnny Chenea88e942010-09-21 21:08:53 +00002542
2543 If the keyword argument matching is set to False, it signifies that the API
2544 client is expecting the output of the command not to match the golden
2545 input.
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002546
2547 Finally, the required argument 'str' represents the lldb command to be
2548 sent to the command interpreter. In case the keyword argument 'exe' is
2549 set to False, the 'str' is treated as a string to be matched/not-matched
2550 against the golden input.
Johnny Chen27f212d2010-08-19 23:26:59 +00002551 """
Johnny Chen8d55a342010-08-31 17:42:54 +00002552 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002553
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002554 if exe:
2555 # First run the command. If we are expecting error, set check=False.
Johnny Chen62d4f862010-10-28 21:10:32 +00002556 # Pass the assert message along since it provides more semantic info.
Enrico Granata7594f142013-06-17 22:51:50 +00002557 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error, inHistory=inHistory)
Johnny Chen27f212d2010-08-19 23:26:59 +00002558
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002559 # Then compare the output against expected strings.
2560 output = self.res.GetError() if error else self.res.GetOutput()
Johnny Chenb3307862010-09-17 22:28:51 +00002561
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002562 # If error is True, the API client expects the command to fail!
2563 if error:
2564 self.assertFalse(self.res.Succeeded(),
2565 "Command '" + str + "' is expected to fail!")
2566 else:
2567 # No execution required, just compare str against the golden input.
Enrico Granatabc08ab42012-10-23 00:09:02 +00002568 if isinstance(str,lldb.SBCommandReturnObject):
2569 output = str.GetOutput()
2570 else:
2571 output = str
Johnny Chen150c3cc2010-10-15 01:18:29 +00002572 with recording(self, trace) as sbuf:
2573 print >> sbuf, "looking at:", output
Johnny Chenb3307862010-09-17 22:28:51 +00002574
Johnny Chenea88e942010-09-21 21:08:53 +00002575 # The heading says either "Expecting" or "Not expecting".
Johnny Chen150c3cc2010-10-15 01:18:29 +00002576 heading = "Expecting" if matching else "Not expecting"
Johnny Chenea88e942010-09-21 21:08:53 +00002577
2578 # Start from the startstr, if specified.
2579 # If there's no startstr, set the initial state appropriately.
2580 matched = output.startswith(startstr) if startstr else (True if matching else False)
Johnny Chenb145bba2010-08-20 18:25:15 +00002581
Johnny Chen150c3cc2010-10-15 01:18:29 +00002582 if startstr:
2583 with recording(self, trace) as sbuf:
2584 print >> sbuf, "%s start string: %s" % (heading, startstr)
2585 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenb145bba2010-08-20 18:25:15 +00002586
Johnny Chen86268e42011-09-30 21:48:35 +00002587 # Look for endstr, if specified.
2588 keepgoing = matched if matching else not matched
2589 if endstr:
2590 matched = output.endswith(endstr)
2591 with recording(self, trace) as sbuf:
2592 print >> sbuf, "%s end string: %s" % (heading, endstr)
2593 print >> sbuf, "Matched" if matched else "Not matched"
2594
Johnny Chenea88e942010-09-21 21:08:53 +00002595 # Look for sub strings, if specified.
2596 keepgoing = matched if matching else not matched
2597 if substrs and keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002598 for str in substrs:
Johnny Chenb052f6c2010-09-23 23:35:28 +00002599 matched = output.find(str) != -1
Johnny Chen150c3cc2010-10-15 01:18:29 +00002600 with recording(self, trace) as sbuf:
2601 print >> sbuf, "%s sub string: %s" % (heading, str)
2602 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenea88e942010-09-21 21:08:53 +00002603 keepgoing = matched if matching else not matched
2604 if not keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002605 break
2606
Johnny Chenea88e942010-09-21 21:08:53 +00002607 # Search for regular expression patterns, if specified.
2608 keepgoing = matched if matching else not matched
2609 if patterns and keepgoing:
2610 for pattern in patterns:
2611 # Match Objects always have a boolean value of True.
2612 matched = bool(re.search(pattern, output))
Johnny Chen150c3cc2010-10-15 01:18:29 +00002613 with recording(self, trace) as sbuf:
2614 print >> sbuf, "%s pattern: %s" % (heading, pattern)
2615 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenea88e942010-09-21 21:08:53 +00002616 keepgoing = matched if matching else not matched
2617 if not keepgoing:
2618 break
Johnny Chenea88e942010-09-21 21:08:53 +00002619
2620 self.assertTrue(matched if matching else not matched,
Johnny Chenc0c67f22010-11-09 18:42:22 +00002621 msg if msg else EXP_MSG(str, exe))
Johnny Chen27f212d2010-08-19 23:26:59 +00002622
Johnny Chenf3c59232010-08-25 22:52:45 +00002623 def invoke(self, obj, name, trace=False):
Johnny Chen61703c92010-08-25 22:56:10 +00002624 """Use reflection to call a method dynamically with no argument."""
Johnny Chen8d55a342010-08-31 17:42:54 +00002625 trace = (True if traceAlways else trace)
Johnny Chenf3c59232010-08-25 22:52:45 +00002626
2627 method = getattr(obj, name)
2628 import inspect
2629 self.assertTrue(inspect.ismethod(method),
2630 name + "is a method name of object: " + str(obj))
2631 result = method()
Johnny Chen150c3cc2010-10-15 01:18:29 +00002632 with recording(self, trace) as sbuf:
2633 print >> sbuf, str(method) + ":", result
Johnny Chenf3c59232010-08-25 22:52:45 +00002634 return result
Johnny Chen827edff2010-08-27 00:15:48 +00002635
Johnny Chenf359cf22011-05-27 23:36:52 +00002636 # =================================================
2637 # Misc. helper methods for debugging test execution
2638 # =================================================
2639
Johnny Chen56b92a72011-07-11 19:15:11 +00002640 def DebugSBValue(self, val):
Johnny Chen8d55a342010-08-31 17:42:54 +00002641 """Debug print a SBValue object, if traceAlways is True."""
Johnny Chende90f1d2011-04-27 17:43:07 +00002642 from lldbutil import value_type_to_str
Johnny Chen87bb5892010-11-03 21:37:58 +00002643
Johnny Chen8d55a342010-08-31 17:42:54 +00002644 if not traceAlways:
Johnny Chen827edff2010-08-27 00:15:48 +00002645 return
2646
2647 err = sys.stderr
2648 err.write(val.GetName() + ":\n")
Johnny Chen86268e42011-09-30 21:48:35 +00002649 err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n')
2650 err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n')
2651 err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n')
2652 err.write('\t' + "Value -> " + str(val.GetValue()) + '\n')
2653 err.write('\t' + "ValueAsUnsigned -> " + str(val.GetValueAsUnsigned())+ '\n')
2654 err.write('\t' + "ValueType -> " + value_type_to_str(val.GetValueType()) + '\n')
2655 err.write('\t' + "Summary -> " + str(val.GetSummary()) + '\n')
2656 err.write('\t' + "IsPointerType -> " + str(val.TypeIsPointerType()) + '\n')
2657 err.write('\t' + "Location -> " + val.GetLocation() + '\n')
Johnny Chen827edff2010-08-27 00:15:48 +00002658
Johnny Chen36c5eb12011-08-05 20:17:27 +00002659 def DebugSBType(self, type):
2660 """Debug print a SBType object, if traceAlways is True."""
2661 if not traceAlways:
2662 return
2663
2664 err = sys.stderr
2665 err.write(type.GetName() + ":\n")
2666 err.write('\t' + "ByteSize -> " + str(type.GetByteSize()) + '\n')
2667 err.write('\t' + "IsPointerType -> " + str(type.IsPointerType()) + '\n')
2668 err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
2669
Johnny Chenb877f1e2011-03-12 01:18:19 +00002670 def DebugPExpect(self, child):
2671 """Debug the spwaned pexpect object."""
2672 if not traceAlways:
2673 return
2674
2675 print child
Filipe Cabecinhas0eec15a2012-06-20 10:13:40 +00002676
2677 @classmethod
2678 def RemoveTempFile(cls, file):
2679 if os.path.exists(file):
2680 os.remove(file)