blob: dc2aeb2f301fc06c6415f5983be5b7674e24db72 [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
Tamas Berghammercf6f92a2015-09-07 15:50:19 +0000644def expectedFailureAll(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, triple=None):
Ying Chen7091c2c2015-04-21 01:15:47 +0000645 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
Tamas Berghammercf6f92a2015-09-07 15:50:19 +0000648 self.expectedArch(archs) and
649 (triple is None or re.match(triple, lldb.DBG.GetSelectedPlatform().GetTriple())))
Ying Chen7091c2c2015-04-21 01:15:47 +0000650 return expectedFailure(fn, bugnumber)
651
Vince Harron8974ce22015-03-13 19:54:54 +0000652# to XFAIL a specific clang versions, try this
653# @expectedFailureClang('bugnumber', ['<=', '3.4'])
654def expectedFailureClang(bugnumber=None, compiler_version=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000655 return expectedFailureCompiler('clang', compiler_version, bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000656
657def expectedFailureGcc(bugnumber=None, compiler_version=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000658 return expectedFailureCompiler('gcc', compiler_version, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000659
Matt Kopec0de53f02013-03-15 19:10:12 +0000660def expectedFailureIcc(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000661 return expectedFailureCompiler('icc', None, bugnumber)
Matt Kopec0de53f02013-03-15 19:10:12 +0000662
Ed Maste433790a2014-04-23 12:55:41 +0000663def expectedFailureArch(arch, bugnumber=None):
664 def fn(self):
665 return arch in self.getArchitecture()
Ying Chen464d1e12015-03-27 00:26:52 +0000666 return expectedFailure(fn, bugnumber)
Daniel Malea249287a2013-02-19 16:08:57 +0000667
Enrico Granatae6cedc12013-02-23 01:05:23 +0000668def expectedFailurei386(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000669 return expectedFailureArch('i386', bugnumber)
Johnny Chena33843f2011-12-22 21:14:31 +0000670
Matt Kopecee969f92013-09-26 23:30:59 +0000671def expectedFailurex86_64(bugnumber=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000672 return expectedFailureArch('x86_64', bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000673
Robert Flackefa49c22015-03-26 19:34:26 +0000674def expectedFailureOS(oslist, bugnumber=None, compilers=None):
Ed Maste433790a2014-04-23 12:55:41 +0000675 def fn(self):
Robert Flack13c7ad92015-03-30 14:12:17 +0000676 return (self.getPlatform() in oslist and
Robert Flackefa49c22015-03-26 19:34:26 +0000677 self.expectedCompiler(compilers))
Ying Chen464d1e12015-03-27 00:26:52 +0000678 return expectedFailure(fn, bugnumber)
Ed Maste433790a2014-04-23 12:55:41 +0000679
Chaoren Linf7160f32015-06-09 17:39:27 +0000680def expectedFailureHostOS(oslist, bugnumber=None, compilers=None):
681 def fn(self):
682 return (getHostPlatform() in oslist and
683 self.expectedCompiler(compilers))
684 return expectedFailure(fn, bugnumber)
685
Ed Maste433790a2014-04-23 12:55:41 +0000686def expectedFailureDarwin(bugnumber=None, compilers=None):
Robert Flackefa49c22015-03-26 19:34:26 +0000687 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
Greg Claytone0d0a762015-04-02 18:24:03 +0000688 return expectedFailureOS(getDarwinOSTriples(), bugnumber, compilers)
Matt Kopecee969f92013-09-26 23:30:59 +0000689
Ed Maste24a7f7d2013-07-24 19:47:08 +0000690def expectedFailureFreeBSD(bugnumber=None, compilers=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000691 return expectedFailureOS(['freebsd'], bugnumber, compilers)
Ed Maste24a7f7d2013-07-24 19:47:08 +0000692
Ashok Thirumurthic97a6082013-05-17 20:15:07 +0000693def expectedFailureLinux(bugnumber=None, compilers=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000694 return expectedFailureOS(['linux'], bugnumber, compilers)
Matt Kopece9ea0da2013-05-07 19:29:28 +0000695
Zachary Turner80c2c602014-12-09 19:28:00 +0000696def expectedFailureWindows(bugnumber=None, compilers=None):
Ying Chen464d1e12015-03-27 00:26:52 +0000697 return expectedFailureOS(['windows'], bugnumber, compilers)
Zachary Turner80c2c602014-12-09 19:28:00 +0000698
Chaoren Linf7160f32015-06-09 17:39:27 +0000699def expectedFailureHostWindows(bugnumber=None, compilers=None):
700 return expectedFailureHostOS(['windows'], bugnumber, compilers)
701
Pavel Labath090152b2015-08-20 11:37:19 +0000702def matchAndroid(api_levels=None, archs=None):
703 def match(self):
704 if not target_is_android():
705 return False
706 if archs is not None and self.getArchitecture() not in archs:
707 return False
708 if api_levels is not None and android_device_api() not in api_levels:
709 return False
710 return True
711 return match
712
713
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000714def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
Siva Chandra8af91662015-06-05 00:22:49 +0000715 """ Mark a test as xfail for Android.
716
717 Arguments:
718 bugnumber - The LLVM pr associated with the problem.
719 api_levels - A sequence of numbers specifying the Android API levels
Tamas Berghammer050d1e82015-07-22 11:00:06 +0000720 for which a test is expected to fail. None means all API level.
721 arch - A sequence of architecture names specifying the architectures
722 for which a test is expected to fail. None means all architectures.
Siva Chandra8af91662015-06-05 00:22:49 +0000723 """
Pavel Labath090152b2015-08-20 11:37:19 +0000724 return expectedFailure(matchAndroid(api_levels, archs), bugnumber)
Pavel Labath674bc7b2015-05-29 14:54:46 +0000725
Vince Harron7ac3ea42015-06-26 15:13:21 +0000726# if the test passes on the first try, we're done (success)
727# if the test fails once, then passes on the second try, raise an ExpectedFailure
728# if the test fails twice in a row, re-throw the exception from the second test run
729def expectedFlakey(expected_fn, bugnumber=None):
730 def expectedFailure_impl(func):
731 @wraps(func)
732 def wrapper(*args, **kwargs):
733 from unittest2 import case
734 self = args[0]
735 try:
736 func(*args, **kwargs)
Ying Chen0a7202b2015-07-01 22:44:27 +0000737 # don't retry if the test case is already decorated with xfail or skip
738 except (case._ExpectedFailure, case.SkipTest, case._UnexpectedSuccess):
739 raise
Vince Harron7ac3ea42015-06-26 15:13:21 +0000740 except Exception:
741 if expected_fn(self):
Ying Chen0a7202b2015-07-01 22:44:27 +0000742 # before retry, run tearDown for previous run and setup for next
Vince Harron7ac3ea42015-06-26 15:13:21 +0000743 try:
Ying Chen0a7202b2015-07-01 22:44:27 +0000744 self.tearDown()
745 self.setUp()
Vince Harron7ac3ea42015-06-26 15:13:21 +0000746 func(*args, **kwargs)
747 except Exception:
748 # oh snap! two failures in a row, record a failure/error
749 raise
750 # record the expected failure
751 raise case._ExpectedFailure(sys.exc_info(), bugnumber)
752 else:
753 raise
754 return wrapper
755 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
756 # return decorator in this case, so it will be used to decorating original method
757 if callable(bugnumber):
758 return expectedFailure_impl(bugnumber)
759 else:
760 return expectedFailure_impl
761
762def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
763 def fn(self):
764 return (self.getPlatform() in oslist and
765 self.expectedCompiler(compilers))
766 return expectedFlakey(fn, bugnumber)
767
768def expectedFlakeyDarwin(bugnumber=None, compilers=None):
769 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
770 return expectedFlakeyOS(getDarwinOSTriples(), bugnumber, compilers)
771
772def expectedFlakeyLinux(bugnumber=None, compilers=None):
773 return expectedFlakeyOS(['linux'], bugnumber, compilers)
774
775def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
776 return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
777
778def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
779 if compiler_version is None:
780 compiler_version=['=', None]
781 def fn(self):
782 return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
783 return expectedFlakey(fn, bugnumber)
784
785# @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
786def expectedFlakeyClang(bugnumber=None, compiler_version=None):
787 return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
788
789# @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
790def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
791 return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
792
Pavel Labath63a579c2015-09-07 12:15:27 +0000793def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
794 return expectedFlakey(matchAndroid(api_levels, archs), bugnumber)
795
Greg Clayton12514562013-12-05 22:22:32 +0000796def skipIfRemote(func):
797 """Decorate the item to skip tests if testing remotely."""
798 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
799 raise Exception("@skipIfRemote can only be used to decorate a test method")
800 @wraps(func)
801 def wrapper(*args, **kwargs):
802 from unittest2 import case
803 if lldb.remote_platform:
804 self = args[0]
805 self.skipTest("skip on remote platform")
806 else:
807 func(*args, **kwargs)
808 return wrapper
809
Siva Chandra4470f382015-06-17 22:32:27 +0000810def skipUnlessListedRemote(remote_list=None):
811 def myImpl(func):
812 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
813 raise Exception("@skipIfRemote can only be used to decorate a "
814 "test method")
815
816 @wraps(func)
817 def wrapper(*args, **kwargs):
818 if remote_list and lldb.remote_platform:
819 self = args[0]
820 triple = self.dbg.GetSelectedPlatform().GetTriple()
821 for r in remote_list:
822 if r in triple:
823 func(*args, **kwargs)
824 return
825 self.skipTest("skip on remote platform %s" % str(triple))
826 else:
827 func(*args, **kwargs)
828 return wrapper
829
830 return myImpl
831
Greg Clayton12514562013-12-05 22:22:32 +0000832def skipIfRemoteDueToDeadlock(func):
833 """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
834 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
835 raise Exception("@skipIfRemote can only be used to decorate a test method")
836 @wraps(func)
837 def wrapper(*args, **kwargs):
838 from unittest2 import case
839 if lldb.remote_platform:
840 self = args[0]
841 self.skipTest("skip on remote platform (deadlocks)")
842 else:
843 func(*args, **kwargs)
844 return wrapper
845
Enrico Granatab633e432014-10-06 21:37:06 +0000846def skipIfNoSBHeaders(func):
847 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
848 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Ed Maste59cca5d2014-10-07 01:57:52 +0000849 raise Exception("@skipIfNoSBHeaders can only be used to decorate a test method")
Enrico Granatab633e432014-10-06 21:37:06 +0000850 @wraps(func)
851 def wrapper(*args, **kwargs):
852 from unittest2 import case
853 self = args[0]
Shawn Best181b09b2014-11-08 00:04:04 +0000854 if sys.platform.startswith("darwin"):
855 header = os.path.join(self.lib_dir, 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
856 else:
857 header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
Enrico Granatab633e432014-10-06 21:37:06 +0000858 platform = sys.platform
Enrico Granatab633e432014-10-06 21:37:06 +0000859 if not os.path.exists(header):
860 self.skipTest("skip because LLDB.h header not found")
861 else:
862 func(*args, **kwargs)
863 return wrapper
864
Robert Flack13c7ad92015-03-30 14:12:17 +0000865def skipIfFreeBSD(func):
866 """Decorate the item to skip tests that should be skipped on FreeBSD."""
867 return skipIfPlatform(["freebsd"])(func)
Zachary Turnerc7826522014-08-13 17:44:53 +0000868
Greg Claytone0d0a762015-04-02 18:24:03 +0000869def getDarwinOSTriples():
870 return ['darwin', 'macosx', 'ios']
871
Daniel Maleab3d41a22013-07-09 00:08:01 +0000872def skipIfDarwin(func):
873 """Decorate the item to skip tests that should be skipped on Darwin."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000874 return skipIfPlatform(getDarwinOSTriples())(func)
Daniel Maleab3d41a22013-07-09 00:08:01 +0000875
Robert Flack13c7ad92015-03-30 14:12:17 +0000876def skipIfLinux(func):
877 """Decorate the item to skip tests that should be skipped on Linux."""
878 return skipIfPlatform(["linux"])(func)
879
Oleksiy Vyalovabb5a352015-07-29 22:18:16 +0000880def skipUnlessHostLinux(func):
881 """Decorate the item to skip tests that should be skipped on any non Linux host."""
882 return skipUnlessHostPlatform(["linux"])(func)
883
Robert Flack13c7ad92015-03-30 14:12:17 +0000884def skipIfWindows(func):
885 """Decorate the item to skip tests that should be skipped on Windows."""
886 return skipIfPlatform(["windows"])(func)
887
Chaoren Line6eea5d2015-06-08 22:13:28 +0000888def skipIfHostWindows(func):
889 """Decorate the item to skip tests that should be skipped on Windows."""
890 return skipIfHostPlatform(["windows"])(func)
891
Robert Flack13c7ad92015-03-30 14:12:17 +0000892def skipUnlessDarwin(func):
893 """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
Greg Claytone0d0a762015-04-02 18:24:03 +0000894 return skipUnlessPlatform(getDarwinOSTriples())(func)
Robert Flack13c7ad92015-03-30 14:12:17 +0000895
Robert Flack068898c2015-04-09 18:07:58 +0000896def getPlatform():
Robert Flack6e1fd352015-05-15 12:39:33 +0000897 """Returns the target platform which the tests are running on."""
Robert Flack068898c2015-04-09 18:07:58 +0000898 platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
899 if platform.startswith('freebsd'):
900 platform = 'freebsd'
901 return platform
902
Robert Flack6e1fd352015-05-15 12:39:33 +0000903def getHostPlatform():
904 """Returns the host platform running the test suite."""
905 # Attempts to return a platform name matching a target Triple platform.
906 if sys.platform.startswith('linux'):
907 return 'linux'
908 elif sys.platform.startswith('win32'):
909 return 'windows'
910 elif sys.platform.startswith('darwin'):
911 return 'darwin'
912 elif sys.platform.startswith('freebsd'):
913 return 'freebsd'
914 else:
915 return sys.platform
916
Robert Flackfb2f6c62015-04-17 08:02:18 +0000917def platformIsDarwin():
918 """Returns true if the OS triple for the selected platform is any valid apple OS"""
919 return getPlatform() in getDarwinOSTriples()
920
Robert Flack6e1fd352015-05-15 12:39:33 +0000921def skipIfHostIncompatibleWithRemote(func):
922 """Decorate the item to skip tests if binaries built on this host are incompatible."""
923 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
924 raise Exception("@skipIfHostIncompatibleWithRemote can only be used to decorate a test method")
925 @wraps(func)
926 def wrapper(*args, **kwargs):
927 from unittest2 import case
928 self = args[0]
929 host_arch = self.getLldbArchitecture()
930 host_platform = getHostPlatform()
931 target_arch = self.getArchitecture()
Robert Flack4629c4b2015-05-15 18:54:32 +0000932 target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
Robert Flack6e1fd352015-05-15 12:39:33 +0000933 if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
934 self.skipTest("skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch))
935 elif target_platform != host_platform:
936 self.skipTest("skipping because target is %s but host is %s" % (target_platform, host_platform))
937 else:
938 func(*args, **kwargs)
939 return wrapper
940
Chaoren Line6eea5d2015-06-08 22:13:28 +0000941def skipIfHostPlatform(oslist):
942 """Decorate the item to skip tests if running on one of the listed host platforms."""
943 return unittest2.skipIf(getHostPlatform() in oslist,
944 "skip on %s" % (", ".join(oslist)))
945
946def skipUnlessHostPlatform(oslist):
947 """Decorate the item to skip tests unless running on one of the listed host platforms."""
948 return unittest2.skipUnless(getHostPlatform() in oslist,
949 "requires on of %s" % (", ".join(oslist)))
950
Zachary Turner793d9972015-08-14 23:29:24 +0000951def skipUnlessArch(archlist):
952 """Decorate the item to skip tests unless running on one of the listed architectures."""
953 def myImpl(func):
954 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
955 raise Exception("@skipUnlessArch can only be used to decorate a test method")
956
957 @wraps(func)
958 def wrapper(*args, **kwargs):
959 self = args[0]
960 if self.getArchitecture() not in archlist:
961 self.skipTest("skipping for architecture %s (requires one of %s)" %
962 (self.getArchitecture(), ", ".join(archlist)))
963 else:
964 func(*args, **kwargs)
965 return wrapper
966
967 return myImpl
968
Robert Flack13c7ad92015-03-30 14:12:17 +0000969def skipIfPlatform(oslist):
970 """Decorate the item to skip tests if running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +0000971 return unittest2.skipIf(getPlatform() in oslist,
972 "skip on %s" % (", ".join(oslist)))
Robert Flack13c7ad92015-03-30 14:12:17 +0000973
974def skipUnlessPlatform(oslist):
975 """Decorate the item to skip tests unless running on one of the listed platforms."""
Robert Flack068898c2015-04-09 18:07:58 +0000976 return unittest2.skipUnless(getPlatform() in oslist,
977 "requires on of %s" % (", ".join(oslist)))
Daniel Maleab3d41a22013-07-09 00:08:01 +0000978
Daniel Malea48359902013-05-14 20:48:54 +0000979def skipIfLinuxClang(func):
980 """Decorate the item to skip tests that should be skipped if building on
981 Linux with clang.
982 """
983 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
984 raise Exception("@skipIfLinuxClang can only be used to decorate a test method")
985 @wraps(func)
986 def wrapper(*args, **kwargs):
987 from unittest2 import case
988 self = args[0]
989 compiler = self.getCompiler()
Vince Harronc8492672015-05-04 02:59:19 +0000990 platform = self.getPlatform()
991 if "clang" in compiler and platform == "linux":
Daniel Malea48359902013-05-14 20:48:54 +0000992 self.skipTest("skipping because Clang is used on Linux")
993 else:
994 func(*args, **kwargs)
995 return wrapper
996
Ying Chen7091c2c2015-04-21 01:15:47 +0000997# provide a function to skip on defined oslist, compiler version, and archs
998# if none is specified for any argument, that argument won't be checked and thus means for all
999# for example,
1000# @skipIf, skip for all platform/compiler/arch,
1001# @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
1002# @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
1003
1004# TODO: refactor current code, to make skipIfxxx functions to call this function
1005def skipIf(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None):
1006 def fn(self):
1007 return ((oslist is None or self.getPlatform() in oslist) and
1008 (compiler is None or (compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version))) and
1009 self.expectedArch(archs))
1010 return skipTestIfFn(fn, bugnumber, skipReason="skipping because os:%s compiler: %s %s arch: %s"%(oslist, compiler, compiler_version, archs))
1011
1012def skipTestIfFn(expected_fn, bugnumber=None, skipReason=None):
1013 def skipTestIfFn_impl(func):
1014 @wraps(func)
1015 def wrapper(*args, **kwargs):
1016 from unittest2 import case
1017 self = args[0]
1018 if expected_fn(self):
1019 self.skipTest(skipReason)
1020 else:
1021 func(*args, **kwargs)
1022 return wrapper
1023 if callable(bugnumber):
1024 return skipTestIfFn_impl(bugnumber)
1025 else:
1026 return skipTestIfFn_impl
1027
Daniel Maleabe230792013-01-24 23:52:09 +00001028def skipIfGcc(func):
1029 """Decorate the item to skip tests that should be skipped if building with gcc ."""
1030 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
Daniel Malea0aea0162013-02-27 17:29:46 +00001031 raise Exception("@skipIfGcc can only be used to decorate a test method")
Daniel Maleabe230792013-01-24 23:52:09 +00001032 @wraps(func)
1033 def wrapper(*args, **kwargs):
1034 from unittest2 import case
1035 self = args[0]
1036 compiler = self.getCompiler()
1037 if "gcc" in compiler:
1038 self.skipTest("skipping because gcc is the test compiler")
1039 else:
1040 func(*args, **kwargs)
1041 return wrapper
1042
Matt Kopec0de53f02013-03-15 19:10:12 +00001043def skipIfIcc(func):
1044 """Decorate the item to skip tests that should be skipped if building with icc ."""
1045 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1046 raise Exception("@skipIfIcc can only be used to decorate a test method")
1047 @wraps(func)
1048 def wrapper(*args, **kwargs):
1049 from unittest2 import case
1050 self = args[0]
1051 compiler = self.getCompiler()
1052 if "icc" in compiler:
1053 self.skipTest("skipping because icc is the test compiler")
1054 else:
1055 func(*args, **kwargs)
1056 return wrapper
1057
Daniel Malea55faa402013-05-02 21:44:31 +00001058def skipIfi386(func):
1059 """Decorate the item to skip tests that should be skipped if building 32-bit."""
1060 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1061 raise Exception("@skipIfi386 can only be used to decorate a test method")
1062 @wraps(func)
1063 def wrapper(*args, **kwargs):
1064 from unittest2 import case
1065 self = args[0]
1066 if "i386" == self.getArchitecture():
1067 self.skipTest("skipping because i386 is not a supported architecture")
1068 else:
1069 func(*args, **kwargs)
1070 return wrapper
1071
Pavel Labath090152b2015-08-20 11:37:19 +00001072def skipIfTargetAndroid(api_levels=None, archs=None):
Siva Chandra77f20fc2015-06-05 19:54:49 +00001073 """Decorator to skip tests when the target is Android.
1074
1075 Arguments:
1076 api_levels - The API levels for which the test should be skipped. If
1077 it is None, then the test will be skipped for all API levels.
Pavel Labath090152b2015-08-20 11:37:19 +00001078 arch - A sequence of architecture names specifying the architectures
1079 for which a test is skipped. None means all architectures.
Siva Chandra77f20fc2015-06-05 19:54:49 +00001080 """
1081 def myImpl(func):
1082 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1083 raise Exception("@skipIfTargetAndroid can only be used to "
1084 "decorate a test method")
1085 @wraps(func)
1086 def wrapper(*args, **kwargs):
1087 from unittest2 import case
1088 self = args[0]
Pavel Labath090152b2015-08-20 11:37:19 +00001089 if matchAndroid(api_levels, archs)(self):
1090 self.skipTest("skiped on Android target with API %d and architecture %s" %
1091 (android_device_api(), self.getArchitecture()))
Tamas Berghammer1253a812015-03-13 10:12:25 +00001092 func(*args, **kwargs)
Siva Chandra77f20fc2015-06-05 19:54:49 +00001093 return wrapper
1094 return myImpl
Tamas Berghammer1253a812015-03-13 10:12:25 +00001095
Ilia Kd9953052015-03-12 07:19:41 +00001096def skipUnlessCompilerRt(func):
1097 """Decorate the item to skip tests if testing remotely."""
1098 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1099 raise Exception("@skipUnless can only be used to decorate a test method")
1100 @wraps(func)
1101 def wrapper(*args, **kwargs):
1102 from unittest2 import case
1103 import os.path
1104 compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "projects", "compiler-rt")
1105 if not os.path.exists(compilerRtPath):
1106 self = args[0]
1107 self.skipTest("skip if compiler-rt not found")
1108 else:
1109 func(*args, **kwargs)
1110 return wrapper
Daniel Malea55faa402013-05-02 21:44:31 +00001111
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001112class _PlatformContext(object):
1113 """Value object class which contains platform-specific options."""
1114
1115 def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
1116 self.shlib_environment_var = shlib_environment_var
1117 self.shlib_prefix = shlib_prefix
1118 self.shlib_extension = shlib_extension
1119
1120
Johnny Chena74bb0a2011-08-01 18:46:13 +00001121class Base(unittest2.TestCase):
Johnny Chen8334dad2010-10-22 23:15:46 +00001122 """
Johnny Chena74bb0a2011-08-01 18:46:13 +00001123 Abstract base for performing lldb (see TestBase) or other generic tests (see
1124 BenchBase for one example). lldbtest.Base works with the test driver to
1125 accomplish things.
1126
Johnny Chen8334dad2010-10-22 23:15:46 +00001127 """
Enrico Granata5020f952012-10-24 21:42:49 +00001128
Enrico Granata19186272012-10-24 21:44:48 +00001129 # The concrete subclass should override this attribute.
1130 mydir = None
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001131
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001132 # Keep track of the old current working directory.
1133 oldcwd = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001134
Greg Clayton4570d3e2013-12-10 23:19:29 +00001135 @staticmethod
1136 def compute_mydir(test_file):
1137 '''Subclasses should call this function to correctly calculate the required "mydir" attribute as follows:
1138
1139 mydir = TestBase.compute_mydir(__file__)'''
1140 test_dir = os.path.dirname(test_file)
1141 return test_dir[len(os.environ["LLDB_TEST"])+1:]
1142
Johnny Chenfb4264c2011-08-01 19:50:58 +00001143 def TraceOn(self):
1144 """Returns True if we are in trace mode (tracing detailed test execution)."""
1145 return traceAlways
Greg Clayton4570d3e2013-12-10 23:19:29 +00001146
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001147 @classmethod
1148 def setUpClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001149 """
1150 Python unittest framework class setup fixture.
1151 Do current directory manipulation.
1152 """
Johnny Chenf02ec122010-07-03 20:41:42 +00001153 # Fail fast if 'mydir' attribute is not overridden.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001154 if not cls.mydir or len(cls.mydir) == 0:
Johnny Chenf02ec122010-07-03 20:41:42 +00001155 raise Exception("Subclasses must override the 'mydir' attribute.")
Enrico Granata7e137e32012-10-24 18:14:21 +00001156
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001157 # Save old working directory.
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001158 cls.oldcwd = os.getcwd()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001159
1160 # Change current working directory if ${LLDB_TEST} is defined.
1161 # See also dotest.py which sets up ${LLDB_TEST}.
1162 if ("LLDB_TEST" in os.environ):
Vince Harron85d19652015-05-21 19:09:29 +00001163 full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001164 if traceAlways:
Vince Harron85d19652015-05-21 19:09:29 +00001165 print >> sys.stderr, "Change dir to:", full_dir
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001166 os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
1167
Vince Harron85d19652015-05-21 19:09:29 +00001168 if debug_confirm_directory_exclusivity:
Zachary Turnerb48b4042015-05-21 20:16:02 +00001169 import lock
Vince Harron85d19652015-05-21 19:09:29 +00001170 cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
1171 try:
1172 cls.dir_lock.try_acquire()
1173 # write the class that owns the lock into the lock file
1174 cls.dir_lock.handle.write(cls.__name__)
1175 except IOError as ioerror:
1176 # nothing else should have this directory lock
1177 # wait here until we get a lock
1178 cls.dir_lock.acquire()
1179 # read the previous owner from the lock file
1180 lock_id = cls.dir_lock.handle.read()
1181 print >> sys.stderr, "LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id)
1182 raise ioerror
1183
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001184 # Set platform context.
Robert Flackfb2f6c62015-04-17 08:02:18 +00001185 if platformIsDarwin():
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001186 cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
Robert Flackfb2f6c62015-04-17 08:02:18 +00001187 elif getPlatform() == "linux" or getPlatform() == "freebsd":
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001188 cls.platformContext = _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001189 else:
1190 cls.platformContext = None
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00001191
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001192 @classmethod
1193 def tearDownClass(cls):
Johnny Chenda884342010-10-01 22:59:49 +00001194 """
1195 Python unittest framework class teardown fixture.
1196 Do class-wide cleanup.
1197 """
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001198
Johnny Chen0fddfb22011-11-17 19:57:27 +00001199 if doCleanup and not lldb.skip_build_and_cleanup:
Johnny Chen707b3c92010-10-11 22:25:46 +00001200 # First, let's do the platform-specific cleanup.
Peter Collingbourne19f48d52011-06-20 19:06:20 +00001201 module = builder_module()
Zachary Turnerb1490b62015-08-26 19:44:56 +00001202 module.cleanup()
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001203
Johnny Chen707b3c92010-10-11 22:25:46 +00001204 # Subclass might have specific cleanup function defined.
1205 if getattr(cls, "classCleanup", None):
1206 if traceAlways:
1207 print >> sys.stderr, "Call class-specific cleanup function for class:", cls
1208 try:
1209 cls.classCleanup()
1210 except:
1211 exc_type, exc_value, exc_tb = sys.exc_info()
1212 traceback.print_exception(exc_type, exc_value, exc_tb)
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001213
Vince Harron85d19652015-05-21 19:09:29 +00001214 if debug_confirm_directory_exclusivity:
1215 cls.dir_lock.release()
1216 del cls.dir_lock
1217
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001218 # Restore old working directory.
1219 if traceAlways:
Johnny Chen703dbd02010-09-30 17:06:24 +00001220 print >> sys.stderr, "Restore dir to:", cls.oldcwd
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001221 os.chdir(cls.oldcwd)
1222
Johnny Chena74bb0a2011-08-01 18:46:13 +00001223 @classmethod
1224 def skipLongRunningTest(cls):
1225 """
1226 By default, we skip long running test case.
1227 This can be overridden by passing '-l' to the test driver (dotest.py).
1228 """
1229 if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
1230 return False
1231 else:
1232 return True
Johnny Chened492022011-06-21 00:53:00 +00001233
Vince Harron6d3d0f12015-05-10 22:01:59 +00001234 def enableLogChannelsForCurrentTest(self):
1235 if len(lldbtest_config.channels) == 0:
1236 return
1237
1238 # if debug channels are specified in lldbtest_config.channels,
1239 # create a new set of log files for every test
1240 log_basename = self.getLogBasenameForCurrentTest()
1241
1242 # confirm that the file is writeable
1243 host_log_path = "{}-host.log".format(log_basename)
1244 open(host_log_path, 'w').close()
1245
1246 log_enable = "log enable -Tpn -f {} ".format(host_log_path)
1247 for channel_with_categories in lldbtest_config.channels:
1248 channel_then_categories = channel_with_categories.split(' ', 1)
1249 channel = channel_then_categories[0]
1250 if len(channel_then_categories) > 1:
1251 categories = channel_then_categories[1]
1252 else:
1253 categories = "default"
1254
1255 if channel == "gdb-remote":
1256 # communicate gdb-remote categories to debugserver
1257 os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
1258
1259 self.ci.HandleCommand(log_enable + channel_with_categories, self.res)
1260 if not self.res.Succeeded():
1261 raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
1262
1263 # Communicate log path name to debugserver & lldb-server
1264 server_log_path = "{}-server.log".format(log_basename)
1265 open(server_log_path, 'w').close()
1266 os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
1267
1268 # Communicate channels to lldb-server
1269 os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
1270
1271 if len(lldbtest_config.channels) == 0:
1272 return
1273
1274 def disableLogChannelsForCurrentTest(self):
1275 # close all log files that we opened
1276 for channel_and_categories in lldbtest_config.channels:
1277 # channel format - <channel-name> [<category0> [<category1> ...]]
1278 channel = channel_and_categories.split(' ', 1)[0]
1279 self.ci.HandleCommand("log disable " + channel, self.res)
1280 if not self.res.Succeeded():
1281 raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
1282
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001283 def setUp(self):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001284 """Fixture for unittest test case setup.
1285
1286 It works with the test driver to conditionally skip tests and does other
1287 initializations."""
Johnny Chen1a9f4dd2010-09-16 01:53:04 +00001288 #import traceback
1289 #traceback.print_stack()
Johnny Chenbf6ffa32010-07-03 03:41:59 +00001290
Daniel Malea9115f072013-08-06 15:02:32 +00001291 if "LIBCXX_PATH" in os.environ:
1292 self.libcxxPath = os.environ["LIBCXX_PATH"]
1293 else:
1294 self.libcxxPath = None
1295
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001296 if "LLDBMI_EXEC" in os.environ:
1297 self.lldbMiExec = os.environ["LLDBMI_EXEC"]
1298 else:
1299 self.lldbMiExec = None
1300 self.dont_do_lldbmi_test = True
Vince Harron790d95c2015-05-18 19:39:03 +00001301
Johnny Chenebe51722011-10-07 19:21:09 +00001302 # If we spawn an lldb process for test (via pexpect), do not load the
1303 # init file unless told otherwise.
1304 if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
1305 self.lldbOption = ""
1306 else:
1307 self.lldbOption = "--no-lldbinit"
Johnny Chenaaa82ff2011-08-02 22:54:37 +00001308
Johnny Chen985e7402011-08-01 21:13:26 +00001309 # Assign the test method name to self.testMethodName.
1310 #
1311 # For an example of the use of this attribute, look at test/types dir.
1312 # There are a bunch of test cases under test/types and we don't want the
1313 # module cacheing subsystem to be confused with executable name "a.out"
1314 # used for all the test cases.
1315 self.testMethodName = self._testMethodName
1316
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001317 # Python API only test is decorated with @python_api_test,
1318 # which also sets the "__python_api_test__" attribute of the
1319 # function object to True.
Johnny Chen4533dad2011-05-31 23:21:42 +00001320 try:
1321 if lldb.just_do_python_api_test:
1322 testMethod = getattr(self, self._testMethodName)
1323 if getattr(testMethod, "__python_api_test__", False):
1324 pass
1325 else:
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001326 self.skipTest("non python api test")
1327 except AttributeError:
1328 pass
1329
Hafiz Abid Qadeer1cbac4e2014-11-25 10:41:57 +00001330 # lldb-mi only test is decorated with @lldbmi_test,
1331 # which also sets the "__lldbmi_test__" attribute of the
1332 # function object to True.
1333 try:
1334 if lldb.just_do_lldbmi_test:
1335 testMethod = getattr(self, self._testMethodName)
1336 if getattr(testMethod, "__lldbmi_test__", False):
1337 pass
1338 else:
1339 self.skipTest("non lldb-mi test")
1340 except AttributeError:
1341 pass
1342
Johnny Chen5ccbccf2011-07-30 01:39:58 +00001343 # Benchmarks test is decorated with @benchmarks_test,
1344 # which also sets the "__benchmarks_test__" attribute of the
1345 # function object to True.
1346 try:
1347 if lldb.just_do_benchmarks_test:
1348 testMethod = getattr(self, self._testMethodName)
1349 if getattr(testMethod, "__benchmarks_test__", False):
1350 pass
1351 else:
1352 self.skipTest("non benchmarks test")
Johnny Chen4533dad2011-05-31 23:21:42 +00001353 except AttributeError:
1354 pass
Johnny Chenf3e22ac2010-12-10 18:52:10 +00001355
Johnny Chen985e7402011-08-01 21:13:26 +00001356 # This is for the case of directly spawning 'lldb'/'gdb' and interacting
1357 # with it using pexpect.
1358 self.child = None
1359 self.child_prompt = "(lldb) "
1360 # If the child is interacting with the embedded script interpreter,
1361 # there are two exits required during tear down, first to quit the
1362 # embedded script interpreter and second to quit the lldb command
1363 # interpreter.
1364 self.child_in_script_interpreter = False
1365
Johnny Chenfb4264c2011-08-01 19:50:58 +00001366 # These are for customized teardown cleanup.
1367 self.dict = None
1368 self.doTearDownCleanup = False
1369 # And in rare cases where there are multiple teardown cleanups.
1370 self.dicts = []
1371 self.doTearDownCleanups = False
1372
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001373 # List of spawned subproces.Popen objects
1374 self.subprocesses = []
1375
Daniel Malea69207462013-06-05 21:07:02 +00001376 # List of forked process PIDs
1377 self.forkedProcessPids = []
1378
Johnny Chenfb4264c2011-08-01 19:50:58 +00001379 # Create a string buffer to record the session info, to be dumped into a
1380 # test case specific file if test failure is encountered.
Vince Harron1f160372015-05-21 18:51:20 +00001381 self.log_basename = self.getLogBasenameForCurrentTest()
Vince Harron35b17dc2015-05-21 18:20:21 +00001382
Vince Harron1f160372015-05-21 18:51:20 +00001383 session_file = "{}.log".format(self.log_basename)
Vince Harron35b17dc2015-05-21 18:20:21 +00001384 unbuffered = 0 # 0 is the constant for unbuffered
Vince Harron1f160372015-05-21 18:51:20 +00001385 self.session = open(session_file, "w", unbuffered)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001386
1387 # Optimistically set __errored__, __failed__, __expected__ to False
1388 # initially. If the test errored/failed, the session info
1389 # (self.session) is then dumped into a session specific file for
1390 # diagnosis.
Zachary Turnerb1490b62015-08-26 19:44:56 +00001391 self.__cleanup_errored__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001392 self.__errored__ = False
1393 self.__failed__ = False
1394 self.__expected__ = False
1395 # We are also interested in unexpected success.
1396 self.__unexpected__ = False
Johnny Chenf79b0762011-08-16 00:48:58 +00001397 # And skipped tests.
1398 self.__skipped__ = False
Johnny Chenfb4264c2011-08-01 19:50:58 +00001399
1400 # See addTearDownHook(self, hook) which allows the client to add a hook
1401 # function to be run during tearDown() time.
1402 self.hooks = []
1403
1404 # See HideStdout(self).
1405 self.sys_stdout_hidden = False
1406
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00001407 if self.platformContext:
1408 # set environment variable names for finding shared libraries
1409 self.dylibPath = self.platformContext.shlib_environment_var
Daniel Malea179ff292012-11-26 21:21:11 +00001410
Vince Harron6d3d0f12015-05-10 22:01:59 +00001411 # Create the debugger instance if necessary.
1412 try:
1413 self.dbg = lldb.DBG
1414 except AttributeError:
1415 self.dbg = lldb.SBDebugger.Create()
1416
1417 if not self.dbg:
1418 raise Exception('Invalid debugger instance')
1419
1420 # Retrieve the associated command interpreter instance.
1421 self.ci = self.dbg.GetCommandInterpreter()
1422 if not self.ci:
1423 raise Exception('Could not get the command interpreter')
1424
1425 # And the result object.
1426 self.res = lldb.SBCommandReturnObject()
1427
1428 self.enableLogChannelsForCurrentTest()
1429
Johnny Chen2a808582011-10-19 16:48:07 +00001430 def runHooks(self, child=None, child_prompt=None, use_cmd_api=False):
Johnny Chena737ba52011-10-19 01:06:21 +00001431 """Perform the run hooks to bring lldb debugger to the desired state.
1432
Johnny Chen2a808582011-10-19 16:48:07 +00001433 By default, expect a pexpect spawned child and child prompt to be
1434 supplied (use_cmd_api=False). If use_cmd_api is true, ignore the child
1435 and child prompt and use self.runCmd() to run the hooks one by one.
1436
Johnny Chena737ba52011-10-19 01:06:21 +00001437 Note that child is a process spawned by pexpect.spawn(). If not, your
1438 test case is mostly likely going to fail.
1439
1440 See also dotest.py where lldb.runHooks are processed/populated.
1441 """
1442 if not lldb.runHooks:
1443 self.skipTest("No runhooks specified for lldb, skip the test")
Johnny Chen2a808582011-10-19 16:48:07 +00001444 if use_cmd_api:
1445 for hook in lldb.runhooks:
1446 self.runCmd(hook)
1447 else:
1448 if not child or not child_prompt:
1449 self.fail("Both child and child_prompt need to be defined.")
1450 for hook in lldb.runHooks:
1451 child.sendline(hook)
1452 child.expect_exact(child_prompt)
Johnny Chena737ba52011-10-19 01:06:21 +00001453
Daniel Malea249287a2013-02-19 16:08:57 +00001454 def setAsync(self, value):
1455 """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
1456 old_async = self.dbg.GetAsync()
1457 self.dbg.SetAsync(value)
1458 self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
1459
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001460 def cleanupSubprocesses(self):
1461 # Ensure any subprocesses are cleaned up
1462 for p in self.subprocesses:
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001463 p.terminate()
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001464 del p
1465 del self.subprocesses[:]
Daniel Malea69207462013-06-05 21:07:02 +00001466 # Ensure any forked processes are cleaned up
1467 for pid in self.forkedProcessPids:
1468 if os.path.exists("/proc/" + str(pid)):
1469 os.kill(pid, signal.SIGTERM)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001470
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001471 def spawnSubprocess(self, executable, args=[], install_remote=True):
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001472 """ Creates a subprocess.Popen object with the specified executable and arguments,
1473 saves it in self.subprocesses, and returns the object.
1474 NOTE: if using this function, ensure you also call:
1475
1476 self.addTearDownHook(self.cleanupSubprocesses)
1477
1478 otherwise the test suite will leak processes.
1479 """
Tamas Berghammer04f51d12015-03-11 13:51:07 +00001480 proc = _RemoteProcess(install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
Oleksiy Vyalov1ef7b2c2015-02-04 23:19:15 +00001481 proc.launch(executable, args)
Daniel Malea2dd69bb2013-02-15 21:21:52 +00001482 self.subprocesses.append(proc)
1483 return proc
1484
Daniel Malea69207462013-06-05 21:07:02 +00001485 def forkSubprocess(self, executable, args=[]):
1486 """ Fork a subprocess with its own group ID.
1487 NOTE: if using this function, ensure you also call:
1488
1489 self.addTearDownHook(self.cleanupSubprocesses)
1490
1491 otherwise the test suite will leak processes.
1492 """
1493 child_pid = os.fork()
1494 if child_pid == 0:
1495 # If more I/O support is required, this can be beefed up.
1496 fd = os.open(os.devnull, os.O_RDWR)
Daniel Malea69207462013-06-05 21:07:02 +00001497 os.dup2(fd, 1)
1498 os.dup2(fd, 2)
1499 # This call causes the child to have its of group ID
1500 os.setpgid(0,0)
1501 os.execvp(executable, [executable] + args)
1502 # Give the child time to get through the execvp() call
1503 time.sleep(0.1)
1504 self.forkedProcessPids.append(child_pid)
1505 return child_pid
1506
Johnny Chenfb4264c2011-08-01 19:50:58 +00001507 def HideStdout(self):
1508 """Hide output to stdout from the user.
1509
1510 During test execution, there might be cases where we don't want to show the
1511 standard output to the user. For example,
1512
1513 self.runCmd(r'''sc print "\n\n\tHello!\n"''')
1514
1515 tests whether command abbreviation for 'script' works or not. There is no
1516 need to show the 'Hello' output to the user as long as the 'script' command
1517 succeeds and we are not in TraceOn() mode (see the '-t' option).
1518
1519 In this case, the test method calls self.HideStdout(self) to redirect the
1520 sys.stdout to a null device, and restores the sys.stdout upon teardown.
1521
1522 Note that you should only call this method at most once during a test case
1523 execution. Any subsequent call has no effect at all."""
1524 if self.sys_stdout_hidden:
1525 return
1526
1527 self.sys_stdout_hidden = True
1528 old_stdout = sys.stdout
1529 sys.stdout = open(os.devnull, 'w')
1530 def restore_stdout():
1531 sys.stdout = old_stdout
1532 self.addTearDownHook(restore_stdout)
1533
1534 # =======================================================================
1535 # Methods for customized teardown cleanups as well as execution of hooks.
1536 # =======================================================================
1537
1538 def setTearDownCleanup(self, dictionary=None):
1539 """Register a cleanup action at tearDown() time with a dictinary"""
1540 self.dict = dictionary
1541 self.doTearDownCleanup = True
1542
1543 def addTearDownCleanup(self, dictionary):
1544 """Add a cleanup action at tearDown() time with a dictinary"""
1545 self.dicts.append(dictionary)
1546 self.doTearDownCleanups = True
1547
1548 def addTearDownHook(self, hook):
1549 """
1550 Add a function to be run during tearDown() time.
1551
1552 Hooks are executed in a first come first serve manner.
1553 """
1554 if callable(hook):
1555 with recording(self, traceAlways) as sbuf:
1556 print >> sbuf, "Adding tearDown hook:", getsource_if_available(hook)
1557 self.hooks.append(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001558
1559 return self
Johnny Chenfb4264c2011-08-01 19:50:58 +00001560
Jim Inghamda3a3862014-10-16 23:02:14 +00001561 def deletePexpectChild(self):
Johnny Chen985e7402011-08-01 21:13:26 +00001562 # This is for the case of directly spawning 'lldb' and interacting with it
1563 # using pexpect.
Johnny Chen985e7402011-08-01 21:13:26 +00001564 if self.child and self.child.isalive():
Zachary Turner9ef307b2014-07-22 16:19:29 +00001565 import pexpect
Johnny Chen985e7402011-08-01 21:13:26 +00001566 with recording(self, traceAlways) as sbuf:
1567 print >> sbuf, "tearing down the child process...."
Johnny Chen985e7402011-08-01 21:13:26 +00001568 try:
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001569 if self.child_in_script_interpreter:
1570 self.child.sendline('quit()')
1571 self.child.expect_exact(self.child_prompt)
1572 self.child.sendline('settings set interpreter.prompt-on-quit false')
1573 self.child.sendline('quit')
Johnny Chen985e7402011-08-01 21:13:26 +00001574 self.child.expect(pexpect.EOF)
Ilia K47448c22015-02-11 21:41:58 +00001575 except (ValueError, pexpect.ExceptionPexpect):
1576 # child is already terminated
1577 pass
1578 except OSError as exception:
1579 import errno
1580 if exception.errno != errno.EIO:
1581 # unexpected error
1582 raise
Daniel Maleac9a0ec32013-02-22 00:41:26 +00001583 # child is already terminated
Johnny Chen985e7402011-08-01 21:13:26 +00001584 pass
Shawn Besteb3e9052014-11-06 17:52:15 +00001585 finally:
1586 # Give it one final blow to make sure the child is terminated.
1587 self.child.close()
Jim Inghamda3a3862014-10-16 23:02:14 +00001588
1589 def tearDown(self):
1590 """Fixture for unittest test case teardown."""
1591 #import traceback
1592 #traceback.print_stack()
1593
1594 self.deletePexpectChild()
1595
Johnny Chenfb4264c2011-08-01 19:50:58 +00001596 # Check and run any hook functions.
1597 for hook in reversed(self.hooks):
1598 with recording(self, traceAlways) as sbuf:
1599 print >> sbuf, "Executing tearDown hook:", getsource_if_available(hook)
Enrico Granataab0e8312014-11-05 21:31:57 +00001600 import inspect
1601 hook_argc = len(inspect.getargspec(hook).args)
Enrico Granata6e0566c2014-11-17 19:00:20 +00001602 if hook_argc == 0 or getattr(hook,'im_self',None):
Enrico Granataab0e8312014-11-05 21:31:57 +00001603 hook()
1604 elif hook_argc == 1:
1605 hook(self)
1606 else:
1607 hook() # try the plain call and hope it works
Johnny Chenfb4264c2011-08-01 19:50:58 +00001608
1609 del self.hooks
1610
1611 # Perform registered teardown cleanup.
1612 if doCleanup and self.doTearDownCleanup:
Johnny Chen0fddfb22011-11-17 19:57:27 +00001613 self.cleanup(dictionary=self.dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001614
1615 # In rare cases where there are multiple teardown cleanups added.
1616 if doCleanup and self.doTearDownCleanups:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001617 if self.dicts:
1618 for dict in reversed(self.dicts):
Johnny Chen0fddfb22011-11-17 19:57:27 +00001619 self.cleanup(dictionary=dict)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001620
Vince Harron9753dd92015-05-10 15:22:09 +00001621 self.disableLogChannelsForCurrentTest()
1622
Johnny Chenfb4264c2011-08-01 19:50:58 +00001623 # =========================================================
1624 # Various callbacks to allow introspection of test progress
1625 # =========================================================
1626
1627 def markError(self):
1628 """Callback invoked when an error (unexpected exception) errored."""
1629 self.__errored__ = True
1630 with recording(self, False) as sbuf:
1631 # False because there's no need to write "ERROR" to the stderr twice.
1632 # Once by the Python unittest framework, and a second time by us.
1633 print >> sbuf, "ERROR"
1634
Zachary Turnerb1490b62015-08-26 19:44:56 +00001635 def markCleanupError(self):
1636 """Callback invoked when an error occurs while a test is cleaning up."""
1637 self.__cleanup_errored__ = True
1638 with recording(self, False) as sbuf:
1639 # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
1640 # Once by the Python unittest framework, and a second time by us.
1641 print >> sbuf, "CLEANUP_ERROR"
1642
Johnny Chenfb4264c2011-08-01 19:50:58 +00001643 def markFailure(self):
1644 """Callback invoked when a failure (test assertion failure) occurred."""
1645 self.__failed__ = True
1646 with recording(self, False) as sbuf:
1647 # False because there's no need to write "FAIL" to the stderr twice.
1648 # Once by the Python unittest framework, and a second time by us.
1649 print >> sbuf, "FAIL"
1650
Enrico Granatae6cedc12013-02-23 01:05:23 +00001651 def markExpectedFailure(self,err,bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001652 """Callback invoked when an expected failure/error occurred."""
1653 self.__expected__ = True
1654 with recording(self, False) as sbuf:
1655 # False because there's no need to write "expected failure" to the
1656 # stderr twice.
1657 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001658 if bugnumber == None:
1659 print >> sbuf, "expected failure"
1660 else:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001661 print >> sbuf, "expected failure (problem id:" + str(bugnumber) + ")"
Johnny Chenfb4264c2011-08-01 19:50:58 +00001662
Johnny Chenc5cc6252011-08-15 23:09:08 +00001663 def markSkippedTest(self):
1664 """Callback invoked when a test is skipped."""
1665 self.__skipped__ = True
1666 with recording(self, False) as sbuf:
1667 # False because there's no need to write "skipped test" to the
1668 # stderr twice.
1669 # Once by the Python unittest framework, and a second time by us.
1670 print >> sbuf, "skipped test"
1671
Enrico Granatae6cedc12013-02-23 01:05:23 +00001672 def markUnexpectedSuccess(self, bugnumber):
Johnny Chenfb4264c2011-08-01 19:50:58 +00001673 """Callback invoked when an unexpected success occurred."""
1674 self.__unexpected__ = True
1675 with recording(self, False) as sbuf:
1676 # False because there's no need to write "unexpected success" to the
1677 # stderr twice.
1678 # Once by the Python unittest framework, and a second time by us.
Enrico Granatae6cedc12013-02-23 01:05:23 +00001679 if bugnumber == None:
1680 print >> sbuf, "unexpected success"
1681 else:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00001682 print >> sbuf, "unexpected success (problem id:" + str(bugnumber) + ")"
Johnny Chenfb4264c2011-08-01 19:50:58 +00001683
Greg Clayton70995582015-01-07 22:25:50 +00001684 def getRerunArgs(self):
1685 return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
Vince Harron9753dd92015-05-10 15:22:09 +00001686
1687 def getLogBasenameForCurrentTest(self, prefix=None):
1688 """
1689 returns a partial path that can be used as the beginning of the name of multiple
1690 log files pertaining to this test
1691
1692 <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
1693 """
1694 dname = os.path.join(os.environ["LLDB_TEST"],
1695 os.environ["LLDB_SESSION_DIRNAME"])
1696 if not os.path.isdir(dname):
1697 os.mkdir(dname)
1698
1699 compiler = self.getCompiler()
1700
1701 if compiler[1] == ':':
1702 compiler = compiler[2:]
Chaoren Lin636a0e32015-07-17 21:40:11 +00001703 if os.path.altsep is not None:
1704 compiler = compiler.replace(os.path.altsep, os.path.sep)
Vince Harron9753dd92015-05-10 15:22:09 +00001705
Vince Harron19e300f2015-05-12 00:50:54 +00001706 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
Vince Harron9753dd92015-05-10 15:22:09 +00001707 if len(fname) > 200:
Vince Harron19e300f2015-05-12 00:50:54 +00001708 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
Vince Harron9753dd92015-05-10 15:22:09 +00001709
1710 if prefix is not None:
1711 fname = "{}-{}".format(prefix, fname)
1712
1713 return os.path.join(dname, fname)
1714
Johnny Chenfb4264c2011-08-01 19:50:58 +00001715 def dumpSessionInfo(self):
1716 """
1717 Dump the debugger interactions leading to a test error/failure. This
1718 allows for more convenient postmortem analysis.
1719
1720 See also LLDBTestResult (dotest.py) which is a singlton class derived
1721 from TextTestResult and overwrites addError, addFailure, and
1722 addExpectedFailure methods to allow us to to mark the test instance as
1723 such.
1724 """
1725
1726 # We are here because self.tearDown() detected that this test instance
1727 # either errored or failed. The lldb.test_result singleton contains
1728 # two lists (erros and failures) which get populated by the unittest
1729 # framework. Look over there for stack trace information.
1730 #
1731 # The lists contain 2-tuples of TestCase instances and strings holding
1732 # formatted tracebacks.
1733 #
1734 # See http://docs.python.org/library/unittest.html#unittest.TestResult.
Vince Harron9753dd92015-05-10 15:22:09 +00001735
Vince Harron35b17dc2015-05-21 18:20:21 +00001736 # output tracebacks into session
Vince Harron9753dd92015-05-10 15:22:09 +00001737 pairs = []
Johnny Chenfb4264c2011-08-01 19:50:58 +00001738 if self.__errored__:
1739 pairs = lldb.test_result.errors
1740 prefix = 'Error'
Zachary Turnerb1490b62015-08-26 19:44:56 +00001741 if self.__cleanup_errored__:
1742 pairs = lldb.test_result.cleanup_errors
1743 prefix = 'CleanupError'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001744 elif self.__failed__:
1745 pairs = lldb.test_result.failures
1746 prefix = 'Failure'
1747 elif self.__expected__:
1748 pairs = lldb.test_result.expectedFailures
1749 prefix = 'ExpectedFailure'
Johnny Chenc5cc6252011-08-15 23:09:08 +00001750 elif self.__skipped__:
1751 prefix = 'SkippedTest'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001752 elif self.__unexpected__:
Vince Harron35b17dc2015-05-21 18:20:21 +00001753 prefix = 'UnexpectedSuccess'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001754 else:
Vince Harron35b17dc2015-05-21 18:20:21 +00001755 prefix = 'Success'
Johnny Chenfb4264c2011-08-01 19:50:58 +00001756
Johnny Chenc5cc6252011-08-15 23:09:08 +00001757 if not self.__unexpected__ and not self.__skipped__:
Johnny Chenfb4264c2011-08-01 19:50:58 +00001758 for test, traceback in pairs:
1759 if test is self:
1760 print >> self.session, traceback
1761
Vince Harron35b17dc2015-05-21 18:20:21 +00001762 # put footer (timestamp/rerun instructions) into session
Johnny Chen8082a002011-08-11 00:16:28 +00001763 testMethod = getattr(self, self._testMethodName)
1764 if getattr(testMethod, "__benchmarks_test__", False):
1765 benchmarks = True
1766 else:
1767 benchmarks = False
1768
Vince Harron35b17dc2015-05-21 18:20:21 +00001769 import datetime
1770 print >> self.session, "Session info generated @", datetime.datetime.now().ctime()
1771 print >> self.session, "To rerun this test, issue the following command from the 'test' directory:\n"
1772 print >> self.session, "./dotest.py %s -v %s %s" % (self.getRunOptions(),
1773 ('+b' if benchmarks else '-t'),
1774 self.getRerunArgs())
1775 self.session.close()
1776 del self.session
1777
1778 # process the log files
Vince Harron1f160372015-05-21 18:51:20 +00001779 log_files_for_this_test = glob.glob(self.log_basename + "*")
Vince Harron35b17dc2015-05-21 18:20:21 +00001780
1781 if prefix != 'Success' or lldbtest_config.log_success:
1782 # keep all log files, rename them to include prefix
1783 dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1784 for src in log_files_for_this_test:
Zachary Turner306278f2015-05-26 20:26:29 +00001785 if os.path.isfile(src):
1786 dst = src.replace(self.log_basename, dst_log_basename)
1787 if os.name == "nt" and os.path.isfile(dst):
1788 # On Windows, renaming a -> b will throw an exception if b exists. On non-Windows platforms
1789 # it silently replaces the destination. Ultimately this means that atomic renames are not
1790 # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
1791 # destination first if it already exists.
1792 os.remove(dst)
Zachary Turner5de068b2015-05-26 19:52:24 +00001793
Zachary Turner306278f2015-05-26 20:26:29 +00001794 os.rename(src, dst)
Vince Harron35b17dc2015-05-21 18:20:21 +00001795 else:
1796 # success! (and we don't want log files) delete log files
1797 for log_file in log_files_for_this_test:
Adrian McCarthya7292042015-09-04 20:48:48 +00001798 try:
1799 os.unlink(log_file)
1800 except:
1801 # We've seen consistent unlink failures on Windows, perhaps because the
1802 # just-created log file is being scanned by anti-virus. Empirically, this
1803 # sleep-and-retry approach allows tests to succeed much more reliably.
1804 # Attempts to figure out exactly what process was still holding a file handle
1805 # have failed because running instrumentation like Process Monitor seems to
1806 # slow things down enough that the problem becomes much less consistent.
1807 time.sleep(0.5)
1808 os.unlink(log_file)
Johnny Chenfb4264c2011-08-01 19:50:58 +00001809
1810 # ====================================================
1811 # Config. methods supported through a plugin interface
1812 # (enables reading of the current test configuration)
1813 # ====================================================
1814
1815 def getArchitecture(self):
1816 """Returns the architecture in effect the test suite is running with."""
1817 module = builder_module()
Ed Maste0f434e62015-04-06 15:50:48 +00001818 arch = module.getArchitecture()
1819 if arch == 'amd64':
1820 arch = 'x86_64'
1821 return arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00001822
Vince Harron02613762015-05-04 00:17:53 +00001823 def getLldbArchitecture(self):
1824 """Returns the architecture of the lldb binary."""
1825 if not hasattr(self, 'lldbArchitecture'):
1826
1827 # spawn local process
1828 command = [
Vince Harron790d95c2015-05-18 19:39:03 +00001829 lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001830 "-o",
Vince Harron790d95c2015-05-18 19:39:03 +00001831 "file " + lldbtest_config.lldbExec,
Vince Harron02613762015-05-04 00:17:53 +00001832 "-o",
1833 "quit"
1834 ]
1835
1836 output = check_output(command)
1837 str = output.decode("utf-8");
1838
1839 for line in str.splitlines():
1840 m = re.search("Current executable set to '.*' \\((.*)\\)\\.", line)
1841 if m:
1842 self.lldbArchitecture = m.group(1)
1843 break
1844
1845 return self.lldbArchitecture
1846
Johnny Chenfb4264c2011-08-01 19:50:58 +00001847 def getCompiler(self):
1848 """Returns the compiler in effect the test suite is running with."""
1849 module = builder_module()
1850 return module.getCompiler()
1851
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001852 def getCompilerBinary(self):
1853 """Returns the compiler binary the test suite is running with."""
1854 return self.getCompiler().split()[0]
1855
Daniel Malea0aea0162013-02-27 17:29:46 +00001856 def getCompilerVersion(self):
1857 """ Returns a string that represents the compiler version.
1858 Supports: llvm, clang.
1859 """
1860 from lldbutil import which
1861 version = 'unknown'
1862
Oleksiy Vyalovdc4067c2014-11-26 18:30:04 +00001863 compiler = self.getCompilerBinary()
Zachary Turner9ef307b2014-07-22 16:19:29 +00001864 version_output = system([[which(compiler), "-v"]])[1]
Daniel Malea0aea0162013-02-27 17:29:46 +00001865 for line in version_output.split(os.linesep):
Greg Clayton2a844b72013-03-06 02:34:51 +00001866 m = re.search('version ([0-9\.]+)', line)
Daniel Malea0aea0162013-02-27 17:29:46 +00001867 if m:
1868 version = m.group(1)
1869 return version
1870
Greg Claytone0d0a762015-04-02 18:24:03 +00001871 def platformIsDarwin(self):
1872 """Returns true if the OS triple for the selected platform is any valid apple OS"""
Robert Flackfb2f6c62015-04-17 08:02:18 +00001873 return platformIsDarwin()
Vince Harron20952cc2015-04-03 01:00:06 +00001874
Robert Flack13c7ad92015-03-30 14:12:17 +00001875 def getPlatform(self):
Robert Flackfb2f6c62015-04-17 08:02:18 +00001876 """Returns the target platform the test suite is running on."""
Robert Flack068898c2015-04-09 18:07:58 +00001877 return getPlatform()
Robert Flack13c7ad92015-03-30 14:12:17 +00001878
Daniel Maleaadaaec92013-08-06 20:51:41 +00001879 def isIntelCompiler(self):
1880 """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1881 return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1882
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001883 def expectedCompilerVersion(self, compiler_version):
1884 """Returns True iff compiler_version[1] matches the current compiler version.
1885 Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1886 Any operator other than the following defaults to an equality test:
1887 '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1888 """
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001889 if (compiler_version == None):
1890 return True
1891 operator = str(compiler_version[0])
1892 version = compiler_version[1]
1893
1894 if (version == None):
1895 return True
1896 if (operator == '>'):
1897 return self.getCompilerVersion() > version
1898 if (operator == '>=' or operator == '=>'):
1899 return self.getCompilerVersion() >= version
1900 if (operator == '<'):
1901 return self.getCompilerVersion() < version
1902 if (operator == '<=' or operator == '=<'):
1903 return self.getCompilerVersion() <= version
1904 if (operator == '!=' or operator == '!' or operator == 'not'):
1905 return str(version) not in str(self.getCompilerVersion())
1906 return str(version) in str(self.getCompilerVersion())
1907
1908 def expectedCompiler(self, compilers):
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001909 """Returns True iff any element of compilers is a sub-string of the current compiler."""
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001910 if (compilers == None):
1911 return True
Ashok Thirumurthi3b037282013-06-06 14:23:31 +00001912
1913 for compiler in compilers:
1914 if compiler in self.getCompiler():
1915 return True
1916
1917 return False
Ashok Thirumurthic97a6082013-05-17 20:15:07 +00001918
Ying Chen7091c2c2015-04-21 01:15:47 +00001919 def expectedArch(self, archs):
1920 """Returns True iff any element of archs is a sub-string of the current architecture."""
1921 if (archs == None):
1922 return True
1923
1924 for arch in archs:
1925 if arch in self.getArchitecture():
1926 return True
1927
1928 return False
1929
Johnny Chenfb4264c2011-08-01 19:50:58 +00001930 def getRunOptions(self):
1931 """Command line option for -A and -C to run this test again, called from
1932 self.dumpSessionInfo()."""
1933 arch = self.getArchitecture()
1934 comp = self.getCompiler()
Johnny Chenb7bdd102011-08-24 19:48:51 +00001935 if arch:
1936 option_str = "-A " + arch
Johnny Chenfb4264c2011-08-01 19:50:58 +00001937 else:
Johnny Chenb7bdd102011-08-24 19:48:51 +00001938 option_str = ""
1939 if comp:
Johnny Chen531c0852012-03-16 20:44:00 +00001940 option_str += " -C " + comp
Johnny Chenb7bdd102011-08-24 19:48:51 +00001941 return option_str
Johnny Chenfb4264c2011-08-01 19:50:58 +00001942
1943 # ==================================================
1944 # Build methods supported through a plugin interface
1945 # ==================================================
1946
Ed Mastec97323e2014-04-01 18:47:58 +00001947 def getstdlibFlag(self):
1948 """ Returns the proper -stdlib flag, or empty if not required."""
Robert Flack4629c4b2015-05-15 18:54:32 +00001949 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Ed Mastec97323e2014-04-01 18:47:58 +00001950 stdlibflag = "-stdlib=libc++"
1951 else:
1952 stdlibflag = ""
1953 return stdlibflag
1954
Matt Kopec7663b3a2013-09-25 17:44:00 +00001955 def getstdFlag(self):
1956 """ Returns the proper stdflag. """
Daniel Malea55faa402013-05-02 21:44:31 +00001957 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
Daniel Malea0b7c6112013-05-06 19:31:31 +00001958 stdflag = "-std=c++0x"
Daniel Malea55faa402013-05-02 21:44:31 +00001959 else:
1960 stdflag = "-std=c++11"
Matt Kopec7663b3a2013-09-25 17:44:00 +00001961 return stdflag
1962
1963 def buildDriver(self, sources, exe_name):
1964 """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
1965 or LLDB.framework).
1966 """
1967
1968 stdflag = self.getstdFlag()
Ed Mastec97323e2014-04-01 18:47:58 +00001969 stdlibflag = self.getstdlibFlag()
Daniel Malea55faa402013-05-02 21:44:31 +00001970
1971 if sys.platform.startswith("darwin"):
1972 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
1973 d = {'CXX_SOURCES' : sources,
1974 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00001975 'CFLAGS_EXTRAS' : "%s %s" % (stdflag, stdlibflag),
Daniel Malea55faa402013-05-02 21:44:31 +00001976 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
Stefanus Du Toit04004442013-07-30 19:19:49 +00001977 'LD_EXTRAS' : "%s -Wl,-rpath,%s" % (dsym, self.lib_dir),
Daniel Malea55faa402013-05-02 21:44:31 +00001978 }
Ed Maste372c24d2013-07-25 21:02:34 +00001979 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 +00001980 d = {'CXX_SOURCES' : sources,
Daniel Malea55faa402013-05-02 21:44:31 +00001981 'EXE' : exe_name,
Ed Mastec97323e2014-04-01 18:47:58 +00001982 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
Daniel Malea55faa402013-05-02 21:44:31 +00001983 'LD_EXTRAS' : "-L%s -llldb" % self.lib_dir}
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00001984 elif sys.platform.startswith('win'):
1985 d = {'CXX_SOURCES' : sources,
1986 'EXE' : exe_name,
1987 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
1988 'LD_EXTRAS' : "-L%s -lliblldb" % self.implib_dir}
Daniel Malea55faa402013-05-02 21:44:31 +00001989 if self.TraceOn():
1990 print "Building LLDB Driver (%s) from sources %s" % (exe_name, sources)
1991
1992 self.buildDefault(dictionary=d)
1993
Matt Kopec7663b3a2013-09-25 17:44:00 +00001994 def buildLibrary(self, sources, lib_name):
1995 """Platform specific way to build a default library. """
1996
1997 stdflag = self.getstdFlag()
1998
Robert Flack4629c4b2015-05-15 18:54:32 +00001999 if self.platformIsDarwin():
Matt Kopec7663b3a2013-09-25 17:44:00 +00002000 dsym = os.path.join(self.lib_dir, 'LLDB.framework', 'LLDB')
2001 d = {'DYLIB_CXX_SOURCES' : sources,
2002 'DYLIB_NAME' : lib_name,
2003 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
2004 'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir,
2005 'LD_EXTRAS' : "%s -Wl,-rpath,%s -dynamiclib" % (dsym, self.lib_dir),
2006 }
Robert Flack4629c4b2015-05-15 18:54:32 +00002007 elif self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux' or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
Matt Kopec7663b3a2013-09-25 17:44:00 +00002008 d = {'DYLIB_CXX_SOURCES' : sources,
2009 'DYLIB_NAME' : lib_name,
2010 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2011 'LD_EXTRAS' : "-shared -L%s -llldb" % self.lib_dir}
Robert Flack4629c4b2015-05-15 18:54:32 +00002012 elif self.getPlatform() == 'windows':
Adrian McCarthyb016b3c2015-03-27 20:47:35 +00002013 d = {'DYLIB_CXX_SOURCES' : sources,
2014 'DYLIB_NAME' : lib_name,
2015 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2016 'LD_EXTRAS' : "-shared -l%s\liblldb.lib" % self.implib_dir}
Matt Kopec7663b3a2013-09-25 17:44:00 +00002017 if self.TraceOn():
2018 print "Building LLDB Library (%s) from sources %s" % (lib_name, sources)
2019
2020 self.buildDefault(dictionary=d)
2021
Daniel Malea55faa402013-05-02 21:44:31 +00002022 def buildProgram(self, sources, exe_name):
2023 """ Platform specific way to build an executable from C/C++ sources. """
2024 d = {'CXX_SOURCES' : sources,
2025 'EXE' : exe_name}
2026 self.buildDefault(dictionary=d)
2027
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002028 def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002029 """Platform specific way to build the default binaries."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002030 if lldb.skip_build_and_cleanup:
2031 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002032 module = builder_module()
Chaoren Line9bbabc2015-07-18 00:37:55 +00002033 if target_is_android():
2034 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002035 if not module.buildDefault(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002036 raise Exception("Don't know how to build default binary")
2037
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002038 def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002039 """Platform specific way to build binaries with dsym info."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002040 if lldb.skip_build_and_cleanup:
2041 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002042 module = builder_module()
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002043 if not module.buildDsym(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002044 raise Exception("Don't know how to build binary with dsym")
2045
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002046 def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002047 """Platform specific way to build binaries with dwarf maps."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002048 if lldb.skip_build_and_cleanup:
2049 return
Johnny Chenfb4264c2011-08-01 19:50:58 +00002050 module = builder_module()
Chaoren Lin9070f532015-07-17 22:13:29 +00002051 if target_is_android():
Chaoren Line9bbabc2015-07-18 00:37:55 +00002052 dictionary = append_android_envs(dictionary)
Johnny Chenfdc80a5c2012-02-01 01:49:50 +00002053 if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
Johnny Chenfb4264c2011-08-01 19:50:58 +00002054 raise Exception("Don't know how to build binary with dwarf")
Johnny Chena74bb0a2011-08-01 18:46:13 +00002055
Oleksiy Vyalov49b71c62015-01-22 20:03:21 +00002056 def signBinary(self, binary_path):
2057 if sys.platform.startswith("darwin"):
2058 codesign_cmd = "codesign --force --sign lldb_codesign %s" % (binary_path)
2059 call(codesign_cmd, shell=True)
2060
Kuba Breckabeed8212014-09-04 01:03:18 +00002061 def findBuiltClang(self):
2062 """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
2063 paths_to_try = [
2064 "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
2065 "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
2066 "llvm-build/Release/x86_64/Release/bin/clang",
2067 "llvm-build/Debug/x86_64/Debug/bin/clang",
2068 ]
2069 lldb_root_path = os.path.join(os.path.dirname(__file__), "..")
2070 for p in paths_to_try:
2071 path = os.path.join(lldb_root_path, p)
2072 if os.path.exists(path):
2073 return path
Ilia Kd9953052015-03-12 07:19:41 +00002074
2075 # Tries to find clang at the same folder as the lldb
Vince Harron790d95c2015-05-18 19:39:03 +00002076 path = os.path.join(os.path.dirname(lldbtest_config.lldbExec), "clang")
Ilia Kd9953052015-03-12 07:19:41 +00002077 if os.path.exists(path):
2078 return path
Kuba Breckabeed8212014-09-04 01:03:18 +00002079
2080 return os.environ["CC"]
2081
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002082 def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False):
Andrew Kaylor93132f52013-05-28 23:04:25 +00002083 """ Returns a dictionary (which can be provided to build* functions above) which
2084 contains OS-specific build flags.
2085 """
2086 cflags = ""
Tamas Berghammer765b5e52015-02-25 13:26:28 +00002087 ldflags = ""
Daniel Malea9115f072013-08-06 15:02:32 +00002088
2089 # On Mac OS X, unless specifically requested to use libstdc++, use libc++
Robert Flack4629c4b2015-05-15 18:54:32 +00002090 if not use_libstdcxx and self.platformIsDarwin():
Daniel Malea9115f072013-08-06 15:02:32 +00002091 use_libcxx = True
2092
2093 if use_libcxx and self.libcxxPath:
2094 cflags += "-stdlib=libc++ "
2095 if self.libcxxPath:
2096 libcxxInclude = os.path.join(self.libcxxPath, "include")
2097 libcxxLib = os.path.join(self.libcxxPath, "lib")
2098 if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
2099 cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (libcxxInclude, libcxxLib, libcxxLib)
2100
Andrew Kaylor93132f52013-05-28 23:04:25 +00002101 if use_cpp11:
2102 cflags += "-std="
2103 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2104 cflags += "c++0x"
2105 else:
2106 cflags += "c++11"
Robert Flack4629c4b2015-05-15 18:54:32 +00002107 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
Andrew Kaylor93132f52013-05-28 23:04:25 +00002108 cflags += " -stdlib=libc++"
2109 elif "clang" in self.getCompiler():
2110 cflags += " -stdlib=libstdc++"
2111
Andrew Kaylor93132f52013-05-28 23:04:25 +00002112 return {'CFLAGS_EXTRAS' : cflags,
2113 'LD_EXTRAS' : ldflags,
2114 }
2115
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002116 def cleanup(self, dictionary=None):
2117 """Platform specific way to do cleanup after build."""
Johnny Chen0fddfb22011-11-17 19:57:27 +00002118 if lldb.skip_build_and_cleanup:
2119 return
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002120 module = builder_module()
2121 if not module.cleanup(self, dictionary):
Johnny Chen0fddfb22011-11-17 19:57:27 +00002122 raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
Johnny Chen9f4f5d92011-08-12 20:19:22 +00002123
Daniel Malea55faa402013-05-02 21:44:31 +00002124 def getLLDBLibraryEnvVal(self):
2125 """ Returns the path that the OS-specific library search environment variable
2126 (self.dylibPath) should be set to in order for a program to find the LLDB
2127 library. If an environment variable named self.dylibPath is already set,
2128 the new path is appended to it and returned.
2129 """
2130 existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
2131 if existing_library_path:
2132 return "%s:%s" % (existing_library_path, self.lib_dir)
2133 elif sys.platform.startswith("darwin"):
2134 return os.path.join(self.lib_dir, 'LLDB.framework')
2135 else:
2136 return self.lib_dir
Johnny Chena74bb0a2011-08-01 18:46:13 +00002137
Ed Maste437f8f62013-09-09 14:04:04 +00002138 def getLibcPlusPlusLibs(self):
Robert Flackfa5ad652015-05-13 20:17:34 +00002139 if self.getPlatform() == 'freebsd' or self.getPlatform() == 'linux':
Ed Maste437f8f62013-09-09 14:04:04 +00002140 return ['libc++.so.1']
2141 else:
2142 return ['libc++.1.dylib','libc++abi.dylib']
2143
Johnny Chena74bb0a2011-08-01 18:46:13 +00002144class TestBase(Base):
2145 """
2146 This abstract base class is meant to be subclassed. It provides default
2147 implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
2148 among other things.
2149
2150 Important things for test class writers:
2151
2152 - Overwrite the mydir class attribute, otherwise your test class won't
2153 run. It specifies the relative directory to the top level 'test' so
2154 the test harness can change to the correct working directory before
2155 running your test.
2156
2157 - The setUp method sets up things to facilitate subsequent interactions
2158 with the debugger as part of the test. These include:
2159 - populate the test method name
2160 - create/get a debugger set with synchronous mode (self.dbg)
2161 - get the command interpreter from with the debugger (self.ci)
2162 - create a result object for use with the command interpreter
2163 (self.res)
2164 - plus other stuffs
2165
2166 - The tearDown method tries to perform some necessary cleanup on behalf
2167 of the test to return the debugger to a good state for the next test.
2168 These include:
2169 - execute any tearDown hooks registered by the test method with
2170 TestBase.addTearDownHook(); examples can be found in
2171 settings/TestSettings.py
2172 - kill the inferior process associated with each target, if any,
2173 and, then delete the target from the debugger's target list
2174 - perform build cleanup before running the next test method in the
2175 same test class; examples of registering for this service can be
2176 found in types/TestIntegerTypes.py with the call:
2177 - self.setTearDownCleanup(dictionary=d)
2178
2179 - Similarly setUpClass and tearDownClass perform classwise setup and
2180 teardown fixtures. The tearDownClass method invokes a default build
2181 cleanup for the entire test class; also, subclasses can implement the
2182 classmethod classCleanup(cls) to perform special class cleanup action.
2183
2184 - The instance methods runCmd and expect are used heavily by existing
2185 test cases to send a command to the command interpreter and to perform
2186 string/pattern matching on the output of such command execution. The
2187 expect method also provides a mode to peform string/pattern matching
2188 without running a command.
2189
2190 - The build methods buildDefault, buildDsym, and buildDwarf are used to
2191 build the binaries used during a particular test scenario. A plugin
2192 should be provided for the sys.platform running the test suite. The
2193 Mac OS X implementation is located in plugins/darwin.py.
2194 """
2195
2196 # Maximum allowed attempts when launching the inferior process.
2197 # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
2198 maxLaunchCount = 3;
2199
2200 # Time to wait before the next launching attempt in second(s).
2201 # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
2202 timeWaitNextLaunch = 1.0;
2203
2204 def doDelay(self):
2205 """See option -w of dotest.py."""
2206 if ("LLDB_WAIT_BETWEEN_TEST_CASES" in os.environ and
2207 os.environ["LLDB_WAIT_BETWEEN_TEST_CASES"] == 'YES'):
2208 waitTime = 1.0
2209 if "LLDB_TIME_WAIT_BETWEEN_TEST_CASES" in os.environ:
2210 waitTime = float(os.environ["LLDB_TIME_WAIT_BETWEEN_TEST_CASES"])
2211 time.sleep(waitTime)
2212
Enrico Granata165f8af2012-09-21 19:10:53 +00002213 # Returns the list of categories to which this test case belongs
2214 # by default, look for a ".categories" file, and read its contents
2215 # if no such file exists, traverse the hierarchy - we guarantee
2216 # a .categories to exist at the top level directory so we do not end up
2217 # looping endlessly - subclasses are free to define their own categories
2218 # in whatever way makes sense to them
2219 def getCategories(self):
2220 import inspect
2221 import os.path
2222 folder = inspect.getfile(self.__class__)
2223 folder = os.path.dirname(folder)
2224 while folder != '/':
2225 categories_file_name = os.path.join(folder,".categories")
2226 if os.path.exists(categories_file_name):
2227 categories_file = open(categories_file_name,'r')
2228 categories = categories_file.readline()
2229 categories_file.close()
2230 categories = str.replace(categories,'\n','')
2231 categories = str.replace(categories,'\r','')
2232 return categories.split(',')
2233 else:
2234 folder = os.path.dirname(folder)
2235 continue
2236
Johnny Chena74bb0a2011-08-01 18:46:13 +00002237 def setUp(self):
2238 #import traceback
2239 #traceback.print_stack()
2240
2241 # Works with the test driver to conditionally skip tests via decorators.
2242 Base.setUp(self)
2243
Johnny Chena74bb0a2011-08-01 18:46:13 +00002244 try:
2245 if lldb.blacklist:
2246 className = self.__class__.__name__
2247 classAndMethodName = "%s.%s" % (className, self._testMethodName)
2248 if className in lldb.blacklist:
2249 self.skipTest(lldb.blacklist.get(className))
2250 elif classAndMethodName in lldb.blacklist:
2251 self.skipTest(lldb.blacklist.get(classAndMethodName))
2252 except AttributeError:
2253 pass
2254
Johnny Chened492022011-06-21 00:53:00 +00002255 # Insert some delay between successive test cases if specified.
2256 self.doDelay()
Johnny Chen0ed37c92010-10-07 02:04:14 +00002257
Johnny Chenf2b70232010-08-25 18:49:48 +00002258 if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
2259 self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
2260
Johnny Chen430eb762010-10-19 16:00:42 +00002261 if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
Johnny Chen4921b112010-11-29 20:20:34 +00002262 self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
Johnny Chenf2b70232010-08-25 18:49:48 +00002263
Daniel Maleae0f8f572013-08-26 23:57:52 +00002264 #
2265 # Warning: MAJOR HACK AHEAD!
2266 # If we are running testsuite remotely (by checking lldb.lldbtest_remote_sandbox),
2267 # redefine the self.dbg.CreateTarget(filename) method to execute a "file filename"
2268 # command, instead. See also runCmd() where it decorates the "file filename" call
2269 # with additional functionality when running testsuite remotely.
2270 #
2271 if lldb.lldbtest_remote_sandbox:
2272 def DecoratedCreateTarget(arg):
2273 self.runCmd("file %s" % arg)
2274 target = self.dbg.GetSelectedTarget()
2275 #
Greg Claytonc6947512013-12-13 19:18:59 +00002276 # SBtarget.LaunchSimple () currently not working for remote platform?
Daniel Maleae0f8f572013-08-26 23:57:52 +00002277 # johnny @ 04/23/2012
2278 #
2279 def DecoratedLaunchSimple(argv, envp, wd):
2280 self.runCmd("run")
2281 return target.GetProcess()
2282 target.LaunchSimple = DecoratedLaunchSimple
2283
2284 return target
2285 self.dbg.CreateTarget = DecoratedCreateTarget
2286 if self.TraceOn():
2287 print "self.dbg.Create is redefined to:\n%s" % getsource_if_available(DecoratedCreateTarget)
2288
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002289 # We want our debugger to be synchronous.
2290 self.dbg.SetAsync(False)
2291
2292 # Retrieve the associated command interpreter instance.
2293 self.ci = self.dbg.GetCommandInterpreter()
2294 if not self.ci:
2295 raise Exception('Could not get the command interpreter')
2296
2297 # And the result object.
2298 self.res = lldb.SBCommandReturnObject()
2299
Johnny Chen44d24972012-04-16 18:55:15 +00002300 # Run global pre-flight code, if defined via the config file.
2301 if lldb.pre_flight:
2302 lldb.pre_flight(self)
2303
Greg Claytonfb909312013-11-23 01:58:15 +00002304 if lldb.remote_platform:
Chaoren Lin3e2bdb42015-05-11 17:53:39 +00002305 remote_test_dir = lldbutil.join_remote_paths(
2306 lldb.remote_platform_working_dir,
2307 self.getArchitecture(),
2308 str(self.test_number),
2309 self.mydir)
Greg Claytonfb909312013-11-23 01:58:15 +00002310 error = lldb.remote_platform.MakeDirectory(remote_test_dir, 0700)
2311 if error.Success():
Greg Claytonfb909312013-11-23 01:58:15 +00002312 lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
2313 else:
2314 print "error: making remote directory '%s': %s" % (remote_test_dir, error)
2315
Greg Clayton35c91342014-11-17 18:40:27 +00002316 def registerSharedLibrariesWithTarget(self, target, shlibs):
2317 '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
2318
2319 Any modules in the target that have their remote install file specification set will
2320 get uploaded to the remote host. This function registers the local copies of the
2321 shared libraries with the target and sets their remote install locations so they will
2322 be uploaded when the target is run.
2323 '''
Zachary Turnerbe40b2f2014-12-02 21:32:44 +00002324 if not shlibs or not self.platformContext:
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002325 return None
Greg Clayton35c91342014-11-17 18:40:27 +00002326
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002327 shlib_environment_var = self.platformContext.shlib_environment_var
2328 shlib_prefix = self.platformContext.shlib_prefix
2329 shlib_extension = '.' + self.platformContext.shlib_extension
2330
2331 working_dir = self.get_process_working_directory()
2332 environment = ['%s=%s' % (shlib_environment_var, working_dir)]
2333 # Add any shared libraries to our target if remote so they get
2334 # uploaded into the working directory on the remote side
2335 for name in shlibs:
2336 # The path can be a full path to a shared library, or a make file name like "Foo" for
2337 # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
2338 # basename like "libFoo.so". So figure out which one it is and resolve the local copy
2339 # of the shared library accordingly
2340 if os.path.exists(name):
2341 local_shlib_path = name # name is the full path to the local shared library
2342 else:
2343 # Check relative names
2344 local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
2345 if not os.path.exists(local_shlib_path):
2346 local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
Greg Clayton35c91342014-11-17 18:40:27 +00002347 if not os.path.exists(local_shlib_path):
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002348 local_shlib_path = os.path.join(os.getcwd(), name)
Greg Clayton35c91342014-11-17 18:40:27 +00002349
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002350 # Make sure we found the local shared library in the above code
2351 self.assertTrue(os.path.exists(local_shlib_path))
2352
2353 # Add the shared library to our target
2354 shlib_module = target.AddModule(local_shlib_path, None, None, None)
2355 if lldb.remote_platform:
Greg Clayton35c91342014-11-17 18:40:27 +00002356 # We must set the remote install location if we want the shared library
2357 # to get uploaded to the remote target
Chaoren Lin5d76b1b2015-06-06 00:25:50 +00002358 remote_shlib_path = lldbutil.append_to_process_working_directory(os.path.basename(local_shlib_path))
Greg Clayton35c91342014-11-17 18:40:27 +00002359 shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
Oleksiy Vyalova3ff6af2014-12-01 23:21:18 +00002360
2361 return environment
2362
Enrico Granata44818162012-10-24 01:23:57 +00002363 # utility methods that tests can use to access the current objects
2364 def target(self):
2365 if not self.dbg:
2366 raise Exception('Invalid debugger instance')
2367 return self.dbg.GetSelectedTarget()
2368
2369 def process(self):
2370 if not self.dbg:
2371 raise Exception('Invalid debugger instance')
2372 return self.dbg.GetSelectedTarget().GetProcess()
2373
2374 def thread(self):
2375 if not self.dbg:
2376 raise Exception('Invalid debugger instance')
2377 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2378
2379 def frame(self):
2380 if not self.dbg:
2381 raise Exception('Invalid debugger instance')
2382 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
2383
Greg Claytonc6947512013-12-13 19:18:59 +00002384 def get_process_working_directory(self):
2385 '''Get the working directory that should be used when launching processes for local or remote processes.'''
2386 if lldb.remote_platform:
2387 # Remote tests set the platform working directory up in TestBase.setUp()
2388 return lldb.remote_platform.GetWorkingDirectory()
2389 else:
2390 # local tests change directory into each test subdirectory
2391 return os.getcwd()
2392
Johnny Chenbf6ffa32010-07-03 03:41:59 +00002393 def tearDown(self):
Johnny Chen7d1d7532010-09-02 21:23:12 +00002394 #import traceback
2395 #traceback.print_stack()
2396
Johnny Chen3794ad92011-06-15 21:24:24 +00002397 # Delete the target(s) from the debugger as a general cleanup step.
2398 # This includes terminating the process for each target, if any.
2399 # We'd like to reuse the debugger for our next test without incurring
2400 # the initialization overhead.
2401 targets = []
2402 for target in self.dbg:
2403 if target:
2404 targets.append(target)
2405 process = target.GetProcess()
2406 if process:
2407 rc = self.invoke(process, "Kill")
2408 self.assertTrue(rc.Success(), PROCESS_KILLED)
2409 for target in targets:
2410 self.dbg.DeleteTarget(target)
Johnny Chen6ca006c2010-08-16 21:28:10 +00002411
Johnny Chen44d24972012-04-16 18:55:15 +00002412 # Run global post-flight code, if defined via the config file.
2413 if lldb.post_flight:
2414 lldb.post_flight(self)
2415
Zachary Turner65fe1eb2015-03-26 16:43:25 +00002416 # Do this last, to make sure it's in reverse order from how we setup.
2417 Base.tearDown(self)
2418
Zachary Turner95812042015-03-26 18:54:21 +00002419 # This must be the last statement, otherwise teardown hooks or other
2420 # lines might depend on this still being active.
2421 del self.dbg
2422
Johnny Chen86268e42011-09-30 21:48:35 +00002423 def switch_to_thread_with_stop_reason(self, stop_reason):
2424 """
2425 Run the 'thread list' command, and select the thread with stop reason as
2426 'stop_reason'. If no such thread exists, no select action is done.
2427 """
2428 from lldbutil import stop_reason_to_str
2429 self.runCmd('thread list')
2430 output = self.res.GetOutput()
2431 thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
2432 stop_reason_to_str(stop_reason))
2433 for line in output.splitlines():
2434 matched = thread_line_pattern.match(line)
2435 if matched:
2436 self.runCmd('thread select %s' % matched.group(1))
2437
Enrico Granata7594f142013-06-17 22:51:50 +00002438 def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
Johnny Chen27f212d2010-08-19 23:26:59 +00002439 """
2440 Ask the command interpreter to handle the command and then check its
2441 return status.
2442 """
2443 # Fail fast if 'cmd' is not meaningful.
2444 if not cmd or len(cmd) == 0:
2445 raise Exception("Bad 'cmd' parameter encountered")
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002446
Johnny Chen8d55a342010-08-31 17:42:54 +00002447 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002448
Daniel Maleae0f8f572013-08-26 23:57:52 +00002449 # This is an opportunity to insert the 'platform target-install' command if we are told so
2450 # via the settig of lldb.lldbtest_remote_sandbox.
2451 if cmd.startswith("target create "):
2452 cmd = cmd.replace("target create ", "file ")
2453 if cmd.startswith("file ") and lldb.lldbtest_remote_sandbox:
2454 with recording(self, trace) as sbuf:
2455 the_rest = cmd.split("file ")[1]
2456 # Split the rest of the command line.
2457 atoms = the_rest.split()
2458 #
2459 # NOTE: This assumes that the options, if any, follow the file command,
2460 # instead of follow the specified target.
2461 #
2462 target = atoms[-1]
2463 # Now let's get the absolute pathname of our target.
2464 abs_target = os.path.abspath(target)
2465 print >> sbuf, "Found a file command, target (with absolute pathname)=%s" % abs_target
2466 fpath, fname = os.path.split(abs_target)
2467 parent_dir = os.path.split(fpath)[0]
2468 platform_target_install_command = 'platform target-install %s %s' % (fpath, lldb.lldbtest_remote_sandbox)
2469 print >> sbuf, "Insert this command to be run first: %s" % platform_target_install_command
2470 self.ci.HandleCommand(platform_target_install_command, self.res)
2471 # And this is the file command we want to execute, instead.
2472 #
2473 # Warning: SIDE EFFECT AHEAD!!!
2474 # Populate the remote executable pathname into the lldb namespace,
2475 # so that test cases can grab this thing out of the namespace.
2476 #
2477 lldb.lldbtest_remote_sandboxed_executable = abs_target.replace(parent_dir, lldb.lldbtest_remote_sandbox)
2478 cmd = "file -P %s %s %s" % (lldb.lldbtest_remote_sandboxed_executable, the_rest.replace(target, ''), abs_target)
2479 print >> sbuf, "And this is the replaced file command: %s" % cmd
2480
Johnny Chen63dfb272010-09-01 00:15:19 +00002481 running = (cmd.startswith("run") or cmd.startswith("process launch"))
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002482
Johnny Chen63dfb272010-09-01 00:15:19 +00002483 for i in range(self.maxLaunchCount if running else 1):
Enrico Granata7594f142013-06-17 22:51:50 +00002484 self.ci.HandleCommand(cmd, self.res, inHistory)
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002485
Johnny Chen150c3cc2010-10-15 01:18:29 +00002486 with recording(self, trace) as sbuf:
2487 print >> sbuf, "runCmd:", cmd
Johnny Chenab254f52010-10-15 16:13:00 +00002488 if not check:
Johnny Chen27b107b2010-10-15 18:52:22 +00002489 print >> sbuf, "check of return status not required"
Johnny Chenf2b70232010-08-25 18:49:48 +00002490 if self.res.Succeeded():
Johnny Chen150c3cc2010-10-15 01:18:29 +00002491 print >> sbuf, "output:", self.res.GetOutput()
Johnny Chenf2b70232010-08-25 18:49:48 +00002492 else:
Johnny Chen150c3cc2010-10-15 01:18:29 +00002493 print >> sbuf, "runCmd failed!"
2494 print >> sbuf, self.res.GetError()
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002495
Johnny Chenff3d01d2010-08-20 21:03:09 +00002496 if self.res.Succeeded():
Johnny Chenf2b70232010-08-25 18:49:48 +00002497 break
Johnny Chen150c3cc2010-10-15 01:18:29 +00002498 elif running:
Johnny Chencf7f74e2011-01-19 02:02:08 +00002499 # For process launch, wait some time before possible next try.
2500 time.sleep(self.timeWaitNextLaunch)
Johnny Chen552d6712012-08-01 19:56:04 +00002501 with recording(self, trace) as sbuf:
Johnny Chen150c3cc2010-10-15 01:18:29 +00002502 print >> sbuf, "Command '" + cmd + "' failed!"
Johnny Chen5bbb88f2010-08-20 17:57:32 +00002503
Johnny Chen27f212d2010-08-19 23:26:59 +00002504 if check:
Sean Callanan05834cd2015-07-01 23:56:30 +00002505 self.assertTrue(self.res.Succeeded(),
2506 msg if msg else CMD_MSG(cmd))
Johnny Chen27f212d2010-08-19 23:26:59 +00002507
Jim Ingham63dfc722012-09-22 00:05:11 +00002508 def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
2509 """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2510
2511 Otherwise, all the arguments have the same meanings as for the expect function"""
2512
2513 trace = (True if traceAlways else trace)
2514
2515 if exe:
2516 # First run the command. If we are expecting error, set check=False.
2517 # Pass the assert message along since it provides more semantic info.
2518 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
2519
2520 # Then compare the output against expected strings.
2521 output = self.res.GetError() if error else self.res.GetOutput()
2522
2523 # If error is True, the API client expects the command to fail!
2524 if error:
2525 self.assertFalse(self.res.Succeeded(),
2526 "Command '" + str + "' is expected to fail!")
2527 else:
2528 # No execution required, just compare str against the golden input.
2529 output = str
2530 with recording(self, trace) as sbuf:
2531 print >> sbuf, "looking at:", output
2532
2533 # The heading says either "Expecting" or "Not expecting".
2534 heading = "Expecting" if matching else "Not expecting"
2535
2536 for pattern in patterns:
2537 # Match Objects always have a boolean value of True.
2538 match_object = re.search(pattern, output)
2539 matched = bool(match_object)
2540 with recording(self, trace) as sbuf:
2541 print >> sbuf, "%s pattern: %s" % (heading, pattern)
2542 print >> sbuf, "Matched" if matched else "Not matched"
2543 if matched:
2544 break
2545
2546 self.assertTrue(matched if matching else not matched,
2547 msg if msg else EXP_MSG(str, exe))
2548
2549 return match_object
2550
Enrico Granata7594f142013-06-17 22:51:50 +00002551 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 +00002552 """
2553 Similar to runCmd; with additional expect style output matching ability.
2554
2555 Ask the command interpreter to handle the command and then check its
2556 return status. The 'msg' parameter specifies an informational assert
2557 message. We expect the output from running the command to start with
Johnny Chenea88e942010-09-21 21:08:53 +00002558 'startstr', matches the substrings contained in 'substrs', and regexp
2559 matches the patterns contained in 'patterns'.
Johnny Chenb3307862010-09-17 22:28:51 +00002560
2561 If the keyword argument error is set to True, it signifies that the API
2562 client is expecting the command to fail. In this case, the error stream
Johnny Chenaa902922010-09-17 22:45:27 +00002563 from running the command is retrieved and compared against the golden
Johnny Chenb3307862010-09-17 22:28:51 +00002564 input, instead.
Johnny Chenea88e942010-09-21 21:08:53 +00002565
2566 If the keyword argument matching is set to False, it signifies that the API
2567 client is expecting the output of the command not to match the golden
2568 input.
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002569
2570 Finally, the required argument 'str' represents the lldb command to be
2571 sent to the command interpreter. In case the keyword argument 'exe' is
2572 set to False, the 'str' is treated as a string to be matched/not-matched
2573 against the golden input.
Johnny Chen27f212d2010-08-19 23:26:59 +00002574 """
Johnny Chen8d55a342010-08-31 17:42:54 +00002575 trace = (True if traceAlways else trace)
Johnny Chend0190a62010-08-23 17:10:44 +00002576
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002577 if exe:
2578 # First run the command. If we are expecting error, set check=False.
Johnny Chen62d4f862010-10-28 21:10:32 +00002579 # Pass the assert message along since it provides more semantic info.
Enrico Granata7594f142013-06-17 22:51:50 +00002580 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error, inHistory=inHistory)
Johnny Chen27f212d2010-08-19 23:26:59 +00002581
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002582 # Then compare the output against expected strings.
2583 output = self.res.GetError() if error else self.res.GetOutput()
Johnny Chenb3307862010-09-17 22:28:51 +00002584
Johnny Chen9c48b8d2010-09-21 23:33:30 +00002585 # If error is True, the API client expects the command to fail!
2586 if error:
2587 self.assertFalse(self.res.Succeeded(),
2588 "Command '" + str + "' is expected to fail!")
2589 else:
2590 # No execution required, just compare str against the golden input.
Enrico Granatabc08ab42012-10-23 00:09:02 +00002591 if isinstance(str,lldb.SBCommandReturnObject):
2592 output = str.GetOutput()
2593 else:
2594 output = str
Johnny Chen150c3cc2010-10-15 01:18:29 +00002595 with recording(self, trace) as sbuf:
2596 print >> sbuf, "looking at:", output
Johnny Chenb3307862010-09-17 22:28:51 +00002597
Johnny Chenea88e942010-09-21 21:08:53 +00002598 # The heading says either "Expecting" or "Not expecting".
Johnny Chen150c3cc2010-10-15 01:18:29 +00002599 heading = "Expecting" if matching else "Not expecting"
Johnny Chenea88e942010-09-21 21:08:53 +00002600
2601 # Start from the startstr, if specified.
2602 # If there's no startstr, set the initial state appropriately.
2603 matched = output.startswith(startstr) if startstr else (True if matching else False)
Johnny Chenb145bba2010-08-20 18:25:15 +00002604
Johnny Chen150c3cc2010-10-15 01:18:29 +00002605 if startstr:
2606 with recording(self, trace) as sbuf:
2607 print >> sbuf, "%s start string: %s" % (heading, startstr)
2608 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenb145bba2010-08-20 18:25:15 +00002609
Johnny Chen86268e42011-09-30 21:48:35 +00002610 # Look for endstr, if specified.
2611 keepgoing = matched if matching else not matched
2612 if endstr:
2613 matched = output.endswith(endstr)
2614 with recording(self, trace) as sbuf:
2615 print >> sbuf, "%s end string: %s" % (heading, endstr)
2616 print >> sbuf, "Matched" if matched else "Not matched"
2617
Johnny Chenea88e942010-09-21 21:08:53 +00002618 # Look for sub strings, if specified.
2619 keepgoing = matched if matching else not matched
2620 if substrs and keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002621 for str in substrs:
Johnny Chenb052f6c2010-09-23 23:35:28 +00002622 matched = output.find(str) != -1
Johnny Chen150c3cc2010-10-15 01:18:29 +00002623 with recording(self, trace) as sbuf:
2624 print >> sbuf, "%s sub string: %s" % (heading, str)
2625 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenea88e942010-09-21 21:08:53 +00002626 keepgoing = matched if matching else not matched
2627 if not keepgoing:
Johnny Chen27f212d2010-08-19 23:26:59 +00002628 break
2629
Johnny Chenea88e942010-09-21 21:08:53 +00002630 # Search for regular expression patterns, if specified.
2631 keepgoing = matched if matching else not matched
2632 if patterns and keepgoing:
2633 for pattern in patterns:
2634 # Match Objects always have a boolean value of True.
2635 matched = bool(re.search(pattern, output))
Johnny Chen150c3cc2010-10-15 01:18:29 +00002636 with recording(self, trace) as sbuf:
2637 print >> sbuf, "%s pattern: %s" % (heading, pattern)
2638 print >> sbuf, "Matched" if matched else "Not matched"
Johnny Chenea88e942010-09-21 21:08:53 +00002639 keepgoing = matched if matching else not matched
2640 if not keepgoing:
2641 break
Johnny Chenea88e942010-09-21 21:08:53 +00002642
2643 self.assertTrue(matched if matching else not matched,
Johnny Chenc0c67f22010-11-09 18:42:22 +00002644 msg if msg else EXP_MSG(str, exe))
Johnny Chen27f212d2010-08-19 23:26:59 +00002645
Johnny Chenf3c59232010-08-25 22:52:45 +00002646 def invoke(self, obj, name, trace=False):
Johnny Chen61703c92010-08-25 22:56:10 +00002647 """Use reflection to call a method dynamically with no argument."""
Johnny Chen8d55a342010-08-31 17:42:54 +00002648 trace = (True if traceAlways else trace)
Johnny Chenf3c59232010-08-25 22:52:45 +00002649
2650 method = getattr(obj, name)
2651 import inspect
2652 self.assertTrue(inspect.ismethod(method),
2653 name + "is a method name of object: " + str(obj))
2654 result = method()
Johnny Chen150c3cc2010-10-15 01:18:29 +00002655 with recording(self, trace) as sbuf:
2656 print >> sbuf, str(method) + ":", result
Johnny Chenf3c59232010-08-25 22:52:45 +00002657 return result
Johnny Chen827edff2010-08-27 00:15:48 +00002658
Johnny Chenf359cf22011-05-27 23:36:52 +00002659 # =================================================
2660 # Misc. helper methods for debugging test execution
2661 # =================================================
2662
Johnny Chen56b92a72011-07-11 19:15:11 +00002663 def DebugSBValue(self, val):
Johnny Chen8d55a342010-08-31 17:42:54 +00002664 """Debug print a SBValue object, if traceAlways is True."""
Johnny Chende90f1d2011-04-27 17:43:07 +00002665 from lldbutil import value_type_to_str
Johnny Chen87bb5892010-11-03 21:37:58 +00002666
Johnny Chen8d55a342010-08-31 17:42:54 +00002667 if not traceAlways:
Johnny Chen827edff2010-08-27 00:15:48 +00002668 return
2669
2670 err = sys.stderr
2671 err.write(val.GetName() + ":\n")
Johnny Chen86268e42011-09-30 21:48:35 +00002672 err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n')
2673 err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n')
2674 err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n')
2675 err.write('\t' + "Value -> " + str(val.GetValue()) + '\n')
2676 err.write('\t' + "ValueAsUnsigned -> " + str(val.GetValueAsUnsigned())+ '\n')
2677 err.write('\t' + "ValueType -> " + value_type_to_str(val.GetValueType()) + '\n')
2678 err.write('\t' + "Summary -> " + str(val.GetSummary()) + '\n')
2679 err.write('\t' + "IsPointerType -> " + str(val.TypeIsPointerType()) + '\n')
2680 err.write('\t' + "Location -> " + val.GetLocation() + '\n')
Johnny Chen827edff2010-08-27 00:15:48 +00002681
Johnny Chen36c5eb12011-08-05 20:17:27 +00002682 def DebugSBType(self, type):
2683 """Debug print a SBType object, if traceAlways is True."""
2684 if not traceAlways:
2685 return
2686
2687 err = sys.stderr
2688 err.write(type.GetName() + ":\n")
2689 err.write('\t' + "ByteSize -> " + str(type.GetByteSize()) + '\n')
2690 err.write('\t' + "IsPointerType -> " + str(type.IsPointerType()) + '\n')
2691 err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
2692
Johnny Chenb877f1e2011-03-12 01:18:19 +00002693 def DebugPExpect(self, child):
2694 """Debug the spwaned pexpect object."""
2695 if not traceAlways:
2696 return
2697
2698 print child
Filipe Cabecinhas0eec15a2012-06-20 10:13:40 +00002699
2700 @classmethod
2701 def RemoveTempFile(cls, file):
2702 if os.path.exists(file):
2703 os.remove(file)