blob: f0602390ca566423951774c5e888278247114e29 [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2019 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import argparse
import logging
import os
import sys
import time
from webkitpy.common.host import Host
from webkitpy.common.system.executive import ScriptError
from webkitpy.common.system.logutils import configure_logging
from webkitpy.port.config import Config
from webkitpy.test.main import Tester
_log = logging.getLogger(__name__)
EXCEPTIONAL_EXIT_STATUS = -1
class NoAction(argparse.Action):
def __init__(self, option_strings, dest, **kwargs):
super(NoAction, self).__init__(option_strings, dest, nargs=0, **kwargs)
def __call__(self, parser, namespace, values, option_string):
setattr(namespace, self.dest, False if option_string.startswith('--no') else True)
class LldbTester(Tester):
def parse_args(self):
parser = argparse.ArgumentParser(description='A script which tests WebKit\'s lldb macros and integration')
parser.add_argument('--build', '--no-build',
dest='build', action=NoAction,
default=None, help='Enable or disable calling build-lldbwebkittester before running the test (enabled by default). This will build the lldb test runner, bmalloc and WTF.')
parser.add_argument('--root',
dest='root', action='store',
default=None, help='Path to a directory containing the binaries needed to run tests.')
parser.add_argument('-v', '--verbose', action='count',
default=0, help='Verbose output (specify once for individual test results, twice for debug messages)')
parser.add_argument('-t', '--timing', action='store_true',
default=False, help='Display per-test execution time (implies --verbose)')
parser.add_argument('-q', '--quiet', action='store_true',
default=False, help='Run quietly (errors, warnings, and progress only)')
parser.add_argument('-p', '--pass-through', action='store_true', default=False,
help='Be debugger friendly by passing captured output through to the system')
parser.add_argument('--debug', const='debug',
dest='configuration', action='store_const',
default=None, help='Alias for configuration=debug.')
parser.add_argument('--release', const='release',
dest='configuration', action='store_const',
default=None, help='Alias for configuration=release.')
parser.add_argument('--configuration',
dest='configuration', action='store',
default=None, help='Set configuration (Debug/Release/ASan/ect.) to build and test the lldb test runner with.')
parser.add_argument('names', nargs='*',
default=None, help='Name (or names) of test, or test suite, to be run. lldb_webkit_unittest.TestSummaryProviders and dump_class_layout_unittest.TestDumpClassLayout are two examples')
return parser.parse_args()
def run(self, host=None, webkit_root=None):
configure_logging(logger=_log)
host = host or Host()
self._options = self.parse_args()
self.printer.configure(self._options)
self.finder.clean_trees()
names = self.finder.find_names(self._options.names or [], True)
if not names:
_log.error('No tests to run')
return False
config = Config(host.executive, self.finder.filesystem)
configuration_to_use = self._options.configuration or config.default_configuration()
self.upload_style = configuration_to_use.lower()
if (not self._options.root and self._options.build is None) or self._options.build:
self.printer.write_update('Building lldbWebKitTester ...')
build_lldbwebkittester = self.finder.filesystem.join(webkit_root, 'Tools', 'Scripts', 'build-lldbwebkittester')
try:
host.executive.run_and_throw_if_fail(
[build_lldbwebkittester, config.flag_for_configuration(configuration_to_use)],
quiet=(not bool(self._options.verbose)),
)
except ScriptError as e:
_log.error(e.message_with_output(output_limit=None))
return False
os.environ['LLDB_WEBKIT_TESTER_EXECUTABLE'] = str(self.finder.filesystem.join(config.build_directory(configuration_to_use), 'lldbWebKitTester'))
if not self.finder.filesystem.exists(os.environ['LLDB_WEBKIT_TESTER_EXECUTABLE']):
_log.error('Failed to find lldbWebKitTester.')
return False
return self._run_tests(names)
def main():
tester = LldbTester()
host = Host()
lldb_python_directory = host.path_to_lldb_python_directory()
if not host.filesystem.isdir(lldb_python_directory):
tester.parse_args()
if not lldb_python_directory:
print('lldb tests are only supported on macOS with XCode installed')
else:
print('Could not find {}, derived from running `xcrun lldb --python-path`'.format(lldb_python_directory))
return 1
up = host.filesystem.dirname
webkit_root = up(up(up(host.filesystem.abspath(__file__))))
if lldb_python_directory not in sys.path:
sys.path.append(lldb_python_directory)
tester.add_tree(host.filesystem.join(webkit_root, 'Tools', 'lldb'))
return not tester.run(host=host, webkit_root=webkit_root)
if __name__ == '__main__':
sys.exit(main())