Example #1
0
    def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None, wait_for_log=True, target_host=None):
        # Note that we do slow-spin here and wait, since it appears the time
        # ReportCrash takes to actually write and flush the file varies when there are
        # lots of simultaneous crashes going on.
        # FIXME: Should most of this be moved into CrashLogs()?
        time_fn = time_fn or time.time
        sleep_fn = sleep_fn or time.sleep
        crash_log = ''
        crash_logs = CrashLogs(target_host or self.host, self.path_to_crash_logs(), crash_logs_to_skip=self._crash_logs_to_skip_for_host.get(target_host or self.host, []))
        now = time_fn()
        # FIXME: delete this after we're sure this code is working ...
        _log.debug('looking for crash log for %s:%s' % (name, str(pid)))
        deadline = now + 5 * int(self.get_option('child_processes', 1))
        while not crash_log and now <= deadline:
            # If the system_pid hasn't been determined yet, just try with the passed in pid.  We'll be checking again later
            system_pid = self._executive.pid_to_system_pid.get(pid)
            if system_pid == None:
                break  # We haven't mapped cygwin pid->win pid yet
            crash_log = crash_logs.find_newest_log(name, system_pid, include_errors=True, newer_than=newer_than)
            if not wait_for_log:
                break
            if not crash_log or not [line for line in crash_log.splitlines() if line.startswith('quit:')]:
                sleep_fn(0.1)
                now = time_fn()

        if not crash_log:
            return (stderr, None)
        return (stderr, crash_log)
Example #2
0
 def _look_for_all_crash_logs_in_log_dir(self, newer_than):
     crash_log = CrashLogs(
         self.host,
         self.path_to_crash_logs(),
         crash_logs_to_skip=self._crash_logs_to_skip_for_host.get(
             self.host, []))
     return crash_log.find_all_logs(newer_than=newer_than)
Example #3
0
    def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=time.time, sleep_fn=time.sleep, wait_for_log=True):
        time_fn = time_fn or time.time
        sleep_fn = sleep_fn or time.sleep
        crash_log = ''
        crash_logs = CrashLogs(self.host)
        now = time_fn()

        crash_prefix = 'CRASH: '
        stderr_lines = []
        crash_lines = []
        for line in (stderr or '').splitlines():
            crash_lines.append(line) if line.startswith(crash_prefix) else stderr_lines.append(line)

        for crash_line in crash_lines:
            identifier, pid = crash_line[len(crash_prefix):].split(' ')
            return self._get_crash_log(identifier, int(pid), stdout, '\n'.join(stderr_lines), newer_than, time_fn, sleep_fn, wait_for_log)

        _log.debug('looking for crash log for %s:%s' % (name, str(pid)))
        deadline = now + 5 * int(self.get_option('child_processes', 1))
        while not crash_log and now <= deadline:
            crash_log = crash_logs.find_newest_log(name, pid, include_errors=True, newer_than=newer_than)
            if not wait_for_log:
                break
            if not crash_log or not [line for line in crash_log.splitlines() if not line.startswith('ERROR')]:
                sleep_fn(0.1)
                now = time_fn()

        if not crash_log:
            return stderr, None
        return stderr, crash_log
Example #4
0
    def _get_crash_log(self,
                       name,
                       pid,
                       stdout,
                       stderr,
                       newer_than,
                       time_fn=None,
                       sleep_fn=None,
                       wait_for_log=True):
        # Note that we do slow-spin here and wait, since it appears the time
        # ReportCrash takes to actually write and flush the file varies when there are
        # lots of simultaneous crashes going on.
        time_fn = time_fn or time.time
        sleep_fn = sleep_fn or time.sleep
        crash_log = ''
        crash_logs = CrashLogs(self.host, self.path_to_crash_logs())
        now = time_fn()
        deadline = now + 5 * int(self.get_option('child_processes', 1))
        while not crash_log and now <= deadline:
            crash_log = crash_logs.find_newest_log(name,
                                                   pid,
                                                   include_errors=True,
                                                   newer_than=newer_than)
            if not wait_for_log:
                break
            if not crash_log or not [
                    line for line in crash_log.splitlines()
                    if not line.startswith('ERROR')
            ]:
                sleep_fn(0.1)
                now = time_fn()

        if not crash_log:
            return (stderr, None)
        return (stderr, crash_log)
Example #5
0
    def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None, wait_for_log=True):
        # Note that we do slow-spin here and wait, since it appears the time
        # ReportCrash takes to actually write and flush the file varies when there are
        # lots of simultaneous crashes going on.
        # FIXME: Should most of this be moved into CrashLogs()?
        time_fn = time_fn or time.time
        sleep_fn = sleep_fn or time.sleep
        crash_log = ''
        crash_logs = CrashLogs(self.host, self.results_directory())
        now = time_fn()
        # FIXME: delete this after we're sure this code is working ...
        _log.debug('looking for crash log for %s:%s' % (name, str(pid)))
        deadline = now + 5 * int(self.get_option('child_processes', 1))
        while not crash_log and now <= deadline:
            # If the system_pid hasn't been determined yet, just try with the passed in pid.  We'll be checking again later
            system_pid = self._executive.pid_to_system_pid.get(pid)
            if system_pid == None:
                break  # We haven't mapped cygwin pid->win pid yet
            crash_log = crash_logs.find_newest_log(name, system_pid, include_errors=True, newer_than=newer_than)
            if not wait_for_log:
                break
            if not crash_log or not [line for line in crash_log.splitlines() if line.startswith('quit:')]:
                sleep_fn(0.1)
                now = time_fn()

        if not crash_log:
            return (stderr, None)
        return (stderr, crash_log)
Example #6
0
    def test_find_log_darwin(self):
        if not SystemHost().platform.is_mac():
            return

        crash_logs = self.create_crash_logs_darwin()
        log = crash_logs.find_newest_log("DumpRenderTree")
        self.assertMultiLineEqual(log, self.newer_mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28529)
        self.assertMultiLineEqual(log, self.newer_mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28530)
        self.assertMultiLineEqual(log, self.mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28531)
        self.assertIsNone(log)
        log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0)
        self.assertIsNone(log)

        def bad_read(path):
            raise IOError('IOError: No such file or directory')

        def bad_mtime(path):
            raise OSError('OSError: No such file or directory')

        self.filesystem.read_text_file = bad_read
        log = crash_logs.find_newest_log("DumpRenderTree", 28531, include_errors=True)
        self.assertIn('IOError: No such file or directory', log)

        self.filesystem = MockFileSystem(self.files)
        crash_logs = CrashLogs(MockSystemHost(filesystem=self.filesystem))
        self.filesystem.mtime = bad_mtime
        log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0, include_errors=True)
        self.assertIn('OSError: No such file or directory', log)
Example #7
0
 def execute(self, options, args, tool):
     default_port = tool.port_factory.get()
     crash_logs = CrashLogs(tool, default_port.path_to_crash_logs())
     pid = None
     if len(args) > 1:
         pid = int(args[1])
     print crash_logs.find_newest_log(args[0], pid)
Example #8
0
 def _get_crash_log(self,
                    name,
                    pid,
                    stdout,
                    stderr,
                    newer_than,
                    time_fn=None,
                    sleep_fn=None):
     # Note that we do slow-spin here and wait, since it appears the time
     # ReportCrash takes to actually write and flush the file varies when there are
     # lots of simultaneous crashes going on.
     # FIXME: Should most of this be moved into CrashLogs()?
     time_fn = time_fn or time.time
     sleep_fn = sleep_fn or time.sleep
     crash_log = ''
     crash_logs = CrashLogs(self._filesystem)
     now = time_fn()
     # FIXME: delete this after we're sure this code is working ...
     _log.debug('looking for crash log for %s:%s' % (name, str(pid)))
     deadline = now + 5 * int(self.get_option('child_processes', 1))
     while not crash_log and now <= deadline:
         crash_log = crash_logs.find_newest_log(name,
                                                pid,
                                                include_errors=True,
                                                newer_than=newer_than)
         if not crash_log or not [
                 line for line in crash_log.splitlines()
                 if not line.startswith('ERROR')
         ]:
             sleep_fn(0.1)
             now = time_fn()
     if not crash_log:
         crash_log = 'no crash log found for %s:%d' % (name, pid)
         _log.warning(crash_log)
     return crash_log
Example #9
0
    def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=time.time, sleep_fn=time.sleep, wait_for_log=True):
        time_fn = time_fn or time.time
        sleep_fn = sleep_fn or time.sleep
        crash_log = ''
        crash_logs = CrashLogs(self.host)
        now = time_fn()

        crash_prefix = 'CRASH: '
        stderr_lines = []
        crash_lines = []
        for line in (stderr or '').splitlines():
            crash_lines.append(line) if line.startswith(crash_prefix) else stderr_lines.append(line)

        for crash_line in crash_lines:
            identifier, pid = crash_line[len(crash_prefix):].split(' ')
            return self._get_crash_log(identifier, int(pid), stdout, '\n'.join(stderr_lines), newer_than, time_fn, sleep_fn, wait_for_log)

        _log.debug('looking for crash log for %s:%s' % (name, str(pid)))
        deadline = now + 5 * int(self.get_option('child_processes', 1))
        while not crash_log and now <= deadline:
            crash_log = crash_logs.find_newest_log(name, pid, include_errors=True, newer_than=newer_than)
            if not wait_for_log:
                break
            if not crash_log or not [line for line in crash_log.splitlines() if not line.startswith('ERROR')]:
                sleep_fn(0.1)
                now = time_fn()

        if not crash_log:
            return stderr, None
        return stderr, crash_log
Example #10
0
    def run_test(self, test_input, stop_when_done):
        start_time = time.time()
        test_name = test_input.test_name
        test_args = test_input.args or []
        test = self._port._tests[test_name]
        if test.keyboard:
            raise KeyboardInterrupt
        if test.exception:
            raise ValueError('exception from ' + test_name)
        if test.hang:
            time.sleep(
                (float(test_input.timeout) * 4) / 1000.0 + 1.0
            )  # The 1.0 comes from thread_padding_sec in layout_test_runnery.

        audio = None
        actual_text = test.actual_text

        if 'flaky' in test_name and not test_name in self._port._flakes:
            self._port._flakes.add(test_name)
            actual_text = 'flaky text failure'

        if actual_text and test_args and test_name == 'passes/args.html':
            actual_text = actual_text + ' ' + ' '.join(test_args)

        if test.actual_audio:
            audio = base64.b64decode(test.actual_audio)
        crashed_process_name = None
        crashed_pid = None
        if test.crash:
            crashed_process_name = self._port.driver_name()
            crashed_pid = 1
        elif test.web_process_crash:
            crashed_process_name = 'WebProcess'
            crashed_pid = 2

        crash_log = ''
        if crashed_process_name:
            crash_logs = CrashLogs(self._port.host)
            crash_log = crash_logs.find_newest_log(crashed_process_name,
                                                   None) or ''

        if stop_when_done:
            self.stop()

        if test.actual_checksum == test_input.image_hash:
            image = None
        else:
            image = test.actual_image
        return DriverOutput(actual_text,
                            image,
                            test.actual_checksum,
                            audio,
                            crash=test.crash or test.web_process_crash,
                            crashed_process_name=crashed_process_name,
                            crashed_pid=crashed_pid,
                            crash_log=crash_log,
                            test_time=time.time() - start_time,
                            timeout=test.timeout,
                            error=test.error)
Example #11
0
    def run_test(self, driver_input, stop_when_done):
        base = self._port.lookup_virtual_test_base(driver_input.test_name)
        if base:
            virtual_driver_input = copy.copy(driver_input)
            virtual_driver_input.test_name = base
            virtual_driver_input.args = self._port.lookup_virtual_test_args(driver_input.test_name)
            return self.run_test(virtual_driver_input, stop_when_done)

        if not self.started:
            self.started = True
            self.pid = TestDriver.next_pid
            TestDriver.next_pid += 1

        start_time = time.time()
        test_name = driver_input.test_name
        test_args = driver_input.args or []
        test = self._port._tests[test_name]
        if test.keyboard:
            raise KeyboardInterrupt
        if test.exception:
            raise ValueError('exception from ' + test_name)

        audio = None
        actual_text = test.actual_text

        if 'flaky' in test_name and not test_name in self._port._flakes:
            self._port._flakes.add(test_name)
            actual_text = 'flaky text failure'

        if actual_text and test_args and test_name == 'passes/args.html':
            actual_text = actual_text + ' ' + ' '.join(test_args)

        if test.actual_audio:
            audio = base64.b64decode(test.actual_audio)
        crashed_process_name = None
        crashed_pid = None
        if test.crash:
            crashed_process_name = self._port.driver_name()
            crashed_pid = 1
        elif test.web_process_crash:
            crashed_process_name = 'WebProcess'
            crashed_pid = 2

        crash_log = ''
        if crashed_process_name:
            crash_logs = CrashLogs(self._port.host)
            crash_log = crash_logs.find_newest_log(crashed_process_name, None) or ''

        if stop_when_done:
            self.stop()

        if test.actual_checksum == driver_input.image_hash:
            image = None
        else:
            image = test.actual_image
        return DriverOutput(actual_text, image, test.actual_checksum, audio,
            crash=test.crash or test.web_process_crash, crashed_process_name=crashed_process_name,
            crashed_pid=crashed_pid, crash_log=crash_log,
            test_time=time.time() - start_time, timeout=test.timeout, error=test.error, pid=self.pid)
Example #12
0
    def _get_crash_log(self,
                       name,
                       pid,
                       stdout,
                       stderr,
                       newer_than,
                       time_fn=time.time,
                       sleep_fn=time.sleep,
                       wait_for_log=True):
        time_fn = time_fn or time.time
        sleep_fn = sleep_fn or time.sleep

        # FIXME: We should collect the actual crash log for DumpRenderTree.app because it includes more
        # information (e.g. exception codes) than is available in the stack trace written to standard error.
        stderr_lines = []
        crashed_subprocess_name_and_pid = None  # e.g. ('DumpRenderTree.app', 1234)
        for line in (stderr or '').splitlines():
            if not crashed_subprocess_name_and_pid:
                match = self.SUBPROCESS_CRASH_REGEX.match(line)
                if match:
                    crashed_subprocess_name_and_pid = (
                        match.group('subprocess_name'),
                        int(match.group('subprocess_pid')))
                    continue
            stderr_lines.append(line)

        if crashed_subprocess_name_and_pid:
            return self._get_crash_log(crashed_subprocess_name_and_pid[0],
                                       crashed_subprocess_name_and_pid[1],
                                       stdout, '\n'.join(stderr_lines),
                                       newer_than, time_fn, sleep_fn,
                                       wait_for_log)

        # LayoutTestRelay crashed
        _log.debug('looking for crash log for %s:%s' % (name, str(pid)))
        crash_log = ''
        crash_logs = CrashLogs(self.host)
        now = time_fn()
        deadline = now + 5 * int(self.get_option('child_processes', 1))
        while not crash_log and now <= deadline:
            crash_log = crash_logs.find_newest_log(name,
                                                   pid,
                                                   include_errors=True,
                                                   newer_than=newer_than)
            if not wait_for_log:
                break
            if not crash_log or not [
                    line for line in crash_log.splitlines()
                    if not line.startswith('ERROR')
            ]:
                sleep_fn(0.1)
                now = time_fn()

        if not crash_log:
            return stderr, None
        return stderr, crash_log
Example #13
0
 def write_crash_report(self, crashed_process_name, error):
     fs = self._port._filesystem
     filename = self.output_filename(self.FILENAME_SUFFIX_CRASH_LOG + ".txt")
     fs.maybe_make_directory(fs.dirname(filename))
     # FIXME: We shouldn't be grabbing private members of port.
     crash_logs = CrashLogs(fs)
     log = crash_logs.find_newest_log(crashed_process_name)
     # CrashLogs doesn't support every platform, so we fall back to
     # including the stderr output, which is admittedly somewhat redundant.
     fs.write_text_file(filename, log if log else error)
Example #14
0
 def write_crash_report(self, error):
     fs = self._port._filesystem
     filename = self.output_filename(self.FILENAME_SUFFIX_CRASH_LOG + ".txt")
     fs.maybe_make_directory(fs.dirname(filename))
     # FIXME: We shouldn't be grabbing private members of port.
     crash_logs = CrashLogs(fs)
     log = crash_logs.find_newest_log(self._port.driver_name())
     # CrashLogs doesn't support every platform, so we fall back to
     # including the stderr output, which is admittedly somewhat redundant.
     fs.write_text_file(filename, log if log else error)
Example #15
0
 def _look_for_all_crash_logs_in_log_dir(self, newer_than):
     log_list = {}
     for device in self.devices():
         crash_log = CrashLogs(
             device,
             self.path_to_crash_logs(),
             crash_logs_to_skip=self._crash_logs_to_skip_for_host.get(
                 device, []))
         log_list.update(crash_log.find_all_logs(newer_than=newer_than))
     return log_list
Example #16
0
    def run_test(self, test_input, stop_when_done):
        if not self.started:
            self.started = True
            self.pid = TestDriver.next_pid
            TestDriver.next_pid += 1

        start_time = time.time()
        test_name = test_input.test_name
        test_args = test_input.args or []
        test = self._port._tests[test_name]
        if test.keyboard:
            raise KeyboardInterrupt
        if test.exception:
            raise ValueError('exception from ' + test_name)
        if test.hang:
            time.sleep((float(test_input.timeout) * 4) / 1000.0 + 1.0)  # The 1.0 comes from thread_padding_sec in layout_test_runnery.

        audio = None
        actual_text = test.actual_text

        if 'flaky' in test_name and not test_name in self._port._flakes:
            self._port._flakes.add(test_name)
            actual_text = 'flaky text failure'

        if actual_text and test_args and test_name == 'passes/args.html':
            actual_text = actual_text + ' ' + ' '.join(test_args)

        if test.actual_audio:
            audio = test.actual_audio
        crashed_process_name = None
        crashed_pid = None
        if test.crash:
            crashed_process_name = self._port.driver_name()
            crashed_pid = 1
        elif test.web_process_crash:
            crashed_process_name = 'WebProcess'
            crashed_pid = 2

        crash_log = ''
        if crashed_process_name:
            crash_logs = CrashLogs(self._port.host)
            crash_log = crash_logs.find_newest_log(crashed_process_name, None) or ''

        if stop_when_done:
            self.stop()

        if test.actual_checksum == test_input.image_hash:
            image = None
        else:
            image = test.actual_image
        return DriverOutput(actual_text, image, test.actual_checksum, audio,
            crash=test.crash or test.web_process_crash, crashed_process_name=crashed_process_name,
            crashed_pid=crashed_pid, crash_log=crash_log,
            test_time=time.time() - start_time, timeout=test.timeout, error=test.error, pid=self.pid)
Example #17
0
    def run_test(self, test_input, stop_when_done):
        start_time = time.time()
        test_name = test_input.test_name
        test_args = test_input.args or []
        test = self._port._tests[test_name]
        if test.keyboard:
            raise KeyboardInterrupt
        if test.exception:
            raise ValueError("exception from " + test_name)
        if test.hang:
            time.sleep((float(test_input.timeout) * 4) / 1000.0)

        audio = None
        actual_text = test.actual_text

        if "flaky" in test_name and not test_name in self._port._flakes:
            self._port._flakes.add(test_name)
            actual_text = "flaky text failure"

        if actual_text and test_args and test_name == "passes/args.html":
            actual_text = actual_text + " " + " ".join(test_args)

        if test.actual_audio:
            audio = base64.b64decode(test.actual_audio)
        crashed_process_name = None
        crashed_pid = None
        if test.crash:
            crashed_process_name = self._port.driver_name()
            crashed_pid = 1
        elif test.web_process_crash:
            crashed_process_name = "WebProcess"
            crashed_pid = 2

        crash_log = ""
        if crashed_process_name:
            crash_logs = CrashLogs(self._port.host)
            crash_log = crash_logs.find_newest_log(crashed_process_name, None) or ""

        if stop_when_done:
            self.stop()

        return DriverOutput(
            actual_text,
            test.actual_image,
            test.actual_checksum,
            audio,
            crash=test.crash or test.web_process_crash,
            crashed_process_name=crashed_process_name,
            crashed_pid=crashed_pid,
            crash_log=crash_log,
            test_time=time.time() - start_time,
            timeout=test.timeout,
            error=test.error,
        )
Example #18
0
 def _look_for_all_crash_logs_in_log_dir(self, newer_than):
     log_list = {}
     for device in self._device_for_worker_number_map():
         crash_log = CrashLogs(
             device,
             self.path_to_crash_logs(),
             crash_logs_to_skip=self._crash_logs_to_skip_for_host.get(
                 device, []))
         log_list.update(
             crash_log.find_all_logs(include_errors=True,
                                     newer_than=newer_than))
     return log_list
Example #19
0
    def test_get_timestamp_from_logs_darwin(self):
        if not SystemHost().platform.is_mac():
            return

        crash_report = make_mock_crash_report_darwin('DumpRenderTree', 28528)
        crash_logs = CrashLogs(MockSystemHost())
        crash_timestamp = crash_logs.get_timestamp_from_log(crash_report)
        self.assertIn('2011-12-07 13:27:34.816', str(crash_timestamp))

        crash_report = crash_report.replace("Date/Time", "")
        crash_timestamp = crash_logs.get_timestamp_from_log(crash_report)
        self.assertIsNone(crash_timestamp)
Example #20
0
    def _get_crash_log(
        self, name, pid, stdout, stderr, newer_than, time_fn=time.time, sleep_fn=time.sleep, wait_for_log=True
    ):
        time_fn = time_fn or time.time
        sleep_fn = sleep_fn or time.sleep

        # FIXME: We should collect the actual crash log for DumpRenderTree.app because it includes more
        # information (e.g. exception codes) than is available in the stack trace written to standard error.
        stderr_lines = []
        crashed_subprocess_name_and_pid = None  # e.g. ('DumpRenderTree.app', 1234)
        for line in (stderr or "").splitlines():
            if not crashed_subprocess_name_and_pid:
                match = self.SUBPROCESS_CRASH_REGEX.match(line)
                if match:
                    crashed_subprocess_name_and_pid = (
                        match.group("subprocess_name"),
                        int(match.group("subprocess_pid")),
                    )
                    continue
            stderr_lines.append(line)

        if crashed_subprocess_name_and_pid:
            return self._get_crash_log(
                crashed_subprocess_name_and_pid[0],
                crashed_subprocess_name_and_pid[1],
                stdout,
                "\n".join(stderr_lines),
                newer_than,
                time_fn,
                sleep_fn,
                wait_for_log,
            )

        # LayoutTestRelay crashed
        _log.debug("looking for crash log for %s:%s" % (name, str(pid)))
        crash_log = ""
        crash_logs = CrashLogs(self.host)
        now = time_fn()
        deadline = now + 5 * int(self.get_option("child_processes", 1))
        while not crash_log and now <= deadline:
            crash_log = crash_logs.find_newest_log(name, pid, include_errors=True, newer_than=newer_than)
            if not wait_for_log:
                break
            if not crash_log or not [line for line in crash_log.splitlines() if not line.startswith("ERROR")]:
                sleep_fn(0.1)
                now = time_fn()

        if not crash_log:
            return stderr, None
        return stderr, crash_log
Example #21
0
    def create_crash_logs_darwin(self):
        if not SystemHost().platform.is_mac():
            return

        self.older_mock_crash_report = make_mock_crash_report_darwin(
            'DumpRenderTree', 28528)
        self.mock_crash_report = make_mock_crash_report_darwin(
            'DumpRenderTree', 28530)
        self.newer_mock_crash_report = make_mock_crash_report_darwin(
            'DumpRenderTree', 28529)
        self.other_process_mock_crash_report = make_mock_crash_report_darwin(
            'FooProcess', 28527)
        self.misformatted_mock_crash_report = 'Junk that should not appear in a crash report' + make_mock_crash_report_darwin(
            'DumpRenderTree', 28526)[200:]
        self.files = {}
        self.files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150718_quadzen.crash'] = self.older_mock_crash_report
        self.files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150719_quadzen.crash'] = self.mock_crash_report
        self.files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150720_quadzen.crash'] = self.newer_mock_crash_report
        self.files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150721_quadzen.crash'] = None
        self.files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150722_quadzen.crash'] = self.other_process_mock_crash_report
        self.files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150723_quadzen.crash'] = self.misformatted_mock_crash_report
        self.filesystem = MockFileSystem(self.files)
        crash_logs = CrashLogs(MockSystemHost(filesystem=self.filesystem),
                               CrashLogsTest.DARWIN_MOCK_CRASH_DIRECTORY)
        logs = self.filesystem.files_under(
            '/Users/mock/Library/Logs/DiagnosticReports/')
        for path in reversed(sorted(logs)):
            self.assertTrue(path in self.files.keys())
        return crash_logs
Example #22
0
    def run_test(self, test_input):
        start_time = time.time()
        test_name = test_input.test_name
        test_args = test_input.args or []
        test = self._port._tests[test_name]
        if test.keyboard:
            raise KeyboardInterrupt
        if test.exception:
            raise ValueError('exception from ' + test_name)
        if test.hang:
            time.sleep((float(test_input.timeout) * 4) / 1000.0)

        audio = None
        actual_text = test.actual_text
        if actual_text and test_args and test_name == 'passes/args.html':
            actual_text = actual_text + ' ' + ' '.join(test_args)

        if test.actual_audio:
            audio = base64.b64decode(test.actual_audio)
        crashed_process_name = None
        crashed_pid = None
        if test.crash:
            crashed_process_name = self._port.driver_name()
            crashed_pid = 1
        elif test.web_process_crash:
            crashed_process_name = 'WebProcess'
            crashed_pid = 2

        crash_log = ''
        if crashed_process_name:
            crash_logs = CrashLogs(self._port.host)
            crash_log = crash_logs.find_newest_log(crashed_process_name,
                                                   None) or ''

        return DriverOutput(actual_text,
                            test.actual_image,
                            test.actual_checksum,
                            audio,
                            crash=test.crash or test.web_process_crash,
                            crashed_process_name=crashed_process_name,
                            crashed_pid=crashed_pid,
                            crash_log=crash_log,
                            test_time=time.time() - start_time,
                            timeout=test.timeout,
                            error=test.error)
Example #23
0
    def test_find_log_darwin(self):
        if not SystemHost().platform.is_mac():
            return

        older_mock_crash_report = make_mock_crash_report_darwin('DumpRenderTree', 28528)
        mock_crash_report = make_mock_crash_report_darwin('DumpRenderTree', 28530)
        newer_mock_crash_report = make_mock_crash_report_darwin('DumpRenderTree', 28529)
        other_process_mock_crash_report = make_mock_crash_report_darwin('FooProcess', 28527)
        misformatted_mock_crash_report = 'Junk that should not appear in a crash report' + make_mock_crash_report_darwin('DumpRenderTree', 28526)[200:]
        files = {}
        files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150718_quadzen.crash'] = older_mock_crash_report
        files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150719_quadzen.crash'] = mock_crash_report
        files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150720_quadzen.crash'] = newer_mock_crash_report
        files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150721_quadzen.crash'] = None
        files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150722_quadzen.crash'] = other_process_mock_crash_report
        files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150723_quadzen.crash'] = misformatted_mock_crash_report
        filesystem = MockFileSystem(files)
        crash_logs = CrashLogs(MockSystemHost(filesystem=filesystem))
        log = crash_logs.find_newest_log("DumpRenderTree")
        self.assertLinesEqual(log, newer_mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28529)
        self.assertLinesEqual(log, newer_mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28530)
        self.assertLinesEqual(log, mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28531)
        self.assertEqual(log, None)
        log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0)
        self.assertEqual(log, None)

        def bad_read(path):
            raise IOError('No such file or directory')

        filesystem.read_text_file = bad_read
        log = crash_logs.find_newest_log("DumpRenderTree", 28531, include_errors=True)
        self.assertTrue('No such file or directory' in log)
Example #24
0
    def test_find_log_darwin(self):
        if not SystemHost().platform.is_mac():
            return

        older_mock_crash_report = make_mock_crash_report_darwin("DumpRenderTree", 28528)
        mock_crash_report = make_mock_crash_report_darwin("DumpRenderTree", 28530)
        newer_mock_crash_report = make_mock_crash_report_darwin("DumpRenderTree", 28529)
        other_process_mock_crash_report = make_mock_crash_report_darwin("FooProcess", 28527)
        misformatted_mock_crash_report = (
            "Junk that should not appear in a crash report"
            + make_mock_crash_report_darwin("DumpRenderTree", 28526)[200:]
        )
        files = {
            "/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150718_quadzen.crash": older_mock_crash_report,
            "/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150719_quadzen.crash": mock_crash_report,
            "/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150720_quadzen.crash": newer_mock_crash_report,
            "/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150721_quadzen.crash": None,
            "/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150722_quadzen.crash": other_process_mock_crash_report,
            "/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150723_quadzen.crash": misformatted_mock_crash_report,
        }
        filesystem = MockFileSystem(files)
        crash_logs = CrashLogs(MockSystemHost(filesystem=filesystem))
        log = crash_logs.find_newest_log("DumpRenderTree")
        self.assertMultiLineEqual(log, newer_mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28529)
        self.assertMultiLineEqual(log, newer_mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28530)
        self.assertMultiLineEqual(log, mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28531)
        self.assertIsNone(log)
        log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0)
        self.assertIsNone(log)

        def bad_read(path):
            raise IOError("IOError: No such file or directory")

        def bad_mtime(path):
            raise OSError("OSError: No such file or directory")

        filesystem.read_text_file = bad_read
        log = crash_logs.find_newest_log("DumpRenderTree", 28531, include_errors=True)
        self.assertIn("IOError: No such file or directory", log)

        filesystem = MockFileSystem(files)
        crash_logs = CrashLogs(MockSystemHost(filesystem=filesystem))
        filesystem.mtime = bad_mtime
        log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0, include_errors=True)
        self.assertIn("OSError: No such file or directory", log)
Example #25
0
 def _get_crash_log(self, name, pid, stdout, stderr):
     # Note that we do slow-spin here and wait, since it appears the time
     # ReportCrash takes to actually write and flush the file varies when there are
     # lots of simultaneous crashes going on.
     # FIXME: Should most of this be moved into CrashLogs()?
     crash_log = ''
     crash_logs = CrashLogs(self._filesystem)
     now = time.time()
     # FIXME: delete this after we're sure this code is working ...
     _log.debug('looking for crash log for %s:%s' % (name, str(pid)))
     deadline = now + 5 * int(self.get_option('child_processes'))
     while not crash_log and now <= deadline:
         crash_log = crash_logs.find_newest_log(name, pid, include_errors=True)
         if not crash_log or not [line for line in crash_log.splitlines() if not line.startswith('ERROR')]:
             time.sleep(0.1)
             now = time.time()
     if not crash_log:
         crash_log = 'no crash log found for %s:%d' % (name, pid)
         _log.warning(crash_log)
     return crash_log
Example #26
0
 def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None):
     # Note that we do slow-spin here and wait, since it appears the time
     # ReportCrash takes to actually write and flush the file varies when there are
     # lots of simultaneous crashes going on.
     # FIXME: Should most of this be moved into CrashLogs()?
     time_fn = time_fn or time.time
     sleep_fn = sleep_fn or time.sleep
     crash_log = ""
     crash_logs = CrashLogs(self.host)
     now = time_fn()
     # FIXME: delete this after we're sure this code is working ...
     _log.debug("looking for crash log for %s:%s" % (name, str(pid)))
     deadline = now + 5 * int(self.get_option("child_processes", 1))
     while not crash_log and now <= deadline:
         crash_log = crash_logs.find_newest_log(name, pid, include_errors=True, newer_than=newer_than)
         if not crash_log or not [line for line in crash_log.splitlines() if not line.startswith("ERROR")]:
             sleep_fn(0.1)
             now = time_fn()
     if not crash_log:
         crash_log = "no crash log found for %s:%d" % (name, pid)
         _log.warning(crash_log)
     return crash_log
Example #27
0
    def test_find_log_darwin(self):
        if not SystemHost().platform.is_mac():
            return

        older_mock_crash_report = make_mock_crash_report_darwin(
            'DumpRenderTree', 28528)
        mock_crash_report = make_mock_crash_report_darwin(
            'DumpRenderTree', 28530)
        newer_mock_crash_report = make_mock_crash_report_darwin(
            'DumpRenderTree', 28529)
        other_process_mock_crash_report = make_mock_crash_report_darwin(
            'FooProcess', 28527)
        misformatted_mock_crash_report = 'Junk that should not appear in a crash report' + make_mock_crash_report_darwin(
            'DumpRenderTree', 28526)[200:]
        files = {}
        files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150718_quadzen.crash'] = older_mock_crash_report
        files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150719_quadzen.crash'] = mock_crash_report
        files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150720_quadzen.crash'] = newer_mock_crash_report
        files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150721_quadzen.crash'] = None
        files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150722_quadzen.crash'] = other_process_mock_crash_report
        files[
            '/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150723_quadzen.crash'] = misformatted_mock_crash_report
        filesystem = MockFileSystem(files)
        crash_logs = CrashLogs(MockSystemHost(filesystem=filesystem))
        log = crash_logs.find_newest_log("DumpRenderTree")
        self.assertLinesEqual(log, newer_mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28529)
        self.assertLinesEqual(log, newer_mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28530)
        self.assertLinesEqual(log, mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28531)
        self.assertEqual(log, None)
        log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0)
        self.assertEqual(log, None)

        def bad_read(path):
            raise IOError('No such file or directory')

        filesystem.read_text_file = bad_read
        log = crash_logs.find_newest_log("DumpRenderTree",
                                         28531,
                                         include_errors=True)
        self.assertTrue('No such file or directory' in log)
Example #28
0
    def run_test(self, test_input):
        start_time = time.time()
        test_name = test_input.test_name
        test_args = test_input.args or []
        test = self._port._tests[test_name]
        if test.keyboard:
            raise KeyboardInterrupt
        if test.exception:
            raise ValueError('exception from ' + test_name)
        if test.hang:
            time.sleep((float(test_input.timeout) * 4) / 1000.0)

        audio = None
        actual_text = test.actual_text
        if actual_text and test_args and test_name == 'passes/args.html':
            actual_text = actual_text + ' ' + ' '.join(test_args)

        if test.actual_audio:
            audio = base64.b64decode(test.actual_audio)
        crashed_process_name = None
        crashed_pid = None
        if test.crash:
            crashed_process_name = self._port.driver_name()
            crashed_pid = 1
        elif test.web_process_crash:
            crashed_process_name = 'WebProcess'
            crashed_pid = 2

        crash_log = ''
        if crashed_process_name:
            crash_logs = CrashLogs(self._port._filesystem)
            crash_log = crash_logs.find_newest_log(crashed_process_name, None) or ''

        return DriverOutput(actual_text, test.actual_image, test.actual_checksum, audio,
            crash=test.crash or test.web_process_crash, crashed_process_name=crashed_process_name,
            crashed_pid=crashed_pid, crash_log=crash_log,
            test_time=time.time() - start_time, timeout=test.timeout, error=test.error)
Example #29
0
    def test_find_log_win(self):
        if not SystemHost().platform.is_win():
            return

        older_mock_crash_report = make_mock_crash_report_win(
            'DumpRenderTree', 28528)
        mock_crash_report = make_mock_crash_report_win('DumpRenderTree', 28530)
        newer_mock_crash_report = make_mock_crash_report_win(
            'DumpRenderTree', 28529)
        other_process_mock_crash_report = make_mock_crash_report_win(
            'FooProcess', 28527)
        misformatted_mock_crash_report = 'Junk that should not appear in a crash report' + make_mock_crash_report_win(
            'DumpRenderTree', 28526)[200:]
        files = {}
        files[
            '~/CrashLog_1d58_2013-06-03_12-21-20-110.txt'] = older_mock_crash_report
        files[
            '~/CrashLog_abcd_2013-06-03_12-22-19-129.txt'] = mock_crash_report
        files[
            '~/CrashLog_2eff_2013-06-03_12-23-20-150.txt'] = newer_mock_crash_report
        files['~/CrashLog_31a0_2013-06-03_12-24-22-119.txt'] = None
        files[
            '~/CrashLog_01a3_2013-06-03_12-25-23-120.txt'] = other_process_mock_crash_report
        files[
            '~/CrashLog_aadd_2013-06-03_12-26-24-121.txt'] = misformatted_mock_crash_report
        filesystem = MockFileSystem(files)
        mock_host = MockSystemHost(os_name='win', filesystem=filesystem)
        crash_logs = CrashLogs(mock_host, "~")

        log = crash_logs.find_newest_log("DumpRenderTree", 28529)
        self.assertMultiLineEqual(log, newer_mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28530)
        self.assertMultiLineEqual(log, mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28531)
        self.assertIsNone(log)
        log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0)
        self.assertIsNone(log)

        def bad_read(path):
            raise IOError('IOError: No such file or directory')

        filesystem.read_text_file = bad_read
        filesystem.read_binary_file = bad_read
        log = crash_logs.find_newest_log("DumpRenderTree",
                                         28531,
                                         include_errors=True)
        self.assertIn('IOError: No such file or directory', log)
    def test_find_log_win(self):
        if not SystemHost().platform.is_win():
            return

        older_mock_crash_report = make_mock_crash_report_win('DumpRenderTree', 28528)
        mock_crash_report = make_mock_crash_report_win('DumpRenderTree', 28530)
        newer_mock_crash_report = make_mock_crash_report_win('DumpRenderTree', 28529)
        other_process_mock_crash_report = make_mock_crash_report_win('FooProcess', 28527)
        misformatted_mock_crash_report = 'Junk that should not appear in a crash report' + make_mock_crash_report_win('DumpRenderTree', 28526)[200:]
        files = {}
        files['~/CrashLog_1d58_2013-06-03_12-21-20-110.txt'] = older_mock_crash_report
        files['~/CrashLog_abcd_2013-06-03_12-22-19-129.txt'] = mock_crash_report
        files['~/CrashLog_2eff_2013-06-03_12-23-20-150.txt'] = newer_mock_crash_report
        files['~/CrashLog_31a0_2013-06-03_12-24-22-119.txt'] = None
        files['~/CrashLog_01a3_2013-06-03_12-25-23-120.txt'] = other_process_mock_crash_report
        files['~/CrashLog_aadd_2013-06-03_12-26-24-121.txt'] = misformatted_mock_crash_report
        filesystem = MockFileSystem(files)
        mock_host = MockSystemHost(os_name='win', filesystem=filesystem)
        crash_logs = CrashLogs(mock_host, "~")

        log = crash_logs.find_newest_log("DumpRenderTree", 28529)
        self.assertMultiLineEqual(log, newer_mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28530)
        self.assertMultiLineEqual(log, mock_crash_report)
        log = crash_logs.find_newest_log("DumpRenderTree", 28531)
        self.assertIsNone(log)
        log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0)
        self.assertIsNone(log)

        def bad_read(path):
            raise IOError('IOError: No such file or directory')

        filesystem.read_text_file = bad_read
        filesystem.read_binary_file = bad_read
        log = crash_logs.find_newest_log("DumpRenderTree", 28531, include_errors=True)
        self.assertIn('IOError: No such file or directory', log)
Example #31
0
 def _look_for_all_crash_logs_in_log_dir(self, newer_than):
     crash_log = CrashLogs(self.host)
     return crash_log.find_all_logs(include_errors=True, newer_than=newer_than)
Example #32
0
 def execute(self, options, args, tool):
     crash_logs = CrashLogs(tool)
     pid = None
     if len(args) > 1:
         pid = int(args[1])
     print crash_logs.find_newest_log(args[0], pid)
Example #33
0
 def execute(self, options, args, tool):
     crash_logs = CrashLogs(tool)
     pid = None
     if len(args) > 1:
         pid = int(args[1])
     print crash_logs.find_newest_log(args[0], pid)
Example #34
0
 def execute(self, options, args, tool):
     crash_logs = CrashLogs(tool.filesystem)
     print crash_logs.find_newest_log(args[0])
Example #35
0
 def execute(self, options, args, tool):
     crash_logs = CrashLogs(tool.filesystem)
     print crash_logs.find_newest_log(args[0])
Example #36
0
    def run_test(self, driver_input, stop_when_done):
        base = self._port.lookup_virtual_test_base(driver_input.test_name)
        if base:
            virtual_driver_input = copy.copy(driver_input)
            virtual_driver_input.test_name = base
            virtual_driver_input.args = self._port.lookup_virtual_test_args(driver_input.test_name)
            return self.run_test(virtual_driver_input, stop_when_done)

        if not self.started:
            self.started = True
            self.pid = TestDriver.next_pid
            TestDriver.next_pid += 1

        start_time = time.time()
        test_name = driver_input.test_name
        test_args = driver_input.args or []
        test = self._port._tests[test_name]
        if test.keyboard:
            raise KeyboardInterrupt
        if test.exception:
            raise ValueError("exception from " + test_name)
        if test.hang:
            time.sleep(
                (float(driver_input.timeout) * 4) / 1000.0 + 1.0
            )  # The 1.0 comes from thread_padding_sec in layout_test_runnery.

        audio = None
        actual_text = test.actual_text

        if "flaky" in test_name and not test_name in self._port._flakes:
            self._port._flakes.add(test_name)
            actual_text = "flaky text failure"

        if actual_text and test_args and test_name == "passes/args.html":
            actual_text = actual_text + " " + " ".join(test_args)

        if test.actual_audio:
            audio = base64.b64decode(test.actual_audio)
        crashed_process_name = None
        crashed_pid = None
        if test.crash:
            crashed_process_name = self._port.driver_name()
            crashed_pid = 1
        elif test.web_process_crash:
            crashed_process_name = "WebProcess"
            crashed_pid = 2

        crash_log = ""
        if crashed_process_name:
            crash_logs = CrashLogs(self._port.host)
            crash_log = crash_logs.find_newest_log(crashed_process_name, None) or ""

        if stop_when_done:
            self.stop()

        if test.actual_checksum == driver_input.image_hash:
            image = None
        else:
            image = test.actual_image
        return DriverOutput(
            actual_text,
            image,
            test.actual_checksum,
            audio,
            crash=test.crash or test.web_process_crash,
            crashed_process_name=crashed_process_name,
            crashed_pid=crashed_pid,
            crash_log=crash_log,
            test_time=time.time() - start_time,
            timeout=test.timeout,
            error=test.error,
            pid=self.pid,
        )
Example #37
0
    def run_test(self, driver_input, stop_when_done):
        if not self.started:
            self.started = True
            self.pid = TestDriver.next_pid
            TestDriver.next_pid += 1

        start_time = time.time()
        test_name = driver_input.test_name
        test_args = driver_input.args or []
        test = self._port._tests[test_name]
        if test.keyboard:
            raise KeyboardInterrupt
        if test.exception:
            raise ValueError('exception from ' + test_name)
        if test.device_failure:
            raise DeviceFailure('device failure in ' + test_name)

        audio = None
        actual_text = test.actual_text
        crash = test.crash
        web_process_crash = test.web_process_crash

        if 'flaky/text.html' in test_name and not test_name in self._port._flakes:
            self._port._flakes.add(test_name)
            actual_text = 'flaky text failure'

        if 'crash_then_text.html' in test_name:
            if test_name in self._port._flakes:
                actual_text = 'text failure'
            else:
                self._port._flakes.add(test_name)
                crashed_process_name = self._port.driver_name()
                crashed_pid = 1
                crash = True

        if 'text_then_crash.html' in test_name:
            if test_name in self._port._flakes:
                crashed_process_name = self._port.driver_name()
                crashed_pid = 1
                crash = True
            else:
                self._port._flakes.add(test_name)
                actual_text = 'text failure'

        if actual_text and test_args and test_name == 'passes/args.html':
            actual_text = actual_text + ' ' + ' '.join(test_args)

        if test.actual_audio:
            audio = base64.b64decode(test.actual_audio)
        crashed_process_name = None
        crashed_pid = None
        if crash:
            crashed_process_name = self._port.driver_name()
            crashed_pid = 1
        elif web_process_crash:
            crashed_process_name = 'WebProcess'
            crashed_pid = 2

        crash_log = ''
        if crashed_process_name:
            crash_logs = CrashLogs(self._port.host)
            crash_log = crash_logs.find_newest_log(crashed_process_name, None) or ''

        if 'crash-reftest.html' in test_name:
            crashed_process_name = self._port.driver_name()
            crashed_pid = 3
            crash = True
            crash_log = 'reftest crash log'

        if stop_when_done:
            self.stop()

        if test.actual_checksum == driver_input.image_hash:
            image = None
        else:
            image = test.actual_image
        return DriverOutput(actual_text, image, test.actual_checksum, audio,
            crash=(crash or web_process_crash), crashed_process_name=crashed_process_name,
            crashed_pid=crashed_pid, crash_log=crash_log,
            test_time=time.time() - start_time, timeout=test.timeout, error=test.error, pid=self.pid,
            leak=test.leak)
Example #38
0
File: test.py Project: ezaca/blink
    def run_test(self, driver_input, stop_when_done):
        if not self.started:
            self.started = True
            self.pid = TestDriver.next_pid
            TestDriver.next_pid += 1

        start_time = time.time()
        test_name = driver_input.test_name
        test_args = driver_input.args or []
        test = self._port._tests[test_name]
        if test.keyboard:
            raise KeyboardInterrupt
        if test.exception:
            raise ValueError('exception from ' + test_name)
        if test.device_failure:
            raise DeviceFailure('device failure in ' + test_name)

        audio = None
        actual_text = test.actual_text
        crash = test.crash
        web_process_crash = test.web_process_crash

        if 'flaky/text.html' in test_name and not test_name in self._port._flakes:
            self._port._flakes.add(test_name)
            actual_text = 'flaky text failure'

        if 'crash_then_text.html' in test_name:
            if test_name in self._port._flakes:
                actual_text = 'text failure'
            else:
                self._port._flakes.add(test_name)
                crashed_process_name = self._port.driver_name()
                crashed_pid = 1
                crash = True

        if 'text_then_crash.html' in test_name:
            if test_name in self._port._flakes:
                crashed_process_name = self._port.driver_name()
                crashed_pid = 1
                crash = True
            else:
                self._port._flakes.add(test_name)
                actual_text = 'text failure'

        if actual_text and test_args and test_name == 'passes/args.html':
            actual_text = actual_text + ' ' + ' '.join(test_args)

        if test.actual_audio:
            audio = base64.b64decode(test.actual_audio)
        crashed_process_name = None
        crashed_pid = None
        if crash:
            crashed_process_name = self._port.driver_name()
            crashed_pid = 1
        elif web_process_crash:
            crashed_process_name = 'WebProcess'
            crashed_pid = 2

        crash_log = ''
        if crashed_process_name:
            crash_logs = CrashLogs(self._port.host)
            crash_log = crash_logs.find_newest_log(crashed_process_name,
                                                   None) or ''

        if stop_when_done:
            self.stop()

        if test.actual_checksum == driver_input.image_hash:
            image = None
        else:
            image = test.actual_image
        return DriverOutput(actual_text,
                            image,
                            test.actual_checksum,
                            audio,
                            crash=(crash or web_process_crash),
                            crashed_process_name=crashed_process_name,
                            crashed_pid=crashed_pid,
                            crash_log=crash_log,
                            test_time=time.time() - start_time,
                            timeout=test.timeout,
                            error=test.error,
                            pid=self.pid,
                            leak=test.leak)