def main(server_constructor, input_fn=None, argv=None, **kwargs):
    input_fn = input_fn or raw_input

    option_parser = optparse.OptionParser()
    option_parser.add_option('--output-dir',
                             dest='output_dir',
                             default=None,
                             help='output directory.')
    option_parser.add_option('-v', '--verbose', action='store_true')
    options, args = option_parser.parse_args(argv)

    logging.basicConfig()
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG if options.verbose else logging.INFO)

    host = Host()
    port_obj = host.port_factory.get()
    if not options.output_dir:
        options.output_dir = port_obj.default_results_directory()

    # Create the output directory if it doesn't already exist.
    port_obj.host.filesystem.maybe_make_directory(options.output_dir)

    server = server_constructor(port_obj, options.output_dir, **kwargs)
    server.start()
    try:
        _ = input_fn('Hit any key to stop the server and exit.')
    except (KeyboardInterrupt, EOFError) as e:
        pass

    server.stop()
Exemple #2
0
def main(argv, stdout, stderr):
    options, args = parse_args(argv)

    if options.platform and 'test' in options.platform and not 'browser_test' in options.platform:
        # It's a bit lame to import mocks into real code, but this allows the user
        # to run tests against the test platform interactively, which is useful for
        # debugging test failures.
        from webkitpy.common.host_mock import MockHost
        host = MockHost()
    else:
        host = Host()

    try:
        port = host.port_factory.get(options.platform, options)
    except (NotImplementedError, ValueError) as e:
        # FIXME: is this the best way to handle unsupported port names?
        print >> stderr, str(e)
        return test_run_results.UNEXPECTED_ERROR_EXIT_STATUS

    try:
        return run(port, options, args, stderr, stdout).exit_code

    # We need to still handle KeyboardInterrupt, at least for webkitpy unittest cases.
    except KeyboardInterrupt:
        return test_run_results.INTERRUPTED_EXIT_STATUS
    except test_run_results.TestRunException as e:
        print >> stderr, e.msg
        return e.code
    except BaseException as e:
        if isinstance(e, Exception):
            print >> stderr, '\n%s raised: %s' % (e.__class__.__name__, str(e))
            traceback.print_exc(file=stderr)
        return test_run_results.UNEXPECTED_ERROR_EXIT_STATUS
Exemple #3
0
def convert_for_webkit(new_path, filename, reference_support_info,
                       host=Host()):
    """Converts a file's contents so the Blink layout test runner can run it.

    Args:
        new_path: Absolute path where file will be copied to in the Chromium repo.
        filename: Absolute path to where the file is.
        reference_support_info: Dict of information about a related reference HTML, if any.

    Returns:
        A pair of (list of modified CSS properties, modified text).
    """
    # Conversion is not necessary for any tests in wpt now; see http://crbug.com/654081.
    contents = host.filesystem.read_binary_file(filename)
    try:
        contents = contents.decode('utf-8')
    except UnicodeDecodeError:
        contents = contents.decode('utf-16')

    converter = _W3CTestConverter(new_path, filename, reference_support_info,
                                  host)
    if filename.endswith('.css'):
        return converter.add_webkit_prefix_to_unprefixed_properties(contents)
    converter.feed(contents)
    converter.close()
    return converter.output()
Exemple #4
0
 def __init__(self):
     self._host = Host()
     self._filesystem = self._host.filesystem
     self._host.initialize_scm()
     self._webkit_root = self._host.scm().checkout_root
     self.prefixed_properties = self.read_webkit_prefixed_css_property_list(
     )
Exemple #5
0
    def _prepare_config(self, options, args, tool):
        results_directory = args[0]
        host = Host()
        host.initialize_scm()

        print 'Parsing full_results.json...'
        results_json_path = host.filesystem.join(results_directory, 'full_results.json')
        results_json = json_results_generator.load_json(host.filesystem, results_json_path)

        port = tool.port_factory.get()
        layout_tests_directory = port.layout_tests_dir()
        platforms = host.filesystem.listdir(host.filesystem.join(layout_tests_directory, 'platform'))
        self._test_config = TestConfig(port, layout_tests_directory, results_directory, platforms, host)

        print 'Gathering current baselines...'
        self._gather_baselines(results_json)

        return {
            'test_config': self._test_config,
            "results_json": results_json,
            "platforms_json": {
                'platforms': platforms,
                'defaultPlatform': port.name(),
            },
        }
def main(_argv, _stdout, _stderr):
    options, args = parse_args()
    import_dir = args[0]
    if len(args) == 1:
        repo_dir_parts = []
        for part in import_dir.split(os.path.sep):
            if part in VALID_TEST_STATUSES:
                break
            else:
                repo_dir_parts.append(part)
        repo_dir = os.path.sep.join(repo_dir_parts)
    else:
        repo_dir = args[1]

    if not os.path.exists(import_dir):
        sys.exit('Source directory %s not found!' % import_dir)

    if not os.path.exists(repo_dir):
        sys.exit('Repository directory %s not found!' % repo_dir)
    if not repo_dir in import_dir:
        sys.exit('Repository directory %s must be a parent of %s' % (repo_dir, import_dir))

    configure_logging()

    test_importer = TestImporter(Host(), import_dir, repo_dir, options)
    test_importer.do_import()
Exemple #7
0
    def __init__(self, port, options, tests=[]):
        if len(options.subtests) > 0 and len(tests) != 1:
            raise ValueError(
                "Passing one or more subtests requires one and only test argument"
            )
        self._options = options

        self._port = Host().port_factory.get(port)
        self._driver = self._create_driver()

        if self._options.debug:
            self._build_type = "Debug"
        elif self._options.release:
            self._build_type = "Release"
        else:
            self._build_type = self._port.default_configuration()
        common.set_build_types((self._build_type, ))

        self._programs_path = common.binary_build_path()
        expectations_file = os.path.join(common.top_level_path(), "Tools",
                                         "TestWebKitAPI", "glib",
                                         "TestExpectations.json")
        self._expectations = TestExpectations(self._port.name(),
                                              expectations_file,
                                              self._build_type)
        self._tests = self._get_tests(tests)
        self._disabled_tests = []
Exemple #8
0
def main(server_constructor, input_fn=None, argv=None, **kwargs):
    input_fn = input_fn or raw_input

    parser = argparse.ArgumentParser()
    parser.add_argument('--output-dir', type=str, default=None,
                        help='output directory, for log files etc.')
    parser.add_argument('-v', '--verbose', action='store_true',
                        help='print more information, including port numbers')
    args = parser.parse_args(argv)

    logging.basicConfig()
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG if args.verbose else logging.INFO)

    host = Host()
    port_obj = host.port_factory.get()
    if not args.output_dir:
        args.output_dir = port_obj.default_results_directory()

    # Create the output directory if it doesn't already exist.
    port_obj.host.filesystem.maybe_make_directory(args.output_dir)

    server = server_constructor(port_obj, args.output_dir, **kwargs)
    server.start()
    try:
        _ = input_fn('Hit any key to stop the server and exit.')
    except (KeyboardInterrupt, EOFError):
        pass

    server.stop()
Exemple #9
0
def main(argv, stderr, host=None):
    parser = optparse.OptionParser(option_list=platform_options(
        use_globs=True))
    parser.add_option('--json', help='Path to JSON output file')
    options, _ = parser.parse_args(argv)

    if not host:
        if options.platform and 'test' in options.platform:
            # It's a bit lame to import mocks into real code, but this allows the user
            # to run tests against the test platform interactively, which is useful for
            # debugging test failures.
            from webkitpy.common.host_mock import MockHost
            host = MockHost()
        else:
            host = Host()

    # Need to generate MANIFEST.json since some expectations correspond to WPT
    # tests that aren't files and only exist in the manifest.
    _log.info('Generating MANIFEST.json for web-platform-tests ...')
    WPTManifest.ensure_manifest(host)

    try:
        exit_status = run_checks(host, options, stderr)
    except KeyboardInterrupt:
        exit_status = exit_codes.INTERRUPTED_EXIT_STATUS
    except Exception as error:  # pylint: disable=broad-except
        print >> stderr, '\n%s raised: %s' % (error.__class__.__name__, error)
        traceback.print_exc(file=stderr)
        exit_status = exit_codes.EXCEPTIONAL_EXIT_STATUS

    return exit_status
Exemple #10
0
    def __init__(self, new_path, filename, host=Host()):
        HTMLParser.__init__(self)

        self._host = host
        self._filesystem = self._host.filesystem
        self._webkit_root = WebKitFinder(self._filesystem).webkit_base()

        self.converted_data = []
        self.converted_properties = []
        self.in_style_tag = False
        self.style_data = []
        self.filename = filename

        resources_path = self.path_from_webkit_root('tests', 'resources')
        resources_relpath = self._filesystem.relpath(resources_path, new_path)
        self.resources_relpath = resources_relpath

        # These settings might vary between WebKit and Blink
        self._css_property_file = self.path_from_webkit_root(
            'Source', 'core', 'css', 'CSSProperties.in')

        self.prefixed_properties = self.read_webkit_prefixed_css_property_list(
        )

        self.prefixed_properties = self.read_webkit_prefixed_css_property_list(
        )
        prop_regex = '([\s{]|^)(' + "|".join(
            prop.replace('-webkit-', '')
            for prop in self.prefixed_properties) + ')(\s+:|:)'
        self.prop_re = re.compile(prop_regex)
Exemple #11
0
    def __init__(self, new_path, filename, reference_support_info,
                 host=Host()):
        HTMLParser.__init__(self)

        self._host = host
        self._filesystem = self._host.filesystem
        self._webkit_root = WebKitFinder(self._filesystem).webkit_base()

        self.converted_data = []
        self.converted_properties = []
        self.in_style_tag = False
        self.style_data = []
        self.filename = filename
        self.reference_support_info = reference_support_info
        resources_path = self.path_from_webkit_root('LayoutTests', 'resources')
        resources_relpath = self._filesystem.relpath(resources_path, new_path)
        self.resources_relpath = resources_relpath

        # These settings might vary between WebKit and Blink.
        # Only -webkit-text-emphasis is currently needed. See:
        # https://bugs.chromium.org/p/chromium/issues/detail?id=614955#c1
        self.prefixed_properties = [
            '-webkit-text-emphasis',
            '-webkit-text-emphasis-color',
            '-webkit-text-emphasis-position',
            '-webkit-text-emphasis-style',
        ]
        prop_regex = r'([\s{]|^)(' + '|'.join(
            prop.replace('-webkit-', '')
            for prop in self.prefixed_properties) + r')(\s+:|:)'
        self.prop_re = re.compile(prop_regex)
Exemple #12
0
    def run(self):
        if not self.host:
            self.host = Host()
        if not self._running_inline:
            self._set_up_logging()

        worker = self._worker
        exception_msg = ""
        _log.debug("%s starting" % self.name)
        self._running = True

        try:
            if hasattr(worker, 'start'):
                worker.start()
            while self._running:
                message = self._messages_to_worker.get()
                if message.from_user:
                    worker.handle(message.name, message.src, *message.args)
                    self._yield_to_manager()
                else:
                    assert message.name == 'stop', 'bad message %s' % repr(
                        message)
                    break

            _log.debug("%s exiting" % self.name)
        except Queue.Empty:
            assert False, '%s: ran out of messages in worker queue.' % self.name
        except KeyboardInterrupt, e:
            self._raise(sys.exc_info())
Exemple #13
0
def main(argv, stdout, stderr):
    options, args = parse_args(argv)
    host = Host()

    try:
        options.webkit_test_runner = True
        port = host.port_factory.get(options.platform, options)
    except NotImplementedError as e:
        print(str(e), file=stderr)
        return EXCEPTIONAL_EXIT_STATUS

    # Some platforms do not support API tests
    does_not_support_api_tests = ['ios-device']
    if port.operating_system() in does_not_support_api_tests:
        print('{} cannot run API tests'.format(port.operating_system()),
              file=stderr)
        return EXCEPTIONAL_EXIT_STATUS

    try:
        return run(port, options, args, stderr)
    except KeyboardInterrupt:
        return INTERRUPT_EXIT_STATUS
    except BaseException as e:
        if isinstance(e, Exception):
            print('\n%s raised: %s' % (e.__class__.__name__, str(e)),
                  file=stderr)
            traceback.print_exc(file=stderr)
        return EXCEPTIONAL_EXIT_STATUS
Exemple #14
0
def main(argv, _, stderr):
    parser = optparse.OptionParser(option_list=platform_options(
        use_globs=True))
    parser.add_option('--json', help='Path to JSON output file')
    options, _ = parser.parse_args(argv)

    if options.platform and 'test' in options.platform:
        # It's a bit lame to import mocks into real code, but this allows the user
        # to run tests against the test platform interactively, which is useful for
        # debugging test failures.
        from webkitpy.common.host_mock import MockHost
        host = MockHost()
    else:
        host = Host()

    try:
        exit_status = run_checks(host, options, stderr)
    except KeyboardInterrupt:
        exit_status = INTERRUPTED_EXIT_STATUS
    except Exception as e:
        print >> stderr, '\n%s raised: %s' % (e.__class__.__name__, str(e))
        traceback.print_exc(file=stderr)
        exit_status = EXCEPTIONAL_EXIT_STATUS

    return exit_status
    def test_generate_repaint_overlay_html(self):
        test_name = 'paint/invalidation/repaint-overlay/layers.html'
        host = Host()
        port = host.port_factory.get()
        layer_tree_file = port.expected_filename(test_name, '.txt')
        if not layer_tree_file or not host.filesystem.exists(layer_tree_file):
            # This can happen if the scripts are not in the standard blink directory.
            return

        layer_tree = str(host.filesystem.read_text_file(layer_tree_file))
        self.assertTrue(repaint_overlay.result_contains_repaint_rects(layer_tree))
        overlay_html = (
            '<!-- Generated by Tools/Scripts/test-webkitpy\n' +
            ' test case: TestRepaintOverlay.test_generate_repaint_overlay_html. -->\n' +
            repaint_overlay.generate_repaint_overlay_html(test_name, layer_tree, layer_tree))

        results_directory = port.results_directory()
        host.filesystem.maybe_make_directory(results_directory)
        actual_overlay_html_file = host.filesystem.join(results_directory, 'layers-overlay.html')
        host.filesystem.write_text_file(actual_overlay_html_file, overlay_html)

        overlay_html_file = port.abspath_for_test('paint/invalidation/repaint-overlay/layers-overlay.html')
        expected = host.filesystem.read_text_file(overlay_html_file)

        self.assertEquals(
            expected, overlay_html,
            'This failure is probably caused by changed repaint_overlay.py. '
            'Please examine the diffs:\n  diff %s %s\n'
            'If the diffs are valid, update the file:\n  cp %s %s\n'
            'then update layers-overlay-expected.html in the same directory if needed,'
            ' and commit the files together with the changed repaint_overlay.py.' %
            (overlay_html_file, actual_overlay_html_file, actual_overlay_html_file, overlay_html_file))
def main(argv):
    parser = optparse.OptionParser(usage='%prog [stats.json]')
    parser.description = "Prints out lists of tests run on each worker as per the stats.json file."
    options, args = parser.parse_args(argv)

    if args and args[0]:
        stats_path = args[0]
    else:
        host = Host()
        stats_path = host.filesystem.join(
            host.port_factory.get().results_directory(), 'stats.json')

    with open(stats_path, 'r') as fp:
        stats_trie = json.load(fp)

    stats = convert_trie_to_flat_paths(stats_trie)
    stats_by_worker = {}
    for test_name, data in stats.items():
        worker = "worker/" + str(data["results"][0])
        if worker not in stats_by_worker:
            stats_by_worker[worker] = []
        test_number = data["results"][1]
        stats_by_worker[worker].append({
            "name": test_name,
            "number": test_number
        })

    for worker in sorted(stats_by_worker.keys()):
        print worker + ':'
        for test in sorted(stats_by_worker[worker],
                           key=lambda test: test["number"]):
            print test["name"]
        print
Exemple #17
0
    def __init__(self, new_path, filename, reference_support_info, host=Host(), convert_test_harness_links=True, webkit_test_runner_options=''):
        HTMLParser.__init__(self)

        self._host = host
        self._filesystem = self._host.filesystem
        self._webkit_root = WebKitFinder(self._filesystem).webkit_base()

        self.converted_data = []
        self.converted_properties = []
        self.converted_property_values = []
        self.in_style_tag = False
        self.style_data = []
        self.filename = filename
        self.reference_support_info = reference_support_info
        self.webkit_test_runner_options = webkit_test_runner_options
        self.has_started = False

        resources_path = self.path_from_webkit_root('LayoutTests', 'resources')
        resources_relpath = self._filesystem.relpath(resources_path, new_path)
        self.new_test_harness_path = resources_relpath
        self.convert_test_harness_links = convert_test_harness_links

        # These settings might vary between WebKit and Blink
        css_property_file = self.path_from_webkit_root('Source', 'WebCore', 'css', 'CSSProperties.json')
        css_property_value_file = self.path_from_webkit_root('Source', 'WebCore', 'css', 'CSSValueKeywords.in')

        self.test_harness_re = re.compile('/resources/testharness')

        self.prefixed_properties = self.read_webkit_prefixed_css_property_list(css_property_file)
        prop_regex = '([\s{]|^)(' + "|".join(prop.replace('-webkit-', '') for prop in self.prefixed_properties) + ')(\s+:|:)'
        self.prop_re = re.compile(prop_regex)

        self.prefixed_property_values = self.legacy_read_webkit_prefixed_css_property_list(css_property_value_file)
        prop_value_regex = '(:\s*|^\s*)(' + "|".join(value.replace('-webkit-', '') for value in self.prefixed_property_values) + ')(\s*;|\s*}|\s*$)'
        self.prop_value_re = re.compile(prop_value_regex)
Exemple #18
0
def main(_argv, _stdout, _stderr):
    options, test_paths = parse_args(_argv)

    configure_logging()

    test_importer = TestImporter(Host(), test_paths, options)
    test_importer.do_import()
Exemple #19
0
        def run(self):
            # We need to create a new Host object here because this is
            # running in a new process and we can't require the parent's
            # Host to be pickleable and passed to the child.
            if self._platform_name.startswith('test'):
                host = MockHost()
            else:
                host = Host()
            host._initialize_scm()

            options = self._options
            port_obj = host.port_factory.get(self._platform_name, options)

            # The unix multiprocessing implementation clones the
            # log handler configuration into the child processes,
            # but the win implementation doesn't.
            configure_logging = (sys.platform == 'win32')

            # FIXME: this won't work if the calling process is logging
            # somewhere other than sys.stderr and sys.stdout, but I'm not sure
            # if this will be an issue in practice.
            printer = printing.Printer(port_obj, options, sys.stderr,
                                       sys.stdout, configure_logging)
            self._client.run(port_obj)
            printer.cleanup()
Exemple #20
0
def convert_for_webkit(new_path,
                       filename,
                       reference_support_info,
                       host=Host(),
                       convert_test_harness_links=True,
                       webkit_test_runner_options=''):
    """ Converts a file's |contents| so it will function correctly in its |new_path| in Webkit.

    Returns the list of modified properties and the modified text if the file was modifed, None otherwise."""
    contents = host.filesystem.read_text_file(filename)

    # WebKit does not have a www test domain.
    contents = contents.replace('{{domains[www]}}', '{{hosts[alt][]}}')

    converter = _W3CTestConverter(new_path, filename, reference_support_info,
                                  host, convert_test_harness_links,
                                  webkit_test_runner_options)
    if filename.endswith('.css'):
        return converter.add_webkit_prefix_to_unprefixed_properties_and_values(
            contents)
    elif filename.endswith('.js'):
        return ([], [], contents)
    else:
        converter.feed(contents)
        converter.close()
        return converter.output()
Exemple #21
0
def main(_argv, _stdout, _stderr):
    options = parse_args(_argv)

    configure_logging()

    test_exporter = TestExporter(Host(), options)

    test_exporter.do_export()
 def _begin_logging(self):
     _queue_log_path = self._delegate.queue_log_path()
     # We are using logging.getLogger("webkitpy") instead of _log since we want to capture all messages logged from webkitpy modules.
     self._log_handler = logutils.configure_logger_to_log_to_file(
         logging.getLogger("webkitpy"), _queue_log_path,
         Host().filesystem)
     self._queue_log = self._output_tee.add_log(_queue_log_path)
     self._work_log = None
Exemple #23
0
def main():
    host = Host()
    importer = TestImporter(host)
    try:
        host.exit(importer.main())
    except KeyboardInterrupt:
        host.print_("Interrupted, exiting")
        host.exit(exit_codes.INTERRUPTED_EXIT_STATUS)
Exemple #24
0
 def do_association_check(self, files, cwd, host=Host()):
     _log.debug("Running TestExpectations linter")
     TestExpectationsChecker.lint_test_expectations(
         files,
         self._configuration,
         cwd,
         self._increment_error_count,
         host=host)
Exemple #25
0
def main():
    configure_logging()
    options = parse_args()
    host = Host()
    wpt_github = WPTGitHub(host)
    test_exporter = TestExporter(host, wpt_github, dry_run=options.dry_run)

    test_exporter.run()
Exemple #26
0
def main(argv, stdout, stderr):
    options, args = parse_args(argv)

    if options.platform and 'test' in options.platform:
        # It's a bit lame to import mocks into real code, but this allows the user
        # to run tests against the test platform interactively, which is useful for
        # debugging test failures.
        from webkitpy.common.host_mock import MockHost
        host = MockHost()
    else:
        host = Host()

    if options.lint_test_files:
        from webkitpy.layout_tests.lint_test_expectations import lint
        return lint(host, options, stderr)

    try:
        port = host.port_factory.get(options.platform, options)
    except NotImplementedError as e:
        # FIXME: is this the best way to handle unsupported port names?
        print(str(e), file=stderr)
        return EXCEPTIONAL_EXIT_STATUS

    stack_trace_path = host.filesystem.join(port.results_directory(),
                                            'python_stack_trace.txt')
    log_stack_trace_on_ctrl_c(output_file=stack_trace_path)
    log_stack_trace_on_term(output_file=stack_trace_path)

    if options.print_expectations:
        return _print_expectations(port, options, args, stderr)

    try:
        # Force all tests to use a smaller stack so that stack overflow tests can run faster.
        stackSizeInBytes = int(1.5 * 1024 * 1024)
        options.additional_env_var.append('JSC_maxPerThreadStackUsage=' +
                                          str(stackSizeInBytes))
        options.additional_env_var.append('__XPC_JSC_maxPerThreadStackUsage=' +
                                          str(stackSizeInBytes))
        options.additional_env_var.append('JSC_useSharedArrayBuffer=1')
        options.additional_env_var.append('__XPC_JSC_useSharedArrayBuffer=1')
        run_details = run(port, options, args, stderr)
        if run_details.exit_code != -1 and run_details.skipped_all_tests:
            return run_details.exit_code
        if run_details.exit_code != -1 and not run_details.initial_results.keyboard_interrupted:
            bot_printer = buildbot_results.BuildBotPrinter(
                stdout, options.debug_rwt_logging)
            bot_printer.print_results(run_details)

        return run_details.exit_code
    # We still need to handle KeyboardInterrupt, at least for webkitpy unittest cases.
    except KeyboardInterrupt:
        return INTERRUPTED_EXIT_STATUS
    except BaseException as e:
        if isinstance(e, Exception):
            print('\n%s raised: %s' % (e.__class__.__name__, str(e)),
                  file=stderr)
            traceback.print_exc(file=stderr)
        return EXCEPTIONAL_EXIT_STATUS
Exemple #27
0
    def _new_or_modified_tests(self):
        touched_files = self._tool.scm().changed_files()
        touched_files.extend(self._tool.scm().untracked_files())
        if not touched_files:
            return None

        configuration = "Debug" if (self._options.build_style == "debug") else "Release"
        port = Host().port_factory.get(self._tool.deprecated_port().port_flag_name, optparse.Values({'configuration': configuration}))
        return LayoutTestFinder(port, optparse.Values({'skipped': 'always', 'skip_failing_tests': False, 'http': True})).find_touched_tests(touched_files)
Exemple #28
0
 def _set_up_host_and_port(self):
     options = self._options
     if options.platform and 'test' in options.platform:
         # It is lame to import mocks into real code, but this allows us to use the test port in multi-process tests as well.
         from webkitpy.common.host_mock import MockHost
         host = MockHost()
     else:
         host = Host()
     self._port = host.port_factory.get(options.platform, options)
Exemple #29
0
    def __init__(self, options, filename, host=Host()):
        self.options = options
        self.filename = filename
        self.host = host
        self.filesystem = self.host.filesystem

        self.test_doc = None
        self.ref_doc = None
        self.load_file(filename)
Exemple #30
0
    def __init__(self, host=None):
        # FIXME: This circular import should be resolved.
        if not Simulator.Device:
            from webkitpy.xcode.simulated_device import SimulatedDevice
            Simulator.Device = SimulatedDevice

        self._host = host or Host()
        self.runtimes = []
        self.device_types = []
        self.refresh()