Diff
Modified: trunk/Tools/ChangeLog (119016 => 119017)
--- trunk/Tools/ChangeLog 2012-05-31 01:38:17 UTC (rev 119016)
+++ trunk/Tools/ChangeLog 2012-05-31 01:51:26 UTC (rev 119017)
@@ -1,3 +1,25 @@
+2012-05-30 Stephanie Lewis <[email protected]>
+
+ https://bugs.webkit.org/show_bug.cgi?id=87714
+ Mac crash logs can take a really long time to be written out.
+
+ Reviewed by Dirk Pranke.
+
+ Make a second pass looking for crash logs after the tests have completed running.
+
+ * Scripts/webkitpy/layout_tests/controllers/manager.py:
+ (use_trac_links_in_results_html):
+ (Manager.run):
+ * Scripts/webkitpy/layout_tests/port/base.py:
+ (Port.repository_paths):
+ (Port.look_for_new_crash_logs):
+ * Scripts/webkitpy/layout_tests/port/mac.py:
+ (MacPort.look_for_new_crash_logs):
+ * Scripts/webkitpy/layout_tests/port/mac_unittest.py:
+ (test_get_crash_log):
+ (test_look_for_new_crash_logs):
+ (test_look_for_new_crash_logs.fake_time_cb):
+
2012-05-30 Kevin Ollivier <[email protected]>
[wx] Fix 2.9 issues with c_str() type by using the wx fprintf wrapper.
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py (119016 => 119017)
--- trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py 2012-05-31 01:38:17 UTC (rev 119016)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py 2012-05-31 01:51:26 UTC (rev 119017)
@@ -46,6 +46,7 @@
from webkitpy.layout_tests.controllers import manager_worker_broker
from webkitpy.layout_tests.controllers import worker
+from webkitpy.layout_tests.controllers.test_result_writer import TestResultWriter
from webkitpy.layout_tests.layout_package import json_layout_results_generator
from webkitpy.layout_tests.layout_package import json_results_generator
from webkitpy.layout_tests.models import test_expectations
@@ -106,6 +107,7 @@
# Use existence of builder_name as a proxy for knowing we're on a bot.
return port_obj.get_option("builder_name")
+
# FIXME: This should be on the Manager class (since that's the only caller)
# or split off from Manager onto another helper class, but should not be a free function.
# Most likely this should be made into its own class, and this super-long function
@@ -909,6 +911,10 @@
end_time = time.time()
+ # Some crash logs can take a long time to be written out so look
+ # for new logs after the test run finishes.
+ self._look_for_new_crash_logs(result_summary, start_time)
+ self._look_for_new_crash_logs(retry_summary, start_time)
self._clean_up_run()
self._print_timing_statistics(end_time - start_time, thread_timings, test_timings, individual_test_timings, result_summary)
@@ -970,6 +976,29 @@
_log.debug("cleaning up port")
self._port.clean_up_test_run()
+ def _look_for_new_crash_logs(self, result_summary, start_time):
+ """Since crash logs can take a long time to be written out if the system is
+ under stress do a second pass at the end of the test run.
+
+ result_summary: the results of the test run
+ start_time: time the tests started at. We're looking for crash
+ logs after that time.
+ """
+ crashed_processes = []
+ for test, result in result_summary.unexpected_results.iteritems():
+ if (result.type != test_expectations.CRASH):
+ continue
+ for failure in result.failures:
+ if not isinstance(failure, test_failures.FailureCrash):
+ continue
+ crashed_processes.append([test, failure.process_name, failure.pid])
+
+ crash_logs = self._port.look_for_new_crash_logs(crashed_processes, start_time)
+ if crash_logs:
+ for test, crash_log in crash_logs.iteritems():
+ writer = TestResultWriter(self._port._filesystem, self._port, self._port.results_directory(), test)
+ writer.write_crash_log(crash_log)
+
def update_summary(self, result_summary):
"""Update the summary and print results with any completed tests."""
while True:
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py (119016 => 119017)
--- trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py 2012-05-31 01:38:17 UTC (rev 119016)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager_unittest.py 2012-05-31 01:51:26 UTC (rev 119017)
@@ -32,6 +32,7 @@
import StringIO
import sys
+import time
import unittest
from webkitpy.common.system.filesystem_mock import MockFileSystem
@@ -326,7 +327,22 @@
manager = get_manager_with_tests(['http\\tests\\mime'])
self.assertTrue(manager.needs_servers())
+ def test_look_for_new_crash_logs(self):
+ def get_manager_with_tests(test_names):
+ host = MockHost()
+ port = host.port_factory.get('test-mac-leopard')
+ manager = Manager(port, options=MockOptions(test_list=None, http=True), printer=Mock())
+ manager.collect_tests(test_names)
+ return manager
+ host = MockHost()
+ port = host.port_factory.get('test-mac-leopard')
+ tests = ['failures/expected/crash.html']
+ expectations = test_expectations.TestExpectations(port, tests)
+ rs = result_summary.ResultSummary(expectations, tests)
+ manager = get_manager_with_tests(tests)
+ manager._look_for_new_crash_logs(rs, time.time())
+
class NaturalCompareTest(unittest.TestCase):
def assert_cmp(self, x, y, result):
self.assertEquals(cmp(natural_sort_key(x), natural_sort_key(y)), result)
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/base.py (119016 => 119017)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/base.py 2012-05-31 01:38:17 UTC (rev 119016)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/base.py 2012-05-31 01:51:26 UTC (rev 119017)
@@ -907,7 +907,6 @@
# where turnk isn't checked out as a whole.
return [('webkit', self.layout_tests_dir())]
-
_WDIFF_DEL = '##WDIFF_DEL##'
_WDIFF_ADD = '##WDIFF_ADD##'
_WDIFF_END = '##WDIFF_END##'
@@ -1085,6 +1084,9 @@
'\n'.join(('STDOUT: ' + l) for l in stdout_lines),
'\n'.join(('STDERR: ' + l) for l in stderr_lines))
+ def look_for_new_crash_logs(self, crashed_processes, start_time):
+ pass
+
def sample_process(self, name, pid):
pass
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/mac.py (119016 => 119017)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/mac.py 2012-05-31 01:38:17 UTC (rev 119016)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/mac.py 2012-05-31 01:51:26 UTC (rev 119017)
@@ -41,6 +41,7 @@
_log = logging.getLogger(__name__)
+
class MacPort(ApplePort):
port_name = "mac"
@@ -177,7 +178,7 @@
def release_http_lock(self):
pass
- def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None):
+ 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.
@@ -192,14 +193,34 @@
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:
- crash_log = 'no crash log found for %s:%d' % (name, pid)
- _log.warning(crash_log)
+ return None
return crash_log
+ def look_for_new_crash_logs(self, crashed_processes, start_time):
+ """Since crash logs can take a long time to be written out if the system is
+ under stress do a second pass at the end of the test run.
+
+ crashes: test_name -> pid, process_name tuple of crashed process
+ start_time: time the tests started at. We're looking for crash
+ logs after that time.
+ """
+ crash_logs = {}
+ for (test_name, process_name, pid) in crashed_processes:
+ # Passing None for output. This is a second pass after the test finished so
+ # if the output had any loggine we would have already collected it.
+ crash_log = self._get_crash_log(process_name, pid, None, None, start_time, wait_for_log=False)
+ if not crash_log:
+ continue
+ crash_logs[test_name] = crash_log
+ return crash_logs
+
def sample_process(self, name, pid):
try:
hang_report = self._filesystem.join(self.results_directory(), "%s-%s.sample.txt" % (name, pid))
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit.py (119016 => 119017)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit.py 2012-05-31 01:38:17 UTC (rev 119016)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit.py 2012-05-31 01:51:26 UTC (rev 119017)
@@ -573,11 +573,15 @@
# FIXME: We may need to also read stderr until the process dies?
self.error_from_test += self._server_process.pop_all_buffered_stderr()
- crash_log = ''
+ crash_log = None
if self.has_crashed():
crash_log = self._port._get_crash_log(self._crashed_process_name, self._crashed_pid, text, self.error_from_test,
newer_than=start_time)
+ # If we don't find a crash log use a placeholder error message instead.
+ if not crash_log:
+ crash_log = 'no crash log found for %s:%d.' % (self._crashed_process_name, self._crashed_pid)
+
timeout = self._server_process.timed_out
if timeout:
# DRT doesn't have a built in timer to abort the test, so we might as well