# 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 os.path import normpath
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.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 []

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


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('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('\([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 = text
        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 = audio  # 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_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 = str()
        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 = str()
        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.

        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:
            # 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 += out
            if err:
                self.error_from_test += err
            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('^([^:]+): ([0-9]+)$', line)
            if m:
                process_name = m.group(1)
                process_id = m.group(2)
                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):
        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)
        # 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'] = os.path.realpath(environment['DUMPRENDERTREE_TEMP'])
        environment['__XPC_SQLITE_EXEMPT_PATH_FROM_VNODE_GUARDS'] = environment['SQLITE_EXEMPT_PATH_FROM_VNODE_GUARDS']

        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 _start(self, pixel_tests, per_test_args):
        self.stop()
        # 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.
        self._port._clear_global_caches_and_temporary_files()
        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
        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 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()

        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 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')

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

        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("#PID UNRESPONSIVE - "):
            match = re.match('#PID UNRESPONSIVE - (\S+)', out_line)
            child_process_name = match.group(1) if match else 'WebProcess'
            match = re.search('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 == "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 "ERROR: AddressSanitizer" in error_line:
            return True

    def _check_for_driver_crash_or_unresponsiveness(self, error_line):
        crashed_check = error_line.rstrip('\r\n')
        if crashed_check == "#CRASHED":
            self._crashed_process_name = self._server_process.process_name()
            self._crashed_pid = self._server_process.system_pid()
            return True
        elif error_line.startswith("#CRASHED - "):
            match = re.match('#CRASHED - (\S+)', error_line)
            self._crashed_process_name = match.group(1) if match else 'WebProcess'
            match = re.search('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("#PROCESS UNRESPONSIVE - "):
            match = re.match('#PROCESS UNRESPONSIVE - (\S+)', error_line)
            child_process_name = match.group(1) if match else 'WebProcess'
            match = re.search('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 += error_line
            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_run_pixel_test:
            command += "'--pixel-test"
        if driver_input.should_dump_jsconsolelog_in_stderr:
            command += "'--dump-jsconsolelog-in-stderr"
        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, 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 = line.split()[1]
            if header_filter:
                value = header_filter(value)
            setattr(block, header_attr, value)
            return True
        return False

    def _process_stdout_line(self, block, line):
        if (self._read_header(block, line, 'Content-Type: ', 'content_type')
            or self._read_header(block, line, 'Content-Transfer-Encoding: ', 'encoding')
            or self._read_header(block, line, 'Content-Length: ', '_content_length', int)
            or self._read_header(block, line, 'ActualHash: ', 'content_hash')
            or self._read_header(block, line, 'DumpMalloc: ', 'malloc')
            or self._read_header(block, line, 'DumpJSHeap: ', 'js_heap')):
            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 += line

    def _strip_eof(self, line):
        if line and line.endswith("#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":
                    _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 = 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 += err_line
                else:
                    self.error_from_test += err_line

        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 = str()  # FIXME: Should be bytearray() once we require Python 2.6.
        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:
            self.decoded_content = self.content


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))
