# Copyright (C) 2011 Google Inc. All rights reserved.
# Copyright (c) 2015-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 Google name 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 base64
import logging
import re
import shlex
import sys
import time
import os

from collections import defaultdict
from webkitcorepy import string_utils

from webkitpy.common.system import path
from webkitpy.common.system.profiler import ProfilerFactory


_log = logging.getLogger(__name__)


class DriverInput(object):
    def __init__(self, test_name, timeout, image_hash, should_run_pixel_test, should_dump_jsconsolelog_in_stderr=None, args=None, self_comparison_header=None, force_dump_pixels=False):
        self.test_name = test_name
        self.timeout = timeout  # in ms
        self.image_hash = image_hash
        self.should_run_pixel_test = should_run_pixel_test
        self.should_dump_jsconsolelog_in_stderr = should_dump_jsconsolelog_in_stderr
        self.args = args or []
        self.self_comparison_header = self_comparison_header
        self.force_dump_pixels = force_dump_pixels

    def __repr__(self):
        return "DriverInput(test_name='{}', timeout={}, image_hash={}, should_run_pixel_test={}, should_dump_jsconsolelog_in_stderr={}, self_comparison_header={}, force_dump_pixels={}'".format(self.test_name, self.timeout, self.image_hash, self.should_run_pixel_test, self.should_dump_jsconsolelog_in_stderr, self.self_comparison_header, self.force_dump_pixels)


class DriverOutput(object):
    """Groups information about a output from driver for easy passing
    and post-processing of data."""

    metrics_patterns = []
    metrics_patterns.append((re.compile(r'at \(-?[0-9]+,-?[0-9]+\) *'), ''))
    metrics_patterns.append((re.compile('size -?[0-9]+x-?[0-9]+ *'), ''))
    metrics_patterns.append((re.compile('text run width -?[0-9]+: '), ''))
    metrics_patterns.append((re.compile('text run width -?[0-9]+ [a-zA-Z ]+: '), ''))
    metrics_patterns.append((re.compile('RenderButton {BUTTON} .*'), 'RenderButton {BUTTON}'))
    metrics_patterns.append((re.compile('RenderImage {INPUT} .*'), 'RenderImage {INPUT}'))
    metrics_patterns.append((re.compile('RenderBlock {INPUT} .*'), 'RenderBlock {INPUT}'))
    metrics_patterns.append((re.compile('RenderTextControl {INPUT} .*'), 'RenderTextControl {INPUT}'))
    metrics_patterns.append((re.compile(r'\([0-9]+px'), 'px'))
    metrics_patterns.append((re.compile(' *" *\n +" *'), ' '))
    metrics_patterns.append((re.compile('" +$'), '"'))
    metrics_patterns.append((re.compile('- '), '-'))
    metrics_patterns.append((re.compile('\n( *)"\\s+'), '\n\\g<1>"'))
    metrics_patterns.append((re.compile('\\s+"\n'), '"\n'))
    metrics_patterns.append((re.compile('scrollWidth [0-9]+'), 'scrollWidth'))
    metrics_patterns.append((re.compile('scrollHeight [0-9]+'), 'scrollHeight'))
    metrics_patterns.append((re.compile('scrollX [0-9]+'), 'scrollX'))
    metrics_patterns.append((re.compile('scrollY [0-9]+'), 'scrollY'))
    metrics_patterns.append((re.compile('scrolled to [0-9]+,[0-9]+'), 'scrolled'))

    def __init__(self, text, image, image_hash, audio, crash=False,
            test_time=0, measurements=None, timeout=False, error='', crashed_process_name='??',
            crashed_pid=None, crash_log=None, pid=None):
        # FIXME: Args could be renamed to better clarify what they do.
        self.text = string_utils.decode(text, target_type=str) if text else None
        self.image = image  # May be empty-string if the test crashes.
        self.image_hash = image_hash
        self.image_diff = None  # image_diff gets filled in after construction.
        self.audio = string_utils.encode(audio) if audio else None  # Binary format is port-dependent.
        self.crash = crash
        self.crashed_process_name = crashed_process_name
        self.crashed_pid = crashed_pid
        self.crash_log = crash_log
        self.test_time = test_time
        self.measurements = measurements
        self.timeout = timeout
        self.error = error  # stderr output
        self.pid = pid

    def has_stderr(self):
        return bool(self.error)

    def strip_metrics(self):
        self.strip_patterns(self.metrics_patterns)

    def strip_patterns(self, patterns):
        if not self.text:
            return
        for pattern in patterns:
            self.text = re.sub(pattern[0], pattern[1], self.text)

    def strip_text_start_if_needed(self, detectors):
        if not self.text or not len(detectors):
            return

        result = self.text.split('Content-Type: text/plain\n')
        if len(result) != 2:
            return

        for detector in detectors:
            if detector in result[0]:
                self.text = result[1]
                self.error += '\nRemoved logging from stdout:\n' + result[0]
                return

    def strip_stderror_patterns(self, patterns):
        if not self.error:
            return
        for pattern in patterns:
            self.error = re.sub(pattern[0], pattern[1], self.error)


class DriverPostTestOutput(object):
    """Groups data collected for a set of tests, collected after all those testse have run
    (for example, data about leaked objects)"""
    def __init__(self, world_leaks_dict):
        self.world_leaks_dict = world_leaks_dict


class Driver(object):
    """object for running test(s) using DumpRenderTree/WebKitTestRunner."""

    def __init__(self, port, worker_number, pixel_tests, no_timeout=False):
        """Initialize a Driver to subsequently run tests.

        Typically this routine will spawn DumpRenderTree in a config
        ready for subsequent input.

        port - reference back to the port object.
        worker_number - identifier for a particular worker/driver instance
        """
        self._port = port
        self._worker_number = worker_number
        self._no_timeout = no_timeout
        self._target_host = port.target_host(worker_number)

        self._driver_tempdir = None
        self._driver_user_directory_suffix = None
        self._driver_user_cache_directory = None

        # WebKitTestRunner can report back subprocess crashes by printing
        # "#CRASHED - PROCESSNAME".  Since those can happen at any time and ServerProcess
        # won't be aware of them (since the actual tool didn't crash, just a subprocess)
        # we record the crashed subprocess name here.
        self._crashed_process_name = None
        self._crashed_pid = None

        self._driver_timed_out = False

        # stderr reading is scoped on a per-test (not per-block) basis, so we store the accumulated
        # stderr output, as well as if we've seen #EOF on this driver instance.
        # FIXME: We should probably remove _read_first_block and _read_optional_image_block and
        # instead scope these locally in run_test.
        self.error_from_test = ''
        self.err_seen_eof = False

        self._server_name = self._port.driver_name()
        self._server_process = None

        self._measurements = {}
        if self._port.get_option("profile"):
            profiler_name = self._port.get_option("profiler")
            self._profiler = ProfilerFactory.create_profiler(self._port.host,
                self._port._path_to_driver(), self._port.results_directory(), profiler_name)
        else:
            self._profiler = None

        self.web_platform_test_server_doc_root = self._port.web_platform_test_server_doc_root()
        self.web_platform_test_server_base_http_url = self._port.web_platform_test_server_base_http_url()
        self.web_platform_test_server_base_https_url = self._port.web_platform_test_server_base_https_url()

    def __del__(self):
        self.stop()

    def run_test(self, driver_input, stop_when_done):
        """Run a single test and return the results.

        Note that it is okay if a test times out or crashes and leaves
        the driver in an indeterminate state. The upper layers of the program
        are responsible for cleaning up and ensuring things are okay.

        Returns a DriverOutput object.
        """
        start_time = time.time()
        self.start(driver_input.should_run_pixel_test, driver_input.args)
        test_begin_time = time.time()
        self._driver_timed_out = False
        self._crash_report_from_driver = None
        self.error_from_test = ''
        self.err_seen_eof = False

        command = self._command_from_driver_input(driver_input)

        # Certain timeouts are detected by the tool itself; tool detection is better,
        # because results contain partial output in this case. Make script timeout longer
        # by 5 seconds to avoid racing for which timeout is detected first.
        # FIXME: It's not the job of the driver to decide what the timeouts should be.
        # Move the additional timeout to driver_input.
        if self._no_timeout:
            deadline = test_begin_time + 60 * 60 * 24 * 7  # 7 days. Using sys.maxint causes a hang.
        else:
            deadline = test_begin_time + int(driver_input.timeout) / 1000.0 + 5

        self._server_process.write(command)
        text, audio = self._read_first_block(deadline, driver_input.test_name)  # First block is either text or audio
        image, actual_image_hash = self._read_optional_image_block(deadline, driver_input.test_name)  # The second (optional) block is image data.
        text = string_utils.decode(text, target_type=str)

        crashed = self.has_crashed()
        timed_out = self._server_process.timed_out
        driver_timed_out = self._driver_timed_out
        pid = self._server_process.pid()

        if stop_when_done or crashed or timed_out:
            if stop_when_done and not (crashed or timed_out):
                self.do_post_tests_work()
            # We call stop() even if we crashed or timed out in order to get any remaining stdout/stderr output.
            # In the timeout case, we kill the hung process as well.
            out, err = self._server_process.stop(self._port.driver_stop_timeout() if stop_when_done else 0.0)
            if out:
                text += string_utils.decode(out, target_type=str, errors='backslashreplace')
            if err:
                self.error_from_test += string_utils.decode(err, target_type=str)
            self._server_process = None

        crash_log = None
        if self._crash_report_from_driver:
            crash_log = self._crash_report_from_driver
        elif crashed:
            self.error_from_test, crash_log = self._get_crash_log(text, self.error_from_test, newer_than=start_time)
            # If we don't find a crash log use a placeholder error message instead.
            if not crash_log:
                pid_str = str(self._crashed_pid) if self._crashed_pid else "unknown pid"
                crash_log = 'No crash log found for %s:%s.\n' % (self._crashed_process_name, pid_str)

                # Print stdout and stderr to the placeholder crash log; we want as much context as possible.
                if self.error_from_test:
                    crash_log += '\nstdout:\n%s\nstderr:\n%s\n' % (text, self.error_from_test)

        return DriverOutput(text, image, actual_image_hash, audio,
            crash=crashed, test_time=time.time() - test_begin_time, measurements=self._measurements,
            timeout=timed_out or driver_timed_out, error=self.error_from_test,
            crashed_process_name=self._crashed_process_name,
            crashed_pid=self._crashed_pid, crash_log=crash_log, pid=pid)

    def do_post_tests_work(self):
        if not self._server_process:
            return None

        if self._port.get_option('leaks'):
            _log.debug('Gathering child processes...')
            self._server_process.write('#LIST CHILD PROCESSES\n')
            deadline = time.time() + 20
            block = self._read_block(deadline, '', wait_for_stderr_eof=True)
            self._server_process.set_child_processes(self._parse_child_processes_output(block.decoded_content))

        if self._port.get_option('world_leaks'):
            _log.debug('Checking for world leaks...')
            self._server_process.write('#CHECK FOR WORLD LEAKS\n')
            deadline = time.time() + 20
            block = self._read_block(deadline, '', wait_for_stderr_eof=True)

            _log.debug('World leak result: %s' % (block.decoded_content))

            return self._parse_world_leaks_output(block.decoded_content)

        return None

    @staticmethod
    def _parse_child_processes_output(output):
        child_processes = defaultdict(list)

        for line in output.splitlines():
            m = re.match(b'^([^:]+): ([0-9]+)$', line)
            if m:
                process_name = string_utils.decode(m.group(1), target_type=str)
                process_id = string_utils.decode(m.group(2), target_type=str)
                child_processes[process_name].append(process_id)

        return child_processes

    def _parse_world_leaks_output(self, output):
        tests_with_world_leaks = defaultdict(list)

        last_test = None
        for line in output.splitlines():
            m = re.match('^TEST: (.+)$', line)
            if m:
                last_test = self.uri_to_test(m.group(1))
            m = re.match('^ABANDONED DOCUMENT: (.+)$', line)
            if m:
                leaked_document_url = m.group(1)
                if last_test:
                    tests_with_world_leaks[last_test].append(leaked_document_url)

        return DriverPostTestOutput(tests_with_world_leaks)

    def _get_crash_log(self, stdout, stderr, newer_than):
        return self._port._get_crash_log(self._crashed_process_name, self._crashed_pid, stdout, stderr, newer_than, target_host=self._target_host)

    def _command_wrapper(self):
        # Hook for injecting valgrind or other runtime instrumentation, used by e.g. tools/valgrind/valgrind_tests.py.
        wrapper_arguments = []
        if self._profiler:
            wrapper_arguments = self._profiler.wrapper_arguments()
        if self._port.get_option('wrapper'):
            return shlex.split(self._port.get_option('wrapper')) + wrapper_arguments
        return wrapper_arguments

    HTTP_DIR = "http/tests/"
    HTTP_LOCAL_DIR = "http/tests/local/"
    WEBKIT_SPECIFIC_WEB_PLATFORM_TEST_SUBDIR = "http/wpt/"
    WEBKIT_WEB_PLATFORM_TEST_SERVER_ROUTE = "WebKit/"

    def is_http_test(self, test_name):
        return test_name.startswith(self.HTTP_DIR) and not test_name.startswith(self.HTTP_LOCAL_DIR)

    def is_webkit_specific_web_platform_test(self, test_name):
        return test_name.startswith(self.WEBKIT_SPECIFIC_WEB_PLATFORM_TEST_SUBDIR)

    def is_web_platform_test(self, test_name):
        return test_name.startswith(self.web_platform_test_server_doc_root)

    def wpt_test_path_to_uri(self, path):
        return self.web_platform_test_server_base_https_url + path if ".https." in path else self.web_platform_test_server_base_http_url + path

    def http_test_path_to_uri(self, path):
        path = path.replace(os.sep, '/')
        return self.http_base_url(secure=self.is_secure_path(path)) + path

    def is_secure_path(self, path):
        return path.startswith("ssl") or ".https." in path

    def http_base_url(self, secure=None):
        return "%s://127.0.0.1:%d/" % (('https', 8443) if secure else ('http', 8000))

    def test_to_uri(self, test_name):
        """Convert a test name to a URI."""
        if self.is_web_platform_test(test_name):
            return self.wpt_test_path_to_uri(test_name[len(self.web_platform_test_server_doc_root):])
        if self.is_webkit_specific_web_platform_test(test_name):
            return self.wpt_test_path_to_uri(self.WEBKIT_WEB_PLATFORM_TEST_SERVER_ROUTE + test_name[len(self.WEBKIT_SPECIFIC_WEB_PLATFORM_TEST_SUBDIR):])

        if not self.is_http_test(test_name):
            return path.abspath_to_uri(self._port.host.platform, self._port.abspath_for_test(test_name))

        return self.http_test_path_to_uri(test_name[len(self.HTTP_DIR):])

    def uri_to_test(self, uri):
        """Return the base layout test name for a given URI.

        This returns the test name for a given URI, e.g., if you passed in
        "file:///src/LayoutTests/fast/html/keygen.html" it would return
        "fast/html/keygen.html".

        """
        if uri.startswith("file:///"):
            prefix = path.abspath_to_uri(self._port.host.platform, self._port.layout_tests_dir())
            if not prefix.endswith('/'):
                prefix += '/'
            return uri[len(prefix):]
        if uri.startswith(self.web_platform_test_server_base_http_url + self.WEBKIT_WEB_PLATFORM_TEST_SERVER_ROUTE):
            return uri.replace(self.web_platform_test_server_base_http_url + self.WEBKIT_WEB_PLATFORM_TEST_SERVER_ROUTE, self.WEBKIT_SPECIFIC_WEB_PLATFORM_TEST_SUBDIR)
        if uri.startswith(self.web_platform_test_server_base_https_url + self.WEBKIT_WEB_PLATFORM_TEST_SERVER_ROUTE):
            return uri.replace(self.web_platform_test_server_base_https_url + self.WEBKIT_WEB_PLATFORM_TEST_SERVER_ROUTE, self.WEBKIT_SPECIFIC_WEB_PLATFORM_TEST_SUBDIR)
        if uri.startswith(self.web_platform_test_server_base_http_url):
            return uri.replace(self.web_platform_test_server_base_http_url, self.web_platform_test_server_doc_root)
        if uri.startswith(self.web_platform_test_server_base_https_url):
            return uri.replace(self.web_platform_test_server_base_https_url, self.web_platform_test_server_doc_root)
        if uri.startswith("http://"):
            return uri.replace(self.http_base_url(secure=False), self.HTTP_DIR)
        if uri.startswith("https://"):
            return uri.replace(self.http_base_url(secure=True), self.HTTP_DIR)
        raise NotImplementedError('unknown url type: %s' % uri)

    def has_crashed(self):
        if self._server_process is None:
            return False
        if self._crashed_process_name:
            return True
        if self._server_process.has_crashed():
            self._crashed_process_name = self._server_process.process_name()
            self._crashed_pid = self._server_process.system_pid()
            return True
        return False

    def start(self, pixel_tests, per_test_args):
        # FIXME: Callers shouldn't normally call this, since this routine
        # may not be specifying the correct combination of pixel test and
        # per_test args.
        #
        # The only reason we have this routine at all is so the perftestrunner
        # can pause before running a test; it might be better to push that
        # into run_test() directly.
        if not self._server_process:
            self._start(pixel_tests, per_test_args)
            self._run_post_start_tasks()

    def _append_environment_variable_path(self, environment, variable, path):
        if variable in environment:
            environment[variable] = environment[variable] + os.pathsep + path
        else:
            environment[variable] = path

    def _setup_environ_for_driver(self, environment):
        self._port._clear_global_caches_and_temporary_files()
        self._create_temporal_directories()
        build_root_path = str(self._port._build_path())
        self._append_environment_variable_path(environment, 'DYLD_LIBRARY_PATH', build_root_path)
        self._append_environment_variable_path(environment, '__XPC_DYLD_LIBRARY_PATH', build_root_path)
        self._append_environment_variable_path(environment, 'DYLD_FRAMEWORK_PATH', build_root_path)
        self._append_environment_variable_path(environment, '__XPC_DYLD_FRAMEWORK_PATH', build_root_path)

        self._port.port_adjust_environment_for_test_driver(environment)

        # Use an isolated temp directory that can be deleted after testing (especially important on Mac, as
        # CoreMedia disk cache is in the temp directory).
        environment['TMPDIR'] = str(self._driver_tempdir)
        environment['DIRHELPER_USER_DIR_SUFFIX'] = self._driver_user_directory_suffix
        # Put certain normally persistent files into the temp directory (e.g. IndexedDB storage).
        if sys.platform == 'cygwin':
            environment['DUMPRENDERTREE_TEMP'] = path.cygpath(str(self._driver_tempdir))
        else:
            environment['DUMPRENDERTREE_TEMP'] = str(self._driver_tempdir)
        environment['LOCAL_RESOURCE_ROOT'] = str(self._port.layout_tests_dir())
        environment['ASAN_OPTIONS'] = "allocator_may_return_null=1"
        environment['__XPC_ASAN_OPTIONS'] = environment['ASAN_OPTIONS']

        # Disable vnode-guard related simulated crashes for WKTR / DRT (rdar://problem/40674034).
        environment['SQLITE_EXEMPT_PATH_FROM_VNODE_GUARDS'] = '/'
        environment['__XPC_SQLITE_EXEMPT_PATH_FROM_VNODE_GUARDS'] = environment['SQLITE_EXEMPT_PATH_FROM_VNODE_GUARDS']

        environment['JSC_useKernTCSM'] = 'false'
        environment['__XPC_JSC_useKernTCSM'] = environment['JSC_useKernTCSM']

        if sys.platform.startswith('linux'):
            # Currently on WebKit2, there is no API for setting the application cache directory.
            # Each worker should have it's own and it should be cleaned afterwards.
            # Set it to inside the temporary folder by prepending XDG_CACHE_HOME with DRIVER_TEMPDIR.
            environment['XDG_CACHE_HOME'] = self._port.host.filesystem.join(str(self._driver_tempdir), 'appcache')
            # Use an empty/volatile home inside DRIVER_TEMPDIR to ensure that the test results
            # are not affected by the user settings of any library.
            environment['HOME'] = self._port.host.filesystem.join(str(self._driver_tempdir), 'home')
            self._target_host.filesystem.maybe_make_directory(environment['HOME'])

        if self._profiler:
            environment = self._profiler.adjusted_environment(environment)
        return environment

    def _setup_environ_for_test(self):
        environment = self._port.setup_environ_for_server(self._server_name)
        environment = self._setup_environ_for_driver(environment)
        return environment

    def _create_temporal_directories(self):
        # Each driver process should be using individual directories under _driver_tempdir (which is deleted when stopping),
        # however some subsystems on some platforms could end up using process default ones.
        if self._driver_tempdir is None:
            self._driver_tempdir = self._port._driver_tempdir(self._target_host)
            self._driver_user_directory_suffix = os.path.basename(str(self._driver_tempdir))
            user_cache_directory = self._port._path_to_user_cache_directory(self._driver_user_directory_suffix)
            if user_cache_directory:
                self._target_host.filesystem.maybe_make_directory(user_cache_directory)
                self._driver_user_cache_directory = user_cache_directory

    def _start(self, pixel_tests, per_test_args):
        self.stop()
        environment = self._setup_environ_for_test()
        self._crashed_process_name = None
        self._crashed_pid = None
        self._server_process = self._port._test_runner_process_constructor(self._port, self._server_name, self.cmd_line(pixel_tests, per_test_args), environment, target_host=self._target_host)
        self._server_process.start()

    def _run_post_start_tasks(self):
        # Remote drivers may override this to delay post-start tasks until the server has ack'd.
        if self._profiler:
            self._profiler.attach_to_pid(self._pid_on_target())

    def _pid_on_target(self):
        # Remote drivers will override this method to return the pid on the device.
        return self._server_process.pid()

    def _delete_temporal_directories(self):
        if self._driver_tempdir:
            self._target_host.filesystem.rmtree(str(self._driver_tempdir))
            self._driver_tempdir = None
        if self._driver_user_cache_directory:
            self._target_host.filesystem.rmtree(self._driver_user_cache_directory)
            self._driver_user_cache_directory = None

    def stop(self):
        if self._server_process:
            self._server_process.stop(self._port.driver_stop_timeout())
            self._server_process = None
            if self._profiler:
                self._profiler.profile_after_exit()
        self._delete_temporal_directories()

    def cmd_line(self, pixel_tests, per_test_args):
        cmd = self._command_wrapper()
        cmd.append(self._port._path_to_driver())
        if self._port.get_option('gc_between_tests'):
            cmd.append('--gc-between-tests')
        if self._port.get_option('complex_text'):
            cmd.append('--complex-text')
        if self._port.get_option('accelerated_drawing'):
            cmd.append('--accelerated-drawing')
        if self._port.get_option('remote_layer_tree'):
            cmd.append('--remote-layer-tree')
        if self._port.get_option('world_leaks'):
            cmd.append('--world-leaks')
        if self._port.get_option('threaded'):
            cmd.append('--threaded')
        if self._no_timeout:
            cmd.append('--no-timeout')
        if self._port.get_option('show_touches'):
            cmd.append('--show-touches')
        if self._port.get_option('show_window'):
            cmd.append('--show-window')
        if self._port.get_option('accessibility_isolated_tree'):
            cmd.append('--accessibility-isolated-tree')

        for allowed_host in self._port.allowed_hosts():
            cmd.append('--allowed-host')
            cmd.append(allowed_host)

        for feature in self._port.internal_feature():
            cmd.append('--internal-feature')
            cmd.append(feature)

        if not self._port.get_option('enable_all_experimental_features'):
            cmd.append('--no-enable-all-experimental-features')

        for feature in self._port.experimental_feature():
            cmd.append('--experimental-feature')
            cmd.append(feature)

        cmd.extend(self._port.get_option('additional_drt_flag', []))
        cmd.extend(self._port.additional_drt_flag())

        cmd.extend(per_test_args)

        cmd.append('-')
        return cmd

    def _check_for_driver_timeout(self, out_line):
        if out_line.startswith(b"#PID UNRESPONSIVE - "):
            match = re.match(br'#PID UNRESPONSIVE - (\S+)', out_line)
            child_process_name = string_utils.decode(match.group(1), target_type=str) if match else 'WebProcess'
            match = re.search(br'pid (\d+)', out_line)
            child_process_pid = int(match.group(1)) if match else None
            err_line = 'Wait on notifyDone timed out, process ' + child_process_name + ' pid = ' + str(child_process_pid)
            self.error_from_test += err_line
            _log.debug(err_line)
            if self._port.get_option("sample_on_timeout"):
                self._port.sample_process(child_process_name, child_process_pid, self._target_host)
        if out_line == b"FAIL: Timed out waiting for notifyDone to be called\n":
            self._driver_timed_out = True

    def _check_for_address_sanitizer_violation(self, error_line):
        if b"ERROR: AddressSanitizer" in error_line:
            return True

    def _check_for_driver_crash_or_unresponsiveness(self, error_line):
        crashed_check = error_line.rstrip(b'\r\n')
        if crashed_check == b"#CRASHED":
            self._crashed_process_name = self._server_process.process_name()
            self._crashed_pid = self._server_process.system_pid()
            return True
        elif error_line.startswith(b"#CRASHED - "):
            match = re.match(br'#CRASHED - (\S+)', error_line)
            self._crashed_process_name = string_utils.decode(match.group(1), target_type=str) if match else 'WebProcess'
            match = re.search(br'pid (\d+)', error_line)
            self._crashed_pid = int(match.group(1)) if match else None
            _log.debug('%s crash, pid = %s' % (self._crashed_process_name, str(self._crashed_pid)))
            return True
        elif error_line.startswith(b"#PROCESS UNRESPONSIVE - "):
            match = re.match(br'#PROCESS UNRESPONSIVE - (\S+)', error_line)
            child_process_name = string_utils.decode(match.group(1), target_type=str) if match else 'WebProcess'
            match = re.search(br'pid (\d+)', error_line)
            child_process_pid = int(match.group(1)) if match else None
            _log.debug('%s is unresponsive, pid = %s' % (child_process_name, str(child_process_pid)))
            self._driver_timed_out = True
            if child_process_pid:
                self._port.sample_process(child_process_name, child_process_pid, self._target_host)
            self.error_from_test += string_utils.decode(error_line, target_type=str)
            self._server_process.write('#SAMPLE FINISHED\n', True)  # Must be able to ignore a broken pipe here, target process may already be closed.
            return True
        return self.has_crashed()

    def _command_from_driver_input(self, driver_input):
        # FIXME: performance tests pass in full URLs instead of test names.
        if driver_input.test_name.startswith('http://') or driver_input.test_name.startswith('https://')  or driver_input.test_name == ('about:blank'):
            command = driver_input.test_name
        elif self.is_web_platform_test(driver_input.test_name) or self.is_webkit_specific_web_platform_test(driver_input.test_name) or self.is_http_test(driver_input.test_name):
            command = self.test_to_uri(driver_input.test_name)
            command += "'--absolutePath'"
            absPath = self._port.abspath_for_test(driver_input.test_name, self._target_host)
            if sys.platform == 'cygwin':
                absPath = path.cygpath(absPath)
            command += absPath
        else:
            command = self._port.abspath_for_test(driver_input.test_name, self._target_host)
            if sys.platform == 'cygwin':
                command = path.cygpath(command)

        assert not driver_input.image_hash or driver_input.should_run_pixel_test

        # ' is the separator between arguments.
        if self._port.supports_per_test_timeout():
            command += "'--timeout'%s" % driver_input.timeout
        if driver_input.should_dump_jsconsolelog_in_stderr:
            command += "'--dump-jsconsolelog-in-stderr"
        if driver_input.self_comparison_header:
            command += "'--self-compare-with-header'%s" % driver_input.self_comparison_header
        if driver_input.force_dump_pixels:
            command += "'--force-dump-pixels"

        # --pixel-test must be the last argument, because the hash is optional,
        # and any argument put in its place will be incorrectly consumed as the hash.
        if driver_input.should_run_pixel_test:
            command += "'--pixel-test"
            if driver_input.image_hash:
                command += "'" + driver_input.image_hash
        return command + "\n"

    def _read_first_block(self, deadline, test_name):
        # returns (text_content, audio_content)
        block = self._read_block(deadline, test_name)
        if block.malloc:
            self._measurements['Malloc'] = float(block.malloc)
        if block.js_heap:
            self._measurements['JSHeap'] = float(block.js_heap)
        if block.content_type == 'audio/wav':
            return (None, block.decoded_content)
        return (block.decoded_content, None)

    def _read_optional_image_block(self, deadline, test_name):
        # returns (image, actual_image_hash)
        block = self._read_block(deadline, test_name, wait_for_stderr_eof=True)
        if block.content and block.content_type == 'image/png':
            return (block.decoded_content if block.encoding == 'base64' else block.content, block.content_hash)
        return (None, block.content_hash)

    def _read_header(self, block, line, header_text, header_attr, header_filter=None):
        if line.startswith(header_text) and getattr(block, header_attr) is None:
            value = string_utils.decode(line.split()[1], target_type=str)
            if header_filter:
                value = header_filter(value)
            setattr(block, header_attr, value)
            return True
        return False

    def _process_stdout_line(self, block, line):
        for header in [
            (b'Content-Type: ', 'content_type', None),
            (b'Content-Transfer-Encoding: ', 'encoding', None),
            (b'Content-Length: ', '_content_length', int),
            (b'ActualHash: ', 'content_hash', None),
            (b'DumpMalloc: ', 'malloc', None),
            (b'DumpJSHeap: ', 'js_heap', None),
        ]:
            if self._read_header(block, line, header[0], header[1], header[2]):
                return

        # Note, we're not reading ExpectedHash: here, but we could.
        # If the line wasn't a header, we just append it to the content.
        block.content = string_utils.encode(block.content) + line

    def _strip_eof(self, line):
        if line and line.endswith(b"#EOF\n"):
            return line[:-5], True
        return line, False

    def _read_block(self, deadline, test_name, wait_for_stderr_eof=False):
        block = ContentBlock()
        out_seen_eof = False
        asan_violation_detected = False

        while True:
            if out_seen_eof and (self.err_seen_eof or not wait_for_stderr_eof):
                break

            if self.err_seen_eof:
                out_line = self._server_process.read_stdout_line(deadline)
                err_line = None
            elif out_seen_eof:
                out_line = None
                err_line = self._server_process.read_stderr_line(deadline)
            else:
                out_line, err_line = self._server_process.read_either_stdout_or_stderr_line(deadline)

            # ServerProcess returns None for time outs and crashes.
            if out_line is None and err_line is None:
                break

            if out_line:
                assert not out_seen_eof
                out_line, out_seen_eof = self._strip_eof(out_line)
            if err_line:
                assert not self.err_seen_eof
                err_line, self.err_seen_eof = self._strip_eof(err_line)

            if out_line:
                self._check_for_driver_timeout(out_line)
                if out_line[-1] != '\n' and out_line[-1] != 10:
                    _log.error("  %s -> Last character read from DRT stdout line was not a newline!  This indicates either a NRWT or DRT bug." % test_name)
                content_length_before_header_check = block._content_length
                self._process_stdout_line(block, out_line)
                # FIXME: Unlike HTTP, DRT dumps the content right after printing a Content-Length header.
                # Don't wait until we're done with headers, just read the binary blob right now.
                if content_length_before_header_check != block._content_length:
                    block.content = string_utils.encode(self._server_process.read_stdout(deadline, block._content_length))

            if err_line:
                if self._check_for_driver_crash_or_unresponsiveness(err_line):
                    break
                elif self._check_for_address_sanitizer_violation(err_line):
                    asan_violation_detected = True
                    self._crash_report_from_driver = ''
                    # ASan report starts with a nondescript line, we only detect the second line.
                    end_of_previous_error_line = self.error_from_test.rfind('\n', 0, -1)
                    if end_of_previous_error_line > 0:
                        self.error_from_test = self.error_from_test[:end_of_previous_error_line]
                    else:
                        self.error_from_test = ''
                    # Symbolication can take a very long time, give it 10 extra minutes to finish.
                    # FIXME: This can likely be removed once <rdar://problem/18701447> is fixed.
                    deadline += 10 * 60 * 1000
                if asan_violation_detected:
                    self._crash_report_from_driver += string_utils.decode(err_line, target_type=str)
                else:
                    self.error_from_test += string_utils.decode(err_line, target_type=str)

        if asan_violation_detected and not self._crashed_process_name:
            self._crashed_process_name = self._server_process.process_name()
            self._crashed_pid = self._server_process.system_pid()

        block.decode_content()
        return block

    @staticmethod
    def check_driver(port):
        # This checks if the required system dependencies for the driver are met.
        # Since this is the generic class implementation, just return True.
        return True


class ContentBlock(object):
    def __init__(self):
        self.content_type = None
        self.encoding = None
        self.content_hash = None
        self._content_length = None
        # Content is treated as binary data even though the text output is usually UTF-8.
        self.content = b''
        self.decoded_content = None
        self.malloc = None
        self.js_heap = None

    def decode_content(self):
        if self.encoding == 'base64' and self.content is not None:
            self.decoded_content = base64.b64decode(self.content)
        else:
            try:
                self.decoded_content = string_utils.decode(self.content, target_type=str)
            except UnicodeDecodeError:
                self.decoded_content = None


class DriverProxy(object):
    """A wrapper for managing two Driver instances, one with pixel tests and
    one without. This allows us to handle plain text tests and ref tests with a
    single driver."""

    def __init__(self, port, worker_number, driver_instance_constructor, pixel_tests, no_timeout):
        self._port = port
        self._worker_number = worker_number
        self._driver_instance_constructor = driver_instance_constructor
        self._no_timeout = no_timeout

        # FIXME: We shouldn't need to create a driver until we actually run a test.
        self._driver = self._make_driver(pixel_tests)
        self._driver_cmd_line = None

    def _make_driver(self, pixel_tests):
        return self._driver_instance_constructor(self._port, self._worker_number, pixel_tests, self._no_timeout)

    @property
    def host(self):
        return self._driver._target_host

    # FIXME: this should be a @classmethod (or implemented on Port instead).
    def is_http_test(self, test_name):
        return self._driver.is_http_test(test_name)

    def is_web_platform_test(self, test_name):
        return self._driver.is_web_platform_test(test_name)

    def is_webkit_specific_web_platform_test(self, test_name):
        return self._driver.is_webkit_specific_web_platform_test(test_name)

    # FIXME: this should be a @classmethod (or implemented on Port instead).
    def test_to_uri(self, test_name):
        return self._driver.test_to_uri(test_name)

    # FIXME: this should be a @classmethod (or implemented on Port instead).
    def uri_to_test(self, uri):
        return self._driver.uri_to_test(uri)

    def run_test(self, driver_input, stop_when_done):
        pixel_tests_needed = driver_input.should_run_pixel_test
        cmd_line_key = self._cmd_line_as_key(pixel_tests_needed, driver_input.args)
        if cmd_line_key != self._driver_cmd_line:
            self._driver.stop()
            self._driver = self._make_driver(pixel_tests_needed)
            self._driver_cmd_line = cmd_line_key

        return self._driver.run_test(driver_input, stop_when_done)

    def do_post_tests_work(self):
        return self._driver.do_post_tests_work()

    def has_crashed(self):
        return self._driver.has_crashed()

    def stop(self):
        self._driver.stop()

    # FIXME: this should be a @classmethod (or implemented on Port instead).
    def cmd_line(self, pixel_tests=None, per_test_args=None):
        return self._driver.cmd_line(pixel_tests, per_test_args or [])

    def _cmd_line_as_key(self, pixel_tests, per_test_args):
        return ' '.join(self.cmd_line(pixel_tests, per_test_args))
