<!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>[213306] trunk/Tools</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/213306">213306</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2017-03-02 14:46:01 -0800 (Thu, 02 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Refactor test results classes in webkitpy to enable faster EWS iteration
https://bugs.webkit.org/show_bug.cgi?id=169053

Patch by Srinivasan Vijayaraghavan &lt;svijayaraghavan@apple.com&gt; on 2017-03-02
Reviewed by Alexey Proskuryakov.

* Scripts/webkitpy/common/net/abstracttestresults.py:
(AbstractTestResults): Import json for parse_json_string().
(AbstractTestResults.parse_json_string): Abstracted out from JSCTestResults.results_from_string().
* Scripts/webkitpy/common/net/abstracttestresults_unittest.py: Added.
(AbstractTestResultsTest): Class that tests AbstractTestResults.
(AbstractTestResultsTest.test_parse_json_string_invalid_inputs): Move unit tests from JSCTestResultsTest.
(AbstractTestResultsTest.test_parse_json_string_valid_input): Add a unit test for a success case.
* Scripts/webkitpy/common/net/jsctestresults.py:
(JSCTestResults.results_from_string): Call parse_json_string because it was abstracted out.
* Scripts/webkitpy/common/net/jsctestresults_unittest.py:
(JSCTestResultsTest.test_results_from_string): Remove JSON parsing unit tests, because they were moved.
* Scripts/webkitpy/tool/bot/abstracttestresultsreader.py: Added.
(AbstractTestResultsReader): Generic TestResultsReader with functions common to jsc, bindings etc.
(AbstractTestResultsReader.__init__): Moved from JSCTestResultsReader.__init__().
(AbstractTestResultsReader._read_file_contents): Moved from JSCTestResultsReader._read_file_contents().
(AbstractTestResultsReader.results): Stub.
* Scripts/webkitpy/tool/bot/jsctestresultsreader.py:
(JSCTestResultsReader): Now inherits from AbstractTestResultsReader.
(JSCTestResultsReader.__init__): Deleted.
(JSCTestResultsReader._read_file_contents): Deleted.
* Scripts/webkitpy/tool/bot/layouttestresultsreader.py:
(LayoutTestResultsReader): Now inherits from AbstractTestResultsReader.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptswebkitpycommonnetabstracttestresultspy">trunk/Tools/Scripts/webkitpy/common/net/abstracttestresults.py</a></li>
<li><a href="#trunkToolsScriptswebkitpycommonnetjsctestresultspy">trunk/Tools/Scripts/webkitpy/common/net/jsctestresults.py</a></li>
<li><a href="#trunkToolsScriptswebkitpycommonnetjsctestresults_unittestpy">trunk/Tools/Scripts/webkitpy/common/net/jsctestresults_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolbotjsctestresultsreaderpy">trunk/Tools/Scripts/webkitpy/tool/bot/jsctestresultsreader.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolbotlayouttestresultsreaderpy">trunk/Tools/Scripts/webkitpy/tool/bot/layouttestresultsreader.py</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsScriptswebkitpycommonnetabstracttestresults_unittestpy">trunk/Tools/Scripts/webkitpy/common/net/abstracttestresults_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpytoolbotabstracttestresultsreaderpy">trunk/Tools/Scripts/webkitpy/tool/bot/abstracttestresultsreader.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (213305 => 213306)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2017-03-02 22:38:07 UTC (rev 213305)
+++ trunk/Tools/ChangeLog        2017-03-02 22:46:01 UTC (rev 213306)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2017-03-02  Srinivasan Vijayaraghavan  &lt;svijayaraghavan@apple.com&gt;
+
+        Refactor test results classes in webkitpy to enable faster EWS iteration
+        https://bugs.webkit.org/show_bug.cgi?id=169053
+
+        Reviewed by Alexey Proskuryakov.
+
+        * Scripts/webkitpy/common/net/abstracttestresults.py:
+        (AbstractTestResults): Import json for parse_json_string().
+        (AbstractTestResults.parse_json_string): Abstracted out from JSCTestResults.results_from_string().
+        * Scripts/webkitpy/common/net/abstracttestresults_unittest.py: Added.
+        (AbstractTestResultsTest): Class that tests AbstractTestResults.
+        (AbstractTestResultsTest.test_parse_json_string_invalid_inputs): Move unit tests from JSCTestResultsTest.
+        (AbstractTestResultsTest.test_parse_json_string_valid_input): Add a unit test for a success case.
+        * Scripts/webkitpy/common/net/jsctestresults.py:
+        (JSCTestResults.results_from_string): Call parse_json_string because it was abstracted out.
+        * Scripts/webkitpy/common/net/jsctestresults_unittest.py:
+        (JSCTestResultsTest.test_results_from_string): Remove JSON parsing unit tests, because they were moved.
+        * Scripts/webkitpy/tool/bot/abstracttestresultsreader.py: Added.
+        (AbstractTestResultsReader): Generic TestResultsReader with functions common to jsc, bindings etc.
+        (AbstractTestResultsReader.__init__): Moved from JSCTestResultsReader.__init__().
+        (AbstractTestResultsReader._read_file_contents): Moved from JSCTestResultsReader._read_file_contents().
+        (AbstractTestResultsReader.results): Stub.
+        * Scripts/webkitpy/tool/bot/jsctestresultsreader.py:
+        (JSCTestResultsReader): Now inherits from AbstractTestResultsReader.
+        (JSCTestResultsReader.__init__): Deleted.
+        (JSCTestResultsReader._read_file_contents): Deleted.
+        * Scripts/webkitpy/tool/bot/layouttestresultsreader.py:
+        (LayoutTestResultsReader): Now inherits from AbstractTestResultsReader.
+
</ins><span class="cx"> 2017-03-02  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Continue enabling WebRTC
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpycommonnetabstracttestresultspy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/common/net/abstracttestresults.py (213305 => 213306)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/common/net/abstracttestresults.py        2017-03-02 22:38:07 UTC (rev 213305)
+++ trunk/Tools/Scripts/webkitpy/common/net/abstracttestresults.py        2017-03-02 22:46:01 UTC (rev 213306)
</span><span class="lines">@@ -20,6 +20,7 @@
</span><span class="cx"> # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
</span><span class="cx"> # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> 
</span><ins>+import json
</ins><span class="cx"> import logging
</span><span class="cx"> 
</span><span class="cx"> _log = logging.getLogger(__name__)
</span><span class="lines">@@ -26,6 +27,17 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> class AbstractTestResults(object):
</span><ins>+    @classmethod
+    def parse_json_string(cls, string):
+        if not string:
+            return None
+
+        try:
+            return json.loads(string)
+        except ValueError:
+            _log.error('Invalid JSON results')
+            return None
+
</ins><span class="cx">     def failing_tests(self):
</span><span class="cx">         raise NotImplementedError(&quot;subclasses must implement&quot;)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpycommonnetabstracttestresults_unittestpyfromrev213305trunkToolsScriptswebkitpytoolbotjsctestresultsreaderpy"></a>
<div class="copfile"><h4>Copied: trunk/Tools/Scripts/webkitpy/common/net/abstracttestresults_unittest.py (from rev 213305, trunk/Tools/Scripts/webkitpy/tool/bot/jsctestresultsreader.py) (0 => 213306)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/common/net/abstracttestresults_unittest.py                                (rev 0)
+++ trunk/Tools/Scripts/webkitpy/common/net/abstracttestresults_unittest.py        2017-03-02 22:46:01 UTC (rev 213306)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+# Copyright (C) 2017 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest
+
+from webkitpy.common.net.abstracttestresults import AbstractTestResults
+
+
+class AbstractTestResultsTest(unittest.TestCase):
+    def test_parse_json_string_invalid_inputs(self):
+        none_item = None
+        empty_json = ''
+        invalid_json = '{&quot;allApiTestsPassed&quot;:'
+        invalid_json_v2 = '{&quot;err'
+        self.assertEqual(None, AbstractTestResults.parse_json_string(none_item))
+        self.assertEqual(None, AbstractTestResults.parse_json_string(empty_json))
+        self.assertEqual(None, AbstractTestResults.parse_json_string(invalid_json))
+        self.assertEqual(None, AbstractTestResults.parse_json_string(invalid_json_v2))
+
+    def test_parse_json_string_valid_input(self):
+        test_string = '{&quot;failures&quot;: [&quot;fail1&quot;, &quot;fail2&quot;], &quot;errors&quot;: []}'
+        test_dict = {&quot;failures&quot;: [&quot;fail1&quot;, &quot;fail2&quot;], &quot;errors&quot;: []}
+
+        self.assertEqual(test_dict, AbstractTestResults.parse_json_string(test_string))
</ins></span></pre></div>
<a id="trunkToolsScriptswebkitpycommonnetjsctestresultspy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/common/net/jsctestresults.py (213305 => 213306)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/common/net/jsctestresults.py        2017-03-02 22:38:07 UTC (rev 213305)
+++ trunk/Tools/Scripts/webkitpy/common/net/jsctestresults.py        2017-03-02 22:46:01 UTC (rev 213306)
</span><span class="lines">@@ -20,7 +20,6 @@
</span><span class="cx"> # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
</span><span class="cx"> # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> 
</span><del>-import json
</del><span class="cx"> import logging
</span><span class="cx"> 
</span><span class="cx"> from webkitpy.common.net.abstracttestresults import AbstractTestResults
</span><span class="lines">@@ -45,15 +44,10 @@
</span><span class="cx"> 
</span><span class="cx">     @classmethod
</span><span class="cx">     def results_from_string(cls, string):
</span><del>-        if not string:
</del><ins>+        parsed_results = cls.parse_json_string(string)
+        if not parsed_results:
</ins><span class="cx">             return None
</span><span class="cx"> 
</span><del>-        try:
-            parsed_results = json.loads(string)
-        except ValueError:
-            _log.error('Invalid JSON results')
-            return None
-
</del><span class="cx">         if 'allApiTestsPassed' not in parsed_results or 'stressTestFailures' not in parsed_results:
</span><span class="cx">             return None
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpycommonnetjsctestresults_unittestpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/common/net/jsctestresults_unittest.py (213305 => 213306)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/common/net/jsctestresults_unittest.py        2017-03-02 22:38:07 UTC (rev 213305)
+++ trunk/Tools/Scripts/webkitpy/common/net/jsctestresults_unittest.py        2017-03-02 22:46:01 UTC (rev 213306)
</span><span class="lines">@@ -27,14 +27,8 @@
</span><span class="cx"> 
</span><span class="cx"> class JSCTestResultsTest(unittest.TestCase):
</span><span class="cx">     def test_results_from_string(self):
</span><del>-        none_item = None
-        empty_json = ''
-        invalid_json = '{&quot;allApiTestsPassed&quot;:'
</del><span class="cx">         incomplete_json_v1 = '{&quot;allApiTestsPassed&quot;: true}'
</span><span class="cx">         incomplete_json_v2 = '{&quot;stressTestFailures&quot;:[]}'
</span><del>-        self.assertEqual(None, JSCTestResults.results_from_string(none_item))
-        self.assertEqual(None, JSCTestResults.results_from_string(empty_json))
-        self.assertEqual(None, JSCTestResults.results_from_string(invalid_json))
</del><span class="cx">         self.assertEqual(None, JSCTestResults.results_from_string(incomplete_json_v1))
</span><span class="cx">         self.assertEqual(None, JSCTestResults.results_from_string(incomplete_json_v2))
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolbotabstracttestresultsreaderpyfromrev213305trunkToolsScriptswebkitpytoolbotjsctestresultsreaderpy"></a>
<div class="copfile"><h4>Copied: trunk/Tools/Scripts/webkitpy/tool/bot/abstracttestresultsreader.py (from rev 213305, trunk/Tools/Scripts/webkitpy/tool/bot/jsctestresultsreader.py) (0 => 213306)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/bot/abstracttestresultsreader.py                                (rev 0)
+++ trunk/Tools/Scripts/webkitpy/tool/bot/abstracttestresultsreader.py        2017-03-02 22:46:01 UTC (rev 213306)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+# Copyright (C) 2017 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import logging
+
+_log = logging.getLogger(__name__)
+
+
+class AbstractTestResultsReader(object):
+    def __init__(self, host, results_directory):
+        self._host = host
+        self._results_directory = results_directory
+
+    def _read_file_contents(self, path):
+        try:
+            return self._host.filesystem.read_text_file(path)
+        except (IOError, KeyError):
+            _log.error('File could not be read: %s' % path)
+            return None
+
+    def results(self):
+        raise NotImplementedError(&quot;subclasses must implement&quot;)
</ins></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolbotjsctestresultsreaderpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/bot/jsctestresultsreader.py (213305 => 213306)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/bot/jsctestresultsreader.py        2017-03-02 22:38:07 UTC (rev 213305)
+++ trunk/Tools/Scripts/webkitpy/tool/bot/jsctestresultsreader.py        2017-03-02 22:46:01 UTC (rev 213306)
</span><span class="lines">@@ -23,21 +23,12 @@
</span><span class="cx"> import logging
</span><span class="cx"> 
</span><span class="cx"> from webkitpy.common.net.jsctestresults import JSCTestResults
</span><ins>+from webkitpy.tool.bot.abstracttestresultsreader import AbstractTestResultsReader
</ins><span class="cx"> 
</span><span class="cx"> _log = logging.getLogger(__name__)
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-class JSCTestResultsReader(object):
-    def __init__(self, host, results_directory):
-        self._host = host
-        self._results_directory = results_directory
-
-    def _read_file_contents(self, path):
-        try:
-            return self._host.filesystem.read_text_file(path)
-        except (IOError, KeyError):
-            return None
-
</del><ins>+class JSCTestResultsReader(AbstractTestResultsReader):
</ins><span class="cx">     def results(self):
</span><span class="cx">         results_path = self._host.filesystem.join(self._results_directory, 'jsc_test_results.json')
</span><span class="cx">         contents = self._read_file_contents(results_path)
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpytoolbotlayouttestresultsreaderpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/tool/bot/layouttestresultsreader.py (213305 => 213306)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/tool/bot/layouttestresultsreader.py        2017-03-02 22:38:07 UTC (rev 213305)
+++ trunk/Tools/Scripts/webkitpy/tool/bot/layouttestresultsreader.py        2017-03-02 22:46:01 UTC (rev 213306)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> from webkitpy.common.net.layouttestresults import LayoutTestResults
</span><span class="cx"> from webkitpy.common.net.unittestresults import UnitTestResults
</span><ins>+from webkitpy.tool.bot.abstracttestresultsreader import AbstractTestResultsReader
</ins><span class="cx"> from webkitpy.tool.steps.runtests import RunTests
</span><span class="cx"> 
</span><span class="cx"> _log = logging.getLogger(__name__)
</span><span class="lines">@@ -37,7 +38,7 @@
</span><span class="cx"> 
</span><span class="cx"> # FIXME: This class no longer has a clear purpose, and should probably
</span><span class="cx"> # be made part of Port, or renamed to LayoutTestResultsArchiver or something more fitting?
</span><del>-class LayoutTestResultsReader(object):
</del><ins>+class LayoutTestResultsReader(AbstractTestResultsReader):
</ins><span class="cx">     def __init__(self, host, results_directory, archive_directory):
</span><span class="cx">         self._host = host
</span><span class="cx">         self._results_directory = results_directory
</span></span></pre>
</div>
</div>

</body>
</html>