<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[191374] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/191374">191374</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-10-20 22:36:49 -0700 (Tue, 20 Oct 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>run-webkit-tests does not copy all crash logs for layout test failures on iOS
https://bugs.webkit.org/show_bug.cgi?id=150056
Tools:

&lt;rdar://problem/9280656&gt;

Patch by Aakash Jain &lt;aakash_jain@apple.com&gt; on 2015-10-20
Reviewed by Alexey Proskuryakov.

* Scripts/webkitpy/common/system/crashlogs.py:
(CrashLogs.find_all_logs): Generic method to find all crash logs.
(CrashLogs._find_all_logs_darwin): Darwin based method to find all crash logs.
It iterates through log directory and returns all the logs based on timestamp.
* Scripts/webkitpy/common/system/crashlogs_unittest.py:
(CrashLogsTest.create_crash_logs_darwin): Creates sample crash logs and verify them.
(CrashLogsTest.test_find_all_log_darwin): Testcase for above find_all_logs method
(CrashLogsTest.test_find_log_darwin): Restructured to share code with other methods.
* Scripts/webkitpy/layout_tests/controllers/manager.py:
(Manager.run): Modified start_time to start counting before simulator launch
so that we can capture crashes during simualator launch.
(Manager._look_for_new_crash_logs): Browse through list of crashes and append
any test which is not already marked as CRASH to the run_results.
* Scripts/webkitpy/layout_tests/models/test_expectations.py:
(TestExpectationsModel.get_expectations_string): return PASS in case there
are no expectations defined for this test.
* Scripts/webkitpy/layout_tests/models/test_run_results.py:
(summarize_results): Add other_crashes in a separte category in full_results.json.
* Scripts/webkitpy/port/ios.py:
(IOSSimulatorPort._merge_crash_logs): Merge unique crash logs from two dictionaries.
(IOSSimulatorPort._look_for_all_crash_logs_in_log_dir): Get the crash logs
from the log directory.
(IOSSimulatorPort.look_for_new_crash_logs): Uses above method to get crash
logs from log directory and merge them with the list of already crashed tests.

LayoutTests:

&lt;rdar://problem/22239750&gt;

Patch by Aakash Jain &lt;aakash_jain@apple.com&gt; on 2015-10-20
Reviewed by Alexey Proskuryakov.

* fast/harness/results.html: Added the column for Other crashes, this contain
all the newly find crashes from the crash-log directory. Added method forOtherCrashes
which processes othre_crashes section from full_results.json. Also fixed the method
splitExtension to handle the case when there is no extension.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastharnessresultshtml">trunk/LayoutTests/fast/harness/results.html</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptswebkitpycommonsystemcrashlogspy">trunk/Tools/Scripts/webkitpy/common/system/crashlogs.py</a></li>
<li><a href="#trunkToolsScriptswebkitpycommonsystemcrashlogs_unittestpy">trunk/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpylayout_testscontrollersmanagerpy">trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py</a></li>
<li><a href="#trunkToolsScriptswebkitpylayout_testsmodelstest_expectationspy">trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py</a></li>
<li><a href="#trunkToolsScriptswebkitpylayout_testsmodelstest_resultspy">trunk/Tools/Scripts/webkitpy/layout_tests/models/test_results.py</a></li>
<li><a href="#trunkToolsScriptswebkitpylayout_testsmodelstest_run_resultspy">trunk/Tools/Scripts/webkitpy/layout_tests/models/test_run_results.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportiospy">trunk/Tools/Scripts/webkitpy/port/ios.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (191373 => 191374)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-10-21 05:09:17 UTC (rev 191373)
+++ trunk/LayoutTests/ChangeLog        2015-10-21 05:36:49 UTC (rev 191374)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2015-10-20  Aakash Jain  &lt;aakash_jain@apple.com&gt;
+
+        run-webkit-tests does not copy all crash logs for layout test failures on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=150056
+        &lt;rdar://problem/22239750&gt;
+
+        Reviewed by Alexey Proskuryakov.
+
+        * fast/harness/results.html: Added the column for Other crashes, this contain
+        all the newly find crashes from the crash-log directory. Added method forOtherCrashes 
+        which processes othre_crashes section from full_results.json. Also fixed the method
+        splitExtension to handle the case when there is no extension.
+
</ins><span class="cx"> 2015-10-20  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         YarrPatternConstructor::containsCapturingTerms() should not assume that its terms.size() is greater than 0.
</span></span></pre></div>
<a id="trunkLayoutTestsfastharnessresultshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/harness/results.html (191373 => 191374)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/harness/results.html        2015-10-21 05:09:17 UTC (rev 191373)
+++ trunk/LayoutTests/fast/harness/results.html        2015-10-21 05:36:49 UTC (rev 191374)
</span><span class="lines">@@ -235,6 +235,7 @@
</span><span class="cx">     if (!g_state) {
</span><span class="cx">         g_state = {
</span><span class="cx">             crashTests: [],
</span><ins>+            crashOther: [],
</ins><span class="cx">             flakyPassTests: [],
</span><span class="cx">             hasHttpTests: false,
</span><span class="cx">             hasImageFailures: false,
</span><span class="lines">@@ -263,6 +264,9 @@
</span><span class="cx"> function splitExtension(test)
</span><span class="cx"> {
</span><span class="cx">     var index = test.lastIndexOf('.');
</span><ins>+    if (index == -1) {
+        return [test, &quot;&quot;];
+    }
</ins><span class="cx">     return [test.substring(0, index), test.substring(index + 1)];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -704,6 +708,16 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function forOtherCrashes()
+{
+    var tree = globalState().results.other_crashes;
+    for (var key in tree) {
+            var testObject = tree[key];
+            testObject.name = key;
+            globalState().crashOther.push(testObject);
+    }
+}
+
</ins><span class="cx"> function hasUnexpected(tests)
</span><span class="cx"> {
</span><span class="cx">     return tests.some(function (test) { return !test.isExpected; });
</span><span class="lines">@@ -1361,6 +1375,7 @@
</span><span class="cx"> function generatePage()
</span><span class="cx"> {
</span><span class="cx">     forEachTest(processGlobalStateFor);
</span><ins>+    forOtherCrashes();
</ins><span class="cx"> 
</span><span class="cx">     var html = &quot;&quot;;
</span><span class="cx"> 
</span><span class="lines">@@ -1370,6 +1385,9 @@
</span><span class="cx">     if (globalState().crashTests.length)
</span><span class="cx">         html += testList(globalState().crashTests, 'Tests that crashed', 'crash-tests-table');
</span><span class="cx"> 
</span><ins>+    if (globalState().crashOther.length)
+        html += testList(globalState().crashOther, 'Other Crashes', 'crash-tests-table');
+
</ins><span class="cx">     html += failingTestsTable(globalState().failingTests,
</span><span class="cx">         'Tests that failed text/pixel/audio diff', 'results-table');
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (191373 => 191374)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-10-21 05:09:17 UTC (rev 191373)
+++ trunk/Tools/ChangeLog        2015-10-21 05:36:49 UTC (rev 191374)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2015-10-20  Aakash Jain  &lt;aakash_jain@apple.com&gt;
+
+        run-webkit-tests does not copy all crash logs for layout test failures on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=150056
+        &lt;rdar://problem/9280656&gt;
+
+        Reviewed by Alexey Proskuryakov.
+
+        * Scripts/webkitpy/common/system/crashlogs.py:
+        (CrashLogs.find_all_logs): Generic method to find all crash logs.
+        (CrashLogs._find_all_logs_darwin): Darwin based method to find all crash logs.
+        It iterates through log directory and returns all the logs based on timestamp.
+        * Scripts/webkitpy/common/system/crashlogs_unittest.py:
+        (CrashLogsTest.create_crash_logs_darwin): Creates sample crash logs and verify them.
+        (CrashLogsTest.test_find_all_log_darwin): Testcase for above find_all_logs method
+        (CrashLogsTest.test_find_log_darwin): Restructured to share code with other methods.
+        * Scripts/webkitpy/layout_tests/controllers/manager.py:
+        (Manager.run): Modified start_time to start counting before simulator launch
+        so that we can capture crashes during simualator launch.
+        (Manager._look_for_new_crash_logs): Browse through list of crashes and append
+        any test which is not already marked as CRASH to the run_results.
+        * Scripts/webkitpy/layout_tests/models/test_expectations.py:
+        (TestExpectationsModel.get_expectations_string): return PASS in case there
+        are no expectations defined for this test.
+        * Scripts/webkitpy/layout_tests/models/test_run_results.py:
+        (summarize_results): Add other_crashes in a separte category in full_results.json.
+        * Scripts/webkitpy/port/ios.py:
+        (IOSSimulatorPort._merge_crash_logs): Merge unique crash logs from two dictionaries.
+        (IOSSimulatorPort._look_for_all_crash_logs_in_log_dir): Get the crash logs
+        from the log directory.
+        (IOSSimulatorPort.look_for_new_crash_logs): Uses above method to get crash
+        logs from log directory and merge them with the list of already crashed tests.
+
</ins><span class="cx"> 2015-10-20  Dana Burkart  &lt;dburkart@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix the build
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpycommonsystemcrashlogspy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/common/system/crashlogs.py (191373 => 191374)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/common/system/crashlogs.py        2015-10-21 05:09:17 UTC (rev 191373)
+++ trunk/Tools/Scripts/webkitpy/common/system/crashlogs.py        2015-10-21 05:36:49 UTC (rev 191374)
</span><span class="lines">@@ -47,6 +47,11 @@
</span><span class="cx">             return self._find_newest_log_win(process_name, pid, include_errors, newer_than)
</span><span class="cx">         return None
</span><span class="cx"> 
</span><ins>+    def find_all_logs(self, include_errors=False, newer_than=None):
+        if self._host.platform.is_mac():
+            return self._find_all_logs_darwin(include_errors, newer_than)
+        return None
+
</ins><span class="cx">     def _log_directory_darwin(self):
</span><span class="cx">         log_directory = self._host.filesystem.expanduser(&quot;~&quot;)
</span><span class="cx">         log_directory = self._host.filesystem.join(log_directory, &quot;Library&quot;, &quot;Logs&quot;)
</span><span class="lines">@@ -118,3 +123,38 @@
</span><span class="cx">         if include_errors and errors:
</span><span class="cx">             return errors
</span><span class="cx">         return None
</span><ins>+
+    def _find_all_logs_darwin(self, include_errors, newer_than):
+        def is_crash_log(fs, dirpath, basename):
+            return basename.endswith(&quot;.crash&quot;)
+
+        log_directory = self._log_directory_darwin()
+        logs = self._host.filesystem.files_under(log_directory, file_filter=is_crash_log)
+        first_line_regex = re.compile(r'^Process:\s+(?P&lt;process_name&gt;.*) \[(?P&lt;pid&gt;\d+)\]$')
+        errors = ''
+        crash_logs = {}
+        for path in reversed(sorted(logs)):
+            try:
+                if not newer_than or self._host.filesystem.mtime(path) &gt; newer_than:
+                    result_name = &quot;Unknown&quot;
+                    pid = 0
+                    log_contents = self._host.filesystem.read_text_file(path)
+                    match = first_line_regex.match(log_contents[0:log_contents.find('\n')])
+                    if match:
+                        process_name = match.group('process_name')
+                        pid = str(match.group('pid'))
+                        result_name = process_name + &quot;-&quot; + pid
+
+                    while result_name in crash_logs:
+                        result_name = result_name + &quot;-1&quot;
+                    crash_logs[result_name] = errors + log_contents
+            except IOError, e:
+                if include_errors:
+                    errors += &quot;ERROR: Failed to read '%s': %s\n&quot; % (path, str(e))
+            except OSError, e:
+                if include_errors:
+                    errors += &quot;ERROR: Failed to read '%s': %s\n&quot; % (path, str(e))
+
+        if include_errors and errors and len(crash_logs) == 0:
+            return errors
+        return crash_logs
</ins></span></pre></div>
<a id="trunkToolsScriptswebkitpycommonsystemcrashlogs_unittestpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py (191373 => 191374)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py        2015-10-21 05:09:17 UTC (rev 191373)
+++ trunk/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py        2015-10-21 05:36:49 UTC (rev 191374)
</span><span class="lines">@@ -233,30 +233,46 @@
</span><span class="cx"> &quot;&quot;&quot;.format(process_name=process_name, pid=pid)
</span><span class="cx"> 
</span><span class="cx"> class CrashLogsTest(unittest.TestCase):
</span><del>-    def test_find_log_darwin(self):
</del><ins>+    def create_crash_logs_darwin(self):
</ins><span class="cx">         if not SystemHost().platform.is_mac():
</span><span class="cx">             return
</span><span class="cx"> 
</span><del>-        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))
</del><ins>+        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))
+        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 test_find_all_log_darwin(self):
+        crash_logs = self.create_crash_logs_darwin()
+        all_logs = crash_logs.find_all_logs()
+        self.assertEqual(len(all_logs), 5)
+
+        for test, crash_log in all_logs.iteritems():
+            self.assertTrue(crash_log in self.files.values())
+            self.assertTrue(test == &quot;Unknown&quot; or int(test.split(&quot;-&quot;)[1]) in range(28527, 28531))
+
+    def test_find_log_darwin(self):
+        crash_logs = self.create_crash_logs_darwin()
</ins><span class="cx">         log = crash_logs.find_newest_log(&quot;DumpRenderTree&quot;)
</span><del>-        self.assertMultiLineEqual(log, newer_mock_crash_report)
</del><ins>+        self.assertMultiLineEqual(log, self.newer_mock_crash_report)
</ins><span class="cx">         log = crash_logs.find_newest_log(&quot;DumpRenderTree&quot;, 28529)
</span><del>-        self.assertMultiLineEqual(log, newer_mock_crash_report)
</del><ins>+        self.assertMultiLineEqual(log, self.newer_mock_crash_report)
</ins><span class="cx">         log = crash_logs.find_newest_log(&quot;DumpRenderTree&quot;, 28530)
</span><del>-        self.assertMultiLineEqual(log, mock_crash_report)
</del><ins>+        self.assertMultiLineEqual(log, self.mock_crash_report)
</ins><span class="cx">         log = crash_logs.find_newest_log(&quot;DumpRenderTree&quot;, 28531)
</span><span class="cx">         self.assertIsNone(log)
</span><span class="cx">         log = crash_logs.find_newest_log(&quot;DumpRenderTree&quot;, newer_than=1.0)
</span><span class="lines">@@ -268,13 +284,13 @@
</span><span class="cx">         def bad_mtime(path):
</span><span class="cx">             raise OSError('OSError: No such file or directory')
</span><span class="cx"> 
</span><del>-        filesystem.read_text_file = bad_read
</del><ins>+        self.filesystem.read_text_file = bad_read
</ins><span class="cx">         log = crash_logs.find_newest_log(&quot;DumpRenderTree&quot;, 28531, include_errors=True)
</span><span class="cx">         self.assertIn('IOError: No such file or directory', log)
</span><span class="cx"> 
</span><del>-        filesystem = MockFileSystem(files)
-        crash_logs = CrashLogs(MockSystemHost(filesystem=filesystem))
-        filesystem.mtime = bad_mtime
</del><ins>+        self.filesystem = MockFileSystem(self.files)
+        crash_logs = CrashLogs(MockSystemHost(filesystem=self.filesystem))
+        self.filesystem.mtime = bad_mtime
</ins><span class="cx">         log = crash_logs.find_newest_log(&quot;DumpRenderTree&quot;, newer_than=1.0, include_errors=True)
</span><span class="cx">         self.assertIn('OSError: No such file or directory', log)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpylayout_testscontrollersmanagerpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py (191373 => 191374)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py        2015-10-21 05:09:17 UTC (rev 191373)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py        2015-10-21 05:36:49 UTC (rev 191374)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> from webkitpy.layout_tests.layout_package import json_results_generator
</span><span class="cx"> from webkitpy.layout_tests.models import test_expectations
</span><span class="cx"> from webkitpy.layout_tests.models import test_failures
</span><ins>+from webkitpy.layout_tests.models import test_results
</ins><span class="cx"> from webkitpy.layout_tests.models import test_run_results
</span><span class="cx"> from webkitpy.layout_tests.models.test_input import TestInput
</span><span class="cx"> from webkitpy.layout_tests.models.test_run_results import INTERRUPTED_EXIT_STATUS
</span><span class="lines">@@ -179,6 +180,7 @@
</span><span class="cx"> 
</span><span class="cx">         tests_to_run, tests_to_skip = self._prepare_lists(paths, test_names)
</span><span class="cx">         self._printer.print_found(len(test_names), len(tests_to_run), self._options.repeat_each, self._options.iterations)
</span><ins>+        start_time = time.time()
</ins><span class="cx"> 
</span><span class="cx">         # Check to make sure we're not skipping every test.
</span><span class="cx">         if not tests_to_run:
</span><span class="lines">@@ -188,7 +190,6 @@
</span><span class="cx">         if not self._set_up_run(tests_to_run):
</span><span class="cx">             return test_run_results.RunDetails(exit_code=-1)
</span><span class="cx"> 
</span><del>-        start_time = time.time()
</del><span class="cx">         enabled_pixel_tests_in_retry = False
</span><span class="cx">         try:
</span><span class="cx">             initial_results = self._run_tests(tests_to_run, tests_to_skip, self._options.repeat_each, self._options.iterations,
</span><span class="lines">@@ -305,6 +306,14 @@
</span><span class="cx">                 writer = TestResultWriter(self._port._filesystem, self._port, self._port.results_directory(), test)
</span><span class="cx">                 writer.write_crash_log(crash_log)
</span><span class="cx"> 
</span><ins>+                # Check if this crashing 'test' is already in list of crashed_processes, if not add it to the run_results
+                if not any(process[0] == test for process in crashed_processes):
+                    result = test_results.TestResult(test)
+                    result.type = test_expectations.CRASH
+                    result.is_other_crash = True
+                    run_results.add(result, expected=False, test_is_slow=False)
+                    _log.debug(&quot;Adding results for other crash: &quot; + str(test))
+
</ins><span class="cx">     def _clobber_old_results(self):
</span><span class="cx">         # Just clobber the actual test results directories since the other
</span><span class="cx">         # files in the results directory are explicitly used for cross-run
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpylayout_testsmodelstest_expectationspy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py (191373 => 191374)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py        2015-10-21 05:09:17 UTC (rev 191373)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py        2015-10-21 05:36:49 UTC (rev 191374)
</span><span class="lines">@@ -561,7 +561,10 @@
</span><span class="cx">     def get_expectations_string(self, test):
</span><span class="cx">         &quot;&quot;&quot;Returns the expectatons for the given test as an uppercase string.
</span><span class="cx">         If there are no expectations for the test, then &quot;PASS&quot; is returned.&quot;&quot;&quot;
</span><del>-        expectations = self.get_expectations(test)
</del><ins>+        try:
+            expectations = self.get_expectations(test)
+        except:
+            return &quot;PASS&quot;
</ins><span class="cx">         retval = []
</span><span class="cx"> 
</span><span class="cx">         for expectation in expectations:
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpylayout_testsmodelstest_resultspy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/layout_tests/models/test_results.py (191373 => 191374)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/layout_tests/models/test_results.py        2015-10-21 05:09:17 UTC (rev 191373)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/models/test_results.py        2015-10-21 05:36:49 UTC (rev 191374)
</span><span class="lines">@@ -55,6 +55,7 @@
</span><span class="cx">         self.shard_name = ''
</span><span class="cx">         self.total_run_time = 0  # The time taken to run the test plus any references, compute diffs, etc.
</span><span class="cx">         self.test_number = None
</span><ins>+        self.is_other_crash = False
</ins><span class="cx"> 
</span><span class="cx">     def __eq__(self, other):
</span><span class="cx">         return (self.test_name == other.test_name and
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpylayout_testsmodelstest_run_resultspy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/layout_tests/models/test_run_results.py (191373 => 191374)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/layout_tests/models/test_run_results.py        2015-10-21 05:09:17 UTC (rev 191373)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/models/test_run_results.py        2015-10-21 05:36:49 UTC (rev 191374)
</span><span class="lines">@@ -133,7 +133,7 @@
</span><span class="cx">         'tests': a dict of tests -&gt; {'expected': '...', 'actual': '...'}
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     results = {}
</span><del>-    results['version'] = 3
</del><ins>+    results['version'] = 4
</ins><span class="cx"> 
</span><span class="cx">     tbe = initial_results.tests_by_expectation
</span><span class="cx">     tbt = initial_results.tests_by_timeline
</span><span class="lines">@@ -152,6 +152,7 @@
</span><span class="cx">         keywords[modifier_enum] = modifier_string.upper()
</span><span class="cx"> 
</span><span class="cx">     tests = {}
</span><ins>+    other_crashes_dict = {}
</ins><span class="cx"> 
</span><span class="cx">     for test_name, result in initial_results.results_by_name.iteritems():
</span><span class="cx">         # Note that if a test crashed in the original run, we ignore
</span><span class="lines">@@ -164,6 +165,10 @@
</span><span class="cx">         if result_type == test_expectations.SKIP:
</span><span class="cx">             continue
</span><span class="cx"> 
</span><ins>+        if result.is_other_crash:
+            other_crashes_dict[test_name] = {}
+            continue
+
</ins><span class="cx">         test_dict = {}
</span><span class="cx">         if result.has_stderr:
</span><span class="cx">             test_dict['has_stderr'] = True
</span><span class="lines">@@ -256,6 +261,7 @@
</span><span class="cx">     results['layout_tests_dir'] = port_obj.layout_tests_dir()
</span><span class="cx">     results['has_pretty_patch'] = port_obj.pretty_patch.pretty_patch_available()
</span><span class="cx">     results['pixel_tests_enabled'] = port_obj.get_option('pixel_tests')
</span><ins>+    results['other_crashes'] = other_crashes_dict
</ins><span class="cx"> 
</span><span class="cx">     try:
</span><span class="cx">         # We only use the svn revision for using trac links in the results.html file,
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpyportiospy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/ios.py (191373 => 191374)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/ios.py        2015-10-21 05:09:17 UTC (rev 191373)
+++ trunk/Tools/Scripts/webkitpy/port/ios.py        2015-10-21 05:36:49 UTC (rev 191374)
</span><span class="lines">@@ -328,6 +328,22 @@
</span><span class="cx">     def testing_device(self):
</span><span class="cx">         return Simulator().lookup_or_create_device(self.simulator_device_type.name + ' WebKit Tester', self.simulator_device_type, self.simulator_runtime)
</span><span class="cx"> 
</span><ins>+    def _merge_crash_logs(self, logs, new_logs, crashed_processes):
+        for test, crash_log in new_logs.iteritems():
+            try:
+                process_name = test.split(&quot;-&quot;)[0]
+                pid = int(test.split(&quot;-&quot;)[1])
+            except IndexError:
+                continue
+            if not any(entry[1] == process_name and entry[2] == pid for entry in crashed_processes):
+                # if this is a new crash, then append the logs
+                logs[test] = crash_log
+        return logs
+
+    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)
+
</ins><span class="cx">     def look_for_new_crash_logs(self, crashed_processes, start_time):
</span><span class="cx">         crash_logs = {}
</span><span class="cx">         for (test_name, process_name, pid) in crashed_processes:
</span><span class="lines">@@ -337,7 +353,8 @@
</span><span class="cx">             if not crash_log:
</span><span class="cx">                 continue
</span><span class="cx">             crash_logs[test_name] = crash_log
</span><del>-        return crash_logs
</del><ins>+        all_crash_log = self._look_for_all_crash_logs_in_log_dir(start_time)
+        return self._merge_crash_logs(crash_logs, all_crash_log, crashed_processes)
</ins><span class="cx"> 
</span><span class="cx">     def look_for_new_samples(self, unresponsive_processes, start_time):
</span><span class="cx">         sample_files = {}
</span></span></pre>
</div>
</div>

</body>
</html>