blob: 11949865349f9e89d9fecd622accbd138a34d4b5 [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
Pavel Labath090152b2015-08-20 11:37:19 +0000701def matchAndroid(api_levels=None, archs=None):
702 def match(self):
703 if not target_is_android():
704 return False
705 if archs is not None and self.getArchitecture() not in archs:
706 return False
707 if api_levels is not None and android_device_api() not in api_levels:
708 return False
709 return True
710 return match
711
712
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000713def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
Siva Chandra8af91662015-06-05 00:22:49 +0000714 """ Mark a test as xfail for Android.
715
716 Arguments:
717 bugnumber - The LLVM pr associated with the problem.
718 api_levels - A sequence of numbers specifying the Android API levels
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000719 for which a test is expected to fail. None means all API level.
720 arch - A sequence of architecture names specifying the architectures
721 for which a test is expected to fail. None means all architectures.
Siva Chandra8af91662015-06-05 00:22:49 +0000722 """
Pavel Labath090152b2015-08-20 11:37:19 +0000723 return expectedFailure(matchAndroid(api_levels, archs), bugnumber)
Pavel Labath674bc7b2015-05-29 14:54:46 +0000724
Vince Harron7ac3ea42015-06-26 15:13:21 +0000725# if the test passes on the first try, we're done (success)
726# if the test fails once, then passes on the second try, raise an ExpectedFailure
727# if the test fails twice in a row, re-throw the exception from the second test run
728def expectedFlakey(expected_fn, bugnumber=None):
729 def expectedFailure_impl(func):
730 @wraps(func)
731 def wrapper(*args, **kwargs):
732 from unittest2 import case
733 self = args[0]
734 try:
735 func(*args, **kwargs)
Ying Chen0a7202b2015-07-01 22:44:27 +0000736 # don't retry if the test case is already decorated with xfail or skip
737 except (case._ExpectedFailure, case.SkipTest, case._UnexpectedSuccess):
738 raise
Vince Harron7ac3ea42015-06-26 15:13:21 +0000739 except Exception:
740 if expected_fn(self):
Ying Chen0a7202b2015-07-01 22:44:27 +0000741 # before retry, run tearDown for previous run and setup for next
Vince Harron7ac3ea42015-06-26 15:13:21 +0000742 try:
Ying Chen0a7202b2015-07-01 22:44:27 +0000743 self.tearDown()
744 self.setUp()
Vince Harron7ac3ea42015-06-26 15:13:21 +0000745 func(*args, **kwargs)
746 except Exception:
747 # oh snap! two failures in a row, record a failure/error
748 raise
749 # record the expected failure
750 raise case._ExpectedFailure(sys.exc_info(), bugnumber)
751 else:
752 raise
753 return wrapper
754 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
755 # return decorator in this case, so it will be used to decorating original method
756 if callable(bugnumber):
757 return expectedFailure_impl(bugnumber)
758 else:
759 return expectedFailure_impl
760
761def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
762 def fn(self):
763 return (self.getPlatform() in oslist and
764 self.expectedCompiler(compilers))
765 return expectedFlakey(fn, bugnumber)
766
767def expectedFlakeyDarwin(bugnumber=None, compilers=None):
768 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
769 return expectedFlakeyOS(getDarwinOSTriples(), bugnumber, compilers)
770
771def expectedFlakeyLinux(bugnumber=None, compilers=None):
772 return expectedFlakeyOS(['linux'], bugnumber, compilers)
773
774def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
775 return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
776
777def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
778 if compiler_version is None:
779 compiler_version=['=', None]
780 def fn(self):
781 return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
782 return expectedFlakey(fn, bugnumber)
783
784# @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
785def expectedFlakeyClang(bugnumber=None, compiler_version=None):
786 return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
787
788# @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
789def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
790 return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
791
Pavel Labath63a579c2015-09-07 12:15:27 +0000792def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
793 return expectedFlakey(matchAndroid(api_levels, archs), bugnumber)
794
Greg Clayton12514562013-12-05 22:22:32 +0000795def skipIfRemote(func):
796 """Decorate the item to skip tests if testing remotely."""
797 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
798 raise Exception("@skipIfRemote can only be used to decorate a test method")
799 @wraps(func)
800 def wrapper(*args, **kwargs):
801 from unittest2 import case
802 if lldb.remote_platform:
803 self = args[0]
804 self.skipTest("skip on remote platform")
805 else:
806 func(*args, **kwargs)
807 return wrapper
808
Siva Chandra4470f382015-06-17 22:32:27 +0000809def skipUnlessListedRemote(remote_list=None):
810 def myImpl(func):
811 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
812 raise Exception("@skipIfRemote can only be used to decorate a "
813 "test method")
814
815 @wraps(func)
816 def wrapper(*args, **kwargs):
817 if remote_list and lldb.remote_platform:
818 self = args[0]
819 triple = self.dbg.GetSelectedPlatform().GetTriple()
820 for r in remote_list:
821 if r in triple:
822 func(*args, **kwargs)
823 return
824 self.skipTest("skip on remote platform %s" % str(triple))
825 else:
826 func(*args, **kwargs)
827 return wrapper
828
829 return myImpl
830
Greg Clayton12514562013-12-05 22:22:32 +0000831def skipIfRemoteDueToDeadlock(func):
832 """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
833 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
834 raise Exception("@skipIfRemote can only be used to decorate a test method")
835 @wraps(func)
836 def wrapper(*args, **kwargs):
837 from unittest2 import case
838 if lldb.remote_platform:
839 self = args[0]
840 self.skipTest("skip on remote platform (deadlocks)")
841 else:
842 func(*args, **kwargs)
843 return wrapper
844
Enrico Granatab633e432014-10-06 21:37:06 +0000845def skipIfNoSBHeaders(func):
846 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
847 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Ed Maste59cca5d2014-10-07 01:57:52 +0000848 raise Exception("@skipIfNoSBHeaders can only be used to decorate a test method")
Enrico Granatab633e432014-10-06 21:37:06 +0000849 @wraps(func)
850 def wrapper(*args, **kwargs):
851 from unittest2 import case
852 self = args[0]
Shawn Best181b09b2014-11-08 00:04:04 +0000853 if sys.platform.startswith("darwin"):
854 header = os.path.join(self.lib_dir, 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
855 else:
856 header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
Enrico Granatab633e432014-10-06 21:37:06 +0000857 platform = sys.platform
Enrico Granatab633e432014-10-06 21:37:06 +0000858 if not os.path.exists(header):
859 self.skipTest("skip because LLDB.h header not found")
860 else:
861 func(*args, **kwargs)
862 return wrapper
863
Robert Flack13c7ad92015-03-30 14:12:17 +0000864def skipIfFreeBSD(func):
865 """Decorate the item to skip tests that should be skipped on FreeBSD."""
866 return skipIfPlatform(["freebsd"])(func)
Zachary Turnerc7826522014-08-13 17:44:53 +0000867
Greg Claytone0d0a762015-04-02 18:24:03 +0000868def getDarwinOSTriples():
869 return ['darwin', 'macosx', 'ios']
870
Daniel Maleab3d41a22013-07-09 00:08:01 +0000871def skipIfDarwin(func):
872 """Decorate the item to skip tests that should be skipped on Darwin."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000873 return skipIfPlatform(getDarwinOSTriples())(func)
Daniel Maleab3d41a22013-07-09 00:08:01 +0000874
Robert Flack13c7ad92015-03-30 14:12:17 +0000875def skipIfLinux(func):
876 """Decorate the item to skip tests that should be skipped on Linux."""
877 return skipIfPlatform(["linux"])(func)
878
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000879def skipUnlessHostLinux(func):
880 """Decorate the item to skip tests that should be skipped on any non Linux host."""
881 return skipUnlessHostPlatform(["linux"])(func)
882
Robert Flack13c7ad92015-03-30 14:12:17 +0000883def skipIfWindows(func):
884 """Decorate the item to skip tests that should be skipped on Windows."""
885 return skipIfPlatform(["windows"])(func)
886
Chaoren Line6eea5d2015-06-08 22:13:28 +0000887def skipIfHostWindows(func):
888 """Decorate the item to skip tests that should be skipped on Windows."""
889 return skipIfHostPlatform(["windows"])(func)
890
Robert Flack13c7ad92015-03-30 14:12:17 +0000891def skipUnlessDarwin(func):
892 """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000893 return skipUnlessPlatform(getDarwinOSTriples())(func)
Robert Flack13c7ad92015-03-30 14:12:17 +0000894
Robert Flack068898c2015-04-09 18:07:58 +0000895def getPlatform():
Robert Flack6e1fd352015-05-15 12:39:33 +0000896 """Returns the target platform which the tests are running on."""
Robert Flack068898c2015-04-09 18:07:58 +0000897 platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
898 if platform.startswith('freebsd'):
899 platform = 'freebsd'
900 return platform
901
Robert Flack6e1fd352015-05-15 12:39:33 +0000902def getHostPlatform():
903 """Returns the host platform running the test suite."""
904 # Attempts to return a platform name matching a target Triple platform.
905 if sys.platform.startswith('linux'):
906 return 'linux'
907 elif sys.platform.startswith('win32'):
908 return 'windows'
909 elif sys.platform.startswith('darwin'):
910 return 'darwin'
911 elif sys.platform.startswith('freebsd'):
912 return 'freebsd'
913 else:
914 return sys.platform
915
Robert Flackfb2f6c62015-04-17 08:02:18 +0000916def platformIsDarwin():
917 """Returns true if the OS triple for the selected platform is any valid apple OS"""
918 return getPlatform() in getDarwinOSTriples()
919
Robert Flack6e1fd352015-05-15 12:39:33 +0000920def skipIfHostIncompatibleWithRemote(func):
921 """Decorate the item to skip tests if binaries built on this host are incompatible."""
922 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
923 raise Exception("@skipIfHostIncompatibleWithRemote can only be used to decorate a test method")
924 @wraps(func)
925 def wrapper(*args, **kwargs):
926 from unittest2 import case
927 self = args[0]
928 host_arch = self.getLldbArchitecture()
929 host_platform = getHostPlatform()
930 target_arch = self.getArchitecture()
Robert Flack4629c4b2015-05-15 18:54:32 +0000931 target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
Robert Flack6e1fd352015-05-15 12:39:33 +0000932 if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
933 self.skipTest("skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch))
934 elif target_platform != host_platform:
935 self.skipTest("skipping because target is %s but host is %s" % (target_platform, host_platform))
936 else:
937 func(*args, **kwargs)
938 return wrapper
939
Chaoren Line6eea5d2015-06-08 22:13:28 +0000940def skipIfHostPlatform(oslist):
941 """Decorate the item to skip tests if running on one of the listed host platforms."""
942 return unittest2.skipIf(getHostPlatform() in oslist,
943 "skip on %s" % (", ".join(oslist)))
944
945def skipUnlessHostPlatform(oslist):
946 """Decorate the item to skip tests unless running on one of the listed host platforms."""
947 return unittest2.skipUnless(getHostPlatform() in oslist,
948 "requires on of %s" % (", ".join(oslist)))
949
Zachary Turner793d9972015-08-14 23:29:24 +0000950def skipUnlessArch(archlist):
951 """Decorate the item to skip tests unless running on one of the listed architectures."""
952 def myImpl(func):
953 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
954 raise Exception("@skipUnlessArch can only be used to decorate a test method")
955
956 @wraps(func)
957 def wrapper(*args, **kwargs):
958 self = args[0]
959 if self.getArchitecture() not in archlist:
960 self.skipTest("skipping for architecture %s (requires one of %s)" %
961 (self.getArchitecture(), ", ".join(archlist)))
962 else:
963 func(*args, **kwargs)
964 return wrapper
965
966 return myImpl
967
Robert Flack13c7ad92015-03-30 14:12:17 +0000968def skipIfPlatform(oslist):
969 """Decorate the item to skip tests if running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +0000970 return unittest2.skipIf(getPlatform() in oslist,
971 "skip on %s" % (", ".join(oslist)))
Robert Flack13c7ad92015-03-30 14:12:17 +0000972
973def skipUnlessPlatform(oslist):
974 """Decorate the item to skip tests unless running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +0000975 return unittest2.skipUnless(getPlatform() in oslist,
976 "requires on of %s" % (", ".join(oslist)))
Daniel Maleab3d41a22013-07-09 00:08:01 +0000977
Daniel Malea48359902013-05-14 20:48:54 +0000978def skipIfLinuxClang(func):
979 """Decorate the item to skip tests that should be skipped if building on
980 Linux with clang.
981 """
982 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
983 raise Exception("@skipIfLinuxClang can only be used to decorate a test method")
984 @wraps(func)
985 def wrapper(*args, **kwargs):
986 from unittest2 import case
987 self = args[0]
988 compiler = self.getCompiler()
Vince Harronc8492672015-05-04 02:59:19 +0000989 platform = self.getPlatform()
990 if "clang" in compiler and platform == "linux":
Daniel Malea48359902013-05-14 20:48:54 +0000991 self.skipTest("skipping because Clang is used on Linux")
992 else:
993 func(*args, **kwargs)
994 return wrapper
995
Ying Chen7091c2c2015-04-21 01:15:47 +0000996# provide a function to skip on defined oslist, compiler version, and archs
997# if none is specified for any argument, that argument won't be checked and thus means for all
998# for example,
999# @skipIf, skip for all platform/compiler/arch,
1000# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
1001# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
1002
1003# TODO: refactor current code, to make skipIfxxx functions to call this function
1004def skipIf(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None):
1005 def fn(self):
1006 return ((oslist is None or self.getPlatform() in oslist) and
1007 (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
1008 self.expectedArch(archs))
1009 return skipTestIfFn(fn, bugnumber, skipReason="skipping because os:%s compiler: %s %s arch: %s"%(oslist, compiler, compiler_version, archs))
1010
1011def skipTestIfFn(expected_fn, bugnumber=None, skipReason=None):
1012 def skipTestIfFn_impl(func):
1013 @wraps(func)
1014 def wrapper(*args, **kwargs):
1015 from unittest2 import case
1016 self = args[0]
1017 if expected_fn(self):
1018 self.skipTest(skipReason)
1019 else:
1020 func(*args, **kwargs)
1021 return wrapper
1022 if callable(bugnumber):
1023 return skipTestIfFn_impl(bugnumber)
1024 else:
1025 return skipTestIfFn_impl
1026
Daniel Maleabe230792013-01-24 23:52:09 +00001027def skipIfGcc(func):
1028 """Decorate the item to skip tests that should be skipped if building with gcc ."""
1029 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Daniel Malea0aea0162013-02-27 17:29:46 +00001030 raise Exception("@skipIfGcc can only be used to decorate a test method")
Daniel Maleabe230792013-01-24 23:52:09 +00001031 @wraps(func)
1032 def wrapper(*args, **kwargs):
1033 from unittest2 import case
1034 self = args[0]
1035 compiler = self.getCompiler()
1036 if "gcc" in compiler:
1037 self.skipTest("skipping because gcc is the test compiler")
1038 else:
1039 func(*args, **kwargs)
1040 return wrapper
1041
Matt Kopec0de53f02013-03-15 19:10:12 +00001042def skipIfIcc(func):
1043 """Decorate the item to skip tests that should be skipped if building with icc ."""
1044 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1045 raise Exception("@skipIfIcc can only be used to decorate a test method")
1046 @wraps(func)
1047 def wrapper(*args, **kwargs):
1048 from unittest2 import case
1049 self = args[0]
1050 compiler = self.getCompiler()
1051 if "icc" in compiler:
1052 self.skipTest("skipping because icc is the test compiler")
1053 else:
1054 func(*args, **kwargs)
1055 return wrapper
1056
Daniel Malea55faa402013-05-02 21:44:31 +00001057def skipIfi386(func):
1058 """Decorate the item to skip tests that should be skipped if building 32-bit."""
1059 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1060 raise Exception("@skipIfi386 can only be used to decorate a test method")
1061 @wraps(func)
1062 def wrapper(*args, **kwargs):
1063 from unittest2 import case
1064 self = args[0]
1065 if "i386" == self.getArchitecture():
1066 self.skipTest("skipping because i386 is not a supported architecture")
1067 else:
1068 func(*args, **kwargs)
1069 return wrapper
1070
Pavel Labath090152b2015-08-20 11:37:19 +00001071def skipIfTargetAndroid(api_levels=None, archs=None):
Siva Chandra77f20fc2015-06-05 19:54:49 +00001072 """Decorator to skip tests when the target is Android.
1073
1074 Arguments:
1075 api_levels - The API levels for which the test should be skipped. If
1076 it is None, then the test will be skipped for all API levels.
Pavel Labath090152b2015-08-20 11:37:19 +00001077 arch - A sequence of architecture names specifying the architectures
1078 for which a test is skipped. None means all architectures.
Siva Chandra77f20fc2015-06-05 19:54:49 +00001079 """
1080 def myImpl(func):
1081 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1082 raise Exception("@skipIfTargetAndroid can only be used to "
1083 "decorate a test method")
1084 @wraps(func)
1085 def wrapper(*args, **kwargs):
1086 from unittest2 import case
1087 self = args[0]
Pavel Labath090152b2015-08-20 11:37:19 +00001088 if matchAndroid(api_levels, archs)(self):
1089 self.skipTest("skiped on Android target with API %d and architecture %s" %
1090 (android_device_api(), self.getArchitecture()))
Tamas Berghammer1253a812015-03-13 10:12:25 +00001091 func(*args, **kwargs)
Siva Chandra77f20fc2015-06-05 19:54:49 +00001092 return wrapper
1093 return myImpl
Tamas Berghammer1253a812015-03-13 10:12:25 +00001094
Ilia Kd9953052015-03-12 07:19:41 +00001095def skipUnlessCompilerRt(func):
1096 """Decorate the item to skip tests if testing remotely."""
1097 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1098 raise Exception("@skipUnless can only be used to decorate a test method")
1099 @wraps(func)
1100 def wrapper(*args, **kwargs):
1101 from unittest2 import case
1102 import os.path
1103 compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "projects", "compiler-rt")
1104 if not os.path.exists(compilerRtPath):
1105 self = args[0]
1106 self.skipTest("skip if compiler-rt not found")
1107 else:
1108 func(*args, **kwargs)
1109 return wrapper
Daniel Malea55faa402013-05-02 21:44:31 +00001110
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001111class _PlatformContext(object):
1112 """Value object class which contains platform-specific options."""
1113
1114 def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
1115 self.shlib_environment_var = shlib_environment_var
1116 self.shlib_prefix = shlib_prefix
1117 self.shlib_extension = shlib_extension
1118
1119
Johnny Chena74bb0a2011-08-01 18:46:13 +00001120class Base(unittest2.TestCase):
Johnny Chen8334dad2010-10-22 23:15:46 +00001121 """
Johnny Chena74bb0a2011-08-01 18:46:13 +00001122 Abstract base for performing lldb (see TestBase) or other generic tests (see
1123 BenchBase for one example). lldbtest.Base works with the test driver to
1124 accomplish things.
1125
Johnny Chen8334dad2010-10-22 23:15:46 +00001126 """
Enrico Granata5020f952012-10-24 21:42:49 +00001127
Enrico Granata19186272012-10-24 21:44:48 +00001128 # The concrete subclass should override this attribute.
1129 mydir = None
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001130
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001131 # Keep track of the old current working directory.
1132 oldcwd = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001133
Greg Clayton4570d3e2013-12-10 23:19:29 +00001134 @staticmethod
1135 def compute_mydir(test_file):
1136 '''Subclasses should call this function to correctly calculate the required "mydir" attribute as follows:
1137
1138 mydir = TestBase.compute_mydir(__file__)'''
1139 test_dir = os.path.dirname(test_file)
1140 return test_dir[len(os.environ["LLDB_TEST"])+1:]
1141
Johnny Chenfb4264c2011-08-01 19:50:58 +00001142 def TraceOn(self):
1143 """Returns True if we are in trace mode (tracing detailed test execution)."""
1144 return traceAlways
Greg Clayton4570d3e2013-12-10 23:19:29 +00001145
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001146 @classmethod
1147 def setUpClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001148 """
1149 Python unittest framework class setup fixture.
1150 Do current directory manipulation.
1151 """
Johnny Chenf02ec122010-07-03 20:41:42 +00001152 # Fail fast if 'mydir' attribute is not overridden.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001153 if not cls.mydir or len(cls.mydir) == 0:
Johnny Chenf02ec122010-07-03 20:41:42 +00001154 raise Exception("Subclasses must override the 'mydir' attribute.")
Enrico Granata7e137e32012-10-24 18:14:21 +00001155
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001156 # Save old working directory.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001157 cls.oldcwd = os.getcwd()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001158
1159 # Change current working directory if ${LLDB_TEST} is defined.
1160 # See also dotest.py which sets up ${LLDB_TEST}.
1161 if ("LLDB_TEST" in os.environ):
Vince Harron85d19652015-05-21 19:09:29 +00001162 full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001163 if traceAlways:
Vince Harron85d19652015-05-21 19:09:29 +00001164 print >> sys.stderr, "Change dir to:", full_dir
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001165 os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
1166
Vince Harron85d19652015-05-21 19:09:29 +00001167 if debug_confirm_directory_exclusivity:
Zachary Turnerb48b4042015-05-21 20:16:02 +00001168 import lock
Vince Harron85d19652015-05-21 19:09:29 +00001169 cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
1170 try:
1171 cls.dir_lock.try_acquire()
1172 # write the class that owns the lock into the lock file
1173 cls.dir_lock.handle.write(cls.__name__)
1174 except IOError as ioerror:
1175 # nothing else should have this directory lock
1176 # wait here until we get a lock
1177 cls.dir_lock.acquire()
1178 # read the previous owner from the lock file
1179 lock_id = cls.dir_lock.handle.read()
1180 print >> sys.stderr, "LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id)
1181 raise ioerror
1182
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001183 # Set platform context.
Robert Flackfb2f6c62015-04-17 08:02:18 +00001184 if platformIsDarwin():
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001185 cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
Robert Flackfb2f6c62015-04-17 08:02:18 +00001186 elif getPlatform() == "linux" or getPlatform() == "freebsd":
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001187 cls.platformContext = _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001188 else:
1189 cls.platformContext = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001190
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001191 @classmethod
1192 def tearDownClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001193 """
1194 Python unittest framework class teardown fixture.
1195 Do class-wide cleanup.
1196 """
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001197
Johnny Chen0fddfb22011-11-17 19:57:27 +00001198 if doCleanup and not lldb.skip_build_and_cleanup:
Johnny Chen707b3c92010-10-11 22:25:46 +00001199 # First, let's do the platform-specific cleanup.
Peter Collingbourne19f48d52011-06-20 19:06:20 +00001200 module = builder_module()
Zachary Turnerb1490b62015-08-26 19:44:56 +00001201 module.cleanup()
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001202
Johnny Chen707b3c92010-10-11 22:25:46 +00001203 # Subclass might have specific cleanup function defined.
1204 if getattr(cls, "classCleanup", None):
1205 if traceAlways:
1206 print >> sys.stderr, "Call class-specific cleanup function for class:", cls
1207 try:
1208 cls.classCleanup()
1209 except:
1210 exc_type, exc_value, exc_tb = sys.exc_info()
1211 traceback.print_exception(exc_type, exc_value, exc_tb)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001212
Vince Harron85d19652015-05-21 19:09:29 +00001213 if debug_confirm_directory_exclusivity:
1214 cls.dir_lock.release()
1215 del cls.dir_lock
1216
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001217 # Restore old working directory.
1218 if traceAlways:
Johnny Chen703dbd02010-09-30 17:06:24 +00001219 print >> sys.stderr, "Restore dir to:", cls.oldcwd
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001220 os.chdir(cls.oldcwd)
1221
Johnny Chena74bb0a2011-08-01 18:46:13 +00001222 @classmethod
1223 def skipLongRunningTest(cls):
1224 """
1225 By default, we skip long running test case.
1226 This can be overridden by passing '-l' to the test driver (dotest.py).
1227 """
1228 if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
1229 return False
1230 else:
1231 return True
Johnny Chened492022011-06-21 00:53:00 +00001232
Vince Harron6d3d0f12015-05-10 22:01:59 +00001233 def enableLogChannelsForCurrentTest(self):
1234 if len(lldbtest_config.channels) == 0:
1235 return
1236
1237 # if debug channels are specified in lldbtest_config.channels,
1238 # create a new set of log files for every test
1239 log_basename = self.getLogBasenameForCurrentTest()
1240
1241 # confirm that the file is writeable
1242 host_log_path = "{}-host.log".format(log_basename)
1243 open(host_log_path, 'w').close()
1244
1245 log_enable = "log enable -Tpn -f {} ".format(host_log_path)
1246 for channel_with_categories in lldbtest_config.channels:
1247 channel_then_categories = channel_with_categories.split(' ', 1)
1248 channel = channel_then_categories[0]
1249 if len(channel_then_categories) > 1:
1250 categories = channel_then_categories[1]
1251 else:
1252 categories = "default"
1253
1254 if channel == "gdb-remote":
1255 # communicate gdb-remote categories to debugserver
1256 os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
1257
1258 self.ci.HandleCommand(log_enable + channel_with_categories, self.res)
1259 if not self.res.Succeeded():
1260 raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
1261
1262 # Communicate log path name to debugserver & lldb-server
1263 server_log_path = "{}-server.log".format(log_basename)
1264 open(server_log_path, 'w').close()
1265 os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
1266
1267 # Communicate channels to lldb-server
1268 os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
1269
1270 if len(lldbtest_config.channels) == 0:
1271 return
1272
1273 def disableLogChannelsForCurrentTest(self):
1274 # close all log files that we opened
1275 for channel_and_categories in lldbtest_config.channels:
1276 # channel format - <channel-name> [<category0> [<category1> ...]]
1277 channel = channel_and_categories.split(' ', 1)[0]
1278 self.ci.HandleCommand("log disable " + channel, self.res)
1279 if not self.res.Succeeded():
1280 raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
1281
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001282 def setUp(self):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001283 """Fixture for unittest test case setup.
1284
1285 It works with the test driver to conditionally skip tests and does other
1286 initializations."""
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001287 #import traceback
1288 #traceback.print_stack()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001289
Daniel Malea9115f072013-08-06 15:02:32 +00001290 if "LIBCXX_PATH" in os.environ:
1291 self.libcxxPath = os.environ["LIBCXX_PATH"]
1292 else:
1293 self.libcxxPath = None
1294
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001295 if "LLDBMI_EXEC" in os.environ:
1296 self.lldbMiExec = os.environ["LLDBMI_EXEC"]
1297 else:
1298 self.lldbMiExec = None
1299 self.dont_do_lldbmi_test = True
Vince Harron790d95c2015-05-18 19:39:03 +00001300
Johnny Chenebe51722011-10-07 19:21:09 +00001301 # If we spawn an lldb process for test (via pexpect), do not load the
1302 # init file unless told otherwise.
1303 if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
1304 self.lldbOption = ""
1305 else:
1306 self.lldbOption = "--no-lldbinit"
Johnny Chenaaa82ff2011-08-02 22:54:37 +00001307
Johnny Chen985e7402011-08-01 21:13:26 +00001308 # Assign the test method name to self.testMethodName.
1309 #
1310 # For an example of the use of this attribute, look at test/types dir.
1311 # There are a bunch of test cases under test/types and we don't want the
1312 # module cacheing subsystem to be confused with executable name "a.out"
1313 # used for all the test cases.
1314 self.testMethodName = self._testMethodName
1315
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001316 # Python API only test is decorated with @python_api_test,
1317 # which also sets the "__python_api_test__" attribute of the
1318 # function object to True.
Johnny Chen4533dad2011-05-31 23:21:42 +00001319 try:
1320 if lldb.just_do_python_api_test:
1321 testMethod = getattr(self, self._testMethodName)
1322 if getattr(testMethod, "__python_api_test__", False):
1323 pass
1324 else:
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001325 self.skipTest("non python api test")
1326 except AttributeError:
1327 pass
1328
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001329 # lldb-mi only test is decorated with @lldbmi_test,
1330 # which also sets the "__lldbmi_test__" attribute of the
1331 # function object to True.
1332 try:
1333 if lldb.just_do_lldbmi_test:
1334 testMethod = getattr(self, self._testMethodName)
1335 if getattr(testMethod, "__lldbmi_test__", False):
1336 pass
1337 else:
1338 self.skipTest("non lldb-mi test")
1339 except AttributeError:
1340 pass
1341
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001342 # Benchmarks test is decorated with @benchmarks_test,
1343 # which also sets the "__benchmarks_test__" attribute of the
1344 # function object to True.
1345 try:
1346 if lldb.just_do_benchmarks_test:
1347 testMethod = getattr(self, self._testMethodName)
1348 if getattr(testMethod, "__benchmarks_test__", False):
1349 pass
1350 else:
1351 self.skipTest("non benchmarks test")
Johnny Chen4533dad2011-05-31 23:21:42 +00001352 except AttributeError:
1353 pass
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001354
Johnny Chen985e7402011-08-01 21:13:26 +00001355 # This is for the case of directly spawning 'lldb'/'gdb' and interacting
1356 # with it using pexpect.
1357 self.child = None
1358 self.child_prompt = "(lldb) "
1359 # If the child is interacting with the embedded script interpreter,
1360 # there are two exits required during tear down, first to quit the
1361 # embedded script interpreter and second to quit the lldb command
1362 # interpreter.
1363 self.child_in_script_interpreter = False
1364
Johnny Chenfb4264c2011-08-01 19:50:58 +00001365 # These are for customized teardown cleanup.
1366 self.dict = None
1367 self.doTearDownCleanup = False
1368 # And in rare cases where there are multiple teardown cleanups.
1369 self.dicts = []
1370 self.doTearDownCleanups = False
1371
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001372 # List of spawned subproces.Popen objects
1373 self.subprocesses = []
1374
Daniel Malea69207462013-06-05 21:07:02 +00001375 # List of forked process PIDs
1376 self.forkedProcessPids = []
1377
Johnny Chenfb4264c2011-08-01 19:50:58 +00001378 # Create a string buffer to record the session info, to be dumped into a
1379 # test case specific file if test failure is encountered.
Vince Harron1f160372015-05-21 18:51:20 +00001380 self.log_basename = self.getLogBasenameForCurrentTest()
Vince Harron35b17dc2015-05-21 18:20:21 +00001381
Vince Harron1f160372015-05-21 18:51:20 +00001382 session_file = "{}.log".format(self.log_basename)
Vince Harron35b17dc2015-05-21 18:20:21 +00001383 unbuffered = 0 # 0 is the constant for unbuffered
Vince Harron1f160372015-05-21 18:51:20 +00001384 self.session = open(session_file, "w", unbuffered)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001385
1386 # Optimistically set __errored__, __failed__, __expected__ to False
1387 # initially. If the test errored/failed, the session info
1388 # (self.session) is then dumped into a session specific file for
1389 # diagnosis.
Zachary Turnerb1490b62015-08-26 19:44:56 +00001390 self.__cleanup_errored__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001391 self.__errored__ = False
1392 self.__failed__ = False
1393 self.__expected__ = False
1394 # We are also interested in unexpected success.
1395 self.__unexpected__ = False
Johnny Chenf79b0762011-08-16 00:48:58 +00001396 # And skipped tests.
1397 self.__skipped__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001398
1399 # See addTearDownHook(self, hook) which allows the client to add a hook
1400 # function to be run during tearDown() time.
1401 self.hooks = []
1402
1403 # See HideStdout(self).
1404 self.sys_stdout_hidden = False
1405
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001406 if self.platformContext:
1407 # set environment variable names for finding shared libraries
1408 self.dylibPath = self.platformContext.shlib_environment_var
Daniel Malea179ff292012-11-26 21:21:11 +00001409
Vince Harron6d3d0f12015-05-10 22:01:59 +00001410 # Create the debugger instance if necessary.
1411 try:
1412 self.dbg = lldb.DBG
1413 except AttributeError:
1414 self.dbg = lldb.SBDebugger.Create()
1415
1416 if not self.dbg:
1417 raise Exception('Invalid debugger instance')
1418
1419 # Retrieve the associated command interpreter instance.
1420 self.ci = self.dbg.GetCommandInterpreter()
1421 if not self.ci:
1422 raise Exception('Could not get the command interpreter')
1423
1424 # And the result object.
1425 self.res = lldb.SBCommandReturnObject()
1426
1427 self.enableLogChannelsForCurrentTest()
1428
Johnny Chen2a808582011-10-19 16:48:07 +00001429 def runHooks(self, child=None, child_prompt=None, use_cmd_api=False):
Johnny Chena737ba52011-10-19 01:06:21 +00001430 """Perform the run hooks to bring lldb debugger to the desired state.
1431
Johnny Chen2a808582011-10-19 16:48:07 +00001432 By default, expect a pexpect spawned child and child prompt to be
1433 supplied (use_cmd_api=False). If use_cmd_api is true, ignore the child
1434 and child prompt and use self.runCmd() to run the hooks one by one.
1435
Johnny Chena737ba52011-10-19 01:06:21 +00001436 Note that child is a process spawned by pexpect.spawn(). If not, your
1437 test case is mostly likely going to fail.
1438
1439 See also dotest.py where lldb.runHooks are processed/populated.
1440 """
1441 if not lldb.runHooks:
1442 self.skipTest("No runhooks specified for lldb, skip the test")
Johnny Chen2a808582011-10-19 16:48:07 +00001443 if use_cmd_api:
1444 for hook in lldb.runhooks:
1445 self.runCmd(hook)
1446 else:
1447 if not child or not child_prompt:
1448 self.fail("Both child and child_prompt need to be defined.")
1449 for hook in lldb.runHooks:
1450 child.sendline(hook)
1451 child.expect_exact(child_prompt)
Johnny Chena737ba52011-10-19 01:06:21 +00001452
Daniel Malea249287a2013-02-19 16:08:57 +00001453 def setAsync(self, value):
1454 """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
1455 old_async = self.dbg.GetAsync()
1456 self.dbg.SetAsync(value)
1457 self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
1458
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001459 def cleanupSubprocesses(self):
1460 # Ensure any subprocesses are cleaned up
1461 for p in self.subprocesses:
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001462 p.terminate()
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001463 del p
1464 del self.subprocesses[:]
Daniel Malea69207462013-06-05 21:07:02 +00001465 # Ensure any forked processes are cleaned up
1466 for pid in self.forkedProcessPids:
1467 if os.path.exists("/proc/" + str(pid)):
1468 os.kill(pid, signal.SIGTERM)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001469
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001470 def spawnSubprocess(self, executable, args=[], install_remote=True):
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001471 """ Creates a subprocess.Popen object with the specified executable and arguments,
1472 saves it in self.subprocesses, and returns the object.
1473 NOTE: if using this function, ensure you also call:
1474
1475 self.addTearDownHook(self.cleanupSubprocesses)
1476
1477 otherwise the test suite will leak processes.
1478 """
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001479 proc = _RemoteProcess(install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001480 proc.launch(executable, args)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001481 self.subprocesses.append(proc)
1482 return proc
1483
Daniel Malea69207462013-06-05 21:07:02 +00001484 def forkSubprocess(self, executable, args=[]):
1485 """ Fork a subprocess with its own group ID.
1486 NOTE: if using this function, ensure you also call:
1487
1488 self.addTearDownHook(self.cleanupSubprocesses)
1489
1490 otherwise the test suite will leak processes.
1491 """
1492 child_pid = os.fork()
1493 if child_pid == 0:
1494 # If more I/O support is required, this can be beefed up.
1495 fd = os.open(os.devnull, os.O_RDWR)
Daniel Malea69207462013-06-05 21:07:02 +00001496 os.dup2(fd, 1)
1497 os.dup2(fd, 2)
1498 # This call causes the child to have its of group ID
1499 os.setpgid(0,0)
1500 os.execvp(executable, [executable] + args)
1501 # Give the child time to get through the execvp() call
1502 time.sleep(0.1)
1503 self.forkedProcessPids.append(child_pid)
1504 return child_pid
1505
Johnny Chenfb4264c2011-08-01 19:50:58 +00001506 def HideStdout(self):
1507 """Hide output to stdout from the user.
1508
1509 During test execution, there might be cases where we don't want to show the
1510 standard output to the user. For example,
1511
1512 self.runCmd(r'''sc print "\n\n\tHello!\n"''')
1513
1514 tests whether command abbreviation for 'script' works or not. There is no
1515 need to show the 'Hello' output to the user as long as the 'script' command
1516 succeeds and we are not in TraceOn() mode (see the '-t' option).
1517
1518 In this case, the test method calls self.HideStdout(self) to redirect the
1519 sys.stdout to a null device, and restores the sys.stdout upon teardown.
1520
1521 Note that you should only call this method at most once during a test case
1522 execution. Any subsequent call has no effect at all."""
1523 if self.sys_stdout_hidden:
1524 return
1525
1526 self.sys_stdout_hidden = True
1527 old_stdout = sys.stdout
1528 sys.stdout = open(os.devnull, 'w')
1529 def restore_stdout():
1530 sys.stdout = old_stdout
1531 self.addTearDownHook(restore_stdout)
1532
1533 # =======================================================================
1534 # Methods for customized teardown cleanups as well as execution of hooks.
1535 # =======================================================================
1536
1537 def setTearDownCleanup(self, dictionary=None):
1538 """Register a cleanup action at tearDown() time with a dictinary"""
1539 self.dict = dictionary
1540 self.doTearDownCleanup = True
1541
1542 def addTearDownCleanup(self, dictionary):
1543 """Add a cleanup action at tearDown() time with a dictinary"""
1544 self.dicts.append(dictionary)
1545 self.doTearDownCleanups = True
1546
1547 def addTearDownHook(self, hook):
1548 """
1549 Add a function to be run during tearDown() time.
1550
1551 Hooks are executed in a first come first serve manner.
1552 """
1553 if callable(hook):
1554 with recording(self, traceAlways) as sbuf:
1555 print >> sbuf, "Adding tearDown hook:", getsource_if_available(hook)
1556 self.hooks.append(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001557
1558 return self
Johnny Chenfb4264c2011-08-01 19:50:58 +00001559
Jim Inghamda3a3862014-10-16 23:02:14 +00001560 def deletePexpectChild(self):
Johnny Chen985e7402011-08-01 21:13:26 +00001561 # This is for the case of directly spawning 'lldb' and interacting with it
1562 # using pexpect.
Johnny Chen985e7402011-08-01 21:13:26 +00001563 if self.child and self.child.isalive():
Zachary Turner9ef307b2014-07-22 16:19:29 +00001564 import pexpect
Johnny Chen985e7402011-08-01 21:13:26 +00001565 with recording(self, traceAlways) as sbuf:
1566 print >> sbuf, "tearing down the child process...."
Johnny Chen985e7402011-08-01 21:13:26 +00001567 try:
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001568 if self.child_in_script_interpreter:
1569 self.child.sendline('quit()')
1570 self.child.expect_exact(self.child_prompt)
1571 self.child.sendline('settings set interpreter.prompt-on-quit false')
1572 self.child.sendline('quit')
Johnny Chen985e7402011-08-01 21:13:26 +00001573 self.child.expect(pexpect.EOF)
Ilia K47448c22015-02-11 21:41:58 +00001574 except (ValueError, pexpect.ExceptionPexpect):
1575 # child is already terminated
1576 pass
1577 except OSError as exception:
1578 import errno
1579 if exception.errno != errno.EIO:
1580 # unexpected error
1581 raise
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001582 # child is already terminated
Johnny Chen985e7402011-08-01 21:13:26 +00001583 pass
Shawn Besteb3e9052014-11-06 17:52:15 +00001584 finally:
1585 # Give it one final blow to make sure the child is terminated.
1586 self.child.close()
Jim Inghamda3a3862014-10-16 23:02:14 +00001587
1588 def tearDown(self):
1589 """Fixture for unittest test case teardown."""
1590 #import traceback
1591 #traceback.print_stack()
1592
1593 self.deletePexpectChild()
1594
Johnny Chenfb4264c2011-08-01 19:50:58 +00001595 # Check and run any hook functions.
1596 for hook in reversed(self.hooks):
1597 with recording(self, traceAlways) as sbuf:
1598 print >> sbuf, "Executing tearDown hook:", getsource_if_available(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001599 import inspect
1600 hook_argc = len(inspect.getargspec(hook).args)
Enrico Granata6e0566c2014-11-17 19:00:20 +00001601 if hook_argc == 0 or getattr(hook,'im_self',None):
Enrico Granataab0e8312014-11-05 21:31:57 +00001602 hook()
1603 elif hook_argc == 1:
1604 hook(self)
1605 else:
1606 hook() # try the plain call and hope it works
Johnny Chenfb4264c2011-08-01 19:50:58 +00001607
1608 del self.hooks
1609
1610 # Perform registered teardown cleanup.
1611 if doCleanup and self.doTearDownCleanup:
Johnny Chen0fddfb22011-11-17 19:57:27 +00001612 self.cleanup(dictionary=self.dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001613
1614 # In rare cases where there are multiple teardown cleanups added.
1615 if doCleanup and self.doTearDownCleanups:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001616 if self.dicts:
1617 for dict in reversed(self.dicts):
Johnny Chen0fddfb22011-11-17 19:57:27 +00001618 self.cleanup(dictionary=dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001619
Vince Harron9753dd92015-05-10 15:22:09 +00001620 self.disableLogChannelsForCurrentTest()
1621
Johnny Chenfb4264c2011-08-01 19:50:58 +00001622 # =========================================================
1623 # Various callbacks to allow introspection of test progress
1624 # =========================================================
1625
1626 def markError(self):
1627 """Callback invoked when an error (unexpected exception) errored."""
1628 self.__errored__ = True
1629 with recording(self, False) as sbuf:
1630 # False because there's no need to write "ERROR" to the stderr twice.
1631 # Once by the Python unittest framework, and a second time by us.
1632 print >> sbuf, "ERROR"
1633
Zachary Turnerb1490b62015-08-26 19:44:56 +00001634 def markCleanupError(self):
1635 """Callback invoked when an error occurs while a test is cleaning up."""
1636 self.__cleanup_errored__ = True
1637 with recording(self, False) as sbuf:
1638 # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
1639 # Once by the Python unittest framework, and a second time by us.
1640 print >> sbuf, "CLEANUP_ERROR"
1641
Johnny Chenfb4264c2011-08-01 19:50:58 +00001642 def markFailure(self):
1643 """Callback invoked when a failure (test assertion failure) occurred."""
1644 self.__failed__ = True
1645 with recording(self, False) as sbuf:
1646 # False because there's no need to write "FAIL" to the stderr twice.
1647 # Once by the Python unittest framework, and a second time by us.
1648 print >> sbuf, "FAIL"
1649
Enrico Granatae6cedc12013-02-23 01:05:23 +00001650 def markExpectedFailure(self,err,bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001651 """Callback invoked when an expected failure/error occurred."""
1652 self.__expected__ = True
1653 with recording(self, False) as sbuf:
1654 # False because there's no need to write "expected failure" to the
1655 # stderr twice.
1656 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001657 if bugnumber == None:
1658 print >> sbuf, "expected failure"
1659 else:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001660 print >> sbuf, "expected failure (problem id:" + str(bugnumber) + ")"
Johnny Chenfb4264c2011-08-01 19:50:58 +00001661
Johnny Chenc5cc6252011-08-15 23:09:08 +00001662 def markSkippedTest(self):
1663 """Callback invoked when a test is skipped."""
1664 self.__skipped__ = True
1665 with recording(self, False) as sbuf:
1666 # False because there's no need to write "skipped test" to the
1667 # stderr twice.
1668 # Once by the Python unittest framework, and a second time by us.
1669 print >> sbuf, "skipped test"
1670
Enrico Granatae6cedc12013-02-23 01:05:23 +00001671 def markUnexpectedSuccess(self, bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001672 """Callback invoked when an unexpected success occurred."""
1673 self.__unexpected__ = True
1674 with recording(self, False) as sbuf:
1675 # False because there's no need to write "unexpected success" to the
1676 # stderr twice.
1677 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001678 if bugnumber == None:
1679 print >> sbuf, "unexpected success"
1680 else:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001681 print >> sbuf, "unexpected success (problem id:" + str(bugnumber) + ")"
Johnny Chenfb4264c2011-08-01 19:50:58 +00001682
Greg Clayton70995582015-01-07 22:25:50 +00001683 def getRerunArgs(self):
1684 return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
Vince Harron9753dd92015-05-10 15:22:09 +00001685
1686 def getLogBasenameForCurrentTest(self, prefix=None):
1687 """
1688 returns a partial path that can be used as the beginning of the name of multiple
1689 log files pertaining to this test
1690
1691 <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
1692 """
1693 dname = os.path.join(os.environ["LLDB_TEST"],
1694 os.environ["LLDB_SESSION_DIRNAME"])
1695 if not os.path.isdir(dname):
1696 os.mkdir(dname)
1697
1698 compiler = self.getCompiler()
1699
1700 if compiler[1] == ':':
1701 compiler = compiler[2:]
Chaoren Lin636a0e32015-07-17 21:40:11 +00001702 if os.path.altsep is not None:
1703 compiler = compiler.replace(os.path.altsep, os.path.sep)
Vince Harron9753dd92015-05-10 15:22:09 +00001704
Vince Harron19e300f2015-05-12 00:50:54 +00001705 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
Vince Harron9753dd92015-05-10 15:22:09 +00001706 if len(fname) > 200:
Vince Harron19e300f2015-05-12 00:50:54 +00001707 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
Vince Harron9753dd92015-05-10 15:22:09 +00001708
1709 if prefix is not None:
1710 fname = "{}-{}".format(prefix, fname)
1711
1712 return os.path.join(dname, fname)
1713
Johnny Chenfb4264c2011-08-01 19:50:58 +00001714 def dumpSessionInfo(self):
1715 """
1716 Dump the debugger interactions leading to a test error/failure. This
1717 allows for more convenient postmortem analysis.
1718
1719 See also LLDBTestResult (dotest.py) which is a singlton class derived
1720 from TextTestResult and overwrites addError, addFailure, and
1721 addExpectedFailure methods to allow us to to mark the test instance as
1722 such.
1723 """
1724
1725 # We are here because self.tearDown() detected that this test instance
1726 # either errored or failed. The lldb.test_result singleton contains
1727 # two lists (erros and failures) which get populated by the unittest
1728 # framework. Look over there for stack trace information.
1729 #
1730 # The lists contain 2-tuples of TestCase instances and strings holding
1731 # formatted tracebacks.
1732 #
1733 # See http://docs.python.org/library/unittest.html#unittest.TestResult.
Vince Harron9753dd92015-05-10 15:22:09 +00001734
Vince Harron35b17dc2015-05-21 18:20:21 +00001735 # output tracebacks into session
Vince Harron9753dd92015-05-10 15:22:09 +00001736 pairs = []
Johnny Chenfb4264c2011-08-01 19:50:58 +00001737 if self.__errored__:
1738 pairs = lldb.test_result.errors
1739 prefix = 'Error'
Zachary Turnerb1490b62015-08-26 19:44:56 +00001740 if self.__cleanup_errored__:
1741 pairs = lldb.test_result.cleanup_errors
1742 prefix = 'CleanupError'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001743 elif self.__failed__:
1744 pairs = lldb.test_result.failures
1745 prefix = 'Failure'
1746 elif self.__expected__:
1747 pairs = lldb.test_result.expectedFailures
1748 prefix = 'ExpectedFailure'
Johnny Chenc5cc6252011-08-15 23:09:08 +00001749 elif self.__skipped__:
1750 prefix = 'SkippedTest'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001751 elif self.__unexpected__:
Vince Harron35b17dc2015-05-21 18:20:21 +00001752 prefix = 'UnexpectedSuccess'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001753 else:
Vince Harron35b17dc2015-05-21 18:20:21 +00001754 prefix = 'Success'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001755
Johnny Chenc5cc6252011-08-15 23:09:08 +00001756 if not self.__unexpected__ and not self.__skipped__:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001757 for test, traceback in pairs:
1758 if test is self:
1759 print >> self.session, traceback
1760
Vince Harron35b17dc2015-05-21 18:20:21 +00001761 # put footer (timestamp/rerun instructions) into session
Johnny Chen8082a002011-08-11 00:16:28 +00001762 testMethod = getattr(self, self._testMethodName)
1763 if getattr(testMethod, "__benchmarks_test__", False):
1764 benchmarks = True
1765 else:
1766 benchmarks = False
1767
Vince Harron35b17dc2015-05-21 18:20:21 +00001768 import datetime
1769 print >> self.session, "Session info generated @", datetime.datetime.now().ctime()
1770 print >> self.session, "To rerun this test, issue the following command from the 'test' directory:\n"
1771 print >> self.session, "./dotest.py %s -v %s %s" % (self.getRunOptions(),
1772 ('+b' if benchmarks else '-t'),
1773 self.getRerunArgs())
1774 self.session.close()
1775 del self.session
1776
1777 # process the log files
Vince Harron1f160372015-05-21 18:51:20 +00001778 log_files_for_this_test = glob.glob(self.log_basename + "*")
Vince Harron35b17dc2015-05-21 18:20:21 +00001779
1780 if prefix != 'Success' or lldbtest_config.log_success:
1781 # keep all log files, rename them to include prefix
1782 dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1783 for src in log_files_for_this_test:
Zachary Turner306278f2015-05-26 20:26:29 +00001784 if os.path.isfile(src):
1785 dst = src.replace(self.log_basename, dst_log_basename)
1786 if os.name == "nt" and os.path.isfile(dst):
1787 # On Windows, renaming a -> b will throw an exception if b exists. On non-Windows platforms
1788 # it silently replaces the destination. Ultimately this means that atomic renames are not
1789 # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
1790 # destination first if it already exists.
1791 os.remove(dst)
Zachary Turner5de068b2015-05-26 19:52:24 +00001792
Zachary Turner306278f2015-05-26 20:26:29 +00001793 os.rename(src, dst)
Vince Harron35b17dc2015-05-21 18:20:21 +00001794 else:
1795 # success! (and we don't want log files) delete log files
1796 for log_file in log_files_for_this_test:
Adrian McCarthya7292042015-09-04 20:48:48 +00001797 try:
1798 os.unlink(log_file)
1799 except:
1800 # We've seen consistent unlink failures on Windows, perhaps because the
1801 # just-created log file is being scanned by anti-virus. Empirically, this
1802 # sleep-and-retry approach allows tests to succeed much more reliably.
1803 # Attempts to figure out exactly what process was still holding a file handle
1804 # have failed because running instrumentation like Process Monitor seems to
1805 # slow things down enough that the problem becomes much less consistent.
1806 time.sleep(0.5)
1807 os.unlink(log_file)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001808
1809 # ====================================================
1810 # Config. methods supported through a plugin interface
1811 # (enables reading of the current test configuration)
1812 # ====================================================
1813
1814 def getArchitecture(self):
1815 """Returns the architecture in effect the test suite is running with."""
1816 module = builder_module()
Ed Maste0f434e62015-04-06 15:50:48 +00001817 arch = module.getArchitecture()
1818 if arch == 'amd64':
1819 arch = 'x86_64'
1820 return arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00001821
Vince Harron02613762015-05-04 00:17:53 +00001822 def getLldbArchitecture(self):
1823 """Returns the architecture of the lldb binary."""
1824 if not hasattr(self, 'lldbArchitecture'):
1825
1826 # spawn local process
1827 command = [
Vince Harron790d95c2015-05-18 19:39:03 +00001828 lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001829 "-o",
Vince Harron790d95c2015-05-18 19:39:03 +00001830 "file " + lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001831 "-o",
1832 "quit"
1833 ]
1834
1835 output = check_output(command)
1836 str = output.decode("utf-8");
1837
1838 for line in str.splitlines():
1839 m = re.search("Current executable set to '.*' \\((.*)\\)\\.", line)
1840 if m:
1841 self.lldbArchitecture = m.group(1)
1842 break
1843
1844 return self.lldbArchitecture
1845
Johnny Chenfb4264c2011-08-01 19:50:58 +00001846 def getCompiler(self):
1847 """Returns the compiler in effect the test suite is running with."""
1848 module = builder_module()
1849 return module.getCompiler()
1850
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001851 def getCompilerBinary(self):
1852 """Returns the compiler binary the test suite is running with."""
1853 return self.getCompiler().split()[0]
1854
Daniel Malea0aea0162013-02-27 17:29:46 +00001855 def getCompilerVersion(self):
1856 """ Returns a string that represents the compiler version.
1857 Supports: llvm, clang.
1858 """
1859 from lldbutil import which
1860 version = 'unknown'
1861
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001862 compiler = self.getCompilerBinary()
Zachary Turner9ef307b2014-07-22 16:19:29 +00001863 version_output = system([[which(compiler), "-v"]])[1]
Daniel Malea0aea0162013-02-27 17:29:46 +00001864 for line in version_output.split(os.linesep):
Greg Clayton2a844b72013-03-06 02:34:51 +00001865 m = re.search('version ([0-9\.]+)', line)
Daniel Malea0aea0162013-02-27 17:29:46 +00001866 if m:
1867 version = m.group(1)
1868 return version
1869
Greg Claytone0d0a762015-04-02 18:24:03 +00001870 def platformIsDarwin(self):
1871 """Returns true if the OS triple for the selected platform is any valid apple OS"""
Robert Flackfb2f6c62015-04-17 08:02:18 +00001872 return platformIsDarwin()
Vince Harron20952cc2015-04-03 01:00:06 +00001873
Robert Flack13c7ad92015-03-30 14:12:17 +00001874 def getPlatform(self):
Robert Flackfb2f6c62015-04-17 08:02:18 +00001875 """Returns the target platform the test suite is running on."""
Robert Flack068898c2015-04-09 18:07:58 +00001876 return getPlatform()
Robert Flack13c7ad92015-03-30 14:12:17 +00001877
Daniel Maleaadaaec92013-08-06 20:51:41 +00001878 def isIntelCompiler(self):
1879 """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1880 return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1881
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001882 def expectedCompilerVersion(self, compiler_version):
1883 """Returns True iff compiler_version[1] matches the current compiler version.
1884 Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1885 Any operator other than the following defaults to an equality test:
1886 '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1887 """
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001888 if (compiler_version == None):
1889 return True
1890 operator = str(compiler_version[0])
1891 version = compiler_version[1]
1892
1893 if (version == None):
1894 return True
1895 if (operator == '>'):
1896 return self.getCompilerVersion() > version
1897 if (operator == '>=' or operator == '=>'):
1898 return self.getCompilerVersion() >= version
1899 if (operator == '<'):
1900 return self.getCompilerVersion() < version
1901 if (operator == '<=' or operator == '=<'):
1902 return self.getCompilerVersion() <= version
1903 if (operator == '!=' or operator == '!' or operator == 'not'):
1904 return str(version) not in str(self.getCompilerVersion())
1905 return str(version) in str(self.getCompilerVersion())
1906
1907 def expectedCompiler(self, compilers):
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001908 """Returns True iff any element of compilers is a sub-string of the current compiler."""
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001909 if (compilers == None):
1910 return True
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001911
1912 for compiler in compilers:
1913 if compiler in self.getCompiler():
1914 return True
1915
1916 return False
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001917
Ying Chen7091c2c2015-04-21 01:15:47 +00001918 def expectedArch(self, archs):
1919 """Returns True iff any element of archs is a sub-string of the current architecture."""
1920 if (archs == None):
1921 return True
1922
1923 for arch in archs:
1924 if arch in self.getArchitecture():
1925 return True
1926
1927 return False
1928
Johnny Chenfb4264c2011-08-01 19:50:58 +00001929 def getRunOptions(self):
1930 """Command line option for -A and -C to run this test again, called from
1931 self.dumpSessionInfo()."""
1932 arch = self.getArchitecture()
1933 comp = self.getCompiler()
Johnny Chenb7bdd102011-08-24 19:48:51 +00001934 if arch:
1935 option_str = "-A " + arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00001936 else:
Johnny Chenb7bdd102011-08-24 19:48:51 +00001937 option_str = ""
1938 if comp:
Johnny Chen531c0852012-03-16 20:44:00 +00001939 option_str += " -C " + comp
Johnny Chenb7bdd102011-08-24 19:48:51 +00001940 return option_str
Johnny Chenfb4264c2011-08-01 19:50:58 +00001941
1942 # ==================================================
1943 # Build methods supported through a plugin interface
1944 # ==================================================
1945
Ed Mastec97323e2014-04-01 18:47:58 +00001946 def getstdlibFlag(self):
1947 """ Returns the proper -stdlib flag, or empty if not required."""
Robert Flack4629c4b2015-05-15 18:54:32 +00001948 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Ed Mastec97323e2014-04-01 18:47:58 +00001949 stdlibflag = "-stdlib=libc++"
1950 else:
1951 stdlibflag = ""
1952 return stdlibflag
1953
Matt Kopec7663b3a2013-09-25 17:44:00 +00001954 def getstdFlag(self):
1955 """ Returns the proper stdflag. """
Daniel Malea55faa402013-05-02 21:44:31 +00001956 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
Daniel Malea0b7c6112013-05-06 19:31:31 +00001957 stdflag = "-std=c++0x"
Daniel Malea55faa402013-05-02 21:44:31 +00001958 else:
1959 stdflag = "-std=c++11"
Matt Kopec7663b3a2013-09-25 17:44:00 +00001960 return stdflag
1961
1962 def buildDriver(self, sources, exe_name):
1963 """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
1964 or LLDB.framework).
1965 """
1966
1967 stdflag = self.getstdFlag()
Ed Mastec97323e2014-04-01 18:47:58 +00001968 stdlibflag = self.getstdlibFlag()
Daniel Malea55faa402013-05-02 21:44:31 +00001969
1970 if sys.platform.startswith("darwin"):
1971 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
1972 d = {'CXX_SOURCES' : sources,
1973 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00001974 'CFLAGS_EXTRAS' : "%s %s" % (stdflag, stdlibflag),
Daniel Malea55faa402013-05-02 21:44:31 +00001975 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
Stefanus Du Toit04004442013-07-30 19:19:49 +00001976 'LD_EXTRAS' : "%s -Wl,-rpath,%s" % (dsym, self.lib_dir),
Daniel Malea55faa402013-05-02 21:44:31 +00001977 }
Ed Maste372c24d2013-07-25 21:02:34 +00001978 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 +00001979 d = {'CXX_SOURCES' : sources,
Daniel Malea55faa402013-05-02 21:44:31 +00001980 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00001981 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
Daniel Malea55faa402013-05-02 21:44:31 +00001982 'LD_EXTRAS' : "-L%s -llldb" % self.lib_dir}
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00001983 elif sys.platform.startswith('win'):
1984 d = {'CXX_SOURCES' : sources,
1985 'EXE' : exe_name,
1986 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1987 'LD_EXTRAS' : "-L%s -lliblldb" % self.implib_dir}
Daniel Malea55faa402013-05-02 21:44:31 +00001988 if self.TraceOn():
1989 print "Building LLDB Driver (%s) from sources %s" % (exe_name, sources)
1990
1991 self.buildDefault(dictionary=d)
1992
Matt Kopec7663b3a2013-09-25 17:44:00 +00001993 def buildLibrary(self, sources, lib_name):
1994 """Platform specific way to build a default library. """
1995
1996 stdflag = self.getstdFlag()
1997
Robert Flack4629c4b2015-05-15 18:54:32 +00001998 if self.platformIsDarwin():
Matt Kopec7663b3a2013-09-25 17:44:00 +00001999 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
2000 d = {'DYLIB_CXX_SOURCES' : sources,
2001 'DYLIB_NAME' : lib_name,
2002 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
2003 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
2004 'LD_EXTRAS' : "%s -Wl,-rpath,%s -dynamiclib" % (dsym, self.lib_dir),
2005 }
Robert Flack4629c4b2015-05-15 18:54:32 +00002006 elif self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux' or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
Matt Kopec7663b3a2013-09-25 17:44:00 +00002007 d = {'DYLIB_CXX_SOURCES' : sources,
2008 'DYLIB_NAME' : lib_name,
2009 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2010 'LD_EXTRAS' : "-shared -L%s -llldb" % self.lib_dir}
Robert Flack4629c4b2015-05-15 18:54:32 +00002011 elif self.getPlatform() == 'windows':
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00002012 d = {'DYLIB_CXX_SOURCES' : sources,
2013 'DYLIB_NAME' : lib_name,
2014 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2015 'LD_EXTRAS' : "-shared -l%s\liblldb.lib" % self.implib_dir}
Matt Kopec7663b3a2013-09-25 17:44:00 +00002016 if self.TraceOn():
2017 print "Building LLDB Library (%s) from sources %s" % (lib_name, sources)
2018
2019 self.buildDefault(dictionary=d)
2020
Daniel Malea55faa402013-05-02 21:44:31 +00002021 def buildProgram(self, sources, exe_name):
2022 """ Platform specific way to build an executable from C/C++ sources. """
2023 d = {'CXX_SOURCES' : sources,
2024 'EXE' : exe_name}
2025 self.buildDefault(dictionary=d)
2026
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002027 def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002028 """Platform specific way to build the default binaries."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002029 if lldb.skip_build_and_cleanup:
2030 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002031 module = builder_module()
Chaoren Line9bbabc2015-07-18 00:37:55 +00002032 if target_is_android():
2033 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002034 if not module.buildDefault(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002035 raise Exception("Don't know how to build default binary")
2036
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002037 def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002038 """Platform specific way to build binaries with dsym info."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002039 if lldb.skip_build_and_cleanup:
2040 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002041 module = builder_module()
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002042 if not module.buildDsym(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002043 raise Exception("Don't know how to build binary with dsym")
2044
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002045 def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002046 """Platform specific way to build binaries with dwarf maps."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002047 if lldb.skip_build_and_cleanup:
2048 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002049 module = builder_module()
Chaoren Lin9070f532015-07-17 22:13:29 +00002050 if target_is_android():
Chaoren Line9bbabc2015-07-18 00:37:55 +00002051 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002052 if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002053 raise Exception("Don't know how to build binary with dwarf")
Johnny Chena74bb0a2011-08-01 18:46:13 +00002054
Oleksiy Vyalov49b71c62015-01-22 20:03:21 +00002055 def signBinary(self, binary_path):
2056 if sys.platform.startswith("darwin"):
2057 codesign_cmd = "codesign --force --sign lldb_codesign %s" % (binary_path)
2058 call(codesign_cmd, shell=True)
2059
Kuba Breckabeed8212014-09-04 01:03:18 +00002060 def findBuiltClang(self):
2061 """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
2062 paths_to_try = [
2063 "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
2064 "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
2065 "llvm-build/Release/x86_64/Release/bin/clang",
2066 "llvm-build/Debug/x86_64/Debug/bin/clang",
2067 ]
2068 lldb_root_path = os.path.join(os.path.dirname(__file__), "..")
2069 for p in paths_to_try:
2070 path = os.path.join(lldb_root_path, p)
2071 if os.path.exists(path):
2072 return path
Ilia Kd9953052015-03-12 07:19:41 +00002073
2074 # Tries to find clang at the same folder as the lldb
Vince Harron790d95c2015-05-18 19:39:03 +00002075 path = os.path.join(os.path.dirname(lldbtest_config.lldbExec), "clang")
Ilia Kd9953052015-03-12 07:19:41 +00002076 if os.path.exists(path):
2077 return path
Kuba Breckabeed8212014-09-04 01:03:18 +00002078
2079 return os.environ["CC"]
2080
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002081 def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False):
Andrew Kaylor93132f52013-05-28 23:04:25 +00002082 """ Returns a dictionary (which can be provided to build* functions above) which
2083 contains OS-specific build flags.
2084 """
2085 cflags = ""
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002086 ldflags = ""
Daniel Malea9115f072013-08-06 15:02:32 +00002087
2088 # On Mac OS X, unless specifically requested to use libstdc++, use libc++
Robert Flack4629c4b2015-05-15 18:54:32 +00002089 if not use_libstdcxx and self.platformIsDarwin():
Daniel Malea9115f072013-08-06 15:02:32 +00002090 use_libcxx = True
2091
2092 if use_libcxx and self.libcxxPath:
2093 cflags += "-stdlib=libc++ "
2094 if self.libcxxPath:
2095 libcxxInclude = os.path.join(self.libcxxPath, "include")
2096 libcxxLib = os.path.join(self.libcxxPath, "lib")
2097 if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
2098 cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (libcxxInclude, libcxxLib, libcxxLib)
2099
Andrew Kaylor93132f52013-05-28 23:04:25 +00002100 if use_cpp11:
2101 cflags += "-std="
2102 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2103 cflags += "c++0x"
2104 else:
2105 cflags += "c++11"
Robert Flack4629c4b2015-05-15 18:54:32 +00002106 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Andrew Kaylor93132f52013-05-28 23:04:25 +00002107 cflags += " -stdlib=libc++"
2108 elif "clang" in self.getCompiler():
2109 cflags += " -stdlib=libstdc++"
2110
Andrew Kaylor93132f52013-05-28 23:04:25 +00002111 return {'CFLAGS_EXTRAS' : cflags,
2112 'LD_EXTRAS' : ldflags,
2113 }
2114
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002115 def cleanup(self, dictionary=None):
2116 """Platform specific way to do cleanup after build."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002117 if lldb.skip_build_and_cleanup:
2118 return
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002119 module = builder_module()
2120 if not module.cleanup(self, dictionary):
Johnny Chen0fddfb22011-11-17 19:57:27 +00002121 raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002122
Daniel Malea55faa402013-05-02 21:44:31 +00002123 def getLLDBLibraryEnvVal(self):
2124 """ Returns the path that the OS-specific library search environment variable
2125 (self.dylibPath) should be set to in order for a program to find the LLDB
2126 library. If an environment variable named self.dylibPath is already set,
2127 the new path is appended to it and returned.
2128 """
2129 existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
2130 if existing_library_path:
2131 return "%s:%s" % (existing_library_path, self.lib_dir)
2132 elif sys.platform.startswith("darwin"):
2133 return os.path.join(self.lib_dir, 'LLDB.framework')
2134 else:
2135 return self.lib_dir
Johnny Chena74bb0a2011-08-01 18:46:13 +00002136
Ed Maste437f8f62013-09-09 14:04:04 +00002137 def getLibcPlusPlusLibs(self):
Robert Flackfa5ad652015-05-13 20:17:34 +00002138 if self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux':
Ed Maste437f8f62013-09-09 14:04:04 +00002139 return ['libc++.so.1']
2140 else:
2141 return ['libc++.1.dylib','libc++abi.dylib']
2142
Johnny Chena74bb0a2011-08-01 18:46:13 +00002143class TestBase(Base):
2144 """
2145 This abstract base class is meant to be subclassed. It provides default
2146 implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
2147 among other things.
2148
2149 Important things for test class writers:
2150
2151 - Overwrite the mydir class attribute, otherwise your test class won't
2152 run. It specifies the relative directory to the top level 'test' so
2153 the test harness can change to the correct working directory before
2154 running your test.
2155
2156 - The setUp method sets up things to facilitate subsequent interactions
2157 with the debugger as part of the test. These include:
2158 - populate the test method name
2159 - create/get a debugger set with synchronous mode (self.dbg)
2160 - get the command interpreter from with the debugger (self.ci)
2161 - create a result object for use with the command interpreter
2162 (self.res)
2163 - plus other stuffs
2164
2165 - The tearDown method tries to perform some necessary cleanup on behalf
2166 of the test to return the debugger to a good state for the next test.
2167 These include:
2168 - execute any tearDown hooks registered by the test method with
2169 TestBase.addTearDownHook(); examples can be found in
2170 settings/TestSettings.py
2171 - kill the inferior process associated with each target, if any,
2172 and, then delete the target from the debugger's target list
2173 - perform build cleanup before running the next test method in the
2174 same test class; examples of registering for this service can be
2175 found in types/TestIntegerTypes.py with the call:
2176 - self.setTearDownCleanup(dictionary=d)
2177
2178 - Similarly setUpClass and tearDownClass perform classwise setup and
2179 teardown fixtures. The tearDownClass method invokes a default build
2180 cleanup for the entire test class; also, subclasses can implement the
2181 classmethod classCleanup(cls) to perform special class cleanup action.
2182
2183 - The instance methods runCmd and expect are used heavily by existing
2184 test cases to send a command to the command interpreter and to perform
2185 string/pattern matching on the output of such command execution. The
2186 expect method also provides a mode to peform string/pattern matching
2187 without running a command.
2188
2189 - The build methods buildDefault, buildDsym, and buildDwarf are used to
2190 build the binaries used during a particular test scenario. A plugin
2191 should be provided for the sys.platform running the test suite. The
2192 Mac OS X implementation is located in plugins/darwin.py.
2193 """
2194
2195 # Maximum allowed attempts when launching the inferior process.
2196 # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
2197 maxLaunchCount = 3;
2198
2199 # Time to wait before the next launching attempt in second(s).
2200 # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
2201 timeWaitNextLaunch = 1.0;
2202
2203 def doDelay(self):
2204 """See option -w of dotest.py."""
2205 if ("LLDB_WAIT_BETWEEN_TEST_CASES" in os.environ and
2206 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] == 'YES'):
2207 waitTime = 1.0
2208 if "LLDB_TIME_WAIT_BETWEEN_TEST_CASES" in os.environ:
2209 waitTime = float(os.environ["LLDB_TIME_WAIT_BETWEEN_TEST_CASES"])
2210 time.sleep(waitTime)
2211
Enrico Granata165f8af2012-09-21 19:10:53 +00002212 # Returns the list of categories to which this test case belongs
2213 # by default, look for a ".categories" file, and read its contents
2214 # if no such file exists, traverse the hierarchy - we guarantee
2215 # a .categories to exist at the top level directory so we do not end up
2216 # looping endlessly - subclasses are free to define their own categories
2217 # in whatever way makes sense to them
2218 def getCategories(self):
2219 import inspect
2220 import os.path
2221 folder = inspect.getfile(self.__class__)
2222 folder = os.path.dirname(folder)
2223 while folder != '/':
2224 categories_file_name = os.path.join(folder,".categories")
2225 if os.path.exists(categories_file_name):
2226 categories_file = open(categories_file_name,'r')
2227 categories = categories_file.readline()
2228 categories_file.close()
2229 categories = str.replace(categories,'\n','')
2230 categories = str.replace(categories,'\r','')
2231 return categories.split(',')
2232 else:
2233 folder = os.path.dirname(folder)
2234 continue
2235
Johnny Chena74bb0a2011-08-01 18:46:13 +00002236 def setUp(self):
2237 #import traceback
2238 #traceback.print_stack()
2239
2240 # Works with the test driver to conditionally skip tests via decorators.
2241 Base.setUp(self)
2242
Johnny Chena74bb0a2011-08-01 18:46:13 +00002243 try:
2244 if lldb.blacklist:
2245 className = self.__class__.__name__
2246 classAndMethodName = "%s.%s" % (className, self._testMethodName)
2247 if className in lldb.blacklist:
2248 self.skipTest(lldb.blacklist.get(className))
2249 elif classAndMethodName in lldb.blacklist:
2250 self.skipTest(lldb.blacklist.get(classAndMethodName))
2251 except AttributeError:
2252 pass
2253
Johnny Chened492022011-06-21 00:53:00 +00002254 # Insert some delay between successive test cases if specified.
2255 self.doDelay()
Johnny Chen0ed37c92010-10-07 02:04:14 +00002256
Johnny Chenf2b70232010-08-25 18:49:48 +00002257 if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
2258 self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
2259
Johnny Chen430eb762010-10-19 16:00:42 +00002260 if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
Johnny Chen4921b112010-11-29 20:20:34 +00002261 self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
Johnny Chenf2b70232010-08-25 18:49:48 +00002262
Daniel Maleae0f8f572013-08-26 23:57:52 +00002263 #
2264 # Warning: MAJOR HACK AHEAD!
2265 # If we are running testsuite remotely (by checking lldb.lldbtest_remote_sandbox),
2266 # redefine the self.dbg.CreateTarget(filename) method to execute a "file filename"
2267 # command, instead. See also runCmd() where it decorates the "file filename" call
2268 # with additional functionality when running testsuite remotely.
2269 #
2270 if lldb.lldbtest_remote_sandbox:
2271 def DecoratedCreateTarget(arg):
2272 self.runCmd("file %s" % arg)
2273 target = self.dbg.GetSelectedTarget()
2274 #
Greg Claytonc6947512013-12-13 19:18:59 +00002275 # SBtarget.LaunchSimple () currently not working for remote platform?
Daniel Maleae0f8f572013-08-26 23:57:52 +00002276 # johnny @ 04/23/2012
2277 #
2278 def DecoratedLaunchSimple(argv, envp, wd):
2279 self.runCmd("run")
2280 return target.GetProcess()
2281 target.LaunchSimple = DecoratedLaunchSimple
2282
2283 return target
2284 self.dbg.CreateTarget = DecoratedCreateTarget
2285 if self.TraceOn():
2286 print "self.dbg.Create is redefined to:\n%s" % getsource_if_available(DecoratedCreateTarget)
2287
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002288 # We want our debugger to be synchronous.
2289 self.dbg.SetAsync(False)
2290
2291 # Retrieve the associated command interpreter instance.
2292 self.ci = self.dbg.GetCommandInterpreter()
2293 if not self.ci:
2294 raise Exception('Could not get the command interpreter')
2295
2296 # And the result object.
2297 self.res = lldb.SBCommandReturnObject()
2298
Johnny Chen44d24972012-04-16 18:55:15 +00002299 # Run global pre-flight code, if defined via the config file.
2300 if lldb.pre_flight:
2301 lldb.pre_flight(self)
2302
Greg Claytonfb909312013-11-23 01:58:15 +00002303 if lldb.remote_platform:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00002304 remote_test_dir = lldbutil.join_remote_paths(
2305 lldb.remote_platform_working_dir,
2306 self.getArchitecture(),
2307 str(self.test_number),
2308 self.mydir)
Greg Claytonfb909312013-11-23 01:58:15 +00002309 error = lldb.remote_platform.MakeDirectory(remote_test_dir, 0700)
2310 if error.Success():
Greg Claytonfb909312013-11-23 01:58:15 +00002311 lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
2312 else:
2313 print "error: making remote directory '%s': %s" % (remote_test_dir, error)
2314
Greg Clayton35c91342014-11-17 18:40:27 +00002315 def registerSharedLibrariesWithTarget(self, target, shlibs):
2316 '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
2317
2318 Any modules in the target that have their remote install file specification set will
2319 get uploaded to the remote host. This function registers the local copies of the
2320 shared libraries with the target and sets their remote install locations so they will
2321 be uploaded when the target is run.
2322 '''
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00002323 if not shlibs or not self.platformContext:
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002324 return None
Greg Clayton35c91342014-11-17 18:40:27 +00002325
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002326 shlib_environment_var = self.platformContext.shlib_environment_var
2327 shlib_prefix = self.platformContext.shlib_prefix
2328 shlib_extension = '.' + self.platformContext.shlib_extension
2329
2330 working_dir = self.get_process_working_directory()
2331 environment = ['%s=%s' % (shlib_environment_var, working_dir)]
2332 # Add any shared libraries to our target if remote so they get
2333 # uploaded into the working directory on the remote side
2334 for name in shlibs:
2335 # The path can be a full path to a shared library, or a make file name like "Foo" for
2336 # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
2337 # basename like "libFoo.so". So figure out which one it is and resolve the local copy
2338 # of the shared library accordingly
2339 if os.path.exists(name):
2340 local_shlib_path = name # name is the full path to the local shared library
2341 else:
2342 # Check relative names
2343 local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
2344 if not os.path.exists(local_shlib_path):
2345 local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
Greg Clayton35c91342014-11-17 18:40:27 +00002346 if not os.path.exists(local_shlib_path):
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002347 local_shlib_path = os.path.join(os.getcwd(), name)
Greg Clayton35c91342014-11-17 18:40:27 +00002348
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002349 # Make sure we found the local shared library in the above code
2350 self.assertTrue(os.path.exists(local_shlib_path))
2351
2352 # Add the shared library to our target
2353 shlib_module = target.AddModule(local_shlib_path, None, None, None)
2354 if lldb.remote_platform:
Greg Clayton35c91342014-11-17 18:40:27 +00002355 # We must set the remote install location if we want the shared library
2356 # to get uploaded to the remote target
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00002357 remote_shlib_path = lldbutil.append_to_process_working_directory(os.path.basename(local_shlib_path))
Greg Clayton35c91342014-11-17 18:40:27 +00002358 shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002359
2360 return environment
2361
Enrico Granata44818162012-10-24 01:23:57 +00002362 # utility methods that tests can use to access the current objects
2363 def target(self):
2364 if not self.dbg:
2365 raise Exception('Invalid debugger instance')
2366 return self.dbg.GetSelectedTarget()
2367
2368 def process(self):
2369 if not self.dbg:
2370 raise Exception('Invalid debugger instance')
2371 return self.dbg.GetSelectedTarget().GetProcess()
2372
2373 def thread(self):
2374 if not self.dbg:
2375 raise Exception('Invalid debugger instance')
2376 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2377
2378 def frame(self):
2379 if not self.dbg:
2380 raise Exception('Invalid debugger instance')
2381 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
2382
Greg Claytonc6947512013-12-13 19:18:59 +00002383 def get_process_working_directory(self):
2384 '''Get the working directory that should be used when launching processes for local or remote processes.'''
2385 if lldb.remote_platform:
2386 # Remote tests set the platform working directory up in TestBase.setUp()
2387 return lldb.remote_platform.GetWorkingDirectory()
2388 else:
2389 # local tests change directory into each test subdirectory
2390 return os.getcwd()
2391
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002392 def tearDown(self):
Johnny Chen7d1d7532010-09-02 21:23:12 +00002393 #import traceback
2394 #traceback.print_stack()
2395
Johnny Chen3794ad92011-06-15 21:24:24 +00002396 # Delete the target(s) from the debugger as a general cleanup step.
2397 # This includes terminating the process for each target, if any.
2398 # We'd like to reuse the debugger for our next test without incurring
2399 # the initialization overhead.
2400 targets = []
2401 for target in self.dbg:
2402 if target:
2403 targets.append(target)
2404 process = target.GetProcess()
2405 if process:
2406 rc = self.invoke(process, "Kill")
2407 self.assertTrue(rc.Success(), PROCESS_KILLED)
2408 for target in targets:
2409 self.dbg.DeleteTarget(target)
Johnny Chen6ca006c2010-08-16 21:28:10 +00002410
Johnny Chen44d24972012-04-16 18:55:15 +00002411 # Run global post-flight code, if defined via the config file.
2412 if lldb.post_flight:
2413 lldb.post_flight(self)
2414
Zachary Turner65fe1eb2015-03-26 16:43:25 +00002415 # Do this last, to make sure it's in reverse order from how we setup.
2416 Base.tearDown(self)
2417
Zachary Turner95812042015-03-26 18:54:21 +00002418 # This must be the last statement, otherwise teardown hooks or other
2419 # lines might depend on this still being active.
2420 del self.dbg
2421
Johnny Chen86268e42011-09-30 21:48:35 +00002422 def switch_to_thread_with_stop_reason(self, stop_reason):
2423 """
2424 Run the 'thread list' command, and select the thread with stop reason as
2425 'stop_reason'. If no such thread exists, no select action is done.
2426 """
2427 from lldbutil import stop_reason_to_str
2428 self.runCmd('thread list')
2429 output = self.res.GetOutput()
2430 thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
2431 stop_reason_to_str(stop_reason))
2432 for line in output.splitlines():
2433 matched = thread_line_pattern.match(line)
2434 if matched:
2435 self.runCmd('thread select %s' % matched.group(1))
2436
Enrico Granata7594f142013-06-17 22:51:50 +00002437 def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
Johnny Chen27f212d2010-08-19 23:26:59 +00002438 """
2439 Ask the command interpreter to handle the command and then check its
2440 return status.
2441 """
2442 # Fail fast if 'cmd' is not meaningful.
2443 if not cmd or len(cmd) == 0:
2444 raise Exception("Bad 'cmd' parameter encountered")
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002445
Johnny Chen8d55a342010-08-31 17:42:54 +00002446 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002447
Daniel Maleae0f8f572013-08-26 23:57:52 +00002448 # This is an opportunity to insert the 'platform target-install' command if we are told so
2449 # via the settig of lldb.lldbtest_remote_sandbox.
2450 if cmd.startswith("target create "):
2451 cmd = cmd.replace("target create ", "file ")
2452 if cmd.startswith("file ") and lldb.lldbtest_remote_sandbox:
2453 with recording(self, trace) as sbuf:
2454 the_rest = cmd.split("file ")[1]
2455 # Split the rest of the command line.
2456 atoms = the_rest.split()
2457 #
2458 # NOTE: This assumes that the options, if any, follow the file command,
2459 # instead of follow the specified target.
2460 #
2461 target = atoms[-1]
2462 # Now let's get the absolute pathname of our target.
2463 abs_target = os.path.abspath(target)
2464 print >> sbuf, "Found a file command, target (with absolute pathname)=%s" % abs_target
2465 fpath, fname = os.path.split(abs_target)
2466 parent_dir = os.path.split(fpath)[0]
2467 platform_target_install_command = 'platform target-install %s %s' % (fpath, lldb.lldbtest_remote_sandbox)
2468 print >> sbuf, "Insert this command to be run first: %s" % platform_target_install_command
2469 self.ci.HandleCommand(platform_target_install_command, self.res)
2470 # And this is the file command we want to execute, instead.
2471 #
2472 # Warning: SIDE EFFECT AHEAD!!!
2473 # Populate the remote executable pathname into the lldb namespace,
2474 # so that test cases can grab this thing out of the namespace.
2475 #
2476 lldb.lldbtest_remote_sandboxed_executable = abs_target.replace(parent_dir, lldb.lldbtest_remote_sandbox)
2477 cmd = "file -P %s %s %s" % (lldb.lldbtest_remote_sandboxed_executable, the_rest.replace(target, ''), abs_target)
2478 print >> sbuf, "And this is the replaced file command: %s" % cmd
2479
Johnny Chen63dfb272010-09-01 00:15:19 +00002480 running = (cmd.startswith("run") or cmd.startswith("process launch"))
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002481
Johnny Chen63dfb272010-09-01 00:15:19 +00002482 for i in range(self.maxLaunchCount if running else 1):
Enrico Granata7594f142013-06-17 22:51:50 +00002483 self.ci.HandleCommand(cmd, self.res, inHistory)
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002484
Johnny Chen150c3cc2010-10-15 01:18:29 +00002485 with recording(self, trace) as sbuf:
2486 print >> sbuf, "runCmd:", cmd
Johnny Chenab254f52010-10-15 16:13:00 +00002487 if not check:
Johnny Chen27b107b2010-10-15 18:52:22 +00002488 print >> sbuf, "check of return status not required"
Johnny Chenf2b70232010-08-25 18:49:48 +00002489 if self.res.Succeeded():
Johnny Chen150c3cc2010-10-15 01:18:29 +00002490 print >> sbuf, "output:", self.res.GetOutput()
Johnny Chenf2b70232010-08-25 18:49:48 +00002491 else:
Johnny Chen150c3cc2010-10-15 01:18:29 +00002492 print >> sbuf, "runCmd failed!"
2493 print >> sbuf, self.res.GetError()
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002494
Johnny Chenff3d01d2010-08-20 21:03:09 +00002495 if self.res.Succeeded():
Johnny Chenf2b70232010-08-25 18:49:48 +00002496 break
Johnny Chen150c3cc2010-10-15 01:18:29 +00002497 elif running:
Johnny Chencf7f74e2011-01-19 02:02:08 +00002498 # For process launch, wait some time before possible next try.
2499 time.sleep(self.timeWaitNextLaunch)
Johnny Chen552d6712012-08-01 19:56:04 +00002500 with recording(self, trace) as sbuf:
Johnny Chen150c3cc2010-10-15 01:18:29 +00002501 print >> sbuf, "Command '" + cmd + "' failed!"
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002502
Johnny Chen27f212d2010-08-19 23:26:59 +00002503 if check:
Sean Callanan05834cd2015-07-01 23:56:30 +00002504 self.assertTrue(self.res.Succeeded(),
2505 msg if msg else CMD_MSG(cmd))
Johnny Chen27f212d2010-08-19 23:26:59 +00002506
Jim Ingham63dfc722012-09-22 00:05:11 +00002507 def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
2508 """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2509
2510 Otherwise, all the arguments have the same meanings as for the expect function"""
2511
2512 trace = (True if traceAlways else trace)
2513
2514 if exe:
2515 # First run the command. If we are expecting error, set check=False.
2516 # Pass the assert message along since it provides more semantic info.
2517 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
2518
2519 # Then compare the output against expected strings.
2520 output = self.res.GetError() if error else self.res.GetOutput()
2521
2522 # If error is True, the API client expects the command to fail!
2523 if error:
2524 self.assertFalse(self.res.Succeeded(),
2525 "Command '" + str + "' is expected to fail!")
2526 else:
2527 # No execution required, just compare str against the golden input.
2528 output = str
2529 with recording(self, trace) as sbuf:
2530 print >> sbuf, "looking at:", output
2531
2532 # The heading says either "Expecting" or "Not expecting".
2533 heading = "Expecting" if matching else "Not expecting"
2534
2535 for pattern in patterns:
2536 # Match Objects always have a boolean value of True.
2537 match_object = re.search(pattern, output)
2538 matched = bool(match_object)
2539 with recording(self, trace) as sbuf:
2540 print >> sbuf, "%s pattern: %s" % (heading, pattern)
2541 print >> sbuf, "Matched" if matched else "Not matched"
2542 if matched:
2543 break
2544
2545 self.assertTrue(matched if matching else not matched,
2546 msg if msg else EXP_MSG(str, exe))
2547
2548 return match_object
2549
Enrico Granata7594f142013-06-17 22:51:50 +00002550 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 +00002551 """
2552 Similar to runCmd; with additional expect style output matching ability.
2553
2554 Ask the command interpreter to handle the command and then check its
2555 return status. The 'msg' parameter specifies an informational assert
2556 message. We expect the output from running the command to start with
Johnny Chenea88e942010-09-21 21:08:53 +00002557 'startstr', matches the substrings contained in 'substrs', and regexp
2558 matches the patterns contained in 'patterns'.
Johnny Chenb3307862010-09-17 22:28:51 +00002559
2560 If the keyword argument error is set to True, it signifies that the API
2561 client is expecting the command to fail. In this case, the error stream
Johnny Chenaa902922010-09-17 22:45:27 +00002562 from running the command is retrieved and compared against the golden
Johnny Chenb3307862010-09-17 22:28:51 +00002563 input, instead.
Johnny Chenea88e942010-09-21 21:08:53 +00002564
2565 If the keyword argument matching is set to False, it signifies that the API
2566 client is expecting the output of the command not to match the golden
2567 input.
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002568
2569 Finally, the required argument 'str' represents the lldb command to be
2570 sent to the command interpreter. In case the keyword argument 'exe' is
2571 set to False, the 'str' is treated as a string to be matched/not-matched
2572 against the golden input.
Johnny Chen27f212d2010-08-19 23:26:59 +00002573 """
Johnny Chen8d55a342010-08-31 17:42:54 +00002574 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002575
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002576 if exe:
2577 # First run the command. If we are expecting error, set check=False.
Johnny Chen62d4f862010-10-28 21:10:32 +00002578 # Pass the assert message along since it provides more semantic info.
Enrico Granata7594f142013-06-17 22:51:50 +00002579 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error, inHistory=inHistory)
Johnny Chen27f212d2010-08-19 23:26:59 +00002580
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002581 # Then compare the output against expected strings.
2582 output = self.res.GetError() if error else self.res.GetOutput()
Johnny Chenb3307862010-09-17 22:28:51 +00002583
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002584 # If error is True, the API client expects the command to fail!
2585 if error:
2586 self.assertFalse(self.res.Succeeded(),
2587 "Command '" + str + "' is expected to fail!")
2588 else:
2589 # No execution required, just compare str against the golden input.
Enrico Granatabc08ab42012-10-23 00:09:02 +00002590 if isinstance(str,lldb.SBCommandReturnObject):
2591 output = str.GetOutput()
2592 else:
2593 output = str
Johnny Chen150c3cc2010-10-15 01:18:29 +00002594 with recording(self, trace) as sbuf:
2595 print >> sbuf, "looking at:", output
Johnny Chenb3307862010-09-17 22:28:51 +00002596
Johnny Chenea88e942010-09-21 21:08:53 +00002597 # The heading says either "Expecting" or "Not expecting".
Johnny Chen150c3cc2010-10-15 01:18:29 +00002598 heading = "Expecting" if matching else "Not expecting"
Johnny Chenea88e942010-09-21 21:08:53 +00002599
2600 # Start from the startstr, if specified.
2601 # If there's no startstr, set the initial state appropriately.
2602 matched = output.startswith(startstr) if startstr else (True if matching else False)
Johnny Chenb145bba2010-08-20 18:25:15 +00002603
Johnny Chen150c3cc2010-10-15 01:18:29 +00002604 if startstr:
2605 with recording(self, trace) as sbuf:
2606 print >> sbuf, "%s start string: %s" % (heading, startstr)
2607 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenb145bba2010-08-20 18:25:15 +00002608
Johnny Chen86268e42011-09-30 21:48:35 +00002609 # Look for endstr, if specified.
2610 keepgoing = matched if matching else not matched
2611 if endstr:
2612 matched = output.endswith(endstr)
2613 with recording(self, trace) as sbuf:
2614 print >> sbuf, "%s end string: %s" % (heading, endstr)
2615 print >> sbuf, "Matched" if matched else "Not matched"
2616
Johnny Chenea88e942010-09-21 21:08:53 +00002617 # Look for sub strings, if specified.
2618 keepgoing = matched if matching else not matched
2619 if substrs and keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002620 for str in substrs:
Johnny Chenb052f6c2010-09-23 23:35:28 +00002621 matched = output.find(str) != -1
Johnny Chen150c3cc2010-10-15 01:18:29 +00002622 with recording(self, trace) as sbuf:
2623 print >> sbuf, "%s sub string: %s" % (heading, str)
2624 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenea88e942010-09-21 21:08:53 +00002625 keepgoing = matched if matching else not matched
2626 if not keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002627 break
2628
Johnny Chenea88e942010-09-21 21:08:53 +00002629 # Search for regular expression patterns, if specified.
2630 keepgoing = matched if matching else not matched
2631 if patterns and keepgoing:
2632 for pattern in patterns:
2633 # Match Objects always have a boolean value of True.
2634 matched = bool(re.search(pattern, output))
Johnny Chen150c3cc2010-10-15 01:18:29 +00002635 with recording(self, trace) as sbuf:
2636 print >> sbuf, "%s pattern: %s" % (heading, pattern)
2637 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenea88e942010-09-21 21:08:53 +00002638 keepgoing = matched if matching else not matched
2639 if not keepgoing:
2640 break
Johnny Chenea88e942010-09-21 21:08:53 +00002641
2642 self.assertTrue(matched if matching else not matched,
Johnny Chenc0c67f22010-11-09 18:42:22 +00002643 msg if msg else EXP_MSG(str, exe))
Johnny Chen27f212d2010-08-19 23:26:59 +00002644
Johnny Chenf3c59232010-08-25 22:52:45 +00002645 def invoke(self, obj, name, trace=False):
Johnny Chen61703c92010-08-25 22:56:10 +00002646 """Use reflection to call a method dynamically with no argument."""
Johnny Chen8d55a342010-08-31 17:42:54 +00002647 trace = (True if traceAlways else trace)
Johnny Chenf3c59232010-08-25 22:52:45 +00002648
2649 method = getattr(obj, name)
2650 import inspect
2651 self.assertTrue(inspect.ismethod(method),
2652 name + "is a method name of object: " + str(obj))
2653 result = method()
Johnny Chen150c3cc2010-10-15 01:18:29 +00002654 with recording(self, trace) as sbuf:
2655 print >> sbuf, str(method) + ":", result
Johnny Chenf3c59232010-08-25 22:52:45 +00002656 return result
Johnny Chen827edff2010-08-27 00:15:48 +00002657
Johnny Chenf359cf22011-05-27 23:36:52 +00002658 # =================================================
2659 # Misc. helper methods for debugging test execution
2660 # =================================================
2661
Johnny Chen56b92a72011-07-11 19:15:11 +00002662 def DebugSBValue(self, val):
Johnny Chen8d55a342010-08-31 17:42:54 +00002663 """Debug print a SBValue object, if traceAlways is True."""
Johnny Chende90f1d2011-04-27 17:43:07 +00002664 from lldbutil import value_type_to_str
Johnny Chen87bb5892010-11-03 21:37:58 +00002665
Johnny Chen8d55a342010-08-31 17:42:54 +00002666 if not traceAlways:
Johnny Chen827edff2010-08-27 00:15:48 +00002667 return
2668
2669 err = sys.stderr
2670 err.write(val.GetName() + ":\n")
Johnny Chen86268e42011-09-30 21:48:35 +00002671 err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n')
2672 err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n')
2673 err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n')
2674 err.write('\t' + "Value -> " + str(val.GetValue()) + '\n')
2675 err.write('\t' + "ValueAsUnsigned -> " + str(val.GetValueAsUnsigned())+ '\n')
2676 err.write('\t' + "ValueType -> " + value_type_to_str(val.GetValueType()) + '\n')
2677 err.write('\t' + "Summary -> " + str(val.GetSummary()) + '\n')
2678 err.write('\t' + "IsPointerType -> " + str(val.TypeIsPointerType()) + '\n')
2679 err.write('\t' + "Location -> " + val.GetLocation() + '\n')
Johnny Chen827edff2010-08-27 00:15:48 +00002680
Johnny Chen36c5eb12011-08-05 20:17:27 +00002681 def DebugSBType(self, type):
2682 """Debug print a SBType object, if traceAlways is True."""
2683 if not traceAlways:
2684 return
2685
2686 err = sys.stderr
2687 err.write(type.GetName() + ":\n")
2688 err.write('\t' + "ByteSize -> " + str(type.GetByteSize()) + '\n')
2689 err.write('\t' + "IsPointerType -> " + str(type.IsPointerType()) + '\n')
2690 err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
2691
Johnny Chenb877f1e2011-03-12 01:18:19 +00002692 def DebugPExpect(self, child):
2693 """Debug the spwaned pexpect object."""
2694 if not traceAlways:
2695 return
2696
2697 print child
Filipe Cabecinhas0eec15a2012-06-20 10:13:40 +00002698
2699 @classmethod
2700 def RemoveTempFile(cls, file):
2701 if os.path.exists(file):
2702 os.remove(file)