Changeset 57423 in webkit


Ignore:
Timestamp:
Apr 10, 2010 3:18:44 PM (14 years ago)
Author:
abarth@webkit.org
Message:

2010-04-10 Adam Barth <abarth@webkit.org>

Reviewed by Eric Seidel.

Factor WebKitPort out of MacPort to allow for WinPort
https://bugs.webkit.org/show_bug.cgi?id=37388

The split is a bit of a guess. We might have to adjust things once we
actually have a second port to work with.

  • Scripts/webkitpy/layout_tests/port/apache_http_server.py:
  • Scripts/webkitpy/layout_tests/port/mac.py:
  • Scripts/webkitpy/layout_tests/port/webkit.py: Added.
  • Scripts/webkitpy/layout_tests/port/websocket_server.py:
Location:
trunk/WebKitTools
Files:
4 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r57422 r57423  
     12010-04-10  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        Factor WebKitPort out of MacPort to allow for WinPort
     6        https://bugs.webkit.org/show_bug.cgi?id=37388
     7
     8        The split is a bit of a guess.  We might have to adjust things once we
     9        actually have a second port to work with.
     10
     11        * Scripts/webkitpy/layout_tests/port/apache_http_server.py:
     12        * Scripts/webkitpy/layout_tests/port/mac.py:
     13        * Scripts/webkitpy/layout_tests/port/webkit.py: Added.
     14        * Scripts/webkitpy/layout_tests/port/websocket_server.py:
     15
    1162010-04-10  Adam Barth  <abarth@webkit.org>
    217
  • trunk/WebKitTools/Scripts/webkitpy/layout_tests/port/apache_http_server.py

    r55603 r57423  
    8080        document_root = self._cygwin_safe_join(test_dir, "http", "tests")
    8181
     82        # FIXME: We shouldn't be calling a protected method of _port_obj!
    8283        executable = self._port_obj._path_to_apache()
    8384        if self._is_cygwin():
     
    218219        if os.path.exists(self._pid_file):
    219220            httpd_pid = int(open(self._pid_file).readline())
     221        # FIXME: We shouldn't be calling a protected method of _port_obj!
    220222        self._port_obj._shut_down_http_server(httpd_pid)
  • trunk/WebKitTools/Scripts/webkitpy/layout_tests/port/mac.py

    r57422 r57423  
    4242import webbrowser
    4343
    44 import base
    45 import server_process
    46 
    47 import webkitpy
    4844import webkitpy.common.system.ospath as ospath
     45import webkitpy.layout_tests.port.server_process as server_process
     46from webkitpy.layout_tests.port.webkit import WebKitPort, WebKitDriver
    4947
    5048_log = logging.getLogger("webkitpy.layout_tests.port.mac")
    5149
    5250
    53 class MacPort(base.Port):
     51class MacPort(WebKitPort):
    5452    """WebKit Mac implementation of the Port class."""
    5553
     
    5755        if port_name is None:
    5856            port_name = 'mac' + self.version()
    59         base.Port.__init__(self, port_name, options)
    60         self._cached_build_root = None
    61 
    62         # FIXME: disable pixel tests until they are run by default on the
    63         # build machines.
    64         if options and (not hasattr(options, "pixel_tests") or
    65            options.pixel_tests is None):
    66             options.pixel_tests = False
     57        WebKitPort.__init__(self, port_name, options)
    6758
    6859    def default_num_dump_render_trees(self):
     
    7061        # four threads in parallel.
    7162        # See https://bugs.webkit.org/show_bug.cgi?id=36622
    72         num_dump_render_trees = base.Port.default_num_dump_render_trees(self)
     63        num_dump_render_trees = WebKitPort.default_num_dump_render_trees(self)
    7364        if num_dump_render_trees > 4:
    7465            return 4
    7566        return num_dump_render_trees
    76 
    77     def baseline_path(self):
    78         return self._webkit_baseline_path(self._name)
    7967
    8068    def baseline_search_path(self):
     
    8977        return dirs
    9078
    91     def check_build(self, needs_http):
    92         build_drt_command = [
    93             self.script_path("build-dumprendertree"),
    94             self.flag_from_configuration(self._options.configuration),
    95         ]
    96         if self._executive.run_command(build_drt_command, return_exit_code=True):
    97             return False
    98 
    99         if not self.check_image_diff():
    100             return False
    101 
    102         driver_path = self._path_to_driver()
    103         if not os.path.exists(driver_path):
    104             _log.error("DumpRenderTree was not found at %s" % driver_path)
    105             return False
    106 
    107         java_tests_path = os.path.join(self.layout_tests_dir(), "java")
    108         build_java = ["/usr/bin/make", "-C", java_tests_path]
    109         if self._executive.run_command(build_java, return_exit_code=True):
    110             _log.error("Failed to build Java support files: %s" % build_java)
    111             return False
    112 
    113         return True
    114 
    115     def check_image_diff(self, override_step=None, logging=True):
    116         image_diff_path = self._path_to_image_diff()
    117         if not os.path.exists(image_diff_path):
    118             _log.error("ImageDiff was not found at %s" % image_diff_path)
    119             return False
    120         return True
    121 
    122     def diff_image(self, expected_filename, actual_filename,
    123                    diff_filename=None):
    124         """Return True if the two files are different. Also write a delta
    125         image of the two images into |diff_filename| if it is not None."""
    126 
    127         # Handle the case where the test didn't actually generate an image.
    128         actual_length = os.stat(actual_filename).st_size
    129         if actual_length == 0:
    130             if diff_filename:
    131                 shutil.copyfile(actual_filename, expected_filename)
    132             return True
    133 
    134         sp = self._diff_image_request(expected_filename, actual_filename)
    135         return self._diff_image_reply(sp, expected_filename, diff_filename)
    136 
    137     def _diff_image_request(self, expected_filename, actual_filename):
    138         # FIXME: either expose the tolerance argument as a command-line
    139         # parameter, or make it go away and aways use exact matches.
    140         cmd = [self._path_to_image_diff(), '--tolerance', '0.1']
    141         sp = server_process.ServerProcess(self, 'ImageDiff', cmd)
    142 
    143         actual_length = os.stat(actual_filename).st_size
    144         actual_file = open(actual_filename).read()
    145         expected_length = os.stat(expected_filename).st_size
    146         expected_file = open(expected_filename).read()
    147         sp.write('Content-Length: %d\n%sContent-Length: %d\n%s' %
    148                  (actual_length, actual_file, expected_length, expected_file))
    149 
    150         return sp
    151 
    152     def _diff_image_reply(self, sp, expected_filename, diff_filename):
    153         timeout = 2.0
    154         deadline = time.time() + timeout
    155         output = sp.read_line(timeout)
    156         while not sp.timed_out and not sp.crashed and output:
    157             if output.startswith('Content-Length'):
    158                 m = re.match('Content-Length: (\d+)', output)
    159                 content_length = int(m.group(1))
    160                 timeout = deadline - time.time()
    161                 output = sp.read(timeout, content_length)
    162                 break
    163             elif output.startswith('diff'):
    164                 break
    165             else:
    166                 timeout = deadline - time.time()
    167                 output = sp.read_line(deadline)
    168 
    169         result = True
    170         if output.startswith('diff'):
    171             m = re.match('diff: (.+)% (passed|failed)', output)
    172             if m.group(2) == 'passed':
    173                 result = False
    174         elif output and diff_filename:
    175             open(diff_filename, 'w').write(output)
    176         elif sp.timed_out:
    177             _log.error("ImageDiff timed out on %s" % expected_filename)
    178         elif sp.crashed:
    179             _log.error("ImageDiff crashed")
    180         sp.stop()
    181         return result
    182 
    18379    def path_to_test_expectations_file(self):
    18480        return self.path_from_webkit_base('LayoutTests', 'platform',
    18581           'mac', 'test_expectations.txt')
    186 
    187     def results_directory(self):
    188         return ('/tmp/run-chromium-webkit-tests-' +
    189                 self._options.results_directory)
    190 
    191     def setup_test_run(self):
    192         # This port doesn't require any specific configuration.
    193         pass
    194 
    195     def show_results_html_file(self, results_filename):
    196         uri = self.filename_to_uri(results_filename)
    197         webbrowser.open(uri, new=1)
    198 
    199     def start_driver(self, image_path, options):
    200         """Starts a new Driver and returns a handle to it."""
    201         return MacDriver(self, image_path, options)
    202 
    203     def test_base_platform_names(self):
    204         # At the moment we don't use test platform names, but we have
    205         # to return something.
    206         return ('mac',)
    20782
    20883    def _skipped_file_paths(self):
     
    21691                                          'Skipped'))
    21792        return skipped_files
     93
     94    def test_platform_name(self):
     95        return 'mac' + self.version()
     96
     97    def version(self):
     98        os_version_string = platform.mac_ver()[0]  # e.g. "10.5.6"
     99        if not os_version_string:
     100            return '-leopard'
     101        release_version = int(os_version_string.split('.')[1])
     102        if release_version == 4:
     103            return '-tiger'
     104        elif release_version == 5:
     105            return '-leopard'
     106        elif release_version == 6:
     107            return '-snowleopard'
     108        return ''
    218109
    219110    def _tests_for_other_platforms(self):
     
    254145        return disabled_feature_tests + webarchive_tests
    255146
    256     def _tests_from_skipped_file(self, skipped_file):
    257         tests_to_skip = []
    258         for line in skipped_file.readlines():
    259             line = line.strip()
    260             if line.startswith('#') or not len(line):
    261                 continue
    262             tests_to_skip.append(line)
    263         return tests_to_skip
    264 
    265     def _expectations_from_skipped_files(self):
    266         tests_to_skip = []
    267         for filename in self._skipped_file_paths():
    268             if not os.path.exists(filename):
    269                 _log.warn("Failed to open Skipped file: %s" % filename)
    270                 continue
    271             skipped_file = file(filename)
    272             tests_to_skip.extend(self._tests_from_skipped_file(skipped_file))
    273             skipped_file.close()
    274         return tests_to_skip
    275 
    276     def test_expectations(self):
    277         # The WebKit mac port uses a combination of a test_expectations file
    278         # and 'Skipped' files.
    279         expectations_file = self.path_to_test_expectations_file()
    280         expectations = file(expectations_file, "r").read()
    281         return expectations + self._skips()
    282 
    283     def _skips(self):
    284         # Each Skipped file contains a list of files
    285         # or directories to be skipped during the test run. The total list
    286         # of tests to skipped is given by the contents of the generic
    287         # Skipped file found in platform/X plus a version-specific file
    288         # found in platform/X-version. Duplicate entries are allowed.
    289         # This routine reads those files and turns contents into the
    290         # format expected by test_expectations.
    291 
    292         # Use a set to allow duplicates
    293         tests_to_skip = set(self._expectations_from_skipped_files())
    294 
    295         tests_to_skip.update(self._tests_for_other_platforms())
    296         tests_to_skip.update(self._tests_for_disabled_features())
    297         skip_lines = map(lambda test_path: "BUG_SKIPPED SKIP : %s = FAIL" %
    298                                 test_path, tests_to_skip)
    299         return "\n".join(skip_lines)
    300 
    301     def test_platform_name(self):
    302         return 'mac' + self.version()
    303 
    304     def test_platform_names(self):
    305         return ('mac', 'mac-tiger', 'mac-leopard', 'mac-snowleopard')
    306 
    307     def version(self):
    308         os_version_string = platform.mac_ver()[0]  # e.g. "10.5.6"
    309         if not os_version_string:
    310             return '-leopard'
    311         release_version = int(os_version_string.split('.')[1])
    312         if release_version == 4:
    313             return '-tiger'
    314         elif release_version == 5:
    315             return '-leopard'
    316         elif release_version == 6:
    317             return '-snowleopard'
    318         return ''
    319 
    320     def default_configuration(self):
    321         # This is a bit of a hack. This state exists in a much nicer form in
    322         # perl-land.
    323         configuration = ospath.relpath(
    324             self._webkit_build_directory(["--configuration"]),
    325             self._webkit_build_directory(["--top-level"]))
    326         assert(configuration == "Debug" or configuration == "Release")
    327         return configuration
    328 
    329     #
    330     # PROTECTED METHODS
    331     #
    332 
    333     def _webkit_build_directory(self, args):
    334         cmd = [self.script_path("webkit-build-directory")] + args
    335         return self._executive.run_command(cmd).rstrip()
    336 
    337     def _build_path(self, *comps):
    338         if not self._cached_build_root:
    339             self._cached_build_root = self._webkit_build_directory(["--top-level"])
    340         return os.path.join(self._cached_build_root, self._options.configuration,
    341                             *comps)
    342 
     147    # FIXME: This doesn't have anything to do with WebKit.
    343148    def _kill_process(self, pid):
    344149        """Forcefully kill the process.
     
    349154        os.kill(pid, signal.SIGKILL)
    350155
     156    # FIXME: This doesn't have anything to do with WebKit.
    351157    def _kill_all_process(self, process_name):
    352158        # On Mac OS X 10.6, killall has a new constraint: -SIGNALNAME or
     
    367173                            'apache2-httpd.conf')
    368174
    369     def _path_to_driver(self):
    370         return self._build_path('DumpRenderTree')
    371 
    372     def _path_to_helper(self):
    373         return None
    374 
    375     def _path_to_image_diff(self):
    376         return self._build_path('ImageDiff')
    377 
    378     def _path_to_wdiff(self):
    379         # FIXME: This does not exist on a default Mac OS X Leopard install.
    380         return 'wdiff'
    381 
     175    # FIXME: This doesn't have anything to do with WebKit.
    382176    def _shut_down_http_server(self, server_pid):
    383177        """Shut down the lighttpd web server. Blocks until it's fully
     
    389183        # server_pid is not set when "http_server.py stop" is run manually.
    390184        if server_pid is None:
    391             # TODO(mmoss) This isn't ideal, since it could conflict with
     185            # FIXME: This isn't ideal, since it could conflict with
    392186            # lighttpd processes not started by http_server.py,
    393187            # but good enough for now.
     
    396190            try:
    397191                os.kill(server_pid, signal.SIGTERM)
    398                 # TODO(mmoss) Maybe throw in a SIGKILL just to be sure?
     192                # FIXME: Maybe throw in a SIGKILL just to be sure?
    399193            except OSError:
    400194                # Sometimes we get a bad PID (e.g. from a stale httpd.pid
     
    402196                # 'killall' web servers.
    403197                self._shut_down_http_server(None)
    404 
    405 
    406 class MacDriver(base.Driver):
    407     """implementation of the DumpRenderTree interface."""
    408 
    409     def __init__(self, port, image_path, driver_options):
    410         self._port = port
    411         self._driver_options = driver_options
    412         self._image_path = image_path
    413 
    414         cmd = []
    415         # Hook for injecting valgrind or other runtime instrumentation,
    416         # used by e.g. tools/valgrind/valgrind_tests.py.
    417         wrapper = os.environ.get("BROWSER_WRAPPER", None)
    418         if wrapper != None:
    419             cmd += [wrapper]
    420         if self._port._options.wrapper:
    421             # This split() isn't really what we want -- it incorrectly will
    422             # split quoted strings within the wrapper argument -- but in
    423             # practice it shouldn't come up and the --help output warns
    424             # about it anyway.
    425             cmd += self._options.wrapper.split()
    426 
    427         cmd += [port._path_to_driver(), '-']
    428 
    429         if image_path:
    430             cmd.append('--pixel-tests')
    431         env = os.environ
    432         env['DYLD_FRAMEWORK_PATH'] = self._port._build_path()
    433         self._sproc = server_process.ServerProcess(self._port,
    434             "DumpRenderTree", cmd, env)
    435 
    436     def poll(self):
    437         return self._sproc.poll()
    438 
    439     def restart(self):
    440         self._sproc.stop()
    441         self._sproc.start()
    442         return
    443 
    444     def returncode(self):
    445         return self._proc.returncode()
    446 
    447     def run_test(self, uri, timeoutms, image_hash):
    448         if uri.startswith("file:///"):
    449             cmd = uri[7:]
    450         else:
    451             cmd = uri
    452 
    453         if image_hash:
    454             cmd += "'" + image_hash
    455         cmd += "\n"
    456 
    457         # pdb.set_trace()
    458         sp = self._sproc
    459         sp.write(cmd)
    460 
    461         have_seen_content_type = False
    462         actual_image_hash = None
    463         output = ''
    464         image = ''
    465 
    466         timeout = int(timeoutms) / 1000.0
    467         deadline = time.time() + timeout
    468         line = sp.read_line(timeout)
    469         while not sp.timed_out and not sp.crashed and line.rstrip() != "#EOF":
    470             if (line.startswith('Content-Type:') and not
    471                 have_seen_content_type):
    472                 have_seen_content_type = True
    473             else:
    474                 output += line
    475             line = sp.read_line(timeout)
    476             timeout = deadline - time.time()
    477 
    478         # Now read a second block of text for the optional image data
    479         remaining_length = -1
    480         HASH_HEADER = 'ActualHash: '
    481         LENGTH_HEADER = 'Content-Length: '
    482         line = sp.read_line(timeout)
    483         while not sp.timed_out and not sp.crashed and line.rstrip() != "#EOF":
    484             if line.startswith(HASH_HEADER):
    485                 actual_image_hash = line[len(HASH_HEADER):].strip()
    486             elif line.startswith('Content-Type:'):
    487                 pass
    488             elif line.startswith(LENGTH_HEADER):
    489                 timeout = deadline - time.time()
    490                 content_length = int(line[len(LENGTH_HEADER):])
    491                 image = sp.read(timeout, content_length)
    492             timeout = deadline - time.time()
    493             line = sp.read_line(timeout)
    494 
    495         if self._image_path and len(self._image_path):
    496             image_file = file(self._image_path, "wb")
    497             image_file.write(image)
    498             image_file.close()
    499         return (sp.crashed, sp.timed_out, actual_image_hash, output, sp.error)
    500 
    501     def stop(self):
    502         if self._sproc:
    503             self._sproc.stop()
    504             self._sproc = None
  • trunk/WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py

    r57422 r57423  
    2828# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2929
    30 """WebKit Mac implementation of the Port interface."""
     30"""WebKit implementations of the Port interface."""
    3131
    3232import logging
     
    4242import webbrowser
    4343
    44 import base
    45 import server_process
    46 
    47 import webkitpy
    4844import webkitpy.common.system.ospath as ospath
    49 
    50 _log = logging.getLogger("webkitpy.layout_tests.port.mac")
    51 
    52 
    53 class MacPort(base.Port):
    54     """WebKit Mac implementation of the Port class."""
     45import webkitpy.layout_tests.port.base as base
     46import webkitpy.layout_tests.port.server_process as server_process
     47
     48_log = logging.getLogger("webkitpy.layout_tests.port.webkit")
     49
     50
     51class WebKitPort(base.Port):
     52    """WebKit implementation of the Port class."""
    5553
    5654    def __init__(self, port_name=None, options=None):
    57         if port_name is None:
    58             port_name = 'mac' + self.version()
    5955        base.Port.__init__(self, port_name, options)
    6056        self._cached_build_root = None
     
    6662            options.pixel_tests = False
    6763
    68     def default_num_dump_render_trees(self):
    69         # FIXME: new-run-webkit-tests is unstable on Mac running more than
    70         # four threads in parallel.
    71         # See https://bugs.webkit.org/show_bug.cgi?id=36622
    72         num_dump_render_trees = base.Port.default_num_dump_render_trees(self)
    73         if num_dump_render_trees > 4:
    74             return 4
    75         return num_dump_render_trees
    76 
    7764    def baseline_path(self):
    7865        return self._webkit_baseline_path(self._name)
    7966
    8067    def baseline_search_path(self):
    81         dirs = []
    82         if self._name == 'mac-tiger':
    83             dirs.append(self._webkit_baseline_path(self._name))
    84         if self._name in ('mac-tiger', 'mac-leopard'):
    85             dirs.append(self._webkit_baseline_path('mac-leopard'))
    86         if self._name in ('mac-tiger', 'mac-leopard', 'mac-snowleopard'):
    87             dirs.append(self._webkit_baseline_path('mac-snowleopard'))
    88         dirs.append(self._webkit_baseline_path('mac'))
    89         return dirs
    90 
    91     def check_build(self, needs_http):
    92         build_drt_command = [
     68        raise NotImplementedError('WebKitPort.baseline_search_path')
     69
     70    def _build_driver(self):
     71        return not self._executive.run_command([
    9372            self.script_path("build-dumprendertree"),
    9473            self.flag_from_configuration(self._options.configuration),
    95         ]
    96         if self._executive.run_command(build_drt_command, return_exit_code=True):
    97             return False
    98 
    99         if not self.check_image_diff():
    100             return False
    101 
    102         driver_path = self._path_to_driver()
    103         if not os.path.exists(driver_path):
    104             _log.error("DumpRenderTree was not found at %s" % driver_path)
    105             return False
    106 
     74        ], return_exit_code=True)
     75
     76    def _build_java(self):
    10777        java_tests_path = os.path.join(self.layout_tests_dir(), "java")
    10878        build_java = ["/usr/bin/make", "-C", java_tests_path]
     
    11080            _log.error("Failed to build Java support files: %s" % build_java)
    11181            return False
    112 
     82        return True
     83
     84    def _check_driver(self):
     85        driver_path = self._path_to_driver()
     86        if not os.path.exists(driver_path):
     87            _log.error("DumpRenderTree was not found at %s" % driver_path)
     88            return False
     89        return True
     90
     91    def check_build(self, needs_http):
     92        if not self._build_driver():
     93            return False
     94        if not self.check_image_diff():
     95            return False
     96        if not self._check_driver():
     97            return False
     98        if not self._build_java():
     99            return False
    113100        return True
    114101
     
    138125        # FIXME: either expose the tolerance argument as a command-line
    139126        # parameter, or make it go away and aways use exact matches.
    140         cmd = [self._path_to_image_diff(), '--tolerance', '0.1']
    141         sp = server_process.ServerProcess(self, 'ImageDiff', cmd)
     127        command = [self._path_to_image_diff(), '--tolerance', '0.1']
     128        sp = server_process.ServerProcess(self, 'ImageDiff', command)
    142129
    143130        actual_length = os.stat(actual_filename).st_size
     
    182169
    183170    def path_to_test_expectations_file(self):
    184         return self.path_from_webkit_base('LayoutTests', 'platform',
    185            'mac', 'test_expectations.txt')
     171        raise NotImplementedError('WebKitPort.path_to_test_expectations_file')
    186172
    187173    def results_directory(self):
     174        # FIXME: Why do we say chromium here?  Maybe "new-run-webkit-tests-"?
    188175        return ('/tmp/run-chromium-webkit-tests-' +
    189176                self._options.results_directory)
     
    195182    def show_results_html_file(self, results_filename):
    196183        uri = self.filename_to_uri(results_filename)
     184        # FIXME: We should open results in the version of WebKit we built.
    197185        webbrowser.open(uri, new=1)
    198186
    199187    def start_driver(self, image_path, options):
    200         """Starts a new Driver and returns a handle to it."""
    201         return MacDriver(self, image_path, options)
     188        return WebKitDriver(self, image_path, options)
    202189
    203190    def test_base_platform_names(self):
     
    206193        return ('mac',)
    207194
    208     def _skipped_file_paths(self):
    209         # FIXME: This method will need to be made work for non-mac
    210         # platforms and moved into base.Port.
    211         skipped_files = []
    212         if self._name in ('mac-tiger', 'mac-leopard', 'mac-snowleopard'):
    213             skipped_files.append(os.path.join(
    214                 self._webkit_baseline_path(self._name), 'Skipped'))
    215         skipped_files.append(os.path.join(self._webkit_baseline_path('mac'),
    216                                           'Skipped'))
    217         return skipped_files
    218 
    219195    def _tests_for_other_platforms(self):
     196        raise NotImplementedError('WebKitPort._tests_for_other_platforms')
    220197        # The original run-webkit-tests builds up a "whitelist" of tests to
    221198        # run, and passes that to DumpRenderTree. new-run-webkit-tests assumes
     
    232209
    233210    def _tests_for_disabled_features(self):
     211        raise NotImplementedError('WebKitPort._tests_for_disabled_features')
    234212        # FIXME: This should use the feature detection from
    235213        # webkitperl/features.pm to match run-webkit-tests.
     
    300278
    301279    def test_platform_name(self):
    302         return 'mac' + self.version()
     280        raise NotImplementedError('WebKitPort.test_platform_name')
    303281
    304282    def test_platform_names(self):
    305         return ('mac', 'mac-tiger', 'mac-leopard', 'mac-snowleopard')
     283        return self.test_base_platform_names() + (
     284            'mac-tiger', 'mac-leopard', 'mac-snowleopard')
    306285
    307286    def version(self):
    308         os_version_string = platform.mac_ver()[0]  # e.g. "10.5.6"
    309         if not os_version_string:
    310             return '-leopard'
    311         release_version = int(os_version_string.split('.')[1])
    312         if release_version == 4:
    313             return '-tiger'
    314         elif release_version == 5:
    315             return '-leopard'
    316         elif release_version == 6:
    317             return '-snowleopard'
    318         return ''
     287        raise NotImplementedError('WebKitPort.version')
    319288
    320289    def default_configuration(self):
     
    327296        return configuration
    328297
    329     #
    330     # PROTECTED METHODS
    331     #
    332 
    333298    def _webkit_build_directory(self, args):
    334         cmd = [self.script_path("webkit-build-directory")] + args
    335         return self._executive.run_command(cmd).rstrip()
     299        args = [self.script_path("webkit-build-directory")] + args
     300        return self._executive.run_command(args).rstrip()
    336301
    337302    def _build_path(self, *comps):
     
    341306                            *comps)
    342307
    343     def _kill_process(self, pid):
    344         """Forcefully kill the process.
    345 
    346         Args:
    347         pid: The id of the process to be killed.
    348         """
    349         os.kill(pid, signal.SIGKILL)
    350 
    351     def _kill_all_process(self, process_name):
    352         # On Mac OS X 10.6, killall has a new constraint: -SIGNALNAME or
    353         # -SIGNALNUMBER must come first.  Example problem:
    354         #   $ killall -u $USER -TERM lighttpd
    355         #   killall: illegal option -- T
    356         # Use of the earlier -TERM placement is just fine on 10.5.
    357         null = open(os.devnull)
    358         subprocess.call(['killall', '-TERM', '-u', os.getenv('USER'),
    359                         process_name], stderr=null)
    360         null.close()
    361 
    362     def _path_to_apache(self):
    363         return '/usr/sbin/httpd'
    364 
    365     def _path_to_apache_config_file(self):
    366         return os.path.join(self.layout_tests_dir(), 'http', 'conf',
    367                             'apache2-httpd.conf')
    368 
    369308    def _path_to_driver(self):
    370309        return self._build_path('DumpRenderTree')
     
    380319        return 'wdiff'
    381320
    382     def _shut_down_http_server(self, server_pid):
    383         """Shut down the lighttpd web server. Blocks until it's fully
    384         shut down.
    385 
    386         Args:
    387             server_pid: The process ID of the running server.
    388         """
    389         # server_pid is not set when "http_server.py stop" is run manually.
    390         if server_pid is None:
    391             # TODO(mmoss) This isn't ideal, since it could conflict with
    392             # lighttpd processes not started by http_server.py,
    393             # but good enough for now.
    394             self._kill_all_process('httpd')
    395         else:
    396             try:
    397                 os.kill(server_pid, signal.SIGTERM)
    398                 # TODO(mmoss) Maybe throw in a SIGKILL just to be sure?
    399             except OSError:
    400                 # Sometimes we get a bad PID (e.g. from a stale httpd.pid
    401                 # file), so if kill fails on the given PID, just try to
    402                 # 'killall' web servers.
    403                 self._shut_down_http_server(None)
    404 
    405 
    406 class MacDriver(base.Driver):
    407     """implementation of the DumpRenderTree interface."""
     321
     322class WebKitDriver(base.Driver):
     323    """WebKit implementation of the DumpRenderTree interface."""
    408324
    409325    def __init__(self, port, image_path, driver_options):
     
    412328        self._image_path = image_path
    413329
    414         cmd = []
     330        command = []
    415331        # Hook for injecting valgrind or other runtime instrumentation,
    416332        # used by e.g. tools/valgrind/valgrind_tests.py.
    417333        wrapper = os.environ.get("BROWSER_WRAPPER", None)
    418334        if wrapper != None:
    419             cmd += [wrapper]
     335            command += [wrapper]
    420336        if self._port._options.wrapper:
    421337            # This split() isn't really what we want -- it incorrectly will
     
    423339            # practice it shouldn't come up and the --help output warns
    424340            # about it anyway.
    425             cmd += self._options.wrapper.split()
    426 
    427         cmd += [port._path_to_driver(), '-']
     341            # FIXME: Use a real shell parser.
     342            command += self._options.wrapper.split()
     343
     344        command += [port._path_to_driver(), '-']
    428345
    429346        if image_path:
    430             cmd.append('--pixel-tests')
    431         env = os.environ
    432         env['DYLD_FRAMEWORK_PATH'] = self._port._build_path()
    433         self._sproc = server_process.ServerProcess(self._port,
    434             "DumpRenderTree", cmd, env)
     347            command.append('--pixel-tests')
     348        environment = os.environ
     349        environment['DYLD_FRAMEWORK_PATH'] = self._port._build_path()
     350        self._server_process = server_process.ServerProcess(self._port,
     351            "DumpRenderTree", command, environment)
    435352
    436353    def poll(self):
    437         return self._sproc.poll()
     354        return self._server_process.poll()
    438355
    439356    def restart(self):
    440         self._sproc.stop()
    441         self._sproc.start()
     357        self._server_process.stop()
     358        self._server_process.start()
    442359        return
    443360
    444361    def returncode(self):
    445         return self._proc.returncode()
    446 
     362        return self._server_process.returncode()
     363
     364    # FIXME: This function is huge.
    447365    def run_test(self, uri, timeoutms, image_hash):
    448366        if uri.startswith("file:///"):
    449             cmd = uri[7:]
     367            command = uri[7:]
    450368        else:
    451             cmd = uri
     369            command = uri
    452370
    453371        if image_hash:
    454             cmd += "'" + image_hash
    455         cmd += "\n"
     372            command += "'" + image_hash
     373        command += "\n"
    456374
    457375        # pdb.set_trace()
    458         sp = self._sproc
    459         sp.write(cmd)
     376        self._server_process.write(command)
    460377
    461378        have_seen_content_type = False
     
    466383        timeout = int(timeoutms) / 1000.0
    467384        deadline = time.time() + timeout
    468         line = sp.read_line(timeout)
    469         while not sp.timed_out and not sp.crashed and line.rstrip() != "#EOF":
     385        line = self._server_process.read_line(timeout)
     386        while (not self._server_process.timed_out
     387               and not self._server_process.crashed
     388               and line.rstrip() != "#EOF"):
    470389            if (line.startswith('Content-Type:') and not
    471390                have_seen_content_type):
     
    473392            else:
    474393                output += line
    475             line = sp.read_line(timeout)
     394            line = self._server_process.read_line(timeout)
    476395            timeout = deadline - time.time()
    477396
     
    480399        HASH_HEADER = 'ActualHash: '
    481400        LENGTH_HEADER = 'Content-Length: '
    482         line = sp.read_line(timeout)
    483         while not sp.timed_out and not sp.crashed and line.rstrip() != "#EOF":
     401        line = self._server_process.read_line(timeout)
     402        while (not self._server_process.timed_out
     403               and not self._server_process.crashed
     404               and line.rstrip() != "#EOF"):
    484405            if line.startswith(HASH_HEADER):
    485406                actual_image_hash = line[len(HASH_HEADER):].strip()
     
    489410                timeout = deadline - time.time()
    490411                content_length = int(line[len(LENGTH_HEADER):])
    491                 image = sp.read(timeout, content_length)
     412                image = self._server_process.read(timeout, content_length)
    492413            timeout = deadline - time.time()
    493             line = sp.read_line(timeout)
     414            line = self._server_process.read_line(timeout)
    494415
    495416        if self._image_path and len(self._image_path):
     
    497418            image_file.write(image)
    498419            image_file.close()
    499         return (sp.crashed, sp.timed_out, actual_image_hash, output, sp.error)
     420        return (self._server_process.crashed,
     421                self._server_process.timed_out,
     422                actual_image_hash,
     423                output,
     424                self._server_process.error)
    500425
    501426    def stop(self):
    502         if self._sproc:
    503             self._sproc.stop()
    504             self._sproc = None
     427        if self._server_process:
     428            self._server_process.stop()
     429            self._server_process = None
  • trunk/WebKitTools/Scripts/webkitpy/layout_tests/port/websocket_server.py

    r56614 r57423  
    251251
    252252        _log.debug('Shutting down %s server %d.' % (self._server_name, pid))
     253        # FIXME: We shouldn't be calling a protected method of the port_obj!
    253254        self._port_obj._kill_process(pid)
    254255
Note: See TracChangeset for help on using the changeset viewer.