1061da546Spatrick""" 2061da546SpatrickA simple testing framework for lldb using python's unit testing framework. 3061da546Spatrick 4061da546SpatrickTests for lldb are written as python scripts which take advantage of the script 5061da546Spatrickbridging provided by LLDB.framework to interact with lldb core. 6061da546Spatrick 7061da546SpatrickA specific naming pattern is followed by the .py script to be recognized as 8061da546Spatricka module which implements a test scenario, namely, Test*.py. 9061da546Spatrick 10061da546SpatrickTo specify the directories where "Test*.py" python test scripts are located, 11061da546Spatrickyou need to pass in a list of directory names. By default, the current 12061da546Spatrickworking directory is searched if nothing is specified on the command line. 13061da546Spatrick 14061da546SpatrickType: 15061da546Spatrick 16061da546Spatrick./dotest.py -h 17061da546Spatrick 18061da546Spatrickfor available options. 19061da546Spatrick""" 20061da546Spatrick 21061da546Spatrickfrom __future__ import absolute_import 22061da546Spatrickfrom __future__ import print_function 23061da546Spatrick 24061da546Spatrick# System modules 25061da546Spatrickimport atexit 26061da546Spatrickimport datetime 27061da546Spatrickimport errno 28061da546Spatrickimport logging 29061da546Spatrickimport os 30061da546Spatrickimport platform 31061da546Spatrickimport re 32be691f3bSpatrickimport shutil 33061da546Spatrickimport signal 34061da546Spatrickimport subprocess 35061da546Spatrickimport sys 36061da546Spatrickimport tempfile 37061da546Spatrick 38061da546Spatrick# Third-party modules 39061da546Spatrickimport unittest2 40061da546Spatrick 41061da546Spatrick# LLDB Modules 42061da546Spatrickimport lldbsuite 43061da546Spatrickfrom . import configuration 44061da546Spatrickfrom . import dotest_args 45061da546Spatrickfrom . import lldbtest_config 46061da546Spatrickfrom . import test_categories 47061da546Spatrickfrom . import test_result 48061da546Spatrickfrom ..support import seven 49061da546Spatrick 50061da546Spatrick 51061da546Spatrickdef is_exe(fpath): 52061da546Spatrick """Returns true if fpath is an executable.""" 53061da546Spatrick if fpath == None: 54061da546Spatrick return False 55be691f3bSpatrick if sys.platform == 'win32': 56be691f3bSpatrick if not fpath.endswith(".exe"): 57be691f3bSpatrick fpath += ".exe" 58061da546Spatrick return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 59061da546Spatrick 60061da546Spatrick 61061da546Spatrickdef which(program): 62061da546Spatrick """Returns the full path to a program; None otherwise.""" 63061da546Spatrick fpath, _ = os.path.split(program) 64061da546Spatrick if fpath: 65061da546Spatrick if is_exe(program): 66061da546Spatrick return program 67061da546Spatrick else: 68061da546Spatrick for path in os.environ["PATH"].split(os.pathsep): 69061da546Spatrick exe_file = os.path.join(path, program) 70061da546Spatrick if is_exe(exe_file): 71061da546Spatrick return exe_file 72061da546Spatrick return None 73061da546Spatrick 74061da546Spatrick 75061da546Spatrickdef usage(parser): 76061da546Spatrick parser.print_help() 77061da546Spatrick if configuration.verbose > 0: 78061da546Spatrick print(""" 79061da546SpatrickExamples: 80061da546Spatrick 81061da546SpatrickThis is an example of using the -f option to pinpoint to a specific test class 82061da546Spatrickand test method to be run: 83061da546Spatrick 84061da546Spatrick$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command 85061da546Spatrick---------------------------------------------------------------------- 86061da546SpatrickCollected 1 test 87061da546Spatrick 88061da546Spatricktest_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase) 89061da546SpatrickTest 'frame variable this' when stopped on a class constructor. ... ok 90061da546Spatrick 91061da546Spatrick---------------------------------------------------------------------- 92061da546SpatrickRan 1 test in 1.396s 93061da546Spatrick 94061da546SpatrickOK 95061da546Spatrick 96061da546SpatrickAnd this is an example of using the -p option to run a single file (the filename 97061da546Spatrickmatches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'): 98061da546Spatrick 99061da546Spatrick$ ./dotest.py -v -p ObjC 100061da546Spatrick---------------------------------------------------------------------- 101061da546SpatrickCollected 4 tests 102061da546Spatrick 103061da546Spatricktest_break_with_dsym (TestObjCMethods.FoundationTestCase) 104061da546SpatrickTest setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok 105061da546Spatricktest_break_with_dwarf (TestObjCMethods.FoundationTestCase) 106061da546SpatrickTest setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok 107061da546Spatricktest_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase) 108061da546SpatrickLookup objective-c data types and evaluate expressions. ... ok 109061da546Spatricktest_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase) 110061da546SpatrickLookup objective-c data types and evaluate expressions. ... ok 111061da546Spatrick 112061da546Spatrick---------------------------------------------------------------------- 113061da546SpatrickRan 4 tests in 16.661s 114061da546Spatrick 115061da546SpatrickOK 116061da546Spatrick 117061da546SpatrickRunning of this script also sets up the LLDB_TEST environment variable so that 118061da546Spatrickindividual test cases can locate their supporting files correctly. The script 119061da546Spatricktries to set up Python's search paths for modules by looking at the build tree 120061da546Spatrickrelative to this script. See also the '-i' option in the following example. 121061da546Spatrick 122061da546SpatrickFinally, this is an example of using the lldb.py module distributed/installed by 123061da546SpatrickXcode4 to run against the tests under the 'forward' directory, and with the '-w' 124061da546Spatrickoption to add some delay between two tests. It uses ARCH=x86_64 to specify that 125061da546Spatrickas the architecture and CC=clang to specify the compiler used for the test run: 126061da546Spatrick 127061da546Spatrick$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward 128061da546Spatrick 129061da546SpatrickSession logs for test failures/errors will go into directory '2010-11-11-13_56_16' 130061da546Spatrick---------------------------------------------------------------------- 131061da546SpatrickCollected 2 tests 132061da546Spatrick 133061da546Spatricktest_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase) 134061da546SpatrickDisplay *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok 135061da546Spatricktest_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase) 136061da546SpatrickDisplay *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok 137061da546Spatrick 138061da546Spatrick---------------------------------------------------------------------- 139061da546SpatrickRan 2 tests in 5.659s 140061da546Spatrick 141061da546SpatrickOK 142061da546Spatrick 143061da546SpatrickThe 'Session ...' verbiage is recently introduced (see also the '-s' option) to 144061da546Spatricknotify the directory containing the session logs for test failures or errors. 145061da546SpatrickIn case there is any test failure/error, a similar message is appended at the 146061da546Spatrickend of the stderr output for your convenience. 147061da546Spatrick 148061da546SpatrickENABLING LOGS FROM TESTS 149061da546Spatrick 150061da546SpatrickOption 1: 151061da546Spatrick 152061da546SpatrickWriting logs into different files per test case:: 153061da546Spatrick 154061da546Spatrick$ ./dotest.py --channel "lldb all" 155061da546Spatrick 156061da546Spatrick$ ./dotest.py --channel "lldb all" --channel "gdb-remote packets" 157061da546Spatrick 158061da546SpatrickThese log files are written to: 159061da546Spatrick 160061da546Spatrick<session-dir>/<test-id>-host.log (logs from lldb host process) 161061da546Spatrick<session-dir>/<test-id>-server.log (logs from debugserver/lldb-server) 162061da546Spatrick<session-dir>/<test-id>-<test-result>.log (console logs) 163061da546Spatrick 164061da546SpatrickBy default, logs from successful runs are deleted. Use the --log-success flag 165061da546Spatrickto create reference logs for debugging. 166061da546Spatrick 167061da546Spatrick$ ./dotest.py --log-success 168061da546Spatrick 169061da546Spatrick""") 170061da546Spatrick sys.exit(0) 171061da546Spatrick 172061da546Spatrick 173061da546Spatrickdef parseExclusion(exclusion_file): 174061da546Spatrick """Parse an exclusion file, of the following format, where 175061da546Spatrick 'skip files', 'skip methods', 'xfail files', and 'xfail methods' 176061da546Spatrick are the possible list heading values: 177061da546Spatrick 178061da546Spatrick skip files 179061da546Spatrick <file name> 180061da546Spatrick <file name> 181061da546Spatrick 182061da546Spatrick xfail methods 183061da546Spatrick <method name> 184061da546Spatrick """ 185061da546Spatrick excl_type = None 186061da546Spatrick 187061da546Spatrick with open(exclusion_file) as f: 188061da546Spatrick for line in f: 189061da546Spatrick line = line.strip() 190061da546Spatrick if not excl_type: 191061da546Spatrick excl_type = line 192061da546Spatrick continue 193061da546Spatrick 194061da546Spatrick if not line: 195061da546Spatrick excl_type = None 196061da546Spatrick elif excl_type == 'skip': 197061da546Spatrick if not configuration.skip_tests: 198061da546Spatrick configuration.skip_tests = [] 199061da546Spatrick configuration.skip_tests.append(line) 200061da546Spatrick elif excl_type == 'xfail': 201061da546Spatrick if not configuration.xfail_tests: 202061da546Spatrick configuration.xfail_tests = [] 203061da546Spatrick configuration.xfail_tests.append(line) 204061da546Spatrick 205061da546Spatrick 206061da546Spatrickdef parseOptionsAndInitTestdirs(): 207061da546Spatrick """Initialize the list of directories containing our unittest scripts. 208061da546Spatrick 209061da546Spatrick '-h/--help as the first option prints out usage info and exit the program. 210061da546Spatrick """ 211061da546Spatrick 212061da546Spatrick do_help = False 213061da546Spatrick 214061da546Spatrick platform_system = platform.system() 215061da546Spatrick platform_machine = platform.machine() 216061da546Spatrick 217061da546Spatrick try: 218061da546Spatrick parser = dotest_args.create_parser() 219061da546Spatrick args = parser.parse_args() 220061da546Spatrick except: 221061da546Spatrick raise 222061da546Spatrick 223061da546Spatrick if args.unset_env_varnames: 224061da546Spatrick for env_var in args.unset_env_varnames: 225061da546Spatrick if env_var in os.environ: 226061da546Spatrick # From Python Doc: When unsetenv() is supported, deletion of items in os.environ 227061da546Spatrick # is automatically translated into a corresponding call to 228061da546Spatrick # unsetenv(). 229061da546Spatrick del os.environ[env_var] 230061da546Spatrick # os.unsetenv(env_var) 231061da546Spatrick 232061da546Spatrick if args.set_env_vars: 233061da546Spatrick for env_var in args.set_env_vars: 234061da546Spatrick parts = env_var.split('=', 1) 235061da546Spatrick if len(parts) == 1: 236061da546Spatrick os.environ[parts[0]] = "" 237061da546Spatrick else: 238061da546Spatrick os.environ[parts[0]] = parts[1] 239061da546Spatrick 240061da546Spatrick if args.set_inferior_env_vars: 241061da546Spatrick lldbtest_config.inferior_env = ' '.join(args.set_inferior_env_vars) 242061da546Spatrick 243061da546Spatrick if args.h: 244061da546Spatrick do_help = True 245061da546Spatrick 246061da546Spatrick if args.compiler: 247be691f3bSpatrick configuration.compiler = os.path.abspath(args.compiler) 248061da546Spatrick if not is_exe(configuration.compiler): 249061da546Spatrick configuration.compiler = which(args.compiler) 250061da546Spatrick if not is_exe(configuration.compiler): 251061da546Spatrick logging.error( 252061da546Spatrick '%s is not a valid compiler executable; aborting...', 253061da546Spatrick args.compiler) 254061da546Spatrick sys.exit(-1) 255061da546Spatrick else: 256061da546Spatrick # Use a compiler appropriate appropriate for the Apple SDK if one was 257061da546Spatrick # specified 258061da546Spatrick if platform_system == 'Darwin' and args.apple_sdk: 259061da546Spatrick configuration.compiler = seven.get_command_output( 260061da546Spatrick 'xcrun -sdk "%s" -find clang 2> /dev/null' % 261061da546Spatrick (args.apple_sdk)) 262061da546Spatrick else: 263061da546Spatrick # 'clang' on ubuntu 14.04 is 3.4 so we try clang-3.5 first 264061da546Spatrick candidateCompilers = ['clang-3.5', 'clang', 'gcc'] 265061da546Spatrick for candidate in candidateCompilers: 266061da546Spatrick if which(candidate): 267061da546Spatrick configuration.compiler = candidate 268061da546Spatrick break 269061da546Spatrick 270061da546Spatrick if args.dsymutil: 271dda28197Spatrick configuration.dsymutil = args.dsymutil 272061da546Spatrick elif platform_system == 'Darwin': 273dda28197Spatrick configuration.dsymutil = seven.get_command_output( 274061da546Spatrick 'xcrun -find -toolchain default dsymutil') 275be691f3bSpatrick if args.llvm_tools_dir: 276be691f3bSpatrick configuration.filecheck = shutil.which("FileCheck", path=args.llvm_tools_dir) 277be691f3bSpatrick configuration.yaml2obj = shutil.which("yaml2obj", path=args.llvm_tools_dir) 278dda28197Spatrick 279061da546Spatrick if not configuration.get_filecheck_path(): 280061da546Spatrick logging.warning('No valid FileCheck executable; some tests may fail...') 281be691f3bSpatrick logging.warning('(Double-check the --llvm-tools-dir argument to dotest.py)') 282061da546Spatrick 283*f6aab3d8Srobert if args.libcxx_include_dir or args.libcxx_library_dir: 284*f6aab3d8Srobert if args.lldb_platform_name: 285*f6aab3d8Srobert logging.warning('Custom libc++ is not supported for remote runs: ignoring --libcxx arguments') 286*f6aab3d8Srobert elif not (args.libcxx_include_dir and args.libcxx_library_dir): 287*f6aab3d8Srobert logging.error('Custom libc++ requires both --libcxx-include-dir and --libcxx-library-dir') 288*f6aab3d8Srobert sys.exit(-1) 289*f6aab3d8Srobert configuration.libcxx_include_dir = args.libcxx_include_dir 290*f6aab3d8Srobert configuration.libcxx_include_target_dir = args.libcxx_include_target_dir 291*f6aab3d8Srobert configuration.libcxx_library_dir = args.libcxx_library_dir 292*f6aab3d8Srobert 293061da546Spatrick if args.channels: 294061da546Spatrick lldbtest_config.channels = args.channels 295061da546Spatrick 296061da546Spatrick if args.log_success: 297061da546Spatrick lldbtest_config.log_success = args.log_success 298061da546Spatrick 299061da546Spatrick if args.out_of_tree_debugserver: 300061da546Spatrick lldbtest_config.out_of_tree_debugserver = args.out_of_tree_debugserver 301061da546Spatrick 302061da546Spatrick # Set SDKROOT if we are using an Apple SDK 303061da546Spatrick if platform_system == 'Darwin' and args.apple_sdk: 304dda28197Spatrick configuration.sdkroot = seven.get_command_output( 305061da546Spatrick 'xcrun --sdk "%s" --show-sdk-path 2> /dev/null' % 306061da546Spatrick (args.apple_sdk)) 307be691f3bSpatrick if not configuration.sdkroot: 308be691f3bSpatrick logging.error( 309be691f3bSpatrick 'No SDK found with the name %s; aborting...', 310be691f3bSpatrick args.apple_sdk) 311be691f3bSpatrick sys.exit(-1) 312061da546Spatrick 313061da546Spatrick if args.arch: 314061da546Spatrick configuration.arch = args.arch 315061da546Spatrick else: 316061da546Spatrick configuration.arch = platform_machine 317061da546Spatrick 318061da546Spatrick if args.categories_list: 319061da546Spatrick configuration.categories_list = set( 320061da546Spatrick test_categories.validate( 321061da546Spatrick args.categories_list, False)) 322061da546Spatrick configuration.use_categories = True 323061da546Spatrick else: 324061da546Spatrick configuration.categories_list = [] 325061da546Spatrick 326061da546Spatrick if args.skip_categories: 327061da546Spatrick configuration.skip_categories += test_categories.validate( 328061da546Spatrick args.skip_categories, False) 329061da546Spatrick 330061da546Spatrick if args.xfail_categories: 331061da546Spatrick configuration.xfail_categories += test_categories.validate( 332061da546Spatrick args.xfail_categories, False) 333061da546Spatrick 334061da546Spatrick if args.E: 335061da546Spatrick os.environ['CFLAGS_EXTRAS'] = args.E 336061da546Spatrick 337061da546Spatrick if args.dwarf_version: 338061da546Spatrick configuration.dwarf_version = args.dwarf_version 339061da546Spatrick # We cannot modify CFLAGS_EXTRAS because they're used in test cases 340061da546Spatrick # that explicitly require no debug info. 341061da546Spatrick os.environ['CFLAGS'] = '-gdwarf-{}'.format(configuration.dwarf_version) 342061da546Spatrick 343061da546Spatrick if args.settings: 344061da546Spatrick for setting in args.settings: 345061da546Spatrick if not len(setting) == 1 or not setting[0].count('='): 346061da546Spatrick logging.error('"%s" is not a setting in the form "key=value"', 347061da546Spatrick setting[0]) 348061da546Spatrick sys.exit(-1) 349dda28197Spatrick setting_list = setting[0].split('=', 1) 350dda28197Spatrick configuration.settings.append((setting_list[0], setting_list[1])) 351061da546Spatrick 352061da546Spatrick if args.d: 353061da546Spatrick sys.stdout.write( 354061da546Spatrick "Suspending the process %d to wait for debugger to attach...\n" % 355061da546Spatrick os.getpid()) 356061da546Spatrick sys.stdout.flush() 357061da546Spatrick os.kill(os.getpid(), signal.SIGSTOP) 358061da546Spatrick 359061da546Spatrick if args.f: 360061da546Spatrick if any([x.startswith('-') for x in args.f]): 361061da546Spatrick usage(parser) 362061da546Spatrick configuration.filters.extend(args.f) 363061da546Spatrick 364061da546Spatrick if args.framework: 365061da546Spatrick configuration.lldb_framework_path = args.framework 366061da546Spatrick 367061da546Spatrick if args.executable: 368061da546Spatrick # lldb executable is passed explicitly 369*f6aab3d8Srobert lldbtest_config.lldbExec = os.path.abspath(args.executable) 370061da546Spatrick if not is_exe(lldbtest_config.lldbExec): 371061da546Spatrick lldbtest_config.lldbExec = which(args.executable) 372061da546Spatrick if not is_exe(lldbtest_config.lldbExec): 373061da546Spatrick logging.error( 374061da546Spatrick '%s is not a valid executable to test; aborting...', 375061da546Spatrick args.executable) 376061da546Spatrick sys.exit(-1) 377061da546Spatrick 378061da546Spatrick if args.excluded: 379061da546Spatrick for excl_file in args.excluded: 380061da546Spatrick parseExclusion(excl_file) 381061da546Spatrick 382061da546Spatrick if args.p: 383061da546Spatrick if args.p.startswith('-'): 384061da546Spatrick usage(parser) 385061da546Spatrick configuration.regexp = args.p 386061da546Spatrick 387061da546Spatrick if args.t: 388061da546Spatrick os.environ['LLDB_COMMAND_TRACE'] = 'YES' 389061da546Spatrick 390061da546Spatrick if args.v: 391061da546Spatrick configuration.verbose = 2 392061da546Spatrick 393061da546Spatrick # argparse makes sure we have a number 394061da546Spatrick if args.sharp: 395061da546Spatrick configuration.count = args.sharp 396061da546Spatrick 397061da546Spatrick if sys.platform.startswith('win32'): 398061da546Spatrick os.environ['LLDB_DISABLE_CRASH_DIALOG'] = str( 399061da546Spatrick args.disable_crash_dialog) 400061da546Spatrick os.environ['LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE'] = str(True) 401061da546Spatrick 402061da546Spatrick if do_help: 403061da546Spatrick usage(parser) 404061da546Spatrick 405061da546Spatrick if args.lldb_platform_name: 406061da546Spatrick configuration.lldb_platform_name = args.lldb_platform_name 407061da546Spatrick if args.lldb_platform_url: 408061da546Spatrick configuration.lldb_platform_url = args.lldb_platform_url 409061da546Spatrick if args.lldb_platform_working_dir: 410061da546Spatrick configuration.lldb_platform_working_dir = args.lldb_platform_working_dir 411be691f3bSpatrick if platform_system == 'Darwin' and args.apple_sdk: 412be691f3bSpatrick configuration.apple_sdk = args.apple_sdk 413061da546Spatrick if args.test_build_dir: 414061da546Spatrick configuration.test_build_dir = args.test_build_dir 415061da546Spatrick if args.lldb_module_cache_dir: 416061da546Spatrick configuration.lldb_module_cache_dir = args.lldb_module_cache_dir 417061da546Spatrick else: 418061da546Spatrick configuration.lldb_module_cache_dir = os.path.join( 419061da546Spatrick configuration.test_build_dir, 'module-cache-lldb') 420061da546Spatrick if args.clang_module_cache_dir: 421061da546Spatrick configuration.clang_module_cache_dir = args.clang_module_cache_dir 422061da546Spatrick else: 423061da546Spatrick configuration.clang_module_cache_dir = os.path.join( 424061da546Spatrick configuration.test_build_dir, 'module-cache-clang') 425061da546Spatrick 426dda28197Spatrick if args.lldb_libs_dir: 427dda28197Spatrick configuration.lldb_libs_dir = args.lldb_libs_dir 428dda28197Spatrick 429dda28197Spatrick if args.enabled_plugins: 430dda28197Spatrick configuration.enabled_plugins = args.enabled_plugins 431061da546Spatrick 432061da546Spatrick # Gather all the dirs passed on the command line. 433061da546Spatrick if len(args.args) > 0: 434061da546Spatrick configuration.testdirs = [os.path.realpath(os.path.abspath(x)) for x in args.args] 435061da546Spatrick 436061da546Spatrick lldbtest_config.codesign_identity = args.codesign_identity 437061da546Spatrick 438be691f3bSpatrickdef registerFaulthandler(): 439be691f3bSpatrick try: 440be691f3bSpatrick import faulthandler 441be691f3bSpatrick except ImportError: 442be691f3bSpatrick # faulthandler is not available until python3 443be691f3bSpatrick return 444061da546Spatrick 445be691f3bSpatrick faulthandler.enable() 446be691f3bSpatrick # faulthandler.register is not available on Windows. 447be691f3bSpatrick if getattr(faulthandler, 'register', None): 448be691f3bSpatrick faulthandler.register(signal.SIGTERM, chain=True) 449061da546Spatrick 450061da546Spatrickdef setupSysPath(): 451061da546Spatrick """ 452061da546Spatrick Add LLDB.framework/Resources/Python to the search paths for modules. 453061da546Spatrick As a side effect, we also discover the 'lldb' executable and export it here. 454061da546Spatrick """ 455061da546Spatrick 456061da546Spatrick # Get the directory containing the current script. 457061da546Spatrick if "DOTEST_PROFILE" in os.environ and "DOTEST_SCRIPT_DIR" in os.environ: 458061da546Spatrick scriptPath = os.environ["DOTEST_SCRIPT_DIR"] 459061da546Spatrick else: 460be691f3bSpatrick scriptPath = os.path.dirname(os.path.abspath(__file__)) 461061da546Spatrick if not scriptPath.endswith('test'): 462061da546Spatrick print("This script expects to reside in lldb's test directory.") 463061da546Spatrick sys.exit(-1) 464061da546Spatrick 465061da546Spatrick os.environ["LLDB_TEST"] = scriptPath 466061da546Spatrick 467061da546Spatrick # Set up the root build directory. 468061da546Spatrick if not configuration.test_build_dir: 469061da546Spatrick raise Exception("test_build_dir is not set") 470dda28197Spatrick configuration.test_build_dir = os.path.abspath(configuration.test_build_dir) 471061da546Spatrick 472061da546Spatrick # Set up the LLDB_SRC environment variable, so that the tests can locate 473061da546Spatrick # the LLDB source code. 474061da546Spatrick os.environ["LLDB_SRC"] = lldbsuite.lldb_root 475061da546Spatrick 476061da546Spatrick pluginPath = os.path.join(scriptPath, 'plugins') 477061da546Spatrick toolsLLDBVSCode = os.path.join(scriptPath, 'tools', 'lldb-vscode') 478061da546Spatrick toolsLLDBServerPath = os.path.join(scriptPath, 'tools', 'lldb-server') 479be691f3bSpatrick intelpt = os.path.join(scriptPath, 'tools', 'intelpt') 480061da546Spatrick 481061da546Spatrick # Insert script dir, plugin dir and lldb-server dir to the sys.path. 482061da546Spatrick sys.path.insert(0, pluginPath) 483061da546Spatrick # Adding test/tools/lldb-vscode to the path makes it easy to 484061da546Spatrick # "import lldb_vscode_testcase" from the VSCode tests 485061da546Spatrick sys.path.insert(0, toolsLLDBVSCode) 486061da546Spatrick # Adding test/tools/lldb-server to the path makes it easy 487061da546Spatrick # to "import lldbgdbserverutils" from the lldb-server tests 488be691f3bSpatrick sys.path.insert(0, toolsLLDBServerPath) 489be691f3bSpatrick # Adding test/tools/intelpt to the path makes it easy 490be691f3bSpatrick # to "import intelpt_testcase" from the lldb-server tests 491be691f3bSpatrick sys.path.insert(0, intelpt) 492061da546Spatrick 493061da546Spatrick # This is the root of the lldb git/svn checkout 494061da546Spatrick # When this changes over to a package instead of a standalone script, this 495061da546Spatrick # will be `lldbsuite.lldb_root` 496061da546Spatrick lldbRootDirectory = lldbsuite.lldb_root 497061da546Spatrick 498061da546Spatrick # Some of the tests can invoke the 'lldb' command directly. 499061da546Spatrick # We'll try to locate the appropriate executable right here. 500061da546Spatrick 501061da546Spatrick # The lldb executable can be set from the command line 502061da546Spatrick # if it's not set, we try to find it now 503061da546Spatrick # first, we try the environment 504061da546Spatrick if not lldbtest_config.lldbExec: 505061da546Spatrick # First, you can define an environment variable LLDB_EXEC specifying the 506061da546Spatrick # full pathname of the lldb executable. 507061da546Spatrick if "LLDB_EXEC" in os.environ: 508061da546Spatrick lldbtest_config.lldbExec = os.environ["LLDB_EXEC"] 509061da546Spatrick 510061da546Spatrick if not lldbtest_config.lldbExec: 511061da546Spatrick # Last, check the path 512061da546Spatrick lldbtest_config.lldbExec = which('lldb') 513061da546Spatrick 514061da546Spatrick if lldbtest_config.lldbExec and not is_exe(lldbtest_config.lldbExec): 515061da546Spatrick print( 516061da546Spatrick "'{}' is not a path to a valid executable".format( 517061da546Spatrick lldbtest_config.lldbExec)) 518061da546Spatrick lldbtest_config.lldbExec = None 519061da546Spatrick 520061da546Spatrick if not lldbtest_config.lldbExec: 521061da546Spatrick print("The 'lldb' executable cannot be located. Some of the tests may not be run as a result.") 522061da546Spatrick sys.exit(-1) 523061da546Spatrick 524061da546Spatrick os.system('%s -v' % lldbtest_config.lldbExec) 525061da546Spatrick 526061da546Spatrick lldbDir = os.path.dirname(lldbtest_config.lldbExec) 527061da546Spatrick 528061da546Spatrick lldbVSCodeExec = os.path.join(lldbDir, "lldb-vscode") 529061da546Spatrick if is_exe(lldbVSCodeExec): 530061da546Spatrick os.environ["LLDBVSCODE_EXEC"] = lldbVSCodeExec 531061da546Spatrick else: 532061da546Spatrick if not configuration.shouldSkipBecauseOfCategories(["lldb-vscode"]): 533061da546Spatrick print( 534061da546Spatrick "The 'lldb-vscode' executable cannot be located. The lldb-vscode tests can not be run as a result.") 535061da546Spatrick configuration.skip_categories.append("lldb-vscode") 536061da546Spatrick 537061da546Spatrick lldbPythonDir = None # The directory that contains 'lldb/__init__.py' 538be691f3bSpatrick 539061da546Spatrick # If our lldb supports the -P option, use it to find the python path: 540be691f3bSpatrick lldb_dash_p_result = subprocess.check_output([lldbtest_config.lldbExec, "-P"], universal_newlines=True) 541be691f3bSpatrick if lldb_dash_p_result: 542be691f3bSpatrick for line in lldb_dash_p_result.splitlines(): 543be691f3bSpatrick if os.path.isdir(line) and os.path.exists(os.path.join(line, 'lldb', '__init__.py')): 544be691f3bSpatrick lldbPythonDir = line 545be691f3bSpatrick break 546061da546Spatrick 547061da546Spatrick if not lldbPythonDir: 548061da546Spatrick print( 549061da546Spatrick "Unable to load lldb extension module. Possible reasons for this include:") 550061da546Spatrick print(" 1) LLDB was built with LLDB_ENABLE_PYTHON=0") 551061da546Spatrick print( 552061da546Spatrick " 2) PYTHONPATH and PYTHONHOME are not set correctly. PYTHONHOME should refer to") 553061da546Spatrick print( 554061da546Spatrick " the version of Python that LLDB built and linked against, and PYTHONPATH") 555061da546Spatrick print( 556061da546Spatrick " should contain the Lib directory for the same python distro, as well as the") 557061da546Spatrick print(" location of LLDB\'s site-packages folder.") 558061da546Spatrick print( 559061da546Spatrick " 3) A different version of Python than that which was built against is exported in") 560061da546Spatrick print(" the system\'s PATH environment variable, causing conflicts.") 561061da546Spatrick print( 562061da546Spatrick " 4) The executable '%s' could not be found. Please check " % 563061da546Spatrick lldbtest_config.lldbExec) 564061da546Spatrick print(" that it exists and is executable.") 565061da546Spatrick 566061da546Spatrick if lldbPythonDir: 567061da546Spatrick lldbPythonDir = os.path.normpath(lldbPythonDir) 568061da546Spatrick # Some of the code that uses this path assumes it hasn't resolved the Versions... link. 569061da546Spatrick # If the path we've constructed looks like that, then we'll strip out 570061da546Spatrick # the Versions/A part. 571061da546Spatrick (before, frameWithVersion, after) = lldbPythonDir.rpartition( 572061da546Spatrick "LLDB.framework/Versions/A") 573061da546Spatrick if frameWithVersion != "": 574061da546Spatrick lldbPythonDir = before + "LLDB.framework" + after 575061da546Spatrick 576061da546Spatrick lldbPythonDir = os.path.abspath(lldbPythonDir) 577061da546Spatrick 578be691f3bSpatrick if "freebsd" in sys.platform or "linux" in sys.platform: 579be691f3bSpatrick os.environ['LLDB_LIB_DIR'] = os.path.join(lldbPythonDir, '..', '..') 580be691f3bSpatrick 581061da546Spatrick # If tests need to find LLDB_FRAMEWORK, now they can do it 582061da546Spatrick os.environ["LLDB_FRAMEWORK"] = os.path.dirname( 583061da546Spatrick os.path.dirname(lldbPythonDir)) 584061da546Spatrick 585061da546Spatrick # This is to locate the lldb.py module. Insert it right after 586061da546Spatrick # sys.path[0]. 587061da546Spatrick sys.path[1:1] = [lldbPythonDir] 588061da546Spatrick 589061da546Spatrick 590061da546Spatrickdef visit_file(dir, name): 591061da546Spatrick # Try to match the regexp pattern, if specified. 592061da546Spatrick if configuration.regexp: 593061da546Spatrick if not re.search(configuration.regexp, name): 594061da546Spatrick # We didn't match the regex, we're done. 595061da546Spatrick return 596061da546Spatrick 597061da546Spatrick if configuration.skip_tests: 598061da546Spatrick for file_regexp in configuration.skip_tests: 599061da546Spatrick if re.search(file_regexp, name): 600061da546Spatrick return 601061da546Spatrick 602061da546Spatrick # We found a match for our test. Add it to the suite. 603061da546Spatrick 604061da546Spatrick # Update the sys.path first. 605061da546Spatrick if not sys.path.count(dir): 606061da546Spatrick sys.path.insert(0, dir) 607061da546Spatrick base = os.path.splitext(name)[0] 608061da546Spatrick 609061da546Spatrick # Thoroughly check the filterspec against the base module and admit 610061da546Spatrick # the (base, filterspec) combination only when it makes sense. 611061da546Spatrick 612061da546Spatrick def check(obj, parts): 613061da546Spatrick for part in parts: 614061da546Spatrick try: 615061da546Spatrick parent, obj = obj, getattr(obj, part) 616061da546Spatrick except AttributeError: 617061da546Spatrick # The filterspec has failed. 618061da546Spatrick return False 619061da546Spatrick return True 620061da546Spatrick 621061da546Spatrick module = __import__(base) 622061da546Spatrick 623061da546Spatrick def iter_filters(): 624061da546Spatrick for filterspec in configuration.filters: 625061da546Spatrick parts = filterspec.split('.') 626061da546Spatrick if check(module, parts): 627061da546Spatrick yield filterspec 628061da546Spatrick elif parts[0] == base and len(parts) > 1 and check(module, parts[1:]): 629061da546Spatrick yield '.'.join(parts[1:]) 630061da546Spatrick else: 631061da546Spatrick for key,value in module.__dict__.items(): 632061da546Spatrick if check(value, parts): 633061da546Spatrick yield key + '.' + filterspec 634061da546Spatrick 635061da546Spatrick filtered = False 636061da546Spatrick for filterspec in iter_filters(): 637061da546Spatrick filtered = True 638061da546Spatrick print("adding filter spec %s to module %s" % (filterspec, repr(module))) 639061da546Spatrick tests = unittest2.defaultTestLoader.loadTestsFromName(filterspec, module) 640061da546Spatrick configuration.suite.addTests(tests) 641061da546Spatrick 642061da546Spatrick # Forgo this module if the (base, filterspec) combo is invalid 643061da546Spatrick if configuration.filters and not filtered: 644061da546Spatrick return 645061da546Spatrick 646061da546Spatrick if not filtered: 647061da546Spatrick # Add the entire file's worth of tests since we're not filtered. 648061da546Spatrick # Also the fail-over case when the filterspec branch 649061da546Spatrick # (base, filterspec) combo doesn't make sense. 650061da546Spatrick configuration.suite.addTests( 651061da546Spatrick unittest2.defaultTestLoader.loadTestsFromName(base)) 652061da546Spatrick 653061da546Spatrick 654061da546Spatrickdef visit(prefix, dir, names): 655061da546Spatrick """Visitor function for os.path.walk(path, visit, arg).""" 656061da546Spatrick 657061da546Spatrick dir_components = set(dir.split(os.sep)) 658061da546Spatrick excluded_components = set(['.svn', '.git']) 659061da546Spatrick if dir_components.intersection(excluded_components): 660061da546Spatrick return 661061da546Spatrick 662061da546Spatrick # Gather all the Python test file names that follow the Test*.py pattern. 663061da546Spatrick python_test_files = [ 664061da546Spatrick name 665061da546Spatrick for name in names 666061da546Spatrick if name.endswith('.py') and name.startswith(prefix)] 667061da546Spatrick 668061da546Spatrick # Visit all the python test files. 669061da546Spatrick for name in python_test_files: 670061da546Spatrick # Ensure we error out if we have multiple tests with the same 671061da546Spatrick # base name. 672061da546Spatrick # Future improvement: find all the places where we work with base 673061da546Spatrick # names and convert to full paths. We have directory structure 674061da546Spatrick # to disambiguate these, so we shouldn't need this constraint. 675061da546Spatrick if name in configuration.all_tests: 676061da546Spatrick raise Exception("Found multiple tests with the name %s" % name) 677061da546Spatrick configuration.all_tests.add(name) 678061da546Spatrick 679061da546Spatrick # Run the relevant tests in the python file. 680061da546Spatrick visit_file(dir, name) 681061da546Spatrick 682061da546Spatrick 683061da546Spatrick# ======================================== # 684061da546Spatrick# # 685061da546Spatrick# Execution of the test driver starts here # 686061da546Spatrick# # 687061da546Spatrick# ======================================== # 688061da546Spatrick 689061da546Spatrick 690061da546Spatrickdef checkDsymForUUIDIsNotOn(): 691061da546Spatrick cmd = ["defaults", "read", "com.apple.DebugSymbols"] 692061da546Spatrick process = subprocess.Popen( 693061da546Spatrick cmd, 694061da546Spatrick stdout=subprocess.PIPE, 695061da546Spatrick stderr=subprocess.STDOUT) 696061da546Spatrick cmd_output = process.stdout.read() 697061da546Spatrick output_str = cmd_output.decode("utf-8") 698061da546Spatrick if "DBGFileMappedPaths = " in output_str: 699061da546Spatrick print("%s =>" % ' '.join(cmd)) 700061da546Spatrick print(output_str) 701061da546Spatrick print( 702061da546Spatrick "Disable automatic lookup and caching of dSYMs before running the test suite!") 703061da546Spatrick print("Exiting...") 704061da546Spatrick sys.exit(0) 705061da546Spatrick 706061da546Spatrick 707061da546Spatrickdef exitTestSuite(exitCode=None): 708dda28197Spatrick # lldb.py does SBDebugger.Initialize(). 709dda28197Spatrick # Call SBDebugger.Terminate() on exit. 710061da546Spatrick import lldb 711061da546Spatrick lldb.SBDebugger.Terminate() 712061da546Spatrick if exitCode: 713061da546Spatrick sys.exit(exitCode) 714061da546Spatrick 715061da546Spatrick 716061da546Spatrickdef getVersionForSDK(sdk): 717061da546Spatrick sdk = str.lower(sdk) 718061da546Spatrick full_path = seven.get_command_output('xcrun -sdk %s --show-sdk-path' % sdk) 719061da546Spatrick basename = os.path.basename(full_path) 720061da546Spatrick basename = os.path.splitext(basename)[0] 721061da546Spatrick basename = str.lower(basename) 722061da546Spatrick ver = basename.replace(sdk, '') 723061da546Spatrick return ver 724061da546Spatrick 725061da546Spatrick 726061da546Spatrickdef checkCompiler(): 727061da546Spatrick # Add some intervention here to sanity check that the compiler requested is sane. 728061da546Spatrick # If found not to be an executable program, we abort. 729061da546Spatrick c = configuration.compiler 730061da546Spatrick if which(c): 731061da546Spatrick return 732061da546Spatrick 733061da546Spatrick if not sys.platform.startswith("darwin"): 734061da546Spatrick raise Exception(c + " is not a valid compiler") 735061da546Spatrick 736061da546Spatrick pipe = subprocess.Popen( 737061da546Spatrick ['xcrun', '-find', c], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 738061da546Spatrick cmd_output = pipe.stdout.read() 739061da546Spatrick if not cmd_output or "not found" in cmd_output: 740061da546Spatrick raise Exception(c + " is not a valid compiler") 741061da546Spatrick 742061da546Spatrick configuration.compiler = cmd_output.split('\n')[0] 743061da546Spatrick print("'xcrun -find %s' returning %s" % (c, configuration.compiler)) 744061da546Spatrick 745061da546Spatrickdef canRunLibcxxTests(): 746061da546Spatrick from lldbsuite.test import lldbplatformutil 747061da546Spatrick 748061da546Spatrick platform = lldbplatformutil.getPlatform() 749061da546Spatrick 750061da546Spatrick if lldbplatformutil.target_is_android() or lldbplatformutil.platformIsDarwin(): 751061da546Spatrick return True, "libc++ always present" 752061da546Spatrick 753061da546Spatrick if platform == "linux": 754061da546Spatrick with tempfile.NamedTemporaryFile() as f: 755061da546Spatrick cmd = [configuration.compiler, "-xc++", "-stdlib=libc++", "-o", f.name, "-"] 756061da546Spatrick p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) 757be691f3bSpatrick _, stderr = p.communicate("#include <cassert>\nint main() {}") 758061da546Spatrick if not p.returncode: 759061da546Spatrick return True, "Compiling with -stdlib=libc++ works" 760061da546Spatrick return False, "Compiling with -stdlib=libc++ fails with the error: %s" % stderr 761061da546Spatrick 762061da546Spatrick return False, "Don't know how to build with libc++ on %s" % platform 763061da546Spatrick 764061da546Spatrickdef checkLibcxxSupport(): 765061da546Spatrick result, reason = canRunLibcxxTests() 766061da546Spatrick if result: 767061da546Spatrick return # libc++ supported 768061da546Spatrick if "libc++" in configuration.categories_list: 769061da546Spatrick return # libc++ category explicitly requested, let it run. 770be691f3bSpatrick if configuration.verbose: 771be691f3bSpatrick print("libc++ tests will not be run because: " + reason) 772061da546Spatrick configuration.skip_categories.append("libc++") 773061da546Spatrick 774061da546Spatrickdef canRunLibstdcxxTests(): 775061da546Spatrick from lldbsuite.test import lldbplatformutil 776061da546Spatrick 777061da546Spatrick platform = lldbplatformutil.getPlatform() 778061da546Spatrick if lldbplatformutil.target_is_android(): 779061da546Spatrick platform = "android" 780061da546Spatrick if platform == "linux": 781061da546Spatrick return True, "libstdcxx always present" 782061da546Spatrick return False, "Don't know how to build with libstdcxx on %s" % platform 783061da546Spatrick 784061da546Spatrickdef checkLibstdcxxSupport(): 785061da546Spatrick result, reason = canRunLibstdcxxTests() 786061da546Spatrick if result: 787061da546Spatrick return # libstdcxx supported 788061da546Spatrick if "libstdcxx" in configuration.categories_list: 789061da546Spatrick return # libstdcxx category explicitly requested, let it run. 790be691f3bSpatrick if configuration.verbose: 791061da546Spatrick print("libstdcxx tests will not be run because: " + reason) 792061da546Spatrick configuration.skip_categories.append("libstdcxx") 793061da546Spatrick 794061da546Spatrickdef canRunWatchpointTests(): 795061da546Spatrick from lldbsuite.test import lldbplatformutil 796061da546Spatrick 797061da546Spatrick platform = lldbplatformutil.getPlatform() 798061da546Spatrick if platform == "netbsd": 799061da546Spatrick if os.geteuid() == 0: 800061da546Spatrick return True, "root can always write dbregs" 801061da546Spatrick try: 802061da546Spatrick output = subprocess.check_output(["/sbin/sysctl", "-n", 803061da546Spatrick "security.models.extensions.user_set_dbregs"]).decode().strip() 804061da546Spatrick if output == "1": 805061da546Spatrick return True, "security.models.extensions.user_set_dbregs enabled" 806061da546Spatrick except subprocess.CalledProcessError: 807061da546Spatrick pass 808061da546Spatrick return False, "security.models.extensions.user_set_dbregs disabled" 809be691f3bSpatrick elif platform == "freebsd" and configuration.arch == "aarch64": 810be691f3bSpatrick import lldb 811be691f3bSpatrick if lldb.SBPlatform.GetHostPlatform().GetOSMajorVersion() < 13: 812be691f3bSpatrick return False, "Watchpoint support on arm64 requires FreeBSD 13.0" 813061da546Spatrick return True, "watchpoint support available" 814061da546Spatrick 815061da546Spatrickdef checkWatchpointSupport(): 816061da546Spatrick result, reason = canRunWatchpointTests() 817061da546Spatrick if result: 818061da546Spatrick return # watchpoints supported 819061da546Spatrick if "watchpoint" in configuration.categories_list: 820061da546Spatrick return # watchpoint category explicitly requested, let it run. 821be691f3bSpatrick if configuration.verbose: 822061da546Spatrick print("watchpoint tests will not be run because: " + reason) 823061da546Spatrick configuration.skip_categories.append("watchpoint") 824061da546Spatrick 825be691f3bSpatrickdef checkObjcSupport(): 826be691f3bSpatrick from lldbsuite.test import lldbplatformutil 827be691f3bSpatrick 828be691f3bSpatrick if not lldbplatformutil.platformIsDarwin(): 829be691f3bSpatrick if configuration.verbose: 830be691f3bSpatrick print("objc tests will be skipped because of unsupported platform") 831be691f3bSpatrick configuration.skip_categories.append("objc") 832be691f3bSpatrick 833061da546Spatrickdef checkDebugInfoSupport(): 834*f6aab3d8Srobert from lldbsuite.test import lldbplatformutil 835061da546Spatrick 836*f6aab3d8Srobert platform = lldbplatformutil.getPlatform() 837061da546Spatrick compiler = configuration.compiler 838061da546Spatrick for cat in test_categories.debug_info_categories: 839061da546Spatrick if cat in configuration.categories_list: 840061da546Spatrick continue # Category explicitly requested, let it run. 841061da546Spatrick if test_categories.is_supported_on_platform(cat, platform, compiler): 842061da546Spatrick continue 843061da546Spatrick configuration.skip_categories.append(cat) 844be691f3bSpatrick 845be691f3bSpatrickdef checkDebugServerSupport(): 846be691f3bSpatrick from lldbsuite.test import lldbplatformutil 847be691f3bSpatrick import lldb 848be691f3bSpatrick 849be691f3bSpatrick skip_msg = "Skipping %s tests, as they are not compatible with remote testing on this platform" 850be691f3bSpatrick if lldbplatformutil.platformIsDarwin(): 851be691f3bSpatrick configuration.skip_categories.append("llgs") 852be691f3bSpatrick if lldb.remote_platform: 853be691f3bSpatrick # <rdar://problem/34539270> 854be691f3bSpatrick configuration.skip_categories.append("debugserver") 855be691f3bSpatrick if configuration.verbose: 856be691f3bSpatrick print(skip_msg%"debugserver"); 857be691f3bSpatrick else: 858be691f3bSpatrick configuration.skip_categories.append("debugserver") 859be691f3bSpatrick if lldb.remote_platform and lldbplatformutil.getPlatform() == "windows": 860be691f3bSpatrick configuration.skip_categories.append("llgs") 861be691f3bSpatrick if configuration.verbose: 862be691f3bSpatrick print(skip_msg%"lldb-server"); 863be691f3bSpatrick 864be691f3bSpatrick 865be691f3bSpatrickdef checkForkVForkSupport(): 866be691f3bSpatrick from lldbsuite.test import lldbplatformutil 867be691f3bSpatrick 868be691f3bSpatrick platform = lldbplatformutil.getPlatform() 869be691f3bSpatrick if platform not in ["freebsd", "linux", "netbsd"]: 870be691f3bSpatrick configuration.skip_categories.append("fork") 871be691f3bSpatrick 872061da546Spatrick 873061da546Spatrickdef run_suite(): 874061da546Spatrick # On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults 875061da546Spatrick # does not exist before proceeding to running the test suite. 876061da546Spatrick if sys.platform.startswith("darwin"): 877061da546Spatrick checkDsymForUUIDIsNotOn() 878061da546Spatrick 879061da546Spatrick # Start the actions by first parsing the options while setting up the test 880061da546Spatrick # directories, followed by setting up the search paths for lldb utilities; 881061da546Spatrick # then, we walk the directory trees and collect the tests into our test suite. 882061da546Spatrick # 883061da546Spatrick parseOptionsAndInitTestdirs() 884061da546Spatrick 885be691f3bSpatrick # Print a stack trace if the test hangs or is passed SIGTERM. 886be691f3bSpatrick registerFaulthandler() 887061da546Spatrick 888061da546Spatrick setupSysPath() 889061da546Spatrick 890061da546Spatrick import lldb 891dda28197Spatrick lldb.SBDebugger.Initialize() 892*f6aab3d8Srobert lldb.SBDebugger.PrintStackTraceOnError() 893dda28197Spatrick 894dda28197Spatrick # Use host platform by default. 895*f6aab3d8Srobert lldb.remote_platform = None 896dda28197Spatrick lldb.selected_platform = lldb.SBPlatform.GetHostPlatform() 897dda28197Spatrick 898061da546Spatrick # Now we can also import lldbutil 899061da546Spatrick from lldbsuite.test import lldbutil 900061da546Spatrick 901061da546Spatrick if configuration.lldb_platform_name: 902061da546Spatrick print("Setting up remote platform '%s'" % 903061da546Spatrick (configuration.lldb_platform_name)) 904061da546Spatrick lldb.remote_platform = lldb.SBPlatform( 905061da546Spatrick configuration.lldb_platform_name) 906*f6aab3d8Srobert lldb.selected_platform = lldb.remote_platform 907061da546Spatrick if not lldb.remote_platform.IsValid(): 908061da546Spatrick print( 909061da546Spatrick "error: unable to create the LLDB platform named '%s'." % 910061da546Spatrick (configuration.lldb_platform_name)) 911061da546Spatrick exitTestSuite(1) 912061da546Spatrick if configuration.lldb_platform_url: 913061da546Spatrick # We must connect to a remote platform if a LLDB platform URL was 914061da546Spatrick # specified 915061da546Spatrick print( 916061da546Spatrick "Connecting to remote platform '%s' at '%s'..." % 917061da546Spatrick (configuration.lldb_platform_name, configuration.lldb_platform_url)) 918061da546Spatrick platform_connect_options = lldb.SBPlatformConnectOptions( 919061da546Spatrick configuration.lldb_platform_url) 920061da546Spatrick err = lldb.remote_platform.ConnectRemote(platform_connect_options) 921061da546Spatrick if err.Success(): 922061da546Spatrick print("Connected.") 923061da546Spatrick else: 924061da546Spatrick print("error: failed to connect to remote platform using URL '%s': %s" % ( 925061da546Spatrick configuration.lldb_platform_url, err)) 926061da546Spatrick exitTestSuite(1) 927061da546Spatrick else: 928061da546Spatrick configuration.lldb_platform_url = None 929061da546Spatrick 930061da546Spatrick if configuration.lldb_platform_working_dir: 931061da546Spatrick print("Setting remote platform working directory to '%s'..." % 932061da546Spatrick (configuration.lldb_platform_working_dir)) 933061da546Spatrick error = lldb.remote_platform.MakeDirectory( 934061da546Spatrick configuration.lldb_platform_working_dir, 448) # 448 = 0o700 935061da546Spatrick if error.Fail(): 936061da546Spatrick raise Exception("making remote directory '%s': %s" % ( 937061da546Spatrick configuration.lldb_platform_working_dir, error)) 938061da546Spatrick 939061da546Spatrick if not lldb.remote_platform.SetWorkingDirectory( 940061da546Spatrick configuration.lldb_platform_working_dir): 941061da546Spatrick raise Exception("failed to set working directory '%s'" % configuration.lldb_platform_working_dir) 942dda28197Spatrick lldb.selected_platform = lldb.remote_platform 943061da546Spatrick else: 944061da546Spatrick lldb.remote_platform = None 945061da546Spatrick configuration.lldb_platform_working_dir = None 946061da546Spatrick configuration.lldb_platform_url = None 947061da546Spatrick 948061da546Spatrick # Set up the working directory. 949061da546Spatrick # Note that it's not dotest's job to clean this directory. 950dda28197Spatrick lldbutil.mkdir_p(configuration.test_build_dir) 951061da546Spatrick 952061da546Spatrick checkLibcxxSupport() 953061da546Spatrick checkLibstdcxxSupport() 954061da546Spatrick checkWatchpointSupport() 955061da546Spatrick checkDebugInfoSupport() 956be691f3bSpatrick checkDebugServerSupport() 957be691f3bSpatrick checkObjcSupport() 958be691f3bSpatrick checkForkVForkSupport() 959061da546Spatrick 960*f6aab3d8Srobert skipped_categories_list = ", ".join(configuration.skip_categories) 961be691f3bSpatrick print("Skipping the following test categories: {}".format(configuration.skip_categories)) 962061da546Spatrick 963dda28197Spatrick for testdir in configuration.testdirs: 964061da546Spatrick for (dirpath, dirnames, filenames) in os.walk(testdir): 965061da546Spatrick visit('Test', dirpath, filenames) 966061da546Spatrick 967061da546Spatrick # 968061da546Spatrick # Now that we have loaded all the test cases, run the whole test suite. 969061da546Spatrick # 970061da546Spatrick 971061da546Spatrick # Install the control-c handler. 972061da546Spatrick unittest2.signals.installHandler() 973061da546Spatrick 974061da546Spatrick # 975061da546Spatrick # Invoke the default TextTestRunner to run the test suite 976061da546Spatrick # 977061da546Spatrick checkCompiler() 978061da546Spatrick 979061da546Spatrick if configuration.verbose: 980061da546Spatrick print("compiler=%s" % configuration.compiler) 981061da546Spatrick 982061da546Spatrick # Iterating over all possible architecture and compiler combinations. 983061da546Spatrick configString = "arch=%s compiler=%s" % (configuration.arch, 984061da546Spatrick configuration.compiler) 985061da546Spatrick 986061da546Spatrick # Output the configuration. 987061da546Spatrick if configuration.verbose: 988061da546Spatrick sys.stderr.write("\nConfiguration: " + configString + "\n") 989061da546Spatrick 990061da546Spatrick # First, write out the number of collected test cases. 991061da546Spatrick if configuration.verbose: 992061da546Spatrick sys.stderr.write(configuration.separator + "\n") 993061da546Spatrick sys.stderr.write( 994061da546Spatrick "Collected %d test%s\n\n" % 995061da546Spatrick (configuration.suite.countTestCases(), 996061da546Spatrick configuration.suite.countTestCases() != 1 and "s" or "")) 997061da546Spatrick 998be691f3bSpatrick if configuration.suite.countTestCases() == 0: 999be691f3bSpatrick logging.error("did not discover any matching tests") 1000be691f3bSpatrick exitTestSuite(1) 1001be691f3bSpatrick 1002061da546Spatrick # Invoke the test runner. 1003061da546Spatrick if configuration.count == 1: 1004061da546Spatrick result = unittest2.TextTestRunner( 1005061da546Spatrick stream=sys.stderr, 1006061da546Spatrick verbosity=configuration.verbose, 1007061da546Spatrick resultclass=test_result.LLDBTestResult).run( 1008061da546Spatrick configuration.suite) 1009061da546Spatrick else: 1010061da546Spatrick # We are invoking the same test suite more than once. In this case, 1011061da546Spatrick # mark __ignore_singleton__ flag as True so the signleton pattern is 1012061da546Spatrick # not enforced. 1013061da546Spatrick test_result.LLDBTestResult.__ignore_singleton__ = True 1014061da546Spatrick for i in range(configuration.count): 1015061da546Spatrick 1016061da546Spatrick result = unittest2.TextTestRunner( 1017061da546Spatrick stream=sys.stderr, 1018061da546Spatrick verbosity=configuration.verbose, 1019061da546Spatrick resultclass=test_result.LLDBTestResult).run( 1020061da546Spatrick configuration.suite) 1021061da546Spatrick 1022061da546Spatrick configuration.failed = not result.wasSuccessful() 1023061da546Spatrick 1024061da546Spatrick if configuration.sdir_has_content and configuration.verbose: 1025061da546Spatrick sys.stderr.write( 1026061da546Spatrick "Session logs for test failures/errors/unexpected successes" 1027be691f3bSpatrick " can be found in the test build directory\n") 1028061da546Spatrick 1029061da546Spatrick if configuration.use_categories and len( 1030061da546Spatrick configuration.failures_per_category) > 0: 1031061da546Spatrick sys.stderr.write("Failures per category:\n") 1032061da546Spatrick for category in configuration.failures_per_category: 1033061da546Spatrick sys.stderr.write( 1034061da546Spatrick "%s - %d\n" % 1035061da546Spatrick (category, configuration.failures_per_category[category])) 1036061da546Spatrick 1037061da546Spatrick # Exiting. 1038061da546Spatrick exitTestSuite(configuration.failed) 1039061da546Spatrick 1040061da546Spatrickif __name__ == "__main__": 1041061da546Spatrick print( 1042061da546Spatrick __file__ + 1043061da546Spatrick " is for use as a module only. It should not be run as a standalone script.") 1044061da546Spatrick sys.exit(-1) 1045