Changeset 204271 in webkit


Ignore:
Timestamp:
Aug 8, 2016, 5:22:06 PM (9 years ago)
Author:
Simon Fraser
Message:

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):

Location:
trunk/Tools
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r204265 r204271  
     12016-08-08  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Have the iOS platform interit from the Apple platform in webkitpy
     4        https://bugs.webkit.org/show_bug.cgi?id=160672
     5
     6        Reviewed by Dan Bates.
     7       
     8        The IOSSimulatorPort used to inherit from Port, rather than ApplePort.
     9        Fix this, and move duplicated code from IOSSimulatorPort and MacPort into
     10        ApplePort.
     11       
     12        Since WinPort also inherits from ApplePort, it needs to stub out some things
     13        that are unavailable on Windows (leaks, sampling).
     14       
     15        Some SnowLeopard-related code and the associated test were removed.
     16
     17        * Scripts/webkitpy/port/apple.py:
     18        (ApplePort.__init__):
     19        (ApplePort):
     20        (ApplePort._make_leak_detector):
     21        (ApplePort.default_timeout_ms):
     22        (ApplePort.supports_per_test_timeout):
     23        (ApplePort.should_retry_crashes):
     24        (ApplePort._generate_all_test_configurations):
     25        (ApplePort.check_for_leaks):
     26        (ApplePort.print_leaks_summary):
     27        (ApplePort._path_to_webcore_library):
     28        (ApplePort.show_results_html_file):
     29        (ApplePort._merge_crash_logs):
     30        (ApplePort._look_for_all_crash_logs_in_log_dir):
     31        (ApplePort._get_crash_log):
     32        (ApplePort.look_for_new_crash_logs):
     33        (ApplePort.sample_process):
     34        (ApplePort.sample_file_path):
     35        (ApplePort.look_for_new_samples):
     36        (ApplePort._path_to_helper):
     37        (ApplePort.determine_full_port_name): Deleted.
     38        * Scripts/webkitpy/port/ios.py:
     39        (IOSSimulatorPort):
     40        (IOSSimulatorPort.__init__):
     41        (IOSSimulatorPort.default_timeout_ms): Deleted.
     42        (IOSSimulatorPort.supports_per_test_timeout): Deleted.
     43        (IOSSimulatorPort.should_retry_crashes): Deleted.
     44        (IOSSimulatorPort.check_for_leaks): Deleted.
     45        (IOSSimulatorPort.print_leaks_summary): Deleted.
     46        (IOSSimulatorPort._path_to_webcore_library): Deleted.
     47        (IOSSimulatorPort.show_results_html_file): Deleted.
     48        (IOSSimulatorPort.sample_file_path): Deleted.
     49        (IOSSimulatorPort._merge_crash_logs): Deleted.
     50        (IOSSimulatorPort._look_for_all_crash_logs_in_log_dir): Deleted.
     51        (IOSSimulatorPort.look_for_new_crash_logs): Deleted.
     52        (IOSSimulatorPort.look_for_new_samples): Deleted.
     53        (IOSSimulatorPort.sample_process): Deleted.
     54        (IOSSimulatorPort._path_to_helper): Deleted.
     55        (IOSSimulatorPort.make_command): Deleted.
     56        * Scripts/webkitpy/port/mac.py:
     57        (MacPort.__init__):
     58        (MacPort.make_command):
     59        (MacPort._build_java_test_support):
     60        (MacPort): Deleted.
     61        (MacPort.default_timeout_ms): Deleted.
     62        (MacPort.supports_per_test_timeout): Deleted.
     63        (MacPort.should_retry_crashes): Deleted.
     64        (MacPort.default_child_processes): Deleted.
     65        (MacPort.check_for_leaks): Deleted.
     66        (MacPort.print_leaks_summary): Deleted.
     67        (MacPort._path_to_webcore_library): Deleted.
     68        (MacPort.show_results_html_file): Deleted.
     69        (MacPort.sample_file_path): Deleted.
     70        (MacPort._merge_crash_logs): Deleted.
     71        (MacPort._look_for_all_crash_logs_in_log_dir): Deleted.
     72        (MacPort.look_for_new_crash_logs): Deleted.
     73        (MacPort.look_for_new_samples): Deleted.
     74        (MacPort.sample_process): Deleted.
     75        (MacPort._path_to_helper): Deleted.
     76        * Scripts/webkitpy/port/mac_unittest.py:
     77        (MacTest.test_default_child_processes): Deleted.
     78        * Scripts/webkitpy/port/win.py:
     79        (WinPort.look_for_new_samples):
     80        (WinPort):
     81        (WinPort.sample_process):
     82        (WinPort._make_leak_detector):
     83        (WinPort.check_for_leaks):
     84        (WinPort.print_leaks_summary):
     85        (WinPort._path_to_webcore_library):
     86
    1872016-08-08  Matt Baker  <mattbaker@apple.com>
    288
  • trunk/Tools/Scripts/webkitpy/port/apple.py

    r148502 r204271  
    2828
    2929import logging
    30 
     30import os
     31
     32from webkitpy.common.system.crashlogs import CrashLogs
     33from webkitpy.common.system.executive import ScriptError
    3134from webkitpy.port.base import Port
    3235from webkitpy.layout_tests.models.test_configuration import TestConfiguration
     36from webkitpy.port.leakdetector import LeakDetector
    3337
    3438
     
    6367            # being run, so this won't work if you're not on mac or win (respectively).
    6468            # If you're not on the o/s in question, you must specify a full version or -future (cf. above).
    65             assert host.platform.os_name in port_name, "%s is not in %s!" % (host.platform.os_name, port_name)
    6669            if port_name == cls.port_name and not getattr(options, 'webkit_test_runner', False):
    6770                port_name = cls.port_name + '-' + host.platform.os_version
     
    8689        port_name = port_name.replace('-wk2', '')
    8790        self._version = self._strip_port_name_prefix(port_name)
    88         assert port_name in allowed_port_names, "%s is not in %s" % (port_name, allowed_port_names)
     91
     92        self._leak_detector = self._make_leak_detector()
     93        if self.get_option("leaks"):
     94            # DumpRenderTree slows down noticably if we run more than about 1000 tests in a batch
     95            # with MallocStackLogging enabled.
     96            self.set_option_default("batch_size", 1000)
     97
     98    def _make_leak_detector(self):
     99        return LeakDetector(self)
     100
     101    def default_timeout_ms(self):
     102        if self.get_option('guard_malloc'):
     103            return 350 * 1000
     104        return super(ApplePort, self).default_timeout_ms()
     105
     106    def supports_per_test_timeout(self):
     107        return True
     108
     109    def should_retry_crashes(self):
     110        return True
    89111
    90112    def _skipped_file_search_paths(self):
     
    107129                    configurations.append(TestConfiguration(version=self._strip_port_name_prefix(port_name), architecture=architecture, build_type=build_type))
    108130        return configurations
     131
     132    def check_for_leaks(self, process_name, process_pid):
     133        if not self.get_option('leaks'):
     134            return
     135        # We could use http://code.google.com/p/psutil/ to get the process_name from the pid.
     136        self._leak_detector.check_for_leaks(process_name, process_pid)
     137
     138    def print_leaks_summary(self):
     139        if not self.get_option('leaks'):
     140            return
     141        # We're in the manager process, so the leak detector will not have a valid list of leak files.
     142        # FIXME: This is a hack, but we don't have a better way to get this information from the workers yet.
     143        # FIXME: This will include too many leaks in subsequent runs until the results directory is cleared!
     144        leaks_files = self._leak_detector.leaks_files_in_directory(self.results_directory())
     145        if not leaks_files:
     146            return
     147        total_bytes_string, unique_leaks = self._leak_detector.count_total_bytes_and_unique_leaks(leaks_files)
     148        total_leaks = self._leak_detector.count_total_leaks(leaks_files)
     149        _log.info("%s total leaks found for a total of %s." % (total_leaks, total_bytes_string))
     150        _log.info("%s unique leaks found." % unique_leaks)
     151
     152    def _path_to_webcore_library(self):
     153        return self._build_path('WebCore.framework/Versions/A/WebCore')
     154
     155    def show_results_html_file(self, results_filename):
     156        # We don't use self._run_script() because we don't want to wait for the script
     157        # to exit and we want the output to show up on stdout in case there are errors
     158        # launching the browser.
     159        self._executive.popen([self.path_to_script('run-safari')] + self._arguments_for_configuration() + ['--no-saved-state', '-NSOpen', results_filename],
     160            cwd=self.webkit_base(), stdout=file(os.devnull), stderr=file(os.devnull))
     161
     162    def _merge_crash_logs(self, logs, new_logs, crashed_processes):
     163        for test, crash_log in new_logs.iteritems():
     164            try:
     165                process_name = test.split("-")[0]
     166                pid = int(test.split("-")[1])
     167            except IndexError:
     168                continue
     169            if not any(entry[1] == process_name and entry[2] == pid for entry in crashed_processes):
     170                # if this is a new crash, then append the logs
     171                logs[test] = crash_log
     172        return logs
     173
     174    def _look_for_all_crash_logs_in_log_dir(self, newer_than):
     175        crash_log = CrashLogs(self.host)
     176        return crash_log.find_all_logs(include_errors=True, newer_than=newer_than)
     177
     178    def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn, sleep_fn, wait_for_log):
     179        return None
     180
     181    def look_for_new_crash_logs(self, crashed_processes, start_time):
     182        """Since crash logs can take a long time to be written out if the system is
     183           under stress do a second pass at the end of the test run.
     184
     185           crashes: test_name -> pid, process_name tuple of crashed process
     186           start_time: time the tests started at.  We're looking for crash
     187               logs after that time.
     188        """
     189        crash_logs = {}
     190        for (test_name, process_name, pid) in crashed_processes:
     191            # Passing None for output.  This is a second pass after the test finished so
     192            # if the output had any logging we would have already collected it.
     193            crash_log = self._get_crash_log(process_name, pid, None, None, start_time, wait_for_log=False)[1]
     194            if not crash_log:
     195                continue
     196            crash_logs[test_name] = crash_log
     197        all_crash_log = self._look_for_all_crash_logs_in_log_dir(start_time)
     198        return self._merge_crash_logs(crash_logs, all_crash_log, crashed_processes)
     199
     200    def sample_process(self, name, pid):
     201        hang_report = self.sample_file_path(name, pid)
     202        exit_status = self._executive.run_command([
     203            "/usr/bin/sudo",
     204            "-n",
     205            "/usr/sbin/spindump",
     206            pid,
     207            10,
     208            10,
     209            "-file",
     210            hang_report,
     211        ], return_exit_code=True)
     212        if exit_status:
     213            try:
     214                self._executive.run_command([
     215                    "/usr/bin/sample",
     216                    pid,
     217                    10,
     218                    10,
     219                    "-file",
     220                    hang_report,
     221                ])
     222            except ScriptError as e:
     223                _log.warning('Unable to sample process:' + str(e))
     224
     225    def sample_file_path(self, name, pid):
     226        return self._filesystem.join(self.results_directory(), "{0}-{1}-sample.txt".format(name, pid))
     227
     228    def look_for_new_samples(self, unresponsive_processes, start_time):
     229        sample_files = {}
     230        for (test_name, process_name, pid) in unresponsive_processes:
     231            sample_file = self.sample_file_path(process_name, pid)
     232            if not self._filesystem.isfile(sample_file):
     233                continue
     234            sample_files[test_name] = sample_file
     235        return sample_files
     236
     237    def _path_to_helper(self):
     238        binary_name = 'LayoutTestHelper'
     239        return self._build_path(binary_name)
  • trunk/Tools/Scripts/webkitpy/port/ios.py

    r204253 r204271  
    3737from webkitpy.port.apple import ApplePort
    3838from webkitpy.port.base import Port
    39 from webkitpy.port.leakdetector import LeakDetector
    4039from webkitpy.xcode.simulator import Simulator, Runtime, DeviceType
    4140
     
    6968
    7069
    71 class IOSSimulatorPort(Port):
     70class IOSSimulatorPort(ApplePort):
    7271    port_name = "ios-simulator"
     72
    7373    FUTURE_VERSION = 'future'
    7474    ARCHITECTURES = ['x86_64', 'x86']
    7575    DEFAULT_ARCHITECTURE = 'x86_64'
     76
    7677    SIMULATOR_BUNDLE_ID = 'com.apple.iphonesimulator'
    7778    relay_name = 'LayoutTestRelay'
     
    8081    PROCESS_COUNT_ESTIMATE_PER_SIMULATOR_INSTANCE = 100
    8182
    82     def __init__(self, *args, **kwargs):
    83         super(IOSSimulatorPort, self).__init__(*args, **kwargs)
    84 
    85         self._leak_detector = LeakDetector(self)
    86         if self.get_option("leaks"):
    87             # DumpRenderTree slows down noticably if we run more than about 1000 tests in a batch
    88             # with MallocStackLogging enabled.
    89             self.set_option_default("batch_size", 1000)
     83    def __init__(self, host, port_name, **kwargs):
     84        super(IOSSimulatorPort, self).__init__(host, port_name, **kwargs)
    9085
    9186    def driver_name(self):
     
    153148        return min(maximum_simulator_count_on_this_system, best_child_process_count_for_cpu)
    154149
    155     def default_timeout_ms(self):
    156         if self.get_option('guard_malloc'):
    157             return 350 * 1000
    158         return super(IOSSimulatorPort, self).default_timeout_ms()
    159 
    160     def supports_per_test_timeout(self):
    161         return True
    162 
    163150    def _check_relay(self):
    164151        if not self._filesystem.exists(self.relay_path):
     
    197184        sdk = ['--sdk', 'iphonesimulator']
    198185        return archs + sdk
    199 
    200     def should_retry_crashes(self):
    201         return True
    202186
    203187    def _generate_all_test_configurations(self):
     
    293277        return super(IOSSimulatorPort, self).check_sys_deps(needs_http)
    294278
    295     def check_for_leaks(self, process_name, process_pid):
    296         if not self.get_option('leaks'):
    297             return
    298         # We could use http://code.google.com/p/psutil/ to get the process_name from the pid.
    299         self._leak_detector.check_for_leaks(process_name, process_pid)
    300 
    301     def print_leaks_summary(self):
    302         if not self.get_option('leaks'):
    303             return
    304         # We're in the manager process, so the leak detector will not have a valid list of leak files.
    305         leaks_files = self._leak_detector.leaks_files_in_directory(self.results_directory())
    306         if not leaks_files:
    307             return
    308         total_bytes_string, unique_leaks = self._leak_detector.count_total_bytes_and_unique_leaks(leaks_files)
    309         total_leaks = self._leak_detector.count_total_leaks(leaks_files)
    310         _log.info("%s total leaks found for a total of %s." % (total_leaks, total_bytes_string))
    311         _log.info("%s unique leaks found." % unique_leaks)
    312 
    313     def _path_to_webcore_library(self):
    314         return self._build_path('WebCore.framework/Versions/A/WebCore')
    315 
    316     def show_results_html_file(self, results_filename):
    317         # We don't use self._run_script() because we don't want to wait for the script
    318         # to exit and we want the output to show up on stdout in case there are errors
    319         # launching the browser.
    320         self._executive.popen([self.path_to_script('run-safari')] + self._arguments_for_configuration() + ['--no-saved-state', '-NSOpen', results_filename],
    321             cwd=self.webkit_base(), stdout=file(os.devnull), stderr=file(os.devnull))
    322 
    323     def sample_file_path(self, name, pid):
    324         return self._filesystem.join(self.results_directory(), "{0}-{1}-sample.txt".format(name, pid))
    325 
    326279    SUBPROCESS_CRASH_REGEX = re.compile('#CRASHED - (?P<subprocess_name>\S+) \(pid (?P<subprocess_pid>\d+)\)')
    327280
     
    371324        return os.path.join(self.SIMULATOR_DIRECTORY, "Simulator" + str(suffix) + ".app")
    372325
    373     def _merge_crash_logs(self, logs, new_logs, crashed_processes):
    374         for test, crash_log in new_logs.iteritems():
    375             try:
    376                 process_name = test.split("-")[0]
    377                 pid = int(test.split("-")[1])
    378             except IndexError:
    379                 continue
    380             if not any(entry[1] == process_name and entry[2] == pid for entry in crashed_processes):
    381                 # if this is a new crash, then append the logs
    382                 logs[test] = crash_log
    383         return logs
    384 
    385     def _look_for_all_crash_logs_in_log_dir(self, newer_than):
    386         crash_log = CrashLogs(self.host)
    387         return crash_log.find_all_logs(include_errors=True, newer_than=newer_than)
    388 
    389     def look_for_new_crash_logs(self, crashed_processes, start_time):
    390         crash_logs = {}
    391         for (test_name, process_name, pid) in crashed_processes:
    392             # Passing None for output.  This is a second pass after the test finished so
    393             # if the output had any logging we would have already collected it.
    394             crash_log = self._get_crash_log(process_name, pid, None, None, start_time, wait_for_log=False)[1]
    395             if not crash_log:
    396                 continue
    397             crash_logs[test_name] = crash_log
    398         all_crash_log = self._look_for_all_crash_logs_in_log_dir(start_time)
    399         return self._merge_crash_logs(crash_logs, all_crash_log, crashed_processes)
    400 
    401     def look_for_new_samples(self, unresponsive_processes, start_time):
    402         sample_files = {}
    403         for (test_name, process_name, pid) in unresponsive_processes:
    404             sample_file = self.sample_file_path(process_name, pid)
    405             if not self._filesystem.isfile(sample_file):
    406                 continue
    407             sample_files[test_name] = sample_file
    408         return sample_files
    409 
    410     def sample_process(self, name, pid):
    411         hang_report = self.sample_file_path(name, pid)
    412         exit_status = self._executive.run_command([
    413             "/usr/bin/sudo",
    414             "-n",
    415             "/usr/sbin/spindump",
    416             pid,
    417             10,
    418             10,
    419             "-file",
    420             hang_report,
    421         ], return_exit_code=True)
    422         if exit_status:
    423             try:
    424                 self._executive.run_command([
    425                     "/usr/bin/sample",
    426                     pid,
    427                     10,
    428                     10,
    429                     "-file",
    430                     hang_report,
    431                 ])
    432             except ScriptError as e:
    433                 _log.warning('Unable to sample process:' + str(e))
    434 
    435     def _path_to_helper(self):
    436         binary_name = 'LayoutTestHelper'
    437         return self._build_path(binary_name)
    438 
    439326    def diff_image(self, expected_contents, actual_contents, tolerance=None):
    440327        if not actual_contents and not expected_contents:
     
    465352                shutil.rmtree(data_path)
    466353
    467     def make_command(self):
    468         return self.xcrun_find('make', '/usr/bin/make')
    469 
    470354    def nm_command(self):
    471355        return self.xcrun_find('nm')
  • trunk/Tools/Scripts/webkitpy/port/mac.py

    r204253 r204271  
    3636from webkitpy.common.system.executive import ScriptError
    3737from webkitpy.port.apple import ApplePort
    38 from webkitpy.port.leakdetector import LeakDetector
    39 
    4038
    4139_log = logging.getLogger(__name__)
     
    5250
    5351    def __init__(self, host, port_name, **kwargs):
    54         ApplePort.__init__(self, host, port_name, **kwargs)
    55 
    56         self._leak_detector = LeakDetector(self)
    57         if self.get_option("leaks"):
    58             # DumpRenderTree slows down noticably if we run more than about 1000 tests in a batch
    59             # with MallocStackLogging enabled.
    60             self.set_option_default("batch_size", 1000)
    61 
    62     def default_timeout_ms(self):
    63         if self.get_option('guard_malloc'):
    64             return 350 * 1000
    65         return super(MacPort, self).default_timeout_ms()
    66 
    67     def supports_per_test_timeout(self):
    68         return True
     52        super(MacPort, self).__init__(host, port_name, **kwargs)
    6953
    7054    def _build_driver_flags(self):
    7155        return ['ARCHS=i386'] if self.architecture() == 'x86' else []
    72 
    73     def should_retry_crashes(self):
    74         # On Apple Mac, we retry crashes due to https://bugs.webkit.org/show_bug.cgi?id=82233
    75         return True
    7656
    7757    def default_baseline_search_path(self):
     
    145125
    146126    def default_child_processes(self):
    147         if self._version == "snowleopard":
    148             _log.warning("Cannot run tests in parallel on Snow Leopard due to rdar://problem/10621525.")
    149             return 1
    150 
    151127        default_count = super(MacPort, self).default_child_processes()
    152128
     
    177153        return min(supportable_instances, default_count)
    178154
     155    def make_command(self):
     156        return self.xcrun_find('make', '/usr/bin/make')
     157
    179158    def _build_java_test_support(self):
     159        # FIXME: This is unused. Remove.
    180160        java_tests_path = self._filesystem.join(self.layout_tests_dir(), "java")
    181161        build_java = [self.make_command(), "-C", java_tests_path]
     
    185165        return True
    186166
    187     def check_for_leaks(self, process_name, process_pid):
    188         if not self.get_option('leaks'):
    189             return
    190         # We could use http://code.google.com/p/psutil/ to get the process_name from the pid.
    191         self._leak_detector.check_for_leaks(process_name, process_pid)
    192 
    193     def print_leaks_summary(self):
    194         if not self.get_option('leaks'):
    195             return
    196         # We're in the manager process, so the leak detector will not have a valid list of leak files.
    197         # FIXME: This is a hack, but we don't have a better way to get this information from the workers yet.
    198         # FIXME: This will include too many leaks in subsequent runs until the results directory is cleared!
    199         leaks_files = self._leak_detector.leaks_files_in_directory(self.results_directory())
    200         if not leaks_files:
    201             return
    202         total_bytes_string, unique_leaks = self._leak_detector.count_total_bytes_and_unique_leaks(leaks_files)
    203         total_leaks = self._leak_detector.count_total_leaks(leaks_files)
    204         _log.info("%s total leaks found for a total of %s." % (total_leaks, total_bytes_string))
    205         _log.info("%s unique leaks found." % unique_leaks)
    206 
    207167    def _check_port_build(self):
    208168        return not self.get_option('java') or self._build_java_test_support()
    209 
    210     def _path_to_webcore_library(self):
    211         return self._build_path('WebCore.framework/Versions/A/WebCore')
    212 
    213     def show_results_html_file(self, results_filename):
    214         # We don't use self._run_script() because we don't want to wait for the script
    215         # to exit and we want the output to show up on stdout in case there are errors
    216         # launching the browser.
    217         self._executive.popen([self.path_to_script('run-safari')] + self._arguments_for_configuration() + ['--no-saved-state', '-NSOpen', results_filename],
    218             cwd=self.webkit_base(), stdout=file(os.devnull), stderr=file(os.devnull))
    219 
    220     def sample_file_path(self, name, pid):
    221         return self._filesystem.join(self.results_directory(), "{0}-{1}-sample.txt".format(name, pid))
    222169
    223170    def _get_crash_log(self, name, pid, stdout, stderr, newer_than, time_fn=None, sleep_fn=None, wait_for_log=True):
     
    246193        return (stderr, crash_log)
    247194
    248     def _merge_crash_logs(self, logs, new_logs, crashed_processes):
    249         for test, crash_log in new_logs.iteritems():
    250             try:
    251                 process_name = test.split("-")[0]
    252                 pid = int(test.split("-")[1])
    253             except IndexError:
    254                 continue
    255             if not any(entry[1] == process_name and entry[2] == pid for entry in crashed_processes):
    256                 # if this is a new crash, then append the logs
    257                 logs[test] = crash_log
    258         return logs
    259 
    260     def _look_for_all_crash_logs_in_log_dir(self, newer_than):
    261         crash_log = CrashLogs(self.host)
    262         return crash_log.find_all_logs(include_errors=True, newer_than=newer_than)
    263 
    264     def look_for_new_crash_logs(self, crashed_processes, start_time):
    265         """Since crash logs can take a long time to be written out if the system is
    266            under stress do a second pass at the end of the test run.
    267 
    268            crashes: test_name -> pid, process_name tuple of crashed process
    269            start_time: time the tests started at.  We're looking for crash
    270                logs after that time.
    271         """
    272         crash_logs = {}
    273         for (test_name, process_name, pid) in crashed_processes:
    274             # Passing None for output.  This is a second pass after the test finished so
    275             # if the output had any logging we would have already collected it.
    276             crash_log = self._get_crash_log(process_name, pid, None, None, start_time, wait_for_log=False)[1]
    277             if not crash_log:
    278                 continue
    279             crash_logs[test_name] = crash_log
    280         all_crash_log = self._look_for_all_crash_logs_in_log_dir(start_time)
    281         return self._merge_crash_logs(crash_logs, all_crash_log, crashed_processes)
    282 
    283     def look_for_new_samples(self, unresponsive_processes, start_time):
    284         sample_files = {}
    285         for (test_name, process_name, pid) in unresponsive_processes:
    286             sample_file = self.sample_file_path(process_name, pid)
    287             if not self._filesystem.isfile(sample_file):
    288                 continue
    289             sample_files[test_name] = sample_file
    290         return sample_files
    291 
    292     def sample_process(self, name, pid):
    293         hang_report = self.sample_file_path(name, pid)
    294         exit_status = self._executive.run_command([
    295             "/usr/bin/sudo",
    296             "-n",
    297             "/usr/sbin/spindump",
    298             pid,
    299             10,
    300             10,
    301             "-file",
    302             hang_report,
    303         ], return_exit_code=True)
    304         if exit_status:
    305             try:
    306                 self._executive.run_command([
    307                     "/usr/bin/sample",
    308                     pid,
    309                     10,
    310                     10,
    311                     "-file",
    312                     hang_report,
    313                 ])
    314             except ScriptError as e:
    315                 _log.warning('Unable to sample process:' + str(e))
    316 
    317     def _path_to_helper(self):
    318         binary_name = 'LayoutTestHelper'
    319         return self._build_path(binary_name)
    320 
    321195    def start_helper(self, pixel_tests=False):
    322196        helper_path = self._path_to_helper()
     
    356230            self._helper = None
    357231
    358     def make_command(self):
    359         return self.xcrun_find('make', '/usr/bin/make')
    360 
    361232    def nm_command(self):
    362233        return self.xcrun_find('nm', 'nm')
  • trunk/Tools/Scripts/webkitpy/port/mac_unittest.py

    r204253 r204271  
    152152        self.assertEqual(child_processes, 1)
    153153
    154         # SnowLeopard has a CFNetwork bug which causes crashes if we execute more than one copy of DRT at once.
    155         port = self.make_port(port_name='mac-snowleopard')
    156         expected_logs = "Cannot run tests in parallel on Snow Leopard due to rdar://problem/10621525.\n"
    157         child_processes = OutputCapture().assert_outputs(self, port.default_child_processes, (), expected_logs=expected_logs)
    158         self.assertEqual(child_processes, 1)
    159 
    160154    def test_get_crash_log(self):
    161155        # Mac crash logs are tested elsewhere, so here we just make sure we don't crash.
  • trunk/Tools/Scripts/webkitpy/port/win.py

    r202362 r204271  
    404404        return crash_logs
    405405
     406    def look_for_new_samples(self, unresponsive_processes, start_time):
     407        # No sampling on Windows.
     408        pass
     409
     410    def sample_process(self, name, pid):
     411        # No sampling on Windows.
     412        pass
     413
     414    def _make_leak_detector(self):
     415        return None
     416
     417    def check_for_leaks(self, process_name, process_pid):
     418        # No leak checking on Windows.
     419        pass
     420
     421    def print_leaks_summary(self):
     422        # No leak checking on Windows.
     423        pass
     424
     425    def _path_to_webcore_library(self):
     426        return None
     427
    406428    def find_system_pid(self, name, pid):
    407429        system_pid = int(pid)
Note: See TracChangeset for help on using the changeset viewer.