Newer
Older
#!/usr/bin/env python
"""
A simple testing framework for lldb using python's unit testing framework.
Tests for lldb are written as python scripts which take advantage of the script
bridging provided by LLDB.framework to interact with lldb core.
A specific naming pattern is followed by the .py script to be recognized as
a module which implements a test scenario, namely, Test*.py.
To specify the directories where "Test*.py" python test scripts are located,
you need to pass in a list of directory names. By default, the current
working directory is searched if nothing is specified on the command line.
Type:
./dotest.py -h
for available options.
"""
Greg Clayton
committed
import os
import platform
import signal
Johnny Chen
committed
import subprocess
Greg Clayton
committed
import sys
import textwrap
import time
import unittest2
if sys.version_info >= (2, 7):
argparse = __import__('argparse')
else:
argparse = __import__('argparse_compat')
def parse_args(parser):
""" Returns an argument object. LLDB_TEST_ARGUMENTS environment variable can
be used to pass additional arguments if a compatible (>=2.7) argparse
library is available.
"""
if sys.version_info >= (2, 7):
args = ArgParseNamespace()
if ('LLDB_TEST_ARGUMENTS' in os.environ):
print "Arguments passed through environment: '%s'" % os.environ['LLDB_TEST_ARGUMENTS']
args = parser.parse_args([sys.argv[0]].__add__(os.environ['LLDB_TEST_ARGUMENTS'].split()),namespace=args)
return parser.parse_args(namespace=args)
else:
return parser.parse_args()
Johnny Chen
committed
def is_exe(fpath):
Johnny Chen
committed
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
def which(program):
Johnny Chen
committed
fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file
return None
Johnny Chen
committed
class _WritelnDecorator(object):
"""Used to decorate file-like objects with a handy 'writeln' method"""
def __init__(self,stream):
self.stream = stream
def __getattr__(self, attr):
if attr in ('stream', '__getstate__'):
raise AttributeError(attr)
return getattr(self.stream,attr)
def writeln(self, arg=None):
if arg:
self.write(arg)
self.write('\n') # text-mode streams translate to \r\n if needed
#
# Global variables:
#
# Dictionary of categories
# When you define a new category for your testcases, be sure to add it here, or the test suite
# will gladly complain as soon as you try to use it. This allows us to centralize which categories
# exist, and to provide a description for each one
validCategories = {
'dataformatters':'Tests related to the type command and the data formatters subsystem',
'expression':'Tests related to the expression parser',
'objc':'Tests related to the Objective-C programming language support',
'pyapi':'Tests related to the Python API',
'basic_process': 'Basic process execution sniff tests.',
'cmdline' : 'Tests related to the LLDB command-line interface'
# The test suite.
suite = unittest2.TestSuite()
# By default, both command line and Python API tests are performed.
Johnny Chen
committed
# Use @python_api_test decorator, defined in lldbtest.py, to mark a test as
# a Python API test.
dont_do_python_api_test = False
# By default, both command line and Python API tests are performed.
just_do_python_api_test = False
Johnny Chen
committed
# By default, benchmarks tests are not run.
just_do_benchmarks_test = False
Johnny Chen
committed
# By default, both dsym and dwarf tests are performed.
# Use @dsym_test or @dwarf_test decorators, defined in lldbtest.py, to mark a test
# as a dsym or dwarf test. Use '-N dsym' or '-N dwarf' to exclude dsym or dwarf
# tests from running.
dont_do_dsym_test = "linux" in sys.platform or "freebsd" in sys.platform
Johnny Chen
committed
dont_do_dwarf_test = False
Johnny Chen
committed
# The blacklist is optional (-b blacklistFile) and allows a central place to skip
# testclass's and/or testclass.testmethod's.
blacklist = None
# The dictionary as a result of sourcing blacklistFile.
blacklistConfig = {}
# The list of categories we said we care about
categoriesList = None
# set to true if we are going to use categories for cherry-picking test cases
useCategories = False
# Categories we want to skip
skipCategories = []
# use this to track per-category failures
failuresPerCategory = {}
# The path to LLDB.framework is optional.
lldbFrameworkPath = None
# The path to lldb is optional
lldbExecutablePath = None
# The config file is optional.
configFile = None
Johnny Chen
committed
# Test suite repeat count. Can be overwritten with '-# count'.
count = 1
Johnny Chen
committed
# The dictionary as a result of sourcing configFile.
config = {}
Johnny Chen
committed
# The pre_flight and post_flight functions come from reading a config file.
pre_flight = None
post_flight = None
# So do the lldbtest_remote_sandbox and lldbtest_remote_shell_template variables.
lldbtest_remote_sandbox = None
lldbtest_remote_shell_template = None
Johnny Chen
committed
Johnny Chen
committed
# The 'archs' and 'compilers' can be specified via either command line or configFile,
Greg Clayton
committed
# with the command line overriding the configFile. The corresponding options can be
# specified more than once. For example, "-A x86_64 -A i386" => archs=['x86_64', 'i386']
Greg Clayton
committed
# and "-C gcc -C clang" => compilers=['gcc', 'clang'].
archs = None # Must be initialized after option parsing
compilers = None # Must be initialized after option parsing
Johnny Chen
committed
Johnny Chen
committed
# The arch might dictate some specific CFLAGS to be passed to the toolchain to build
# the inferior programs. The global variable cflags_extras provides a hook to do
# just that.
cflags_extras = ''
Johnny Chen
committed
# Delay startup in order for the debugger to attach.
delay = False
# Dump the Python sys.path variable. Use '-D' to dump sys.path.
dumpSysPath = False
Johnny Chen
committed
# Full path of the benchmark executable, as specified by the '-e' option.
bmExecutable = None
# The breakpoint specification of bmExecutable, as specified by the '-x' option.
bmBreakpointSpec = None
# The benchamrk iteration count, as specified by the '-y' option.
bmIterationCount = -1
Johnny Chen
committed
Johnny Chen
committed
# By default, don't exclude any directories. Use '-X' to add one excluded directory.
excluded = set(['.svn', '.git'])
Johnny Chen
committed
# By default, failfast is False. Use '-F' to overwrite it.
failfast = False
Johnny Chen
committed
# The filters (testclass.testmethod) used to admit tests into our test suite.
filters = []
Johnny Chen
committed
# The runhooks is a list of lldb commands specifically for the debugger.
# Use '-k' to specify a runhook.
runHooks = []
Johnny Chen
committed
# If '-g' is specified, the filterspec is not exclusive. If a test module does
# not contain testclass.testmethod which matches the filterspec, the whole test
Loading
Loading full blame...