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)
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)
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
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)
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)
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)
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)
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
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)
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)
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
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)
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)
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
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)
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, )
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
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)
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
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
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)
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)
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)
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
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
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)
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)
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)
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)
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)
def execute(self, options, args, tool): crash_logs = CrashLogs(tool.filesystem) print crash_logs.find_newest_log(args[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, )
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)
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)