2 LLDB module which provides the abstract base class of lldb test case.
4 The concrete subclass can override lldbtest.TesBase in order to inherit the
5 common behavior for unitest.TestCase.setUp/tearDown implemented in this file.
7 The subclass should override the attribute mydir in order for the python runtime
8 to locate the individual test cases when running as part of a large test suite
9 or when running each test case as a separate python invocation.
11 ./dotest.py provides a test driver which sets up the environment to run the
12 entire of part of the test suite . Example:
14 # Exercises the test suite in the types directory....
15 /Volumes/data/lldb/svn/ToT/test $ ./dotest.py -A x86_64 types
18 Session logs for test failures/errors/unexpected successes will go into directory '2012-05-16-13_35_42'
19 Command invoked: python ./dotest.py -A x86_64 types
22 Configuration: arch=x86_64 compiler=clang
23 ----------------------------------------------------------------------
26 ........................................................................
27 ----------------------------------------------------------------------
28 Ran 72 tests in 135.468s
34 from __future__ import print_function
35 from __future__ import absolute_import
40 from distutils.version import LooseVersion
44 import os, sys, traceback
48 from subprocess import *
54 from six import add_metaclass
55 from six import StringIO as SixStringIO
56 from six.moves.urllib import parse as urlparse
61 from . import configuration
62 from . import lldbtest_config
63 from . import lldbutil
64 from . import test_categories
66 from .result_formatter import EventBuilder
68 # dosep.py starts lots and lots of dotest instances
69 # This option helps you find if two (or more) dotest instances are using the same
70 # directory at the same time
71 # Enable it to cause test failures and stderr messages if dotest instances try to run in
72 # the same directory simultaneously
73 # it is disabled by default because it litters the test directories with ".dirlock" files
74 debug_confirm_directory_exclusivity = False
76 # See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
77 # LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' options.
79 # By default, traceAlways is False.
80 if "LLDB_COMMAND_TRACE" in os.environ and os.environ["LLDB_COMMAND_TRACE"]=="YES":
85 # By default, doCleanup is True.
86 if "LLDB_DO_CLEANUP" in os.environ and os.environ["LLDB_DO_CLEANUP"]=="NO":
93 # Some commonly used assert messages.
96 COMMAND_FAILED_AS_EXPECTED = "Command has failed as expected"
98 CURRENT_EXECUTABLE_SET = "Current executable set successfully"
100 PROCESS_IS_VALID = "Process is valid"
102 PROCESS_KILLED = "Process is killed successfully"
104 PROCESS_EXITED = "Process exited successfully"
106 PROCESS_STOPPED = "Process status should be stopped"
108 RUN_SUCCEEDED = "Process is launched successfully"
110 RUN_COMPLETED = "Process exited successfully"
112 BACKTRACE_DISPLAYED_CORRECTLY = "Backtrace displayed correctly"
114 BREAKPOINT_CREATED = "Breakpoint created successfully"
116 BREAKPOINT_STATE_CORRECT = "Breakpoint state is correct"
118 BREAKPOINT_PENDING_CREATED = "Pending breakpoint created successfully"
120 BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1"
122 BREAKPOINT_HIT_TWICE = "Breakpoint resolved with hit cout = 2"
124 BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3"
126 MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."
128 OBJECT_PRINTED_CORRECTLY = "Object printed correctly"
130 SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"
132 STEP_OUT_SUCCEEDED = "Thread step-out succeeded"
134 STOPPED_DUE_TO_EXC_BAD_ACCESS = "Process should be stopped due to bad access exception"
136 STOPPED_DUE_TO_ASSERT = "Process should be stopped due to an assertion"
138 STOPPED_DUE_TO_BREAKPOINT = "Process should be stopped due to breakpoint"
140 STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS = "%s, %s" % (
141 STOPPED_DUE_TO_BREAKPOINT, "instead, the actual stop reason is: '%s'")
143 STOPPED_DUE_TO_BREAKPOINT_CONDITION = "Stopped due to breakpoint condition"
145 STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT = "Stopped due to breakpoint and ignore count"
147 STOPPED_DUE_TO_SIGNAL = "Process state is stopped due to signal"
149 STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in"
151 STOPPED_DUE_TO_WATCHPOINT = "Process should be stopped due to watchpoint"
153 DATA_TYPES_DISPLAYED_CORRECTLY = "Data type(s) displayed correctly"
155 VALID_BREAKPOINT = "Got a valid breakpoint"
157 VALID_BREAKPOINT_LOCATION = "Got a valid breakpoint location"
159 VALID_COMMAND_INTERPRETER = "Got a valid command interpreter"
161 VALID_FILESPEC = "Got a valid filespec"
163 VALID_MODULE = "Got a valid module"
165 VALID_PROCESS = "Got a valid process"
167 VALID_SYMBOL = "Got a valid symbol"
169 VALID_TARGET = "Got a valid target"
171 VALID_PLATFORM = "Got a valid platform"
173 VALID_TYPE = "Got a valid type"
175 VALID_VARIABLE = "Got a valid variable"
177 VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
179 WATCHPOINT_CREATED = "Watchpoint created successfully"
182 '''A generic "Command '%s' returns successfully" message generator.'''
183 return "Command '%s' returns successfully" % str
185 def COMPLETION_MSG(str_before, str_after):
186 '''A generic message generator for the completion mechanism.'''
187 return "'%s' successfully completes to '%s'" % (str_before, str_after)
189 def EXP_MSG(str, exe):
190 '''A generic "'%s' returns expected result" message generator if exe.
191 Otherwise, it generates "'%s' matches expected result" message.'''
192 return "'%s' %s expected result" % (str, 'returns' if exe else 'matches')
194 def SETTING_MSG(setting):
195 '''A generic "Value of setting '%s' is correct" message generator.'''
196 return "Value of setting '%s' is correct" % setting
199 """Returns an env variable array from the os.environ map object."""
200 return list(map(lambda k,v: k+"="+v, list(os.environ.keys()), list(os.environ.values())))
202 def line_number(filename, string_to_match):
203 """Helper function to return the line number of the first matched string."""
204 with open(filename, 'r') as f:
205 for i, line in enumerate(f):
206 if line.find(string_to_match) != -1:
209 raise Exception("Unable to find '%s' within file %s" % (string_to_match, filename))
212 """Return the pointer size of the host system."""
214 a_pointer = ctypes.c_void_p(0xffff)
215 return 8 * ctypes.sizeof(a_pointer)
218 """Returns true if fpath is an executable."""
219 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
222 """Returns the full path to a program; None otherwise."""
223 fpath, fname = os.path.split(program)
228 for path in os.environ["PATH"].split(os.pathsep):
229 exe_file = os.path.join(path, program)
234 class recording(SixStringIO):
236 A nice little context manager for recording the debugger interactions into
237 our session object. If trace flag is ON, it also emits the interactions
240 def __init__(self, test, trace):
241 """Create a SixStringIO instance; record the session obj and trace flag."""
242 SixStringIO.__init__(self)
243 # The test might not have undergone the 'setUp(self)' phase yet, so that
244 # the attribute 'session' might not even exist yet.
245 self.session = getattr(test, "session", None) if test else None
250 Context management protocol on entry to the body of the with statement.
251 Just return the SixStringIO object.
255 def __exit__(self, type, value, tb):
257 Context management protocol on exit from the body of the with statement.
258 If trace is ON, it emits the recordings into stderr. Always add the
259 recordings to our session object. And close the SixStringIO object, too.
262 print(self.getvalue(), file=sys.stderr)
264 print(self.getvalue(), file=self.session)
267 @add_metaclass(abc.ABCMeta)
268 class _BaseProcess(object):
270 @abc.abstractproperty
272 """Returns process PID if has been launched already."""
275 def launch(self, executable, args):
276 """Launches new process with given executable and args."""
280 """Terminates previously launched process.."""
282 class _LocalProcess(_BaseProcess):
284 def __init__(self, trace_on):
286 self._trace_on = trace_on
287 self._delayafterterminate = 0.1
291 return self._proc.pid
293 def launch(self, executable, args):
294 self._proc = Popen([executable] + args,
295 stdout = open(os.devnull) if not self._trace_on else None,
299 if self._proc.poll() == None:
300 # Terminate _proc like it does the pexpect
301 signals_to_try = [sig for sig in ['SIGHUP', 'SIGCONT', 'SIGINT'] if sig in dir(signal)]
302 for sig in signals_to_try:
304 self._proc.send_signal(getattr(signal, sig))
305 time.sleep(self._delayafterterminate)
306 if self._proc.poll() != None:
309 pass # Windows says SIGINT is not a valid signal to send
310 self._proc.terminate()
311 time.sleep(self._delayafterterminate)
312 if self._proc.poll() != None:
315 time.sleep(self._delayafterterminate)
318 return self._proc.poll()
320 class _RemoteProcess(_BaseProcess):
322 def __init__(self, install_remote):
324 self._install_remote = install_remote
330 def launch(self, executable, args):
331 if self._install_remote:
332 src_path = executable
333 dst_path = lldbutil.append_to_process_working_directory(os.path.basename(executable))
335 dst_file_spec = lldb.SBFileSpec(dst_path, False)
336 err = lldb.remote_platform.Install(lldb.SBFileSpec(src_path, True), dst_file_spec)
338 raise Exception("remote_platform.Install('%s', '%s') failed: %s" % (src_path, dst_path, err))
340 dst_path = executable
341 dst_file_spec = lldb.SBFileSpec(executable, False)
343 launch_info = lldb.SBLaunchInfo(args)
344 launch_info.SetExecutableFile(dst_file_spec, True)
345 launch_info.SetWorkingDirectory(lldb.remote_platform.GetWorkingDirectory())
347 # Redirect stdout and stderr to /dev/null
348 launch_info.AddSuppressFileAction(1, False, True)
349 launch_info.AddSuppressFileAction(2, False, True)
351 err = lldb.remote_platform.Launch(launch_info)
353 raise Exception("remote_platform.Launch('%s', '%s') failed: %s" % (dst_path, args, err))
354 self._pid = launch_info.GetProcessID()
357 lldb.remote_platform.Kill(self._pid)
359 # From 2.7's subprocess.check_output() convenience function.
360 # Return a tuple (stdoutdata, stderrdata).
361 def system(commands, **kwargs):
362 r"""Run an os command with arguments and return its output as a byte string.
364 If the exit code was non-zero it raises a CalledProcessError. The
365 CalledProcessError object will have the return code in the returncode
366 attribute and output in the output attribute.
368 The arguments are the same as for the Popen constructor. Example:
370 >>> check_output(["ls", "-l", "/dev/null"])
371 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
373 The stdout argument is not allowed as it is used internally.
374 To capture standard error in the result, use stderr=STDOUT.
376 >>> check_output(["/bin/sh", "-c",
377 ... "ls -l non_existent_file ; exit 0"],
379 'ls: non_existent_file: No such file or directory\n'
382 # Assign the sender object to variable 'test' and remove it from kwargs.
383 test = kwargs.pop('sender', None)
385 # [['make', 'clean', 'foo'], ['make', 'foo']] -> ['make clean foo', 'make foo']
386 commandList = [' '.join(x) for x in commands]
389 for shellCommand in commandList:
390 if 'stdout' in kwargs:
391 raise ValueError('stdout argument not allowed, it will be overridden.')
392 if 'shell' in kwargs and kwargs['shell']==False:
393 raise ValueError('shell=False not allowed')
394 process = Popen(shellCommand, stdout=PIPE, stderr=PIPE, shell=True, universal_newlines=True, **kwargs)
396 this_output, this_error = process.communicate()
397 retcode = process.poll()
399 # Enable trace on failure return while tracking down FreeBSD buildbot issues
401 if not trace and retcode and sys.platform.startswith("freebsd"):
404 with recording(test, trace) as sbuf:
406 print("os command:", shellCommand, file=sbuf)
407 print("with pid:", pid, file=sbuf)
408 print("stdout:", this_output, file=sbuf)
409 print("stderr:", this_error, file=sbuf)
410 print("retcode:", retcode, file=sbuf)
414 cmd = kwargs.get("args")
417 raise CalledProcessError(retcode, cmd)
418 output = output + this_output
419 error = error + this_error
420 return (output, error)
422 def getsource_if_available(obj):
424 Return the text of the source code for an object if available. Otherwise,
425 a print representation is returned.
429 return inspect.getsource(obj)
433 def builder_module():
434 if sys.platform.startswith("freebsd"):
435 return __import__("builder_freebsd")
436 if sys.platform.startswith("netbsd"):
437 return __import__("builder_netbsd")
438 return __import__("builder_" + sys.platform)
440 def run_adb_command(cmd, device_id):
443 device_id_args = ["-s", device_id]
444 full_cmd = ["adb"] + device_id_args + cmd
445 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE)
446 stdout, stderr = p.communicate()
447 return p.returncode, stdout, stderr
449 def append_android_envs(dictionary):
450 if dictionary is None:
452 dictionary["OS"] = "Android"
453 if android_device_api() >= 16:
454 dictionary["PIE"] = 1
457 def target_is_android():
458 if not hasattr(target_is_android, 'result'):
459 triple = lldb.DBG.GetSelectedPlatform().GetTriple()
460 match = re.match(".*-.*-.*-android", triple)
461 target_is_android.result = match is not None
462 return target_is_android.result
464 def android_device_api():
465 if not hasattr(android_device_api, 'result'):
466 assert configuration.lldb_platform_url is not None
468 parsed_url = urlparse.urlparse(configuration.lldb_platform_url)
469 host_name = parsed_url.netloc.split(":")[0]
470 if host_name != 'localhost':
471 device_id = host_name
472 if device_id.startswith('[') and device_id.endswith(']'):
473 device_id = device_id[1:-1]
474 retcode, stdout, stderr = run_adb_command(
475 ["shell", "getprop", "ro.build.version.sdk"], device_id)
477 android_device_api.result = int(stdout)
480 ">>> Unable to determine the API level of the Android device.\n"
482 ">>> stderr:\n%s\n" % (stdout, stderr))
483 return android_device_api.result
485 def check_expected_version(comparison, expected, actual):
486 def fn_leq(x,y): return x <= y
487 def fn_less(x,y): return x < y
488 def fn_geq(x,y): return x >= y
489 def fn_greater(x,y): return x > y
490 def fn_eq(x,y): return x == y
491 def fn_neq(x,y): return x != y
503 expected_str = '.'.join([str(x) for x in expected])
504 actual_str = '.'.join([str(x) for x in actual])
506 return op_lookup[comparison](LooseVersion(actual_str), LooseVersion(expected_str))
509 # Decorators for categorizing test cases.
511 from functools import wraps
513 def add_test_categories(cat):
514 """Add test categories to a TestCase method"""
515 cat = test_categories.validate(cat, True)
517 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
518 raise Exception("@add_test_categories can only be used to decorate a test method")
519 if hasattr(func, "categories"):
520 cat.extend(func.categories)
521 func.categories = cat
526 def benchmarks_test(func):
527 """Decorate the item as a benchmarks test."""
528 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
529 raise Exception("@benchmarks_test can only be used to decorate a test method")
531 def wrapper(self, *args, **kwargs):
532 self.skipTest("benchmarks test")
533 return func(self, *args, **kwargs)
535 # Mark this function as such to separate them from the regular tests.
536 wrapper.__benchmarks_test__ = True
539 def no_debug_info_test(func):
540 """Decorate the item as a test what don't use any debug info. If this annotation is specified
541 then the test runner won't generate a separate test for each debug info format. """
542 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
543 raise Exception("@no_debug_info_test can only be used to decorate a test method")
545 def wrapper(self, *args, **kwargs):
546 return func(self, *args, **kwargs)
548 # Mark this function as such to separate them from the regular tests.
549 wrapper.__no_debug_info_test__ = True
552 def debugserver_test(func):
553 """Decorate the item as a debugserver test."""
554 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
555 raise Exception("@debugserver_test can only be used to decorate a test method")
557 def wrapper(self, *args, **kwargs):
558 if configuration.dont_do_debugserver_test:
559 self.skipTest("debugserver tests")
560 return func(self, *args, **kwargs)
562 # Mark this function as such to separate them from the regular tests.
563 wrapper.__debugserver_test__ = True
567 """Decorate the item as a lldb-server test."""
568 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
569 raise Exception("@llgs_test can only be used to decorate a test method")
571 def wrapper(self, *args, **kwargs):
572 if configuration.dont_do_llgs_test:
573 self.skipTest("llgs tests")
574 return func(self, *args, **kwargs)
576 # Mark this function as such to separate them from the regular tests.
577 wrapper.__llgs_test__ = True
580 def not_remote_testsuite_ready(func):
581 """Decorate the item as a test which is not ready yet for remote testsuite."""
582 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
583 raise Exception("@not_remote_testsuite_ready can only be used to decorate a test method")
585 def wrapper(self, *args, **kwargs):
586 if lldb.remote_platform:
587 self.skipTest("not ready for remote testsuite")
588 return func(self, *args, **kwargs)
590 # Mark this function as such to separate them from the regular tests.
591 wrapper.__not_ready_for_remote_testsuite_test__ = True
594 def expectedFailure(expected_fn, bugnumber=None):
595 def expectedFailure_impl(func):
597 def wrapper(*args, **kwargs):
598 from unittest2 import case
600 if expected_fn(self):
601 if configuration.results_formatter_object is not None:
602 # Mark this test as expected to fail.
603 configuration.results_formatter_object.handle_event(
604 EventBuilder.event_for_mark_test_expected_failure(self))
605 xfail_func = unittest2.expectedFailure(func)
606 xfail_func(*args, **kwargs)
608 func(*args, **kwargs)
610 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
611 # return decorator in this case, so it will be used to decorating original method
612 if six.callable(bugnumber):
613 return expectedFailure_impl(bugnumber)
615 return expectedFailure_impl
617 # You can also pass not_in(list) to reverse the sense of the test for the arguments that
618 # are simple lists, namely oslist, compiler, and debug_info.
620 def not_in(iterable):
621 return lambda x : x not in iterable
623 def check_list_or_lambda(list_or_lambda, value):
624 if six.callable(list_or_lambda):
625 return list_or_lambda(value)
626 elif isinstance(list_or_lambda, list):
627 for item in list_or_lambda:
631 elif isinstance(list_or_lambda, str):
632 return value is None or value in list_or_lambda
634 return list_or_lambda is None or value is None or list_or_lambda == value
636 # provide a function to xfail on defined oslist, compiler version, and archs
637 # if none is specified for any argument, that argument won't be checked and thus means for all
639 # @expectedFailureAll, xfail for all platform/compiler/arch,
640 # @expectedFailureAll(compiler='gcc'), xfail for gcc on all platform/architecture
641 # @expectedFailureAll(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), xfail for gcc>=4.9 on linux with i386
642 def expectedFailureAll(bugnumber=None, oslist=None, hostoslist=None, compiler=None, compiler_version=None, archs=None, triple=None, debug_info=None, swig_version=None, py_version=None):
644 oslist_passes = check_list_or_lambda(oslist, self.getPlatform())
645 hostoslist_passes = check_list_or_lambda(hostoslist, getHostPlatform())
646 compiler_passes = check_list_or_lambda(self.getCompiler(), compiler) and self.expectedCompilerVersion(compiler_version)
647 arch_passes = check_list_or_lambda(archs, self.getArchitecture())
648 triple_passes = triple is None or re.match(triple, lldb.DBG.GetSelectedPlatform().GetTriple())
649 debug_info_passes = check_list_or_lambda(debug_info, self.debug_info)
650 swig_version_passes = (swig_version is None) or (not hasattr(lldb, 'swig_version')) or (check_expected_version(swig_version[0], swig_version[1], lldb.swig_version))
651 py_version_passes = (py_version is None) or check_expected_version(py_version[0], py_version[1], sys.version_info)
653 return (oslist_passes and
654 hostoslist_passes and
658 debug_info_passes and
659 swig_version_passes and
661 return expectedFailure(fn, bugnumber)
663 def expectedFailureDwarf(bugnumber=None):
664 return expectedFailureAll(bugnumber=bugnumber, debug_info="dwarf")
666 def expectedFailureDwo(bugnumber=None):
667 return expectedFailureAll(bugnumber=bugnumber, debug_info="dwo")
669 def expectedFailureDsym(bugnumber=None):
670 return expectedFailureAll(bugnumber=bugnumber, debug_info="dsym")
672 def expectedFailureCompiler(compiler, compiler_version=None, bugnumber=None):
673 if compiler_version is None:
674 compiler_version=['=', None]
675 return expectedFailureAll(bugnumber=bugnumber, compiler=compiler, compiler_version=compiler_version)
677 # to XFAIL a specific clang versions, try this
678 # @expectedFailureClang('bugnumber', ['<=', '3.4'])
679 def expectedFailureClang(bugnumber=None, compiler_version=None):
680 return expectedFailureCompiler('clang', compiler_version, bugnumber)
682 def expectedFailureGcc(bugnumber=None, compiler_version=None):
683 return expectedFailureCompiler('gcc', compiler_version, bugnumber)
685 def expectedFailureIcc(bugnumber=None):
686 return expectedFailureCompiler('icc', None, bugnumber)
688 def expectedFailureArch(arch, bugnumber=None):
690 return arch in self.getArchitecture()
691 return expectedFailure(fn, bugnumber)
693 def expectedFailurei386(bugnumber=None):
694 return expectedFailureArch('i386', bugnumber)
696 def expectedFailurex86_64(bugnumber=None):
697 return expectedFailureArch('x86_64', bugnumber)
699 def expectedFailureOS(oslist, bugnumber=None, compilers=None, debug_info=None):
701 return (self.getPlatform() in oslist and
702 self.expectedCompiler(compilers) and
703 (debug_info is None or self.debug_info in debug_info))
704 return expectedFailure(fn, bugnumber)
706 def expectedFailureHostOS(oslist, bugnumber=None, compilers=None):
708 return (getHostPlatform() in oslist and
709 self.expectedCompiler(compilers))
710 return expectedFailure(fn, bugnumber)
712 def expectedFailureDarwin(bugnumber=None, compilers=None, debug_info=None):
713 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
714 return expectedFailureOS(getDarwinOSTriples(), bugnumber, compilers, debug_info=debug_info)
716 def expectedFailureFreeBSD(bugnumber=None, compilers=None, debug_info=None):
717 return expectedFailureOS(['freebsd'], bugnumber, compilers, debug_info=debug_info)
719 def expectedFailureLinux(bugnumber=None, compilers=None, debug_info=None):
720 return expectedFailureOS(['linux'], bugnumber, compilers, debug_info=debug_info)
722 def expectedFailureNetBSD(bugnumber=None, compilers=None, debug_info=None):
723 return expectedFailureOS(['netbsd'], bugnumber, compilers, debug_info=debug_info)
725 def expectedFailureWindows(bugnumber=None, compilers=None, debug_info=None):
726 return expectedFailureOS(['windows'], bugnumber, compilers, debug_info=debug_info)
728 def expectedFailureHostWindows(bugnumber=None, compilers=None):
729 return expectedFailureHostOS(['windows'], bugnumber, compilers)
731 def matchAndroid(api_levels=None, archs=None):
733 if not target_is_android():
735 if archs is not None and self.getArchitecture() not in archs:
737 if api_levels is not None and android_device_api() not in api_levels:
743 def expectedFailureAndroid(bugnumber=None, api_levels=None, archs=None):
744 """ Mark a test as xfail for Android.
747 bugnumber - The LLVM pr associated with the problem.
748 api_levels - A sequence of numbers specifying the Android API levels
749 for which a test is expected to fail. None means all API level.
750 arch - A sequence of architecture names specifying the architectures
751 for which a test is expected to fail. None means all architectures.
753 return expectedFailure(matchAndroid(api_levels, archs), bugnumber)
755 # Flakey tests get two chances to run. If they fail the first time round, the result formatter
756 # makes sure it is run one more time.
757 def expectedFlakey(expected_fn, bugnumber=None):
758 def expectedFailure_impl(func):
760 def wrapper(*args, **kwargs):
762 if expected_fn(self):
763 # Send event marking test as explicitly eligible for rerunning.
764 if configuration.results_formatter_object is not None:
765 # Mark this test as rerunnable.
766 configuration.results_formatter_object.handle_event(
767 EventBuilder.event_for_mark_test_rerun_eligible(self))
768 func(*args, **kwargs)
770 # if bugnumber is not-callable(incluing None), that means decorator function is called with optional arguments
771 # return decorator in this case, so it will be used to decorating original method
772 if six.callable(bugnumber):
773 return expectedFailure_impl(bugnumber)
775 return expectedFailure_impl
777 def expectedFlakeyDwarf(bugnumber=None):
779 return self.debug_info == "dwarf"
780 return expectedFlakey(fn, bugnumber)
782 def expectedFlakeyDsym(bugnumber=None):
784 return self.debug_info == "dwarf"
785 return expectedFlakey(fn, bugnumber)
787 def expectedFlakeyOS(oslist, bugnumber=None, compilers=None):
789 return (self.getPlatform() in oslist and
790 self.expectedCompiler(compilers))
791 return expectedFlakey(fn, bugnumber)
793 def expectedFlakeyDarwin(bugnumber=None, compilers=None):
794 # For legacy reasons, we support both "darwin" and "macosx" as OS X triples.
795 return expectedFlakeyOS(getDarwinOSTriples(), bugnumber, compilers)
797 def expectedFlakeyFreeBSD(bugnumber=None, compilers=None):
798 return expectedFlakeyOS(['freebsd'], bugnumber, compilers)
800 def expectedFlakeyLinux(bugnumber=None, compilers=None):
801 return expectedFlakeyOS(['linux'], bugnumber, compilers)
803 def expectedFlakeyNetBSD(bugnumber=None, compilers=None):
804 return expectedFlakeyOS(['netbsd'], bugnumber, compilers)
806 def expectedFlakeyCompiler(compiler, compiler_version=None, bugnumber=None):
807 if compiler_version is None:
808 compiler_version=['=', None]
810 return compiler in self.getCompiler() and self.expectedCompilerVersion(compiler_version)
811 return expectedFlakey(fn, bugnumber)
813 # @expectedFlakeyClang('bugnumber', ['<=', '3.4'])
814 def expectedFlakeyClang(bugnumber=None, compiler_version=None):
815 return expectedFlakeyCompiler('clang', compiler_version, bugnumber)
817 # @expectedFlakeyGcc('bugnumber', ['<=', '3.4'])
818 def expectedFlakeyGcc(bugnumber=None, compiler_version=None):
819 return expectedFlakeyCompiler('gcc', compiler_version, bugnumber)
821 def expectedFlakeyAndroid(bugnumber=None, api_levels=None, archs=None):
822 return expectedFlakey(matchAndroid(api_levels, archs), bugnumber)
824 def skipIfRemote(func):
825 """Decorate the item to skip tests if testing remotely."""
826 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
827 raise Exception("@skipIfRemote can only be used to decorate a test method")
829 def wrapper(*args, **kwargs):
830 from unittest2 import case
831 if lldb.remote_platform:
833 self.skipTest("skip on remote platform")
835 func(*args, **kwargs)
838 def skipUnlessListedRemote(remote_list=None):
840 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
841 raise Exception("@skipIfRemote can only be used to decorate a "
845 def wrapper(*args, **kwargs):
846 if remote_list and lldb.remote_platform:
848 triple = self.dbg.GetSelectedPlatform().GetTriple()
849 for r in remote_list:
851 func(*args, **kwargs)
853 self.skipTest("skip on remote platform %s" % str(triple))
855 func(*args, **kwargs)
860 def skipIfRemoteDueToDeadlock(func):
861 """Decorate the item to skip tests if testing remotely due to the test deadlocking."""
862 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
863 raise Exception("@skipIfRemote can only be used to decorate a test method")
865 def wrapper(*args, **kwargs):
866 from unittest2 import case
867 if lldb.remote_platform:
869 self.skipTest("skip on remote platform (deadlocks)")
871 func(*args, **kwargs)
874 def skipIfNoSBHeaders(func):
875 """Decorate the item to mark tests that should be skipped when LLDB is built with no SB API headers."""
876 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
877 raise Exception("@skipIfNoSBHeaders can only be used to decorate a test method")
879 def wrapper(*args, **kwargs):
880 from unittest2 import case
882 if sys.platform.startswith("darwin"):
883 header = os.path.join(os.environ["LLDB_LIB_DIR"], 'LLDB.framework', 'Versions','Current','Headers','LLDB.h')
885 header = os.path.join(os.environ["LLDB_SRC"], "include", "lldb", "API", "LLDB.h")
886 platform = sys.platform
887 if not os.path.exists(header):
888 self.skipTest("skip because LLDB.h header not found")
890 func(*args, **kwargs)
893 def skipIfiOSSimulator(func):
894 """Decorate the item to skip tests that should be skipped on the iOS Simulator."""
895 return unittest2.skipIf(configuration.lldb_platform_name == 'ios-simulator', 'skip on the iOS Simulator')(func)
897 def skipIfFreeBSD(func):
898 """Decorate the item to skip tests that should be skipped on FreeBSD."""
899 return skipIfPlatform(["freebsd"])(func)
901 def skipIfNetBSD(func):
902 """Decorate the item to skip tests that should be skipped on NetBSD."""
903 return skipIfPlatform(["netbsd"])(func)
905 def getDarwinOSTriples():
906 return ['darwin', 'macosx', 'ios']
908 def skipIfDarwin(func):
909 """Decorate the item to skip tests that should be skipped on Darwin."""
910 return skipIfPlatform(getDarwinOSTriples())(func)
912 def skipIfLinux(func):
913 """Decorate the item to skip tests that should be skipped on Linux."""
914 return skipIfPlatform(["linux"])(func)
916 def skipUnlessHostLinux(func):
917 """Decorate the item to skip tests that should be skipped on any non Linux host."""
918 return skipUnlessHostPlatform(["linux"])(func)
920 def skipIfWindows(func):
921 """Decorate the item to skip tests that should be skipped on Windows."""
922 return skipIfPlatform(["windows"])(func)
924 def skipIfHostWindows(func):
925 """Decorate the item to skip tests that should be skipped on Windows."""
926 return skipIfHostPlatform(["windows"])(func)
928 def skipUnlessWindows(func):
929 """Decorate the item to skip tests that should be skipped on any non-Windows platform."""
930 return skipUnlessPlatform(["windows"])(func)
932 def skipUnlessDarwin(func):
933 """Decorate the item to skip tests that should be skipped on any non Darwin platform."""
934 return skipUnlessPlatform(getDarwinOSTriples())(func)
936 def skipUnlessGoInstalled(func):
937 """Decorate the item to skip tests when no Go compiler is available."""
938 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
939 raise Exception("@skipIfGcc can only be used to decorate a test method")
941 def wrapper(*args, **kwargs):
942 from unittest2 import case
944 compiler = self.getGoCompilerVersion()
946 self.skipTest("skipping because go compiler not found")
948 # Ensure the version is the minimum version supported by
949 # the LLDB go support.
950 match_version = re.search(r"(\d+\.\d+(\.\d+)?)", compiler)
951 if not match_version:
952 # Couldn't determine version.
954 "skipping because go version could not be parsed "
955 "out of {}".format(compiler))
957 from distutils.version import StrictVersion
958 min_strict_version = StrictVersion("1.4.0")
959 compiler_strict_version = StrictVersion(match_version.group(1))
960 if compiler_strict_version < min_strict_version:
962 "skipping because available go version ({}) does "
963 "not meet minimum required go version ({})".format(
964 compiler_strict_version,
966 func(*args, **kwargs)
970 """Returns the target platform which the tests are running on."""
971 platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
972 if platform.startswith('freebsd'):
974 elif platform.startswith('netbsd'):
978 def getHostPlatform():
979 """Returns the host platform running the test suite."""
980 # Attempts to return a platform name matching a target Triple platform.
981 if sys.platform.startswith('linux'):
983 elif sys.platform.startswith('win32'):
985 elif sys.platform.startswith('darwin'):
987 elif sys.platform.startswith('freebsd'):
989 elif sys.platform.startswith('netbsd'):
994 def platformIsDarwin():
995 """Returns true if the OS triple for the selected platform is any valid apple OS"""
996 return getPlatform() in getDarwinOSTriples()
998 def skipIfHostIncompatibleWithRemote(func):
999 """Decorate the item to skip tests if binaries built on this host are incompatible."""
1000 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1001 raise Exception("@skipIfHostIncompatibleWithRemote can only be used to decorate a test method")
1003 def wrapper(*args, **kwargs):
1004 from unittest2 import case
1006 host_arch = self.getLldbArchitecture()
1007 host_platform = getHostPlatform()
1008 target_arch = self.getArchitecture()
1009 target_platform = 'darwin' if self.platformIsDarwin() else self.getPlatform()
1010 if not (target_arch == 'x86_64' and host_arch == 'i386') and host_arch != target_arch:
1011 self.skipTest("skipping because target %s is not compatible with host architecture %s" % (target_arch, host_arch))
1012 elif target_platform != host_platform:
1013 self.skipTest("skipping because target is %s but host is %s" % (target_platform, host_platform))
1015 func(*args, **kwargs)
1018 def skipIfHostPlatform(oslist):
1019 """Decorate the item to skip tests if running on one of the listed host platforms."""
1020 return unittest2.skipIf(getHostPlatform() in oslist,
1021 "skip on %s" % (", ".join(oslist)))
1023 def skipUnlessHostPlatform(oslist):
1024 """Decorate the item to skip tests unless running on one of the listed host platforms."""
1025 return unittest2.skipUnless(getHostPlatform() in oslist,
1026 "requires on of %s" % (", ".join(oslist)))
1028 def skipUnlessArch(archlist):
1029 """Decorate the item to skip tests unless running on one of the listed architectures."""
1031 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1032 raise Exception("@skipUnlessArch can only be used to decorate a test method")
1035 def wrapper(*args, **kwargs):
1037 if self.getArchitecture() not in archlist:
1038 self.skipTest("skipping for architecture %s (requires one of %s)" %
1039 (self.getArchitecture(), ", ".join(archlist)))
1041 func(*args, **kwargs)
1046 def skipIfPlatform(oslist):
1047 """Decorate the item to skip tests if running on one of the listed platforms."""
1048 return unittest2.skipIf(getPlatform() in oslist,
1049 "skip on %s" % (", ".join(oslist)))
1051 def skipUnlessPlatform(oslist):
1052 """Decorate the item to skip tests unless running on one of the listed platforms."""
1053 return unittest2.skipUnless(getPlatform() in oslist,
1054 "requires on of %s" % (", ".join(oslist)))
1056 def skipIfLinuxClang(func):
1057 """Decorate the item to skip tests that should be skipped if building on
1060 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1061 raise Exception("@skipIfLinuxClang can only be used to decorate a test method")
1063 def wrapper(*args, **kwargs):
1064 from unittest2 import case
1066 compiler = self.getCompiler()
1067 platform = self.getPlatform()
1068 if "clang" in compiler and platform == "linux":
1069 self.skipTest("skipping because Clang is used on Linux")
1071 func(*args, **kwargs)
1074 # provide a function to skip on defined oslist, compiler version, and archs
1075 # if none is specified for any argument, that argument won't be checked and thus means for all
1077 # @skipIf, skip for all platform/compiler/arch,
1078 # @skipIf(compiler='gcc'), skip for gcc on all platform/architecture
1079 # @skipIf(bugnumber, ["linux"], "gcc", ['>=', '4.9'], ['i386']), skip for gcc>=4.9 on linux with i386
1081 # TODO: refactor current code, to make skipIfxxx functions to call this function
1082 def skipIf(bugnumber=None, oslist=None, compiler=None, compiler_version=None, archs=None, debug_info=None, swig_version=None, py_version=None, remote=None):
1084 oslist_passes = check_list_or_lambda(oslist, self.getPlatform())
1085 compiler_passes = check_list_or_lambda(self.getCompiler(), compiler) and self.expectedCompilerVersion(compiler_version)
1086 arch_passes = check_list_or_lambda(archs, self.getArchitecture())
1087 debug_info_passes = check_list_or_lambda(debug_info, self.debug_info)
1088 swig_version_passes = (swig_version is None) or (not hasattr(lldb, 'swig_version')) or (check_expected_version(swig_version[0], swig_version[1], lldb.swig_version))
1089 py_version_passes = (py_version is None) or check_expected_version(py_version[0], py_version[1], sys.version_info)
1090 remote_passes = (remote is None) or (remote == (lldb.remote_platform is not None))
1092 return (oslist_passes and
1095 debug_info_passes and
1096 swig_version_passes and
1097 py_version_passes and
1100 local_vars = locals()
1101 args = [x for x in inspect.getargspec(skipIf).args]
1102 arg_vals = [eval(x, globals(), local_vars) for x in args]
1103 args = [x for x in zip(args, arg_vals) if x[1] is not None]
1104 reasons = ['%s=%s' % (x, str(y)) for (x,y) in args]
1105 return skipTestIfFn(fn, bugnumber, skipReason='skipping because ' + ' && '.join(reasons))
1107 def skipIfDebugInfo(bugnumber=None, debug_info=None):
1108 return skipIf(bugnumber=bugnumber, debug_info=debug_info)
1110 def skipIfDWO(bugnumber=None):
1111 return skipIfDebugInfo(bugnumber, ["dwo"])
1113 def skipIfDwarf(bugnumber=None):
1114 return skipIfDebugInfo(bugnumber, ["dwarf"])
1116 def skipIfDsym(bugnumber=None):
1117 return skipIfDebugInfo(bugnumber, ["dsym"])
1119 def skipTestIfFn(expected_fn, bugnumber=None, skipReason=None):
1120 def skipTestIfFn_impl(func):
1122 def wrapper(*args, **kwargs):
1123 from unittest2 import case
1125 if expected_fn(self):
1126 self.skipTest(skipReason)
1128 func(*args, **kwargs)
1130 if six.callable(bugnumber):
1131 return skipTestIfFn_impl(bugnumber)
1133 return skipTestIfFn_impl
1135 def skipIfGcc(func):
1136 """Decorate the item to skip tests that should be skipped if building with gcc ."""
1137 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1138 raise Exception("@skipIfGcc can only be used to decorate a test method")
1140 def wrapper(*args, **kwargs):
1141 from unittest2 import case
1143 compiler = self.getCompiler()
1144 if "gcc" in compiler:
1145 self.skipTest("skipping because gcc is the test compiler")
1147 func(*args, **kwargs)
1150 def skipIfIcc(func):
1151 """Decorate the item to skip tests that should be skipped if building with icc ."""
1152 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1153 raise Exception("@skipIfIcc can only be used to decorate a test method")
1155 def wrapper(*args, **kwargs):
1156 from unittest2 import case
1158 compiler = self.getCompiler()
1159 if "icc" in compiler:
1160 self.skipTest("skipping because icc is the test compiler")
1162 func(*args, **kwargs)
1165 def skipIfi386(func):
1166 """Decorate the item to skip tests that should be skipped if building 32-bit."""
1167 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1168 raise Exception("@skipIfi386 can only be used to decorate a test method")
1170 def wrapper(*args, **kwargs):
1171 from unittest2 import case
1173 if "i386" == self.getArchitecture():
1174 self.skipTest("skipping because i386 is not a supported architecture")
1176 func(*args, **kwargs)
1179 def skipIfTargetAndroid(api_levels=None, archs=None):
1180 """Decorator to skip tests when the target is Android.
1183 api_levels - The API levels for which the test should be skipped. If
1184 it is None, then the test will be skipped for all API levels.
1185 arch - A sequence of architecture names specifying the architectures
1186 for which a test is skipped. None means all architectures.
1189 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1190 raise Exception("@skipIfTargetAndroid can only be used to "
1191 "decorate a test method")
1193 def wrapper(*args, **kwargs):
1194 from unittest2 import case
1196 if matchAndroid(api_levels, archs)(self):
1197 self.skipTest("skiped on Android target with API %d and architecture %s" %
1198 (android_device_api(), self.getArchitecture()))
1199 func(*args, **kwargs)
1203 def skipUnlessCompilerRt(func):
1204 """Decorate the item to skip tests if testing remotely."""
1205 if isinstance(func, type) and issubclass(func, unittest2.TestCase):
1206 raise Exception("@skipUnless can only be used to decorate a test method")
1208 def wrapper(*args, **kwargs):
1209 from unittest2 import case
1211 compilerRtPath = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", "llvm","projects","compiler-rt")
1212 print(compilerRtPath)
1213 if not os.path.exists(compilerRtPath):
1215 self.skipTest("skip if compiler-rt not found")
1217 func(*args, **kwargs)
1220 class _PlatformContext(object):
1221 """Value object class which contains platform-specific options."""
1223 def __init__(self, shlib_environment_var, shlib_prefix, shlib_extension):
1224 self.shlib_environment_var = shlib_environment_var
1225 self.shlib_prefix = shlib_prefix
1226 self.shlib_extension = shlib_extension
1229 class Base(unittest2.TestCase):
1231 Abstract base for performing lldb (see TestBase) or other generic tests (see
1232 BenchBase for one example). lldbtest.Base works with the test driver to
1237 # The concrete subclass should override this attribute.
1240 # Keep track of the old current working directory.
1244 def compute_mydir(test_file):
1245 '''Subclasses should call this function to correctly calculate the required "mydir" attribute as follows:
1247 mydir = TestBase.compute_mydir(__file__)'''
1248 test_dir = os.path.dirname(test_file)
1249 return test_dir[len(os.environ["LLDB_TEST"])+1:]
1252 """Returns True if we are in trace mode (tracing detailed test execution)."""
1256 def setUpClass(cls):
1258 Python unittest framework class setup fixture.
1259 Do current directory manipulation.
1261 # Fail fast if 'mydir' attribute is not overridden.
1262 if not cls.mydir or len(cls.mydir) == 0:
1263 raise Exception("Subclasses must override the 'mydir' attribute.")
1265 # Save old working directory.
1266 cls.oldcwd = os.getcwd()
1268 # Change current working directory if ${LLDB_TEST} is defined.
1269 # See also dotest.py which sets up ${LLDB_TEST}.
1270 if ("LLDB_TEST" in os.environ):
1271 full_dir = os.path.join(os.environ["LLDB_TEST"], cls.mydir)
1273 print("Change dir to:", full_dir, file=sys.stderr)
1274 os.chdir(os.path.join(os.environ["LLDB_TEST"], cls.mydir))
1276 if debug_confirm_directory_exclusivity:
1278 cls.dir_lock = lock.Lock(os.path.join(full_dir, ".dirlock"))
1280 cls.dir_lock.try_acquire()
1281 # write the class that owns the lock into the lock file
1282 cls.dir_lock.handle.write(cls.__name__)
1283 except IOError as ioerror:
1284 # nothing else should have this directory lock
1285 # wait here until we get a lock
1286 cls.dir_lock.acquire()
1287 # read the previous owner from the lock file
1288 lock_id = cls.dir_lock.handle.read()
1289 print("LOCK ERROR: {} wants to lock '{}' but it is already locked by '{}'".format(cls.__name__, full_dir, lock_id), file=sys.stderr)
1292 # Set platform context.
1293 if platformIsDarwin():
1294 cls.platformContext = _PlatformContext('DYLD_LIBRARY_PATH', 'lib', 'dylib')
1295 elif getPlatform() in ("freebsd", "linux", "netbsd"):
1296 cls.platformContext = _PlatformContext('LD_LIBRARY_PATH', 'lib', 'so')
1298 cls.platformContext = None
1301 def tearDownClass(cls):
1303 Python unittest framework class teardown fixture.
1304 Do class-wide cleanup.
1308 # First, let's do the platform-specific cleanup.
1309 module = builder_module()
1312 # Subclass might have specific cleanup function defined.
1313 if getattr(cls, "classCleanup", None):
1315 print("Call class-specific cleanup function for class:", cls, file=sys.stderr)
1319 exc_type, exc_value, exc_tb = sys.exc_info()
1320 traceback.print_exception(exc_type, exc_value, exc_tb)
1322 if debug_confirm_directory_exclusivity:
1323 cls.dir_lock.release()
1326 # Restore old working directory.
1328 print("Restore dir to:", cls.oldcwd, file=sys.stderr)
1329 os.chdir(cls.oldcwd)
1332 def skipLongRunningTest(cls):
1334 By default, we skip long running test case.
1335 This can be overridden by passing '-l' to the test driver (dotest.py).
1337 if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
1342 def enableLogChannelsForCurrentTest(self):
1343 if len(lldbtest_config.channels) == 0:
1346 # if debug channels are specified in lldbtest_config.channels,
1347 # create a new set of log files for every test
1348 log_basename = self.getLogBasenameForCurrentTest()
1350 # confirm that the file is writeable
1351 host_log_path = "{}-host.log".format(log_basename)
1352 open(host_log_path, 'w').close()
1354 log_enable = "log enable -Tpn -f {} ".format(host_log_path)
1355 for channel_with_categories in lldbtest_config.channels:
1356 channel_then_categories = channel_with_categories.split(' ', 1)
1357 channel = channel_then_categories[0]
1358 if len(channel_then_categories) > 1:
1359 categories = channel_then_categories[1]
1361 categories = "default"
1363 if channel == "gdb-remote":
1364 # communicate gdb-remote categories to debugserver
1365 os.environ["LLDB_DEBUGSERVER_LOG_FLAGS"] = categories
1367 self.ci.HandleCommand(log_enable + channel_with_categories, self.res)
1368 if not self.res.Succeeded():
1369 raise Exception('log enable failed (check LLDB_LOG_OPTION env variable)')
1371 # Communicate log path name to debugserver & lldb-server
1372 server_log_path = "{}-server.log".format(log_basename)
1373 open(server_log_path, 'w').close()
1374 os.environ["LLDB_DEBUGSERVER_LOG_FILE"] = server_log_path
1376 # Communicate channels to lldb-server
1377 os.environ["LLDB_SERVER_LOG_CHANNELS"] = ":".join(lldbtest_config.channels)
1379 if len(lldbtest_config.channels) == 0:
1382 def disableLogChannelsForCurrentTest(self):
1383 # close all log files that we opened
1384 for channel_and_categories in lldbtest_config.channels:
1385 # channel format - <channel-name> [<category0> [<category1> ...]]
1386 channel = channel_and_categories.split(' ', 1)[0]
1387 self.ci.HandleCommand("log disable " + channel, self.res)
1388 if not self.res.Succeeded():
1389 raise Exception('log disable failed (check LLDB_LOG_OPTION env variable)')
1392 """Fixture for unittest test case setup.
1394 It works with the test driver to conditionally skip tests and does other
1397 #traceback.print_stack()
1399 if "LIBCXX_PATH" in os.environ:
1400 self.libcxxPath = os.environ["LIBCXX_PATH"]
1402 self.libcxxPath = None
1404 if "LLDBMI_EXEC" in os.environ:
1405 self.lldbMiExec = os.environ["LLDBMI_EXEC"]
1407 self.lldbMiExec = None
1409 # If we spawn an lldb process for test (via pexpect), do not load the
1410 # init file unless told otherwise.
1411 if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]:
1412 self.lldbOption = ""
1414 self.lldbOption = "--no-lldbinit"
1416 # Assign the test method name to self.testMethodName.
1418 # For an example of the use of this attribute, look at test/types dir.
1419 # There are a bunch of test cases under test/types and we don't want the
1420 # module cacheing subsystem to be confused with executable name "a.out"
1421 # used for all the test cases.
1422 self.testMethodName = self._testMethodName
1424 # This is for the case of directly spawning 'lldb'/'gdb' and interacting
1425 # with it using pexpect.
1427 self.child_prompt = "(lldb) "
1428 # If the child is interacting with the embedded script interpreter,
1429 # there are two exits required during tear down, first to quit the
1430 # embedded script interpreter and second to quit the lldb command
1432 self.child_in_script_interpreter = False
1434 # These are for customized teardown cleanup.
1436 self.doTearDownCleanup = False
1437 # And in rare cases where there are multiple teardown cleanups.
1439 self.doTearDownCleanups = False
1441 # List of spawned subproces.Popen objects
1442 self.subprocesses = []
1444 # List of forked process PIDs
1445 self.forkedProcessPids = []
1447 # Create a string buffer to record the session info, to be dumped into a
1448 # test case specific file if test failure is encountered.
1449 self.log_basename = self.getLogBasenameForCurrentTest()
1451 session_file = "{}.log".format(self.log_basename)
1452 # Python 3 doesn't support unbuffered I/O in text mode. Open buffered.
1453 self.session = open(session_file, "w")
1455 # Optimistically set __errored__, __failed__, __expected__ to False
1456 # initially. If the test errored/failed, the session info
1457 # (self.session) is then dumped into a session specific file for
1459 self.__cleanup_errored__ = False
1460 self.__errored__ = False
1461 self.__failed__ = False
1462 self.__expected__ = False
1463 # We are also interested in unexpected success.
1464 self.__unexpected__ = False
1465 # And skipped tests.
1466 self.__skipped__ = False
1468 # See addTearDownHook(self, hook) which allows the client to add a hook
1469 # function to be run during tearDown() time.
1472 # See HideStdout(self).
1473 self.sys_stdout_hidden = False
1475 if self.platformContext:
1476 # set environment variable names for finding shared libraries
1477 self.dylibPath = self.platformContext.shlib_environment_var
1479 # Create the debugger instance if necessary.
1482 except AttributeError:
1483 self.dbg = lldb.SBDebugger.Create()
1486 raise Exception('Invalid debugger instance')
1488 # Retrieve the associated command interpreter instance.
1489 self.ci = self.dbg.GetCommandInterpreter()
1491 raise Exception('Could not get the command interpreter')
1493 # And the result object.
1494 self.res = lldb.SBCommandReturnObject()
1496 self.enableLogChannelsForCurrentTest()
1498 #Initialize debug_info
1499 self.debug_info = None
1501 def setAsync(self, value):
1502 """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
1503 old_async = self.dbg.GetAsync()
1504 self.dbg.SetAsync(value)
1505 self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
1507 def cleanupSubprocesses(self):
1508 # Ensure any subprocesses are cleaned up
1509 for p in self.subprocesses:
1512 del self.subprocesses[:]
1513 # Ensure any forked processes are cleaned up
1514 for pid in self.forkedProcessPids:
1515 if os.path.exists("/proc/" + str(pid)):
1516 os.kill(pid, signal.SIGTERM)
1518 def spawnSubprocess(self, executable, args=[], install_remote=True):
1519 """ Creates a subprocess.Popen object with the specified executable and arguments,
1520 saves it in self.subprocesses, and returns the object.
1521 NOTE: if using this function, ensure you also call:
1523 self.addTearDownHook(self.cleanupSubprocesses)
1525 otherwise the test suite will leak processes.
1527 proc = _RemoteProcess(install_remote) if lldb.remote_platform else _LocalProcess(self.TraceOn())
1528 proc.launch(executable, args)
1529 self.subprocesses.append(proc)
1532 def forkSubprocess(self, executable, args=[]):
1533 """ Fork a subprocess with its own group ID.
1534 NOTE: if using this function, ensure you also call:
1536 self.addTearDownHook(self.cleanupSubprocesses)
1538 otherwise the test suite will leak processes.
1540 child_pid = os.fork()
1542 # If more I/O support is required, this can be beefed up.
1543 fd = os.open(os.devnull, os.O_RDWR)
1546 # This call causes the child to have its of group ID
1548 os.execvp(executable, [executable] + args)
1549 # Give the child time to get through the execvp() call
1551 self.forkedProcessPids.append(child_pid)
1554 def HideStdout(self):
1555 """Hide output to stdout from the user.
1557 During test execution, there might be cases where we don't want to show the
1558 standard output to the user. For example,
1560 self.runCmd(r'''sc print("\n\n\tHello!\n")''')
1562 tests whether command abbreviation for 'script' works or not. There is no
1563 need to show the 'Hello' output to the user as long as the 'script' command
1564 succeeds and we are not in TraceOn() mode (see the '-t' option).
1566 In this case, the test method calls self.HideStdout(self) to redirect the
1567 sys.stdout to a null device, and restores the sys.stdout upon teardown.
1569 Note that you should only call this method at most once during a test case
1570 execution. Any subsequent call has no effect at all."""
1571 if self.sys_stdout_hidden:
1574 self.sys_stdout_hidden = True
1575 old_stdout = sys.stdout
1576 sys.stdout = open(os.devnull, 'w')
1577 def restore_stdout():
1578 sys.stdout = old_stdout
1579 self.addTearDownHook(restore_stdout)
1581 # =======================================================================
1582 # Methods for customized teardown cleanups as well as execution of hooks.
1583 # =======================================================================
1585 def setTearDownCleanup(self, dictionary=None):
1586 """Register a cleanup action at tearDown() time with a dictinary"""
1587 self.dict = dictionary
1588 self.doTearDownCleanup = True
1590 def addTearDownCleanup(self, dictionary):
1591 """Add a cleanup action at tearDown() time with a dictinary"""
1592 self.dicts.append(dictionary)
1593 self.doTearDownCleanups = True
1595 def addTearDownHook(self, hook):
1597 Add a function to be run during tearDown() time.
1599 Hooks are executed in a first come first serve manner.
1601 if six.callable(hook):
1602 with recording(self, traceAlways) as sbuf:
1603 print("Adding tearDown hook:", getsource_if_available(hook), file=sbuf)
1604 self.hooks.append(hook)
1608 def deletePexpectChild(self):
1609 # This is for the case of directly spawning 'lldb' and interacting with it
1611 if self.child and self.child.isalive():
1613 with recording(self, traceAlways) as sbuf:
1614 print("tearing down the child process....", file=sbuf)
1616 if self.child_in_script_interpreter:
1617 self.child.sendline('quit()')
1618 self.child.expect_exact(self.child_prompt)
1619 self.child.sendline('settings set interpreter.prompt-on-quit false')
1620 self.child.sendline('quit')
1621 self.child.expect(pexpect.EOF)
1622 except (ValueError, pexpect.ExceptionPexpect):
1623 # child is already terminated
1625 except OSError as exception:
1627 if exception.errno != errno.EIO:
1630 # child is already terminated
1633 # Give it one final blow to make sure the child is terminated.
1637 """Fixture for unittest test case teardown."""
1639 #traceback.print_stack()
1641 self.deletePexpectChild()
1643 # Check and run any hook functions.
1644 for hook in reversed(self.hooks):
1645 with recording(self, traceAlways) as sbuf:
1646 print("Executing tearDown hook:", getsource_if_available(hook), file=sbuf)
1648 hook_argc = len(inspect.getargspec(hook).args)
1649 if hook_argc == 0 or getattr(hook,'im_self',None):
1651 elif hook_argc == 1:
1654 hook() # try the plain call and hope it works
1658 # Perform registered teardown cleanup.
1659 if doCleanup and self.doTearDownCleanup:
1660 self.cleanup(dictionary=self.dict)
1662 # In rare cases where there are multiple teardown cleanups added.
1663 if doCleanup and self.doTearDownCleanups:
1665 for dict in reversed(self.dicts):
1666 self.cleanup(dictionary=dict)
1668 self.disableLogChannelsForCurrentTest()
1670 # =========================================================
1671 # Various callbacks to allow introspection of test progress
1672 # =========================================================
1674 def markError(self):
1675 """Callback invoked when an error (unexpected exception) errored."""
1676 self.__errored__ = True
1677 with recording(self, False) as sbuf:
1678 # False because there's no need to write "ERROR" to the stderr twice.
1679 # Once by the Python unittest framework, and a second time by us.
1680 print("ERROR", file=sbuf)
1682 def markCleanupError(self):
1683 """Callback invoked when an error occurs while a test is cleaning up."""
1684 self.__cleanup_errored__ = True
1685 with recording(self, False) as sbuf:
1686 # False because there's no need to write "CLEANUP_ERROR" to the stderr twice.
1687 # Once by the Python unittest framework, and a second time by us.
1688 print("CLEANUP_ERROR", file=sbuf)
1690 def markFailure(self):
1691 """Callback invoked when a failure (test assertion failure) occurred."""
1692 self.__failed__ = True
1693 with recording(self, False) as sbuf:
1694 # False because there's no need to write "FAIL" to the stderr twice.
1695 # Once by the Python unittest framework, and a second time by us.
1696 print("FAIL", file=sbuf)
1698 def markExpectedFailure(self,err,bugnumber):
1699 """Callback invoked when an expected failure/error occurred."""
1700 self.__expected__ = True
1701 with recording(self, False) as sbuf:
1702 # False because there's no need to write "expected failure" to the
1704 # Once by the Python unittest framework, and a second time by us.
1705 if bugnumber == None:
1706 print("expected failure", file=sbuf)
1708 print("expected failure (problem id:" + str(bugnumber) + ")", file=sbuf)
1710 def markSkippedTest(self):
1711 """Callback invoked when a test is skipped."""
1712 self.__skipped__ = True
1713 with recording(self, False) as sbuf:
1714 # False because there's no need to write "skipped test" to the
1716 # Once by the Python unittest framework, and a second time by us.
1717 print("skipped test", file=sbuf)
1719 def markUnexpectedSuccess(self, bugnumber):
1720 """Callback invoked when an unexpected success occurred."""
1721 self.__unexpected__ = True
1722 with recording(self, False) as sbuf:
1723 # False because there's no need to write "unexpected success" to the
1725 # Once by the Python unittest framework, and a second time by us.
1726 if bugnumber == None:
1727 print("unexpected success", file=sbuf)
1729 print("unexpected success (problem id:" + str(bugnumber) + ")", file=sbuf)
1731 def getRerunArgs(self):
1732 return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
1734 def getLogBasenameForCurrentTest(self, prefix=None):
1736 returns a partial path that can be used as the beginning of the name of multiple
1737 log files pertaining to this test
1739 <session-dir>/<arch>-<compiler>-<test-file>.<test-class>.<test-method>
1741 dname = os.path.join(os.environ["LLDB_TEST"],
1742 os.environ["LLDB_SESSION_DIRNAME"])
1743 if not os.path.isdir(dname):
1746 compiler = self.getCompiler()
1748 if compiler[1] == ':':
1749 compiler = compiler[2:]
1750 if os.path.altsep is not None:
1751 compiler = compiler.replace(os.path.altsep, os.path.sep)
1753 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), "_".join(compiler.split(os.path.sep)))
1754 if len(fname) > 200:
1755 fname = "{}-{}-{}".format(self.id(), self.getArchitecture(), compiler.split(os.path.sep)[-1])
1757 if prefix is not None:
1758 fname = "{}-{}".format(prefix, fname)
1760 return os.path.join(dname, fname)
1762 def dumpSessionInfo(self):
1764 Dump the debugger interactions leading to a test error/failure. This
1765 allows for more convenient postmortem analysis.
1767 See also LLDBTestResult (dotest.py) which is a singlton class derived
1768 from TextTestResult and overwrites addError, addFailure, and
1769 addExpectedFailure methods to allow us to to mark the test instance as
1773 # We are here because self.tearDown() detected that this test instance
1774 # either errored or failed. The lldb.test_result singleton contains
1775 # two lists (erros and failures) which get populated by the unittest
1776 # framework. Look over there for stack trace information.
1778 # The lists contain 2-tuples of TestCase instances and strings holding
1779 # formatted tracebacks.
1781 # See http://docs.python.org/library/unittest.html#unittest.TestResult.
1783 # output tracebacks into session
1785 if self.__errored__:
1786 pairs = configuration.test_result.errors
1788 elif self.__cleanup_errored__:
1789 pairs = configuration.test_result.cleanup_errors
1790 prefix = 'CleanupError'
1791 elif self.__failed__:
1792 pairs = configuration.test_result.failures
1794 elif self.__expected__:
1795 pairs = configuration.test_result.expectedFailures
1796 prefix = 'ExpectedFailure'
1797 elif self.__skipped__:
1798 prefix = 'SkippedTest'
1799 elif self.__unexpected__:
1800 prefix = 'UnexpectedSuccess'
1804 if not self.__unexpected__ and not self.__skipped__:
1805 for test, traceback in pairs:
1807 print(traceback, file=self.session)
1809 # put footer (timestamp/rerun instructions) into session
1810 testMethod = getattr(self, self._testMethodName)
1811 if getattr(testMethod, "__benchmarks_test__", False):
1817 print("Session info generated @", datetime.datetime.now().ctime(), file=self.session)
1818 print("To rerun this test, issue the following command from the 'test' directory:\n", file=self.session)
1819 print("./dotest.py %s -v %s %s" % (self.getRunOptions(),
1820 ('+b' if benchmarks else '-t'),
1821 self.getRerunArgs()), file=self.session)
1822 self.session.close()
1825 # process the log files
1826 log_files_for_this_test = glob.glob(self.log_basename + "*")
1828 if prefix != 'Success' or lldbtest_config.log_success:
1829 # keep all log files, rename them to include prefix
1830 dst_log_basename = self.getLogBasenameForCurrentTest(prefix)
1831 for src in log_files_for_this_test:
1832 if os.path.isfile(src):
1833 dst = src.replace(self.log_basename, dst_log_basename)
1834 if os.name == "nt" and os.path.isfile(dst):
1835 # On Windows, renaming a -> b will throw an exception if b exists. On non-Windows platforms
1836 # it silently replaces the destination. Ultimately this means that atomic renames are not
1837 # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the
1838 # destination first if it already exists.
1843 # success! (and we don't want log files) delete log files
1844 for log_file in log_files_for_this_test:
1848 # We've seen consistent unlink failures on Windows, perhaps because the
1849 # just-created log file is being scanned by anti-virus. Empirically, this
1850 # sleep-and-retry approach allows tests to succeed much more reliably.
1851 # Attempts to figure out exactly what process was still holding a file handle
1852 # have failed because running instrumentation like Process Monitor seems to
1853 # slow things down enough that the problem becomes much less consistent.
1857 # ====================================================
1858 # Config. methods supported through a plugin interface
1859 # (enables reading of the current test configuration)
1860 # ====================================================
1862 def getArchitecture(self):
1863 """Returns the architecture in effect the test suite is running with."""
1864 module = builder_module()
1865 arch = module.getArchitecture()
1870 def getLldbArchitecture(self):
1871 """Returns the architecture of the lldb binary."""
1872 if not hasattr(self, 'lldbArchitecture'):
1874 # spawn local process
1876 lldbtest_config.lldbExec,
1878 "file " + lldbtest_config.lldbExec,
1883 output = check_output(command)
1884 str = output.decode("utf-8");
1886 for line in str.splitlines():
1887 m = re.search("Current executable set to '.*' \\((.*)\\)\\.", line)
1889 self.lldbArchitecture = m.group(1)
1892 return self.lldbArchitecture
1894 def getCompiler(self):
1895 """Returns the compiler in effect the test suite is running with."""
1896 module = builder_module()
1897 return module.getCompiler()
1899 def getCompilerBinary(self):
1900 """Returns the compiler binary the test suite is running with."""
1901 return self.getCompiler().split()[0]
1903 def getCompilerVersion(self):
1904 """ Returns a string that represents the compiler version.
1905 Supports: llvm, clang.
1907 from .lldbutil import which
1910 compiler = self.getCompilerBinary()
1911 version_output = system([[which(compiler), "-v"]])[1]
1912 for line in version_output.split(os.linesep):
1913 m = re.search('version ([0-9\.]+)', line)
1915 version = m.group(1)
1918 def getGoCompilerVersion(self):
1919 """ Returns a string that represents the go compiler version, or None if go is not found.
1921 compiler = which("go")
1923 version_output = system([[compiler, "version"]])[0]
1924 for line in version_output.split(os.linesep):
1925 m = re.search('go version (devel|go\\S+)', line)
1930 def platformIsDarwin(self):
1931 """Returns true if the OS triple for the selected platform is any valid apple OS"""
1932 return platformIsDarwin()
1934 def getPlatform(self):
1935 """Returns the target platform the test suite is running on."""
1936 return getPlatform()
1938 def isIntelCompiler(self):
1939 """ Returns true if using an Intel (ICC) compiler, false otherwise. """
1940 return any([x in self.getCompiler() for x in ["icc", "icpc", "icl"]])
1942 def expectedCompilerVersion(self, compiler_version):
1943 """Returns True iff compiler_version[1] matches the current compiler version.
1944 Use compiler_version[0] to specify the operator used to determine if a match has occurred.
1945 Any operator other than the following defaults to an equality test:
1946 '>', '>=', "=>", '<', '<=', '=<', '!=', "!" or 'not'
1948 if (compiler_version == None):
1950 operator = str(compiler_version[0])
1951 version = compiler_version[1]
1953 if (version == None):
1955 if (operator == '>'):
1956 return self.getCompilerVersion() > version
1957 if (operator == '>=' or operator == '=>'):
1958 return self.getCompilerVersion() >= version
1959 if (operator == '<'):
1960 return self.getCompilerVersion() < version
1961 if (operator == '<=' or operator == '=<'):
1962 return self.getCompilerVersion() <= version
1963 if (operator == '!=' or operator == '!' or operator == 'not'):
1964 return str(version) not in str(self.getCompilerVersion())
1965 return str(version) in str(self.getCompilerVersion())
1967 def expectedCompiler(self, compilers):
1968 """Returns True iff any element of compilers is a sub-string of the current compiler."""
1969 if (compilers == None):
1972 for compiler in compilers:
1973 if compiler in self.getCompiler():
1978 def expectedArch(self, archs):
1979 """Returns True iff any element of archs is a sub-string of the current architecture."""
1984 if arch in self.getArchitecture():
1989 def getRunOptions(self):
1990 """Command line option for -A and -C to run this test again, called from
1991 self.dumpSessionInfo()."""
1992 arch = self.getArchitecture()
1993 comp = self.getCompiler()
1995 option_str = "-A " + arch
1999 option_str += " -C " + comp
2002 # ==================================================
2003 # Build methods supported through a plugin interface
2004 # ==================================================
2006 def getstdlibFlag(self):
2007 """ Returns the proper -stdlib flag, or empty if not required."""
2008 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
2009 stdlibflag = "-stdlib=libc++"
2010 else: # this includes NetBSD
2014 def getstdFlag(self):
2015 """ Returns the proper stdflag. """
2016 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2017 stdflag = "-std=c++0x"
2019 stdflag = "-std=c++11"
2022 def buildDriver(self, sources, exe_name):
2023 """ Platform-specific way to build a program that links with LLDB (via the liblldb.so
2027 stdflag = self.getstdFlag()
2028 stdlibflag = self.getstdlibFlag()
2030 lib_dir = os.environ["LLDB_LIB_DIR"]
2031 if sys.platform.startswith("darwin"):
2032 dsym = os.path.join(lib_dir, 'LLDB.framework', 'LLDB')
2033 d = {'CXX_SOURCES' : sources,
2035 'CFLAGS_EXTRAS' : "%s %s" % (stdflag, stdlibflag),
2036 'FRAMEWORK_INCLUDES' : "-F%s" % lib_dir,
2037 'LD_EXTRAS' : "%s -Wl,-rpath,%s" % (dsym, lib_dir),
2039 elif sys.platform.rstrip('0123456789') in ('freebsd', 'linux', 'netbsd') or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
2040 d = {'CXX_SOURCES' : sources,
2042 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2043 'LD_EXTRAS' : "-L%s -llldb" % lib_dir}
2044 elif sys.platform.startswith('win'):
2045 d = {'CXX_SOURCES' : sources,
2047 'CFLAGS_EXTRAS' : "%s %s -I%s" % (stdflag, stdlibflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2048 'LD_EXTRAS' : "-L%s -lliblldb" % os.environ["LLDB_IMPLIB_DIR"]}
2050 print("Building LLDB Driver (%s) from sources %s" % (exe_name, sources))
2052 self.buildDefault(dictionary=d)
2054 def buildLibrary(self, sources, lib_name):
2055 """Platform specific way to build a default library. """
2057 stdflag = self.getstdFlag()
2059 lib_dir = os.environ["LLDB_LIB_DIR"]
2060 if self.platformIsDarwin():
2061 dsym = os.path.join(lib_dir, 'LLDB.framework', 'LLDB')
2062 d = {'DYLIB_CXX_SOURCES' : sources,
2063 'DYLIB_NAME' : lib_name,
2064 'CFLAGS_EXTRAS' : "%s -stdlib=libc++" % stdflag,
2065 'FRAMEWORK_INCLUDES' : "-F%s" % lib_dir,
2066 'LD_EXTRAS' : "%s -Wl,-rpath,%s -dynamiclib" % (dsym, lib_dir),
2068 elif self.getPlatform() in ('freebsd', 'linux', 'netbsd') or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
2069 d = {'DYLIB_CXX_SOURCES' : sources,
2070 'DYLIB_NAME' : lib_name,
2071 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2072 'LD_EXTRAS' : "-shared -L%s -llldb" % lib_dir}
2073 elif self.getPlatform() == 'windows':
2074 d = {'DYLIB_CXX_SOURCES' : sources,
2075 'DYLIB_NAME' : lib_name,
2076 'CFLAGS_EXTRAS' : "%s -I%s -fPIC" % (stdflag, os.path.join(os.environ["LLDB_SRC"], "include")),
2077 'LD_EXTRAS' : "-shared -l%s\liblldb.lib" % self.os.environ["LLDB_IMPLIB_DIR"]}
2079 print("Building LLDB Library (%s) from sources %s" % (lib_name, sources))
2081 self.buildDefault(dictionary=d)
2083 def buildProgram(self, sources, exe_name):
2084 """ Platform specific way to build an executable from C/C++ sources. """
2085 d = {'CXX_SOURCES' : sources,
2087 self.buildDefault(dictionary=d)
2089 def buildDefault(self, architecture=None, compiler=None, dictionary=None, clean=True):
2090 """Platform specific way to build the default binaries."""
2091 module = builder_module()
2092 if target_is_android():
2093 dictionary = append_android_envs(dictionary)
2094 if not module.buildDefault(self, architecture, compiler, dictionary, clean):
2095 raise Exception("Don't know how to build default binary")
2097 def buildDsym(self, architecture=None, compiler=None, dictionary=None, clean=True):
2098 """Platform specific way to build binaries with dsym info."""
2099 module = builder_module()
2100 if not module.buildDsym(self, architecture, compiler, dictionary, clean):
2101 raise Exception("Don't know how to build binary with dsym")
2103 def buildDwarf(self, architecture=None, compiler=None, dictionary=None, clean=True):
2104 """Platform specific way to build binaries with dwarf maps."""
2105 module = builder_module()
2106 if target_is_android():
2107 dictionary = append_android_envs(dictionary)
2108 if not module.buildDwarf(self, architecture, compiler, dictionary, clean):
2109 raise Exception("Don't know how to build binary with dwarf")
2111 def buildDwo(self, architecture=None, compiler=None, dictionary=None, clean=True):
2112 """Platform specific way to build binaries with dwarf maps."""
2113 module = builder_module()
2114 if target_is_android():
2115 dictionary = append_android_envs(dictionary)
2116 if not module.buildDwo(self, architecture, compiler, dictionary, clean):
2117 raise Exception("Don't know how to build binary with dwo")
2120 """Build the default go binary.
2122 system([[which('go'), 'build -gcflags "-N -l" -o a.out main.go']])
2124 def signBinary(self, binary_path):
2125 if sys.platform.startswith("darwin"):
2126 codesign_cmd = "codesign --force --sign lldb_codesign %s" % (binary_path)
2127 call(codesign_cmd, shell=True)
2129 def findBuiltClang(self):
2130 """Tries to find and use Clang from the build directory as the compiler (instead of the system compiler)."""
2132 "llvm-build/Release+Asserts/x86_64/Release+Asserts/bin/clang",
2133 "llvm-build/Debug+Asserts/x86_64/Debug+Asserts/bin/clang",
2134 "llvm-build/Release/x86_64/Release/bin/clang",
2135 "llvm-build/Debug/x86_64/Debug/bin/clang",
2137 lldb_root_path = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..")
2138 for p in paths_to_try:
2139 path = os.path.join(lldb_root_path, p)
2140 if os.path.exists(path):
2143 # Tries to find clang at the same folder as the lldb
2144 path = os.path.join(os.path.dirname(lldbtest_config.lldbExec), "clang")
2145 if os.path.exists(path):
2148 return os.environ["CC"]
2150 def getBuildFlags(self, use_cpp11=True, use_libcxx=False, use_libstdcxx=False):
2151 """ Returns a dictionary (which can be provided to build* functions above) which
2152 contains OS-specific build flags.
2157 # On Mac OS X, unless specifically requested to use libstdc++, use libc++
2158 if not use_libstdcxx and self.platformIsDarwin():
2161 if use_libcxx and self.libcxxPath:
2162 cflags += "-stdlib=libc++ "
2164 libcxxInclude = os.path.join(self.libcxxPath, "include")
2165 libcxxLib = os.path.join(self.libcxxPath, "lib")
2166 if os.path.isdir(libcxxInclude) and os.path.isdir(libcxxLib):
2167 cflags += "-nostdinc++ -I%s -L%s -Wl,-rpath,%s " % (libcxxInclude, libcxxLib, libcxxLib)
2171 if "gcc" in self.getCompiler() and "4.6" in self.getCompilerVersion():
2175 if self.platformIsDarwin() or self.getPlatform() == "freebsd":
2176 cflags += " -stdlib=libc++"
2177 elif self.getPlatform() == "netbsd":
2178 cflags += " -stdlib=libstdc++"
2179 elif "clang" in self.getCompiler():
2180 cflags += " -stdlib=libstdc++"
2182 return {'CFLAGS_EXTRAS' : cflags,
2183 'LD_EXTRAS' : ldflags,
2186 def cleanup(self, dictionary=None):
2187 """Platform specific way to do cleanup after build."""
2188 module = builder_module()
2189 if not module.cleanup(self, dictionary):
2190 raise Exception("Don't know how to do cleanup with dictionary: "+dictionary)
2192 def getLLDBLibraryEnvVal(self):
2193 """ Returns the path that the OS-specific library search environment variable
2194 (self.dylibPath) should be set to in order for a program to find the LLDB
2195 library. If an environment variable named self.dylibPath is already set,
2196 the new path is appended to it and returned.
2198 existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
2199 lib_dir = os.environ["LLDB_LIB_DIR"]
2200 if existing_library_path:
2201 return "%s:%s" % (existing_library_path, lib_dir)
2202 elif sys.platform.startswith("darwin"):
2203 return os.path.join(lib_dir, 'LLDB.framework')
2207 def getLibcPlusPlusLibs(self):
2208 if self.getPlatform() in ('freebsd', 'linux', 'netbsd'):
2209 return ['libc++.so.1']
2211 return ['libc++.1.dylib','libc++abi.dylib']
2213 # Metaclass for TestBase to change the list of test metods when a new TestCase is loaded.
2214 # We change the test methods to create a new test method for each test for each debug info we are
2215 # testing. The name of the new test method will be '<original-name>_<debug-info>' and with adding
2216 # the new test method we remove the old method at the same time.
2217 class LLDBTestCaseFactory(type):
2218 def __new__(cls, name, bases, attrs):
2220 for attrname, attrvalue in attrs.items():
2221 if attrname.startswith("test") and not getattr(attrvalue, "__no_debug_info_test__", False):
2222 target_platform = lldb.DBG.GetSelectedPlatform().GetTriple().split('-')[2]
2224 # If any debug info categories were explicitly tagged, assume that list to be
2225 # authoritative. If none were specified, try with all debug info formats.
2226 all_dbginfo_categories = set(test_categories.debug_info_categories)
2227 categories = set(getattr(attrvalue, "categories", [])) & all_dbginfo_categories
2229 categories = all_dbginfo_categories
2231 supported_categories = [x for x in categories
2232 if test_categories.is_supported_on_platform(x, target_platform)]
2233 if "dsym" in supported_categories:
2234 @add_test_categories(["dsym"])
2236 def dsym_test_method(self, attrvalue=attrvalue):
2237 self.debug_info = "dsym"
2238 return attrvalue(self)
2239 dsym_method_name = attrname + "_dsym"
2240 dsym_test_method.__name__ = dsym_method_name
2241 newattrs[dsym_method_name] = dsym_test_method
2243 if "dwarf" in supported_categories:
2244 @add_test_categories(["dwarf"])
2246 def dwarf_test_method(self, attrvalue=attrvalue):
2247 self.debug_info = "dwarf"
2248 return attrvalue(self)
2249 dwarf_method_name = attrname + "_dwarf"
2250 dwarf_test_method.__name__ = dwarf_method_name
2251 newattrs[dwarf_method_name] = dwarf_test_method
2253 if "dwo" in supported_categories:
2254 @add_test_categories(["dwo"])
2256 def dwo_test_method(self, attrvalue=attrvalue):
2257 self.debug_info = "dwo"
2258 return attrvalue(self)
2259 dwo_method_name = attrname + "_dwo"
2260 dwo_test_method.__name__ = dwo_method_name
2261 newattrs[dwo_method_name] = dwo_test_method
2263 newattrs[attrname] = attrvalue
2264 return super(LLDBTestCaseFactory, cls).__new__(cls, name, bases, newattrs)
2266 # Setup the metaclass for this class to change the list of the test methods when a new class is loaded
2267 @add_metaclass(LLDBTestCaseFactory)
2268 class TestBase(Base):
2270 This abstract base class is meant to be subclassed. It provides default
2271 implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
2274 Important things for test class writers:
2276 - Overwrite the mydir class attribute, otherwise your test class won't
2277 run. It specifies the relative directory to the top level 'test' so
2278 the test harness can change to the correct working directory before
2281 - The setUp method sets up things to facilitate subsequent interactions
2282 with the debugger as part of the test. These include:
2283 - populate the test method name
2284 - create/get a debugger set with synchronous mode (self.dbg)
2285 - get the command interpreter from with the debugger (self.ci)
2286 - create a result object for use with the command interpreter
2290 - The tearDown method tries to perform some necessary cleanup on behalf
2291 of the test to return the debugger to a good state for the next test.
2293 - execute any tearDown hooks registered by the test method with
2294 TestBase.addTearDownHook(); examples can be found in
2295 settings/TestSettings.py
2296 - kill the inferior process associated with each target, if any,
2297 and, then delete the target from the debugger's target list
2298 - perform build cleanup before running the next test method in the
2299 same test class; examples of registering for this service can be
2300 found in types/TestIntegerTypes.py with the call:
2301 - self.setTearDownCleanup(dictionary=d)
2303 - Similarly setUpClass and tearDownClass perform classwise setup and
2304 teardown fixtures. The tearDownClass method invokes a default build
2305 cleanup for the entire test class; also, subclasses can implement the
2306 classmethod classCleanup(cls) to perform special class cleanup action.
2308 - The instance methods runCmd and expect are used heavily by existing
2309 test cases to send a command to the command interpreter and to perform
2310 string/pattern matching on the output of such command execution. The
2311 expect method also provides a mode to peform string/pattern matching
2312 without running a command.
2314 - The build methods buildDefault, buildDsym, and buildDwarf are used to
2315 build the binaries used during a particular test scenario. A plugin
2316 should be provided for the sys.platform running the test suite. The
2317 Mac OS X implementation is located in plugins/darwin.py.
2320 # Maximum allowed attempts when launching the inferior process.
2321 # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
2324 # Time to wait before the next launching attempt in second(s).
2325 # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
2326 timeWaitNextLaunch = 1.0;
2328 # Returns the list of categories to which this test case belongs
2329 # by default, look for a ".categories" file, and read its contents
2330 # if no such file exists, traverse the hierarchy - we guarantee
2331 # a .categories to exist at the top level directory so we do not end up
2332 # looping endlessly - subclasses are free to define their own categories
2333 # in whatever way makes sense to them
2334 def getCategories(self):
2337 folder = inspect.getfile(self.__class__)
2338 folder = os.path.dirname(folder)
2339 while folder != '/':
2340 categories_file_name = os.path.join(folder,".categories")
2341 if os.path.exists(categories_file_name):
2342 categories_file = open(categories_file_name,'r')
2343 categories = categories_file.readline()
2344 categories_file.close()
2345 categories = str.replace(categories,'\n','')
2346 categories = str.replace(categories,'\r','')
2347 return categories.split(',')
2349 folder = os.path.dirname(folder)
2354 #traceback.print_stack()
2356 # Works with the test driver to conditionally skip tests via decorators.
2359 if "LLDB_MAX_LAUNCH_COUNT" in os.environ:
2360 self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"])
2362 if "LLDB_TIME_WAIT_NEXT_LAUNCH" in os.environ:
2363 self.timeWaitNextLaunch = float(os.environ["LLDB_TIME_WAIT_NEXT_LAUNCH"])
2365 # We want our debugger to be synchronous.
2366 self.dbg.SetAsync(False)
2368 # Retrieve the associated command interpreter instance.
2369 self.ci = self.dbg.GetCommandInterpreter()
2371 raise Exception('Could not get the command interpreter')
2373 # And the result object.
2374 self.res = lldb.SBCommandReturnObject()
2376 if lldb.remote_platform and configuration.lldb_platform_working_dir:
2377 remote_test_dir = lldbutil.join_remote_paths(
2378 configuration.lldb_platform_working_dir,
2379 self.getArchitecture(),
2380 str(self.test_number),
2382 error = lldb.remote_platform.MakeDirectory(remote_test_dir, 448) # 448 = 0o700
2384 lldb.remote_platform.SetWorkingDirectory(remote_test_dir)
2386 # This function removes all files from the current working directory while leaving
2387 # the directories in place. The cleaup is required to reduce the disk space required
2388 # by the test suit while leaving the directories untached is neccessary because
2389 # sub-directories might belong to an other test
2390 def clean_working_directory():
2391 # TODO: Make it working on Windows when we need it for remote debugging support
2392 # TODO: Replace the heuristic to remove the files with a logic what collects the
2393 # list of files we have to remove during test runs.
2394 shell_cmd = lldb.SBPlatformShellCommand("rm %s/*" % remote_test_dir)
2395 lldb.remote_platform.Run(shell_cmd)
2396 self.addTearDownHook(clean_working_directory)
2398 print("error: making remote directory '%s': %s" % (remote_test_dir, error))
2400 def registerSharedLibrariesWithTarget(self, target, shlibs):
2401 '''If we are remotely running the test suite, register the shared libraries with the target so they get uploaded, otherwise do nothing
2403 Any modules in the target that have their remote install file specification set will
2404 get uploaded to the remote host. This function registers the local copies of the
2405 shared libraries with the target and sets their remote install locations so they will
2406 be uploaded when the target is run.
2408 if not shlibs or not self.platformContext:
2411 shlib_environment_var = self.platformContext.shlib_environment_var
2412 shlib_prefix = self.platformContext.shlib_prefix
2413 shlib_extension = '.' + self.platformContext.shlib_extension
2415 working_dir = self.get_process_working_directory()
2416 environment = ['%s=%s' % (shlib_environment_var, working_dir)]
2417 # Add any shared libraries to our target if remote so they get
2418 # uploaded into the working directory on the remote side
2420 # The path can be a full path to a shared library, or a make file name like "Foo" for
2421 # "libFoo.dylib" or "libFoo.so", or "Foo.so" for "Foo.so" or "libFoo.so", or just a
2422 # basename like "libFoo.so". So figure out which one it is and resolve the local copy
2423 # of the shared library accordingly
2424 if os.path.exists(name):
2425 local_shlib_path = name # name is the full path to the local shared library
2427 # Check relative names
2428 local_shlib_path = os.path.join(os.getcwd(), shlib_prefix + name + shlib_extension)
2429 if not os.path.exists(local_shlib_path):
2430 local_shlib_path = os.path.join(os.getcwd(), name + shlib_extension)
2431 if not os.path.exists(local_shlib_path):
2432 local_shlib_path = os.path.join(os.getcwd(), name)
2434 # Make sure we found the local shared library in the above code
2435 self.assertTrue(os.path.exists(local_shlib_path))
2437 # Add the shared library to our target
2438 shlib_module = target.AddModule(local_shlib_path, None, None, None)
2439 if lldb.remote_platform:
2440 # We must set the remote install location if we want the shared library
2441 # to get uploaded to the remote target
2442 remote_shlib_path = lldbutil.append_to_process_working_directory(os.path.basename(local_shlib_path))
2443 shlib_module.SetRemoteInstallFileSpec(lldb.SBFileSpec(remote_shlib_path, False))
2447 # utility methods that tests can use to access the current objects
2450 raise Exception('Invalid debugger instance')
2451 return self.dbg.GetSelectedTarget()
2455 raise Exception('Invalid debugger instance')
2456 return self.dbg.GetSelectedTarget().GetProcess()
2460 raise Exception('Invalid debugger instance')
2461 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
2465 raise Exception('Invalid debugger instance')
2466 return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
2468 def get_process_working_directory(self):
2469 '''Get the working directory that should be used when launching processes for local or remote processes.'''
2470 if lldb.remote_platform:
2471 # Remote tests set the platform working directory up in TestBase.setUp()
2472 return lldb.remote_platform.GetWorkingDirectory()
2474 # local tests change directory into each test subdirectory
2479 #traceback.print_stack()
2481 # Ensure all the references to SB objects have gone away so that we can
2482 # be sure that all test-specific resources have been freed before we
2483 # attempt to delete the targets.
2486 # Delete the target(s) from the debugger as a general cleanup step.
2487 # This includes terminating the process for each target, if any.
2488 # We'd like to reuse the debugger for our next test without incurring
2489 # the initialization overhead.
2491 for target in self.dbg:
2493 targets.append(target)
2494 process = target.GetProcess()
2496 rc = self.invoke(process, "Kill")
2497 self.assertTrue(rc.Success(), PROCESS_KILLED)
2498 for target in targets:
2499 self.dbg.DeleteTarget(target)
2501 # Do this last, to make sure it's in reverse order from how we setup.
2504 # This must be the last statement, otherwise teardown hooks or other
2505 # lines might depend on this still being active.
2508 def switch_to_thread_with_stop_reason(self, stop_reason):
2510 Run the 'thread list' command, and select the thread with stop reason as
2511 'stop_reason'. If no such thread exists, no select action is done.
2513 from .lldbutil import stop_reason_to_str
2514 self.runCmd('thread list')
2515 output = self.res.GetOutput()
2516 thread_line_pattern = re.compile("^[ *] thread #([0-9]+):.*stop reason = %s" %
2517 stop_reason_to_str(stop_reason))
2518 for line in output.splitlines():
2519 matched = thread_line_pattern.match(line)
2521 self.runCmd('thread select %s' % matched.group(1))
2523 def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False):
2525 Ask the command interpreter to handle the command and then check its
2528 # Fail fast if 'cmd' is not meaningful.
2529 if not cmd or len(cmd) == 0:
2530 raise Exception("Bad 'cmd' parameter encountered")
2532 trace = (True if traceAlways else trace)
2534 if cmd.startswith("target create "):
2535 cmd = cmd.replace("target create ", "file ")
2537 running = (cmd.startswith("run") or cmd.startswith("process launch"))
2539 for i in range(self.maxLaunchCount if running else 1):
2540 self.ci.HandleCommand(cmd, self.res, inHistory)
2542 with recording(self, trace) as sbuf:
2543 print("runCmd:", cmd, file=sbuf)
2545 print("check of return status not required", file=sbuf)
2546 if self.res.Succeeded():
2547 print("output:", self.res.GetOutput(), file=sbuf)
2549 print("runCmd failed!", file=sbuf)
2550 print(self.res.GetError(), file=sbuf)
2552 if self.res.Succeeded():
2555 # For process launch, wait some time before possible next try.
2556 time.sleep(self.timeWaitNextLaunch)
2557 with recording(self, trace) as sbuf:
2558 print("Command '" + cmd + "' failed!", file=sbuf)
2561 self.assertTrue(self.res.Succeeded(),
2562 msg if msg else CMD_MSG(cmd))
2564 def match (self, str, patterns, msg=None, trace=False, error=False, matching=True, exe=True):
2565 """run command in str, and match the result against regexp in patterns returning the match object for the first matching pattern
2567 Otherwise, all the arguments have the same meanings as for the expect function"""
2569 trace = (True if traceAlways else trace)
2572 # First run the command. If we are expecting error, set check=False.
2573 # Pass the assert message along since it provides more semantic info.
2574 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error)
2576 # Then compare the output against expected strings.
2577 output = self.res.GetError() if error else self.res.GetOutput()
2579 # If error is True, the API client expects the command to fail!
2581 self.assertFalse(self.res.Succeeded(),
2582 "Command '" + str + "' is expected to fail!")
2584 # No execution required, just compare str against the golden input.
2586 with recording(self, trace) as sbuf:
2587 print("looking at:", output, file=sbuf)
2589 # The heading says either "Expecting" or "Not expecting".
2590 heading = "Expecting" if matching else "Not expecting"
2592 for pattern in patterns:
2593 # Match Objects always have a boolean value of True.
2594 match_object = re.search(pattern, output)
2595 matched = bool(match_object)
2596 with recording(self, trace) as sbuf:
2597 print("%s pattern: %s" % (heading, pattern), file=sbuf)
2598 print("Matched" if matched else "Not matched", file=sbuf)
2602 self.assertTrue(matched if matching else not matched,
2603 msg if msg else EXP_MSG(str, exe))
2607 def expect(self, str, msg=None, patterns=None, startstr=None, endstr=None, substrs=None, trace=False, error=False, matching=True, exe=True, inHistory=False):
2609 Similar to runCmd; with additional expect style output matching ability.
2611 Ask the command interpreter to handle the command and then check its
2612 return status. The 'msg' parameter specifies an informational assert
2613 message. We expect the output from running the command to start with
2614 'startstr', matches the substrings contained in 'substrs', and regexp
2615 matches the patterns contained in 'patterns'.
2617 If the keyword argument error is set to True, it signifies that the API
2618 client is expecting the command to fail. In this case, the error stream
2619 from running the command is retrieved and compared against the golden
2622 If the keyword argument matching is set to False, it signifies that the API
2623 client is expecting the output of the command not to match the golden
2626 Finally, the required argument 'str' represents the lldb command to be
2627 sent to the command interpreter. In case the keyword argument 'exe' is
2628 set to False, the 'str' is treated as a string to be matched/not-matched
2629 against the golden input.
2631 trace = (True if traceAlways else trace)
2634 # First run the command. If we are expecting error, set check=False.
2635 # Pass the assert message along since it provides more semantic info.
2636 self.runCmd(str, msg=msg, trace = (True if trace else False), check = not error, inHistory=inHistory)
2638 # Then compare the output against expected strings.
2639 output = self.res.GetError() if error else self.res.GetOutput()
2641 # If error is True, the API client expects the command to fail!
2643 self.assertFalse(self.res.Succeeded(),
2644 "Command '" + str + "' is expected to fail!")
2646 # No execution required, just compare str against the golden input.
2647 if isinstance(str,lldb.SBCommandReturnObject):
2648 output = str.GetOutput()
2651 with recording(self, trace) as sbuf:
2652 print("looking at:", output, file=sbuf)
2654 # The heading says either "Expecting" or "Not expecting".
2655 heading = "Expecting" if matching else "Not expecting"
2657 # Start from the startstr, if specified.
2658 # If there's no startstr, set the initial state appropriately.
2659 matched = output.startswith(startstr) if startstr else (True if matching else False)
2662 with recording(self, trace) as sbuf:
2663 print("%s start string: %s" % (heading, startstr), file=sbuf)
2664 print("Matched" if matched else "Not matched", file=sbuf)
2666 # Look for endstr, if specified.
2667 keepgoing = matched if matching else not matched
2669 matched = output.endswith(endstr)
2670 with recording(self, trace) as sbuf:
2671 print("%s end string: %s" % (heading, endstr), file=sbuf)
2672 print("Matched" if matched else "Not matched", file=sbuf)
2674 # Look for sub strings, if specified.
2675 keepgoing = matched if matching else not matched
2676 if substrs and keepgoing:
2678 matched = output.find(str) != -1
2679 with recording(self, trace) as sbuf:
2680 print("%s sub string: %s" % (heading, str), file=sbuf)
2681 print("Matched" if matched else "Not matched", file=sbuf)
2682 keepgoing = matched if matching else not matched
2686 # Search for regular expression patterns, if specified.
2687 keepgoing = matched if matching else not matched
2688 if patterns and keepgoing:
2689 for pattern in patterns:
2690 # Match Objects always have a boolean value of True.
2691 matched = bool(re.search(pattern, output))
2692 with recording(self, trace) as sbuf:
2693 print("%s pattern: %s" % (heading, pattern), file=sbuf)
2694 print("Matched" if matched else "Not matched", file=sbuf)
2695 keepgoing = matched if matching else not matched
2699 self.assertTrue(matched if matching else not matched,
2700 msg if msg else EXP_MSG(str, exe))
2702 def invoke(self, obj, name, trace=False):
2703 """Use reflection to call a method dynamically with no argument."""
2704 trace = (True if traceAlways else trace)
2706 method = getattr(obj, name)
2708 self.assertTrue(inspect.ismethod(method),
2709 name + "is a method name of object: " + str(obj))
2711 with recording(self, trace) as sbuf:
2712 print(str(method) + ":", result, file=sbuf)
2715 def build(self, architecture=None, compiler=None, dictionary=None, clean=True):
2716 """Platform specific way to build the default binaries."""
2717 module = builder_module()
2718 if target_is_android():
2719 dictionary = append_android_envs(dictionary)
2720 if self.debug_info is None:
2721 return self.buildDefault(architecture, compiler, dictionary, clean)
2722 elif self.debug_info == "dsym":
2723 return self.buildDsym(architecture, compiler, dictionary, clean)
2724 elif self.debug_info == "dwarf":
2725 return self.buildDwarf(architecture, compiler, dictionary, clean)
2726 elif self.debug_info == "dwo":
2727 return self.buildDwo(architecture, compiler, dictionary, clean)
2729 self.fail("Can't build for debug info: %s" % self.debug_info)
2731 # =================================================
2732 # Misc. helper methods for debugging test execution
2733 # =================================================
2735 def DebugSBValue(self, val):
2736 """Debug print a SBValue object, if traceAlways is True."""
2737 from .lldbutil import value_type_to_str
2743 err.write(val.GetName() + ":\n")
2744 err.write('\t' + "TypeName -> " + val.GetTypeName() + '\n')
2745 err.write('\t' + "ByteSize -> " + str(val.GetByteSize()) + '\n')
2746 err.write('\t' + "NumChildren -> " + str(val.GetNumChildren()) + '\n')
2747 err.write('\t' + "Value -> " + str(val.GetValue()) + '\n')
2748 err.write('\t' + "ValueAsUnsigned -> " + str(val.GetValueAsUnsigned())+ '\n')
2749 err.write('\t' + "ValueType -> " + value_type_to_str(val.GetValueType()) + '\n')
2750 err.write('\t' + "Summary -> " + str(val.GetSummary()) + '\n')
2751 err.write('\t' + "IsPointerType -> " + str(val.TypeIsPointerType()) + '\n')
2752 err.write('\t' + "Location -> " + val.GetLocation() + '\n')
2754 def DebugSBType(self, type):
2755 """Debug print a SBType object, if traceAlways is True."""
2760 err.write(type.GetName() + ":\n")
2761 err.write('\t' + "ByteSize -> " + str(type.GetByteSize()) + '\n')
2762 err.write('\t' + "IsPointerType -> " + str(type.IsPointerType()) + '\n')
2763 err.write('\t' + "IsReferenceType -> " + str(type.IsReferenceType()) + '\n')
2765 def DebugPExpect(self, child):
2766 """Debug the spwaned pexpect object."""
2773 def RemoveTempFile(cls, file):
2774 if os.path.exists(file):