<!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>[204271] 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/204271">204271</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2016-08-08 17:22:06 -0700 (Mon, 08 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Have the iOS platform interit from the Apple platform in webkitpy
https://bugs.webkit.org/show_bug.cgi?id=160672

Reviewed by Dan Bates.

The IOSSimulatorPort used to inherit from Port, rather than ApplePort.
Fix this, and move duplicated code from IOSSimulatorPort and MacPort into
ApplePort.

Since WinPort also inherits from ApplePort, it needs to stub out some things
that are unavailable on Windows (leaks, sampling).

Some SnowLeopard-related code and the associated test were removed.

* Scripts/webkitpy/port/apple.py:
(ApplePort.__init__):
(ApplePort):
(ApplePort._make_leak_detector):
(ApplePort.default_timeout_ms):
(ApplePort.supports_per_test_timeout):
(ApplePort.should_retry_crashes):
(ApplePort._generate_all_test_configurations):
(ApplePort.check_for_leaks):
(ApplePort.print_leaks_summary):
(ApplePort._path_to_webcore_library):
(ApplePort.show_results_html_file):
(ApplePort._merge_crash_logs):
(ApplePort._look_for_all_crash_logs_in_log_dir):
(ApplePort._get_crash_log):
(ApplePort.look_for_new_crash_logs):
(ApplePort.sample_process):
(ApplePort.sample_file_path):
(ApplePort.look_for_new_samples):
(ApplePort._path_to_helper):
(ApplePort.determine_full_port_name): Deleted.
* Scripts/webkitpy/port/ios.py:
(IOSSimulatorPort):
(IOSSimulatorPort.__init__):
(IOSSimulatorPort.default_timeout_ms): Deleted.
(IOSSimulatorPort.supports_per_test_timeout): Deleted.
(IOSSimulatorPort.should_retry_crashes): Deleted.
(IOSSimulatorPort.check_for_leaks): Deleted.
(IOSSimulatorPort.print_leaks_summary): Deleted.
(IOSSimulatorPort._path_to_webcore_library): Deleted.
(IOSSimulatorPort.show_results_html_file): Deleted.
(IOSSimulatorPort.sample_file_path): Deleted.
(IOSSimulatorPort._merge_crash_logs): Deleted.
(IOSSimulatorPort._look_for_all_crash_logs_in_log_dir): Deleted.
(IOSSimulatorPort.look_for_new_crash_logs): Deleted.
(IOSSimulatorPort.look_for_new_samples): Deleted.
(IOSSimulatorPort.sample_process): Deleted.
(IOSSimulatorPort._path_to_helper): Deleted.
(IOSSimulatorPort.make_command): Deleted.
* Scripts/webkitpy/port/mac.py:
(MacPort.__init__):
(MacPort.make_command):
(MacPort._build_java_test_support):
(MacPort): Deleted.
(MacPort.default_timeout_ms): Deleted.
(MacPort.supports_per_test_timeout): Deleted.
(MacPort.should_retry_crashes): Deleted.
(MacPort.default_child_processes): Deleted.
(MacPort.check_for_leaks): Deleted.
(MacPort.print_leaks_summary): Deleted.
(MacPort._path_to_webcore_library): Deleted.
(MacPort.show_results_html_file): Deleted.
(MacPort.sample_file_path): Deleted.
(MacPort._merge_crash_logs): Deleted.
(MacPort._look_for_all_crash_logs_in_log_dir): Deleted.
(MacPort.look_for_new_crash_logs): Deleted.
(MacPort.look_for_new_samples): Deleted.
(MacPort.sample_process): Deleted.
(MacPort._path_to_helper): Deleted.
* Scripts/webkitpy/port/mac_unittest.py:
(MacTest.test_default_child_processes): Deleted.
* Scripts/webkitpy/port/win.py:
(WinPort.look_for_new_samples):
(WinPort):
(WinPort.sample_process):
(WinPort._make_leak_detector):
(WinPort.check_for_leaks):
(WinPort.print_leaks_summary):
(WinPort._path_to_webcore_library):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptswebkitpyportapplepy">trunk/Tools/Scripts/webkitpy/port/apple.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportiospy">trunk/Tools/Scripts/webkitpy/port/ios.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportmacpy">trunk/Tools/Scripts/webkitpy/port/mac.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportmac_unittestpy">trunk/Tools/Scripts/webkitpy/port/mac_unittest.py</a></li>
<li><a href="#trunkToolsScriptswebkitpyportwinpy">trunk/Tools/Scripts/webkitpy/port/win.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (204270 => 204271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-08-09 00:08:28 UTC (rev 204270)
+++ trunk/Tools/ChangeLog        2016-08-09 00:22:06 UTC (rev 204271)
</span><span class="lines">@@ -1,3 +1,89 @@
</span><ins>+2016-08-08  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Have the iOS platform interit from the Apple platform in webkitpy
+        https://bugs.webkit.org/show_bug.cgi?id=160672
+
+        Reviewed by Dan Bates.
+        
+        The IOSSimulatorPort used to inherit from Port, rather than ApplePort.
+        Fix this, and move duplicated code from IOSSimulatorPort and MacPort into
+        ApplePort.
+        
+        Since WinPort also inherits from ApplePort, it needs to stub out some things
+        that are unavailable on Windows (leaks, sampling).
+        
+        Some SnowLeopard-related code and the associated test were removed.
+
+        * Scripts/webkitpy/port/apple.py:
+        (ApplePort.__init__):
+        (ApplePort):
+        (ApplePort._make_leak_detector):
+        (ApplePort.default_timeout_ms):
+        (ApplePort.supports_per_test_timeout):
+        (ApplePort.should_retry_crashes):
+        (ApplePort._generate_all_test_configurations):
+        (ApplePort.check_for_leaks):
+        (ApplePort.print_leaks_summary):
+        (ApplePort._path_to_webcore_library):
+        (ApplePort.show_results_html_file):
+        (ApplePort._merge_crash_logs):
+        (ApplePort._look_for_all_crash_logs_in_log_dir):
+        (ApplePort._get_crash_log):
+        (ApplePort.look_for_new_crash_logs):
+        (ApplePort.sample_process):
+        (ApplePort.sample_file_path):
+        (ApplePort.look_for_new_samples):
+        (ApplePort._path_to_helper):
+        (ApplePort.determine_full_port_name): Deleted.
+        * Scripts/webkitpy/port/ios.py:
+        (IOSSimulatorPort):
+        (IOSSimulatorPort.__init__):
+        (IOSSimulatorPort.default_timeout_ms): Deleted.
+        (IOSSimulatorPort.supports_per_test_timeout): Deleted.
+        (IOSSimulatorPort.should_retry_crashes): Deleted.
+        (IOSSimulatorPort.check_for_leaks): Deleted.
+        (IOSSimulatorPort.print_leaks_summary): Deleted.
+        (IOSSimulatorPort._path_to_webcore_library): Deleted.
+        (IOSSimulatorPort.show_results_html_file): Deleted.
+        (IOSSimulatorPort.sample_file_path): Deleted.
+        (IOSSimulatorPort._merge_crash_logs): Deleted.
+        (IOSSimulatorPort._look_for_all_crash_logs_in_log_dir): Deleted.
+        (IOSSimulatorPort.look_for_new_crash_logs): Deleted.
+        (IOSSimulatorPort.look_for_new_samples): Deleted.
+        (IOSSimulatorPort.sample_process): Deleted.
+        (IOSSimulatorPort._path_to_helper): Deleted.
+        (IOSSimulatorPort.make_command): Deleted.
+        * Scripts/webkitpy/port/mac.py:
+        (MacPort.__init__):
+        (MacPort.make_command):
+        (MacPort._build_java_test_support):
+        (MacPort): Deleted.
+        (MacPort.default_timeout_ms): Deleted.
+        (MacPort.supports_per_test_timeout): Deleted.
+        (MacPort.should_retry_crashes): Deleted.
+        (MacPort.default_child_processes): Deleted.
+        (MacPort.check_for_leaks): Deleted.
+        (MacPort.print_leaks_summary): Deleted.
+        (MacPort._path_to_webcore_library): Deleted.
+        (MacPort.show_results_html_file): Deleted.
+        (MacPort.sample_file_path): Deleted.
+        (MacPort._merge_crash_logs): Deleted.
+        (MacPort._look_for_all_crash_logs_in_log_dir): Deleted.
+        (MacPort.look_for_new_crash_logs): Deleted.
+        (MacPort.look_for_new_samples): Deleted.
+        (MacPort.sample_process): Deleted.
+        (MacPort._path_to_helper): Deleted.
+        * Scripts/webkitpy/port/mac_unittest.py:
+        (MacTest.test_default_child_processes): Deleted.
+        * Scripts/webkitpy/port/win.py:
+        (WinPort.look_for_new_samples):
+        (WinPort):
+        (WinPort.sample_process):
+        (WinPort._make_leak_detector):
+        (WinPort.check_for_leaks):
+        (WinPort.print_leaks_summary):
+        (WinPort._path_to_webcore_library):
+
</ins><span class="cx"> 2016-08-08  Matt Baker  &lt;mattbaker@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed: moved myself to the reviewers list.
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpyportapplepy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/apple.py (204270 => 204271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/apple.py        2016-08-09 00:08:28 UTC (rev 204270)
+++ trunk/Tools/Scripts/webkitpy/port/apple.py        2016-08-09 00:22:06 UTC (rev 204271)
</span><span class="lines">@@ -27,9 +27,13 @@
</span><span class="cx"> # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> 
</span><span class="cx"> import logging
</span><ins>+import os
</ins><span class="cx"> 
</span><ins>+from webkitpy.common.system.crashlogs import CrashLogs
+from webkitpy.common.system.executive import ScriptError
</ins><span class="cx"> from webkitpy.port.base import Port
</span><span class="cx"> from webkitpy.layout_tests.models.test_configuration import TestConfiguration
</span><ins>+from webkitpy.port.leakdetector import LeakDetector
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> _log = logging.getLogger(__name__)
</span><span class="lines">@@ -62,7 +66,6 @@
</span><span class="cx">             # That convention means that we're supposed to use the version currently
</span><span class="cx">             # being run, so this won't work if you're not on mac or win (respectively).
</span><span class="cx">             # If you're not on the o/s in question, you must specify a full version or -future (cf. above).
</span><del>-            assert host.platform.os_name in port_name, &quot;%s is not in %s!&quot; % (host.platform.os_name, port_name)
</del><span class="cx">             if port_name == cls.port_name and not getattr(options, 'webkit_test_runner', False):
</span><span class="cx">                 port_name = cls.port_name + '-' + host.platform.os_version
</span><span class="cx">             else:
</span><span class="lines">@@ -85,8 +88,27 @@
</span><span class="cx">         allowed_port_names = self.VERSION_FALLBACK_ORDER + [self.operating_system() + &quot;-future&quot;]
</span><span class="cx">         port_name = port_name.replace('-wk2', '')
</span><span class="cx">         self._version = self._strip_port_name_prefix(port_name)
</span><del>-        assert port_name in allowed_port_names, &quot;%s is not in %s&quot; % (port_name, allowed_port_names)
</del><span class="cx"> 
</span><ins>+        self._leak_detector = self._make_leak_detector()
+        if self.get_option(&quot;leaks&quot;):
+            # DumpRenderTree slows down noticably if we run more than about 1000 tests in a batch
+            # with MallocStackLogging enabled.
+            self.set_option_default(&quot;batch_size&quot;, 1000)
+
+    def _make_leak_detector(self):
+        return LeakDetector(self)
+
+    def default_timeout_ms(self):
+        if self.get_option('guard_malloc'):
+            return 350 * 1000
+        return super(ApplePort, self).default_timeout_ms()
+
+    def supports_per_test_timeout(self):
+        return True
+
+    def should_retry_crashes(self):
+        return True
+
</ins><span class="cx">     def _skipped_file_search_paths(self):
</span><span class="cx">         # We don't have a dedicated Skipped file for the most recent version of the port;
</span><span class="cx">         # we just use the one in platform/{mac,win}
</span><span class="lines">@@ -106,3 +128,112 @@
</span><span class="cx">                 for architecture in self.ARCHITECTURES:
</span><span class="cx">                     configurations.append(TestConfiguration(version=self._strip_port_name_prefix(port_name), architecture=architecture, build_type=build_type))
</span><span class="cx">         return configurations
</span><ins>+
+    def check_for_leaks(self, process_name, process_pid):
+        if not self.get_option('leaks'):
+            return
+        # We could use http://code.google.com/p/psutil/ to get the process_name from the pid.
+        self._leak_detector.check_for_leaks(process_name, process_pid)
+
+    def print_leaks_summary(self):
+        if not self.get_option('leaks'):
+            return
+        # We're in the manager process, so the leak detector will not have a valid list of leak files.
+        # FIXME: This is a hack, but we don't have a better way to get this information from the workers yet.
+        # FIXME: This will include too many leaks in subsequent runs until the results directory is cleared!
+        leaks_files = self._leak_detector.leaks_files_in_directory(self.results_directory())
+        if not leaks_files:
+            return
+        total_bytes_string, unique_leaks = self._leak_detector.count_total_bytes_and_unique_leaks(leaks_files)
+        total_leaks = self._leak_detector.count_total_leaks(leaks_files)
+        _log.info(&quot;%s total leaks found for a total of %s.&quot; % (total_leaks, total_bytes_string))
+        _log.info(&quot;%s unique leaks found.&quot; % unique_leaks)
+
+    def _path_to_webcore_library(self):
+        return self._build_path('WebCore.framework/Versions/A/WebCore')
+
+    def show_results_html_file(self, results_filename):
+        # We don't use self._run_script() because we don't want to wait for the script
+        # to exit and we want the output to show up on stdout in case there are errors
+        # launching the browser.
+        self._executive.popen([self.path_to_script('run-safari')] + self._arguments_for_configuration() + ['--no-saved-state', '-NSOpen', results_filename],
+            cwd=self.webkit_base(), stdout=file(os.devnull), stderr=file(os.devnull))
+
+    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)
+
+    def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn, sleep_fn, wait_for_log):
+        return None
+
+    def look_for_new_crash_logs(self, crashed_processes, start_time):
+        &quot;&quot;&quot;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 -&gt; pid, process_name tuple of crashed process
+           start_time: time the tests started at.  We're looking for crash
+               logs after that time.
+        &quot;&quot;&quot;
+        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 logging we would have already collected it.
+            crash_log = self._get_crash_log(process_name, pid, None, None, start_time, wait_for_log=False)[1]
+            if not crash_log:
+                continue
+            crash_logs[test_name] = crash_log
+        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)
+
+    def sample_process(self, name, pid):
+        hang_report = self.sample_file_path(name, pid)
+        exit_status = self._executive.run_command([
+            &quot;/usr/bin/sudo&quot;,
+            &quot;-n&quot;,
+            &quot;/usr/sbin/spindump&quot;,
+            pid,
+            10,
+            10,
+            &quot;-file&quot;,
+            hang_report,
+        ], return_exit_code=True)
+        if exit_status:
+            try:
+                self._executive.run_command([
+                    &quot;/usr/bin/sample&quot;,
+                    pid,
+                    10,
+                    10,
+                    &quot;-file&quot;,
+                    hang_report,
+                ])
+            except ScriptError as e:
+                _log.warning('Unable to sample process:' + str(e))
+
+    def sample_file_path(self, name, pid):
+        return self._filesystem.join(self.results_directory(), &quot;{0}-{1}-sample.txt&quot;.format(name, pid))
+
+    def look_for_new_samples(self, unresponsive_processes, start_time):
+        sample_files = {}
+        for (test_name, process_name, pid) in unresponsive_processes:
+            sample_file = self.sample_file_path(process_name, pid)
+            if not self._filesystem.isfile(sample_file):
+                continue
+            sample_files[test_name] = sample_file
+        return sample_files
+
+    def _path_to_helper(self):
+        binary_name = 'LayoutTestHelper'
+        return self._build_path(binary_name)
</ins></span></pre></div>
<a id="trunkToolsScriptswebkitpyportiospy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/ios.py (204270 => 204271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/ios.py        2016-08-09 00:08:28 UTC (rev 204270)
+++ trunk/Tools/Scripts/webkitpy/port/ios.py        2016-08-09 00:22:06 UTC (rev 204271)
</span><span class="lines">@@ -36,7 +36,6 @@
</span><span class="cx"> from webkitpy.port import driver, image_diff
</span><span class="cx"> from webkitpy.port.apple import ApplePort
</span><span class="cx"> from webkitpy.port.base import Port
</span><del>-from webkitpy.port.leakdetector import LeakDetector
</del><span class="cx"> from webkitpy.xcode.simulator import Simulator, Runtime, DeviceType
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -68,11 +67,13 @@
</span><span class="cx">         return 'ios'
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-class IOSSimulatorPort(Port):
</del><ins>+class IOSSimulatorPort(ApplePort):
</ins><span class="cx">     port_name = &quot;ios-simulator&quot;
</span><ins>+
</ins><span class="cx">     FUTURE_VERSION = 'future'
</span><span class="cx">     ARCHITECTURES = ['x86_64', 'x86']
</span><span class="cx">     DEFAULT_ARCHITECTURE = 'x86_64'
</span><ins>+
</ins><span class="cx">     SIMULATOR_BUNDLE_ID = 'com.apple.iphonesimulator'
</span><span class="cx">     relay_name = 'LayoutTestRelay'
</span><span class="cx">     SIMULATOR_DIRECTORY = &quot;/tmp/WebKitTestingSimulators/&quot;
</span><span class="lines">@@ -79,15 +80,9 @@
</span><span class="cx">     LSREGISTER_PATH = &quot;/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/Current/Support/lsregister&quot;
</span><span class="cx">     PROCESS_COUNT_ESTIMATE_PER_SIMULATOR_INSTANCE = 100
</span><span class="cx"> 
</span><del>-    def __init__(self, *args, **kwargs):
-        super(IOSSimulatorPort, self).__init__(*args, **kwargs)
</del><ins>+    def __init__(self, host, port_name, **kwargs):
+        super(IOSSimulatorPort, self).__init__(host, port_name, **kwargs)
</ins><span class="cx"> 
</span><del>-        self._leak_detector = LeakDetector(self)
-        if self.get_option(&quot;leaks&quot;):
-            # DumpRenderTree slows down noticably if we run more than about 1000 tests in a batch
-            # with MallocStackLogging enabled.
-            self.set_option_default(&quot;batch_size&quot;, 1000)
-
</del><span class="cx">     def driver_name(self):
</span><span class="cx">         if self.get_option('driver_name'):
</span><span class="cx">             return self.get_option('driver_name')
</span><span class="lines">@@ -152,14 +147,6 @@
</span><span class="cx"> 
</span><span class="cx">         return min(maximum_simulator_count_on_this_system, best_child_process_count_for_cpu)
</span><span class="cx"> 
</span><del>-    def default_timeout_ms(self):
-        if self.get_option('guard_malloc'):
-            return 350 * 1000
-        return super(IOSSimulatorPort, self).default_timeout_ms()
-
-    def supports_per_test_timeout(self):
-        return True
-
</del><span class="cx">     def _check_relay(self):
</span><span class="cx">         if not self._filesystem.exists(self.relay_path):
</span><span class="cx">             _log.error(&quot;%s was not found at %s&quot; % (self.relay_name, self.relay_path))
</span><span class="lines">@@ -197,9 +184,6 @@
</span><span class="cx">         sdk = ['--sdk', 'iphonesimulator']
</span><span class="cx">         return archs + sdk
</span><span class="cx"> 
</span><del>-    def should_retry_crashes(self):
-        return True
-
</del><span class="cx">     def _generate_all_test_configurations(self):
</span><span class="cx">         configurations = []
</span><span class="cx">         for build_type in self.ALL_BUILD_TYPES:
</span><span class="lines">@@ -292,37 +276,6 @@
</span><span class="cx">             testing_device = self.testing_device(i)
</span><span class="cx">         return super(IOSSimulatorPort, self).check_sys_deps(needs_http)
</span><span class="cx"> 
</span><del>-    def check_for_leaks(self, process_name, process_pid):
-        if not self.get_option('leaks'):
-            return
-        # We could use http://code.google.com/p/psutil/ to get the process_name from the pid.
-        self._leak_detector.check_for_leaks(process_name, process_pid)
-
-    def print_leaks_summary(self):
-        if not self.get_option('leaks'):
-            return
-        # We're in the manager process, so the leak detector will not have a valid list of leak files.
-        leaks_files = self._leak_detector.leaks_files_in_directory(self.results_directory())
-        if not leaks_files:
-            return
-        total_bytes_string, unique_leaks = self._leak_detector.count_total_bytes_and_unique_leaks(leaks_files)
-        total_leaks = self._leak_detector.count_total_leaks(leaks_files)
-        _log.info(&quot;%s total leaks found for a total of %s.&quot; % (total_leaks, total_bytes_string))
-        _log.info(&quot;%s unique leaks found.&quot; % unique_leaks)
-
-    def _path_to_webcore_library(self):
-        return self._build_path('WebCore.framework/Versions/A/WebCore')
-
-    def show_results_html_file(self, results_filename):
-        # We don't use self._run_script() because we don't want to wait for the script
-        # to exit and we want the output to show up on stdout in case there are errors
-        # launching the browser.
-        self._executive.popen([self.path_to_script('run-safari')] + self._arguments_for_configuration() + ['--no-saved-state', '-NSOpen', results_filename],
-            cwd=self.webkit_base(), stdout=file(os.devnull), stderr=file(os.devnull))
-
-    def sample_file_path(self, name, pid):
-        return self._filesystem.join(self.results_directory(), &quot;{0}-{1}-sample.txt&quot;.format(name, pid))
-
</del><span class="cx">     SUBPROCESS_CRASH_REGEX = re.compile('#CRASHED - (?P&lt;subprocess_name&gt;\S+) \(pid (?P&lt;subprocess_pid&gt;\d+)\)')
</span><span class="cx"> 
</span><span class="cx">     def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=time.time, sleep_fn=time.sleep, wait_for_log=True):
</span><span class="lines">@@ -370,72 +323,6 @@
</span><span class="cx">     def get_simulator_path(self, suffix=&quot;&quot;):
</span><span class="cx">         return os.path.join(self.SIMULATOR_DIRECTORY, &quot;Simulator&quot; + str(suffix) + &quot;.app&quot;)
</span><span class="cx"> 
</span><del>-    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)
-
-    def look_for_new_crash_logs(self, crashed_processes, start_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 logging we would have already collected it.
-            crash_log = self._get_crash_log(process_name, pid, None, None, start_time, wait_for_log=False)[1]
-            if not crash_log:
-                continue
-            crash_logs[test_name] = crash_log
-        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)
-
-    def look_for_new_samples(self, unresponsive_processes, start_time):
-        sample_files = {}
-        for (test_name, process_name, pid) in unresponsive_processes:
-            sample_file = self.sample_file_path(process_name, pid)
-            if not self._filesystem.isfile(sample_file):
-                continue
-            sample_files[test_name] = sample_file
-        return sample_files
-
-    def sample_process(self, name, pid):
-        hang_report = self.sample_file_path(name, pid)
-        exit_status = self._executive.run_command([
-            &quot;/usr/bin/sudo&quot;,
-            &quot;-n&quot;,
-            &quot;/usr/sbin/spindump&quot;,
-            pid,
-            10,
-            10,
-            &quot;-file&quot;,
-            hang_report,
-        ], return_exit_code=True)
-        if exit_status:
-            try:
-                self._executive.run_command([
-                    &quot;/usr/bin/sample&quot;,
-                    pid,
-                    10,
-                    10,
-                    &quot;-file&quot;,
-                    hang_report,
-                ])
-            except ScriptError as e:
-                _log.warning('Unable to sample process:' + str(e))
-
-    def _path_to_helper(self):
-        binary_name = 'LayoutTestHelper'
-        return self._build_path(binary_name)
-
</del><span class="cx">     def diff_image(self, expected_contents, actual_contents, tolerance=None):
</span><span class="cx">         if not actual_contents and not expected_contents:
</span><span class="cx">             return (None, 0, None)
</span><span class="lines">@@ -464,9 +351,6 @@
</span><span class="cx">             if os.path.isdir(data_path):
</span><span class="cx">                 shutil.rmtree(data_path)
</span><span class="cx"> 
</span><del>-    def make_command(self):
-        return self.xcrun_find('make', '/usr/bin/make')
-
</del><span class="cx">     def nm_command(self):
</span><span class="cx">         return self.xcrun_find('nm')
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpyportmacpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/mac.py (204270 => 204271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/mac.py        2016-08-09 00:08:28 UTC (rev 204270)
+++ trunk/Tools/Scripts/webkitpy/port/mac.py        2016-08-09 00:22:06 UTC (rev 204271)
</span><span class="lines">@@ -35,9 +35,7 @@
</span><span class="cx"> from webkitpy.common.system.crashlogs import CrashLogs
</span><span class="cx"> from webkitpy.common.system.executive import ScriptError
</span><span class="cx"> from webkitpy.port.apple import ApplePort
</span><del>-from webkitpy.port.leakdetector import LeakDetector
</del><span class="cx"> 
</span><del>-
</del><span class="cx"> _log = logging.getLogger(__name__)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -51,29 +49,11 @@
</span><span class="cx">     DEFAULT_ARCHITECTURE = 'x86_64'
</span><span class="cx"> 
</span><span class="cx">     def __init__(self, host, port_name, **kwargs):
</span><del>-        ApplePort.__init__(self, host, port_name, **kwargs)
</del><ins>+        super(MacPort, self).__init__(host, port_name, **kwargs)
</ins><span class="cx"> 
</span><del>-        self._leak_detector = LeakDetector(self)
-        if self.get_option(&quot;leaks&quot;):
-            # DumpRenderTree slows down noticably if we run more than about 1000 tests in a batch
-            # with MallocStackLogging enabled.
-            self.set_option_default(&quot;batch_size&quot;, 1000)
-
-    def default_timeout_ms(self):
-        if self.get_option('guard_malloc'):
-            return 350 * 1000
-        return super(MacPort, self).default_timeout_ms()
-
-    def supports_per_test_timeout(self):
-        return True
-
</del><span class="cx">     def _build_driver_flags(self):
</span><span class="cx">         return ['ARCHS=i386'] if self.architecture() == 'x86' else []
</span><span class="cx"> 
</span><del>-    def should_retry_crashes(self):
-        # On Apple Mac, we retry crashes due to https://bugs.webkit.org/show_bug.cgi?id=82233
-        return True
-
</del><span class="cx">     def default_baseline_search_path(self):
</span><span class="cx">         name = self._name.replace('-wk2', '')
</span><span class="cx">         wk_version = [] if self.get_option('webkit_test_runner') else ['mac-wk1']
</span><span class="lines">@@ -144,10 +124,6 @@
</span><span class="cx">         return self._version == 'mavericks'
</span><span class="cx"> 
</span><span class="cx">     def default_child_processes(self):
</span><del>-        if self._version == &quot;snowleopard&quot;:
-            _log.warning(&quot;Cannot run tests in parallel on Snow Leopard due to rdar://problem/10621525.&quot;)
-            return 1
-
</del><span class="cx">         default_count = super(MacPort, self).default_child_processes()
</span><span class="cx"> 
</span><span class="cx">         # FIXME: https://bugs.webkit.org/show_bug.cgi?id=95906  With too many WebProcess WK2 tests get stuck in resource contention.
</span><span class="lines">@@ -176,7 +152,11 @@
</span><span class="cx">             supportable_instances = default_count
</span><span class="cx">         return min(supportable_instances, default_count)
</span><span class="cx"> 
</span><ins>+    def make_command(self):
+        return self.xcrun_find('make', '/usr/bin/make')
+
</ins><span class="cx">     def _build_java_test_support(self):
</span><ins>+        # FIXME: This is unused. Remove.
</ins><span class="cx">         java_tests_path = self._filesystem.join(self.layout_tests_dir(), &quot;java&quot;)
</span><span class="cx">         build_java = [self.make_command(), &quot;-C&quot;, java_tests_path]
</span><span class="cx">         if self._executive.run_command(build_java, return_exit_code=True):  # Paths are absolute, so we don't need to set a cwd.
</span><span class="lines">@@ -184,42 +164,9 @@
</span><span class="cx">             return False
</span><span class="cx">         return True
</span><span class="cx"> 
</span><del>-    def check_for_leaks(self, process_name, process_pid):
-        if not self.get_option('leaks'):
-            return
-        # We could use http://code.google.com/p/psutil/ to get the process_name from the pid.
-        self._leak_detector.check_for_leaks(process_name, process_pid)
-
-    def print_leaks_summary(self):
-        if not self.get_option('leaks'):
-            return
-        # We're in the manager process, so the leak detector will not have a valid list of leak files.
-        # FIXME: This is a hack, but we don't have a better way to get this information from the workers yet.
-        # FIXME: This will include too many leaks in subsequent runs until the results directory is cleared!
-        leaks_files = self._leak_detector.leaks_files_in_directory(self.results_directory())
-        if not leaks_files:
-            return
-        total_bytes_string, unique_leaks = self._leak_detector.count_total_bytes_and_unique_leaks(leaks_files)
-        total_leaks = self._leak_detector.count_total_leaks(leaks_files)
-        _log.info(&quot;%s total leaks found for a total of %s.&quot; % (total_leaks, total_bytes_string))
-        _log.info(&quot;%s unique leaks found.&quot; % unique_leaks)
-
</del><span class="cx">     def _check_port_build(self):
</span><span class="cx">         return not self.get_option('java') or self._build_java_test_support()
</span><span class="cx"> 
</span><del>-    def _path_to_webcore_library(self):
-        return self._build_path('WebCore.framework/Versions/A/WebCore')
-
-    def show_results_html_file(self, results_filename):
-        # We don't use self._run_script() because we don't want to wait for the script
-        # to exit and we want the output to show up on stdout in case there are errors
-        # launching the browser.
-        self._executive.popen([self.path_to_script('run-safari')] + self._arguments_for_configuration() + ['--no-saved-state', '-NSOpen', results_filename],
-            cwd=self.webkit_base(), stdout=file(os.devnull), stderr=file(os.devnull))
-
-    def sample_file_path(self, name, pid):
-        return self._filesystem.join(self.results_directory(), &quot;{0}-{1}-sample.txt&quot;.format(name, pid))
-
</del><span class="cx">     def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None, wait_for_log=True):
</span><span class="cx">         # Note that we do slow-spin here and wait, since it appears the time
</span><span class="cx">         # ReportCrash takes to actually write and flush the file varies when there are
</span><span class="lines">@@ -245,79 +192,6 @@
</span><span class="cx">             return (stderr, None)
</span><span class="cx">         return (stderr, crash_log)
</span><span class="cx"> 
</span><del>-    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)
-
-    def look_for_new_crash_logs(self, crashed_processes, start_time):
-        &quot;&quot;&quot;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 -&gt; pid, process_name tuple of crashed process
-           start_time: time the tests started at.  We're looking for crash
-               logs after that time.
-        &quot;&quot;&quot;
-        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 logging we would have already collected it.
-            crash_log = self._get_crash_log(process_name, pid, None, None, start_time, wait_for_log=False)[1]
-            if not crash_log:
-                continue
-            crash_logs[test_name] = crash_log
-        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)
-
-    def look_for_new_samples(self, unresponsive_processes, start_time):
-        sample_files = {}
-        for (test_name, process_name, pid) in unresponsive_processes:
-            sample_file = self.sample_file_path(process_name, pid)
-            if not self._filesystem.isfile(sample_file):
-                continue
-            sample_files[test_name] = sample_file
-        return sample_files
-
-    def sample_process(self, name, pid):
-        hang_report = self.sample_file_path(name, pid)
-        exit_status = self._executive.run_command([
-            &quot;/usr/bin/sudo&quot;,
-            &quot;-n&quot;,
-            &quot;/usr/sbin/spindump&quot;,
-            pid,
-            10,
-            10,
-            &quot;-file&quot;,
-            hang_report,
-        ], return_exit_code=True)
-        if exit_status:
-            try:
-                self._executive.run_command([
-                    &quot;/usr/bin/sample&quot;,
-                    pid,
-                    10,
-                    10,
-                    &quot;-file&quot;,
-                    hang_report,
-                ])
-            except ScriptError as e:
-                _log.warning('Unable to sample process:' + str(e))
-
-    def _path_to_helper(self):
-        binary_name = 'LayoutTestHelper'
-        return self._build_path(binary_name)
-
</del><span class="cx">     def start_helper(self, pixel_tests=False):
</span><span class="cx">         helper_path = self._path_to_helper()
</span><span class="cx">         if not helper_path:
</span><span class="lines">@@ -355,9 +229,6 @@
</span><span class="cx">                 _log.debug(&quot;IOError raised while stopping helper: %s&quot; % str(e))
</span><span class="cx">             self._helper = None
</span><span class="cx"> 
</span><del>-    def make_command(self):
-        return self.xcrun_find('make', '/usr/bin/make')
-
</del><span class="cx">     def nm_command(self):
</span><span class="cx">         return self.xcrun_find('nm', 'nm')
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpyportmac_unittestpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/mac_unittest.py (204270 => 204271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/mac_unittest.py        2016-08-09 00:08:28 UTC (rev 204270)
+++ trunk/Tools/Scripts/webkitpy/port/mac_unittest.py        2016-08-09 00:22:06 UTC (rev 204271)
</span><span class="lines">@@ -151,12 +151,6 @@
</span><span class="cx">         child_processes = OutputCapture().assert_outputs(self, port.default_child_processes, (), expected_logs=expected_logs)
</span><span class="cx">         self.assertEqual(child_processes, 1)
</span><span class="cx"> 
</span><del>-        # SnowLeopard has a CFNetwork bug which causes crashes if we execute more than one copy of DRT at once.
-        port = self.make_port(port_name='mac-snowleopard')
-        expected_logs = &quot;Cannot run tests in parallel on Snow Leopard due to rdar://problem/10621525.\n&quot;
-        child_processes = OutputCapture().assert_outputs(self, port.default_child_processes, (), expected_logs=expected_logs)
-        self.assertEqual(child_processes, 1)
-
</del><span class="cx">     def test_get_crash_log(self):
</span><span class="cx">         # Mac crash logs are tested elsewhere, so here we just make sure we don't crash.
</span><span class="cx">         def fake_time_cb():
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpyportwinpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/port/win.py (204270 => 204271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/webkitpy/port/win.py        2016-08-09 00:08:28 UTC (rev 204270)
+++ trunk/Tools/Scripts/webkitpy/port/win.py        2016-08-09 00:22:06 UTC (rev 204271)
</span><span class="lines">@@ -403,6 +403,28 @@
</span><span class="cx">                 crash_logs[test_name] = crash_log
</span><span class="cx">         return crash_logs
</span><span class="cx"> 
</span><ins>+    def look_for_new_samples(self, unresponsive_processes, start_time):
+        # No sampling on Windows.
+        pass
+
+    def sample_process(self, name, pid):
+        # No sampling on Windows.
+        pass
+
+    def _make_leak_detector(self):
+        return None
+
+    def check_for_leaks(self, process_name, process_pid):
+        # No leak checking on Windows.
+        pass
+
+    def print_leaks_summary(self):
+        # No leak checking on Windows.
+        pass
+
+    def _path_to_webcore_library(self):
+        return None
+
</ins><span class="cx">     def find_system_pid(self, name, pid):
</span><span class="cx">         system_pid = int(pid)
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>