Diff
Modified: trunk/Tools/ChangeLog (106415 => 106416)
--- trunk/Tools/ChangeLog 2012-02-01 01:21:32 UTC (rev 106415)
+++ trunk/Tools/ChangeLog 2012-02-01 01:41:35 UTC (rev 106416)
@@ -1,3 +1,33 @@
+2012-01-31 Dirk Pranke <dpra...@chromium.org>
+
+ nrwt: fix the mock port to work with DriverProxy, reftests
+ https://bugs.webkit.org/show_bug.cgi?id=77170
+
+ Reviewed by Eric Seidel.
+
+ The DryrunPort used for benchmarking and testing NRWT has been
+ broken since we added the DriverProxy code. It isn't really
+ needed any more, so I've removed it.
+
+ The MockDRT port was also broken by DriverProxy, and moreover,
+ never worked w/ reftests. Since we don't exercise this module in
+ the unit tests, the code had also bitrotted some. I have cleaned
+ it up and made it use DriverInput and DriverOutput for
+ consistency.
+
+ * Scripts/webkitpy/layout_tests/port/dryrun.py:
+ (DryRunPort.__init__):
+ (DryRunPort):
+ (DryRunPort.real_name):
+ (DryRunPort.create_driver):
+ (DryRunPort.driver_cmd_line):
+ (DryRunPort._driver_class):
+ (DryrunDriver):
+ (DryrunDriver.run_test):
+ * Scripts/webkitpy/layout_tests/port/mock_drt.py:
+ (MockDRTPort.create_driver):
+ (MockChromiumDRT.run_one_test):
+
2012-01-31 Ojan Vafai <o...@chromium.org>
run-webkit-tests calls out to webkit-build-directory twice
Deleted: trunk/Tools/Scripts/webkitpy/layout_tests/port/dryrun.py (106415 => 106416)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/dryrun.py 2012-02-01 01:21:32 UTC (rev 106415)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/dryrun.py 2012-02-01 01:41:35 UTC (rev 106416)
@@ -1,136 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2010 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the Google name nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""This is a test implementation of the Port interface that generates the
- correct output for every test. It can be used for perf testing, because
- it is pretty much a lower limit on how fast a port can possibly run.
-
- This implementation acts as a wrapper around a real port (the real port
- is held as a delegate object). To specify which port, use the port name
- 'dryrun-XXX' (e.g., 'dryrun-chromium-mac-leopard'). If you use just
- 'dryrun', it uses the default port.
-
- Note that because this is really acting as a wrapper around the underlying
- port, you must be able to run the underlying port as well
- (check_build() and check_sys_deps() must pass and auxiliary binaries
- like layout_test_helper and httpd must work).
-
- This implementation also modifies the test expectations so that all
- tests are either SKIPPED or expected to PASS."""
-
-from __future__ import with_statement
-
-import os
-import sys
-import time
-
-from webkitpy.layout_tests.port import Driver, DriverOutput, factory
-
-
-# Note that we don't inherit from base.Port in order for delegation to
-# work properly: except for the methods defined here, we want to ensure that
-# all of the methods are passed to the __delegate, not to the base class.
-class DryRunPort(object):
- """DryRun implementation of the Port interface."""
- port_name = 'dryrun'
-
- @classmethod
- def determine_full_port_name(cls, host, options, port_name):
- """Return a fully-specified port name that can be used to construct objects."""
- # Subclasses will usually override this.
- return port_name
-
- def __init__(self, host, port_name, **kwargs):
- self.__delegate = factory.PortFactory(host).get(port_name.replace('dryrun-', ''), **kwargs)
-
- def __getattr__(self, name):
- return getattr(self.__delegate, name)
-
- def acquire_http_lock(self):
- pass
-
- def release_http_lock(self):
- pass
-
- def check_build(self, needs_http):
- return True
-
- def check_sys_deps(self, needs_http):
- return True
-
- def start_helper(self):
- pass
-
- def start_http_server(self):
- pass
-
- def start_websocket_server(self):
- pass
-
- def stop_helper(self):
- pass
-
- def stop_http_server(self):
- pass
-
- def stop_websocket_server(self):
- pass
-
- def driver_class(self):
- return DryrunDriver
-
-
-class DryrunDriver(Driver):
- """Dryrun implementation of the DumpRenderTree / Driver interface."""
-
- def cmd_line(self):
- return ['None']
-
- def run_test(self, driver_input):
- start_time = time.time()
- fs = self._port._filesystem
- if (self._port.is_reftest(driver_input.test_name) or driver_input.test_name.endswith('-expected.html')):
- text = 'test-text'
- image = 'test-image'
- checksum = 'test-checksum'
- audio = None
- elif driver_input.test_name.endswith('-expected-mismatch.html'):
- text = 'test-text-mismatch'
- image = 'test-image-mismatch'
- checksum = 'test-checksum-mismatch'
- audio = None
- else:
- text = self._port.expected_text(driver_input.test_name)
- image = self._port.expected_image(driver_input.test_name)
- checksum = self._port.expected_checksum(driver_input.test_name)
- audio = self._port.expected_audio(driver_input.test_name)
- return DriverOutput(text, image, checksum, audio, crash=False, test_time=time.time() - start_time, timeout=False, error='')
-
- def stop(self):
- pass
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/factory.py (106415 => 106416)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/factory.py 2012-02-01 01:21:32 UTC (rev 106415)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/factory.py 2012-02-01 01:41:35 UTC (rev 106416)
@@ -48,7 +48,6 @@
'chromium_linux.ChromiumLinuxPort',
'chromium_mac.ChromiumMacPort',
'chromium_win.ChromiumWinPort',
- 'dryrun.DryRunPort',
'efl.EflPort',
'google_chrome.GoogleChromeLinux32Port',
'google_chrome.GoogleChromeLinux64Port',
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/factory_unittest.py (106415 => 106416)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/factory_unittest.py 2012-02-01 01:21:32 UTC (rev 106415)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/factory_unittest.py 2012-02-01 01:41:35 UTC (rev 106416)
@@ -35,7 +35,6 @@
from webkitpy.layout_tests.port import chromium_linux
from webkitpy.layout_tests.port import chromium_mac
from webkitpy.layout_tests.port import chromium_win
-from webkitpy.layout_tests.port import dryrun
from webkitpy.layout_tests.port import factory
from webkitpy.layout_tests.port import google_chrome
from webkitpy.layout_tests.port import gtk
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py (106415 => 106416)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py 2012-02-01 01:21:32 UTC (rev 106415)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py 2012-02-01 01:41:35 UTC (rev 106416)
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-# Copyright (C) 2011 Google Inc. All rights reserved.
+# Copyright (c) 2012 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@@ -39,9 +39,17 @@
import base64
import logging
+import os
import sys
+# Since we execute this script directly as part of the unit tests, we need to ensure
+# that Tools/Scripts is in sys.path for the next imports to work correctly.
+script_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
+if script_dir not in sys.path:
+ sys.path.append(script_dir)
+
from webkitpy.common.system.systemhost import SystemHost
+from webkitpy.layout_tests.port.driver import DriverInput, DriverOutput, DriverProxy
from webkitpy.layout_tests.port.factory import PortFactory
from webkitpy.tool.mocktool import MockOptions
@@ -49,19 +57,15 @@
class MockDRTPort(object):
- """MockPort implementation of the Port interface."""
port_name = 'mock'
@classmethod
def determine_full_port_name(cls, host, options, port_name):
- """Return a fully-specified port name that can be used to construct objects."""
- # Subclasses will usually override this.
return port_name
def __init__(self, host, port_name, **kwargs):
self.__delegate = PortFactory(host).get(port_name.replace('mock-', ''), **kwargs)
self.__real_name = port_name
- self._host = host
def real_name(self):
return self.__real_name
@@ -75,32 +79,32 @@
def check_sys_deps(self, needs_http):
return True
- def driver_cmd_line(self):
- driver = self.create_driver(0)
- return driver.cmd_line()
+ def create_driver(self, worker_number, no_timeout=False):
+ # The magic of the MockDRTPort is that we create a driver that has a
+ # cmd_line() method monkey-patched to invoke this script instead of DRT.
+ return DriverProxy(self, worker_number, self._mocked_driver_maker, pixel_tests=self.get_option('pixel_tests'), no_timeout=no_timeout)
- def _path_to_driver(self):
- return self._host.filesystem.abspath(__file__)
+ @staticmethod
+ def _mocked_driver_maker(port, worker_number, pixel_tests, no_timeout=False):
+ path_to_this_file = port.host.filesystem.abspath(__file__.replace('.pyc', '.py'))
+ driver = port.__delegate._driver_class()(port, worker_number, pixel_tests, no_timeout)
+ driver.cmd_line = port._overriding_cmd_line(driver.cmd_line,
+ port.__delegate._path_to_driver(),
+ sys.executable,
+ path_to_this_file,
+ port.__delegate.name())
+ return driver
- def create_driver(self, worker_number):
- # We need to create a driver object as the delegate would, but
- # overwrite the path to the driver binary in its command line. We do
- # this by actually overwriting its cmd_line() method with a proxy
- # method that splices in the mock_drt path and command line arguments
- # in place of the actual path to the driver binary.
+ @staticmethod
+ def _overriding_cmd_line(original_cmd_line, driver_path, python_exe, this_file, port_name):
+ def new_cmd_line():
+ cmd_line = original_cmd_line()
+ index = cmd_line.index(driver_path)
+ cmd_line[index:index + 1] = [python_exe, this_file, '--platform', port_name]
+ return cmd_line
- def overriding_cmd_line():
- cmd = self.__original_driver_cmd_line()
- index = cmd.index(self.__delegate._path_to_driver())
- # FIXME: Why does this need to use sys.executable (instead of something mockable)?
- cmd[index:index + 1] = [sys.executable, self._path_to_driver(), '--platform', self.name()]
- return cmd
+ return new_cmd_line
- delegated_driver = self.__delegate.create_driver(worker_number)
- self.__original_driver_cmd_line = delegated_driver.cmd_line
- delegated_driver.cmd_line = overriding_cmd_line
- return delegated_driver
-
def start_helper(self):
pass
@@ -164,26 +168,7 @@
return (options, [])
-# FIXME: Should probably change this to use DriverInput after
-# https://bugs.webkit.org/show_bug.cgi?id=53004 lands (it's landed as of 2/3/11).
-class _DRTInput(object):
- def __init__(self, line):
- vals = line.strip().split("'")
- if len(vals) == 1:
- self.uri = vals[0]
- self.checksum = None
- else:
- self.uri = vals[0]
- self.checksum = vals[1]
-
-
class MockDRT(object):
- @classmethod
- def determine_full_port_name(cls, host, options, port_name):
- """Return a fully-specified port name that can be used to construct objects."""
- # Subclasses will usually override this.
- return cls.port_name
-
def __init__(self, options, args, host, stdin, stdout, stderr):
self._options = options
self._args = args
@@ -202,91 +187,105 @@
while True:
line = self._stdin.readline()
if not line:
- break
- self.run_one_test(self.parse_input(line))
- return 0
+ return 0
+ self.run_one_test(self.input_from_line(line))
- def parse_input(self, line):
- return _DRTInput(line)
+ def input_from_line(self, line):
+ vals = line.strip().split("'")
+ if len(vals) == 1:
+ uri = vals[0]
+ checksum = None
+ else:
+ uri = vals[0]
+ checksum = vals[1]
+ if uri.startswith('http://') or uri.startswith('https://'):
+ test_name = self._driver.uri_to_test(uri)
+ else:
+ test_name = self._port.relative_test_filename(uri)
- def run_one_test(self, test_input):
+ is_reftest = (self._port.is_reftest(test_name) or
+ test_name.endswith('-expected.html') or
+ test_name.endswith('-mismatch.html'))
+ return DriverInput(test_name, 0, checksum, is_reftest)
+
+ def output_for_test(self, test_input):
port = self._port
- if test_input.uri.startswith('http://') or test_input.uri.startswith('https://'):
- test_name = self._driver.uri_to_test(test_input.uri)
- else:
- test_name = port.relative_test_filename(test_input.uri)
+ actual_text = port.expected_text(test_input.test_name)
+ actual_audio = port.expected_audio(test_input.test_name)
+ actual_image = None
+ actual_checksum = None
+ if test_input.is_reftest:
+ # Make up some output for reftests.
+ actual_text = 'reference text\n'
+ actual_checksum = 'None'
+ actual_image = 'blank'
+ if test_name.endswith('-mismatch.html'):
+ actual_checksum = 'True'
+ actual_image = 'not blank'
+ elif self._options.pixel_tests and test_input.image_hash:
+ actual_checksum = port.expected_checksum(test_input.test_name)
+ actual_image = port.expected_image(test_input.test_name)
- actual_text = port.expected_text(test_name)
- actual_audio = port.expected_audio(test_name)
- if self._options.pixel_tests and test_input.checksum:
- actual_checksum = port.expected_checksum(test_name)
- actual_image = port.expected_image(test_name)
+ return DriverOutput(actual_text, actual_image, actual_checksum, actual_audio)
- if actual_audio:
+ def run_one_test(self, test_input):
+ output = self.output_for_test(test_input)
+
+ if output.audio:
self._stdout.write('Content-Type: audio/wav\n')
self._stdout.write('Content-Transfer-Encoding: base64\n')
- output = base64.b64encode(actual_audio)
- self._stdout.write(output)
+ self._stdout.write(base64.b64encode(output.audio))
else:
self._stdout.write('Content-Type: text/plain\n')
# FIXME: Note that we don't ensure there is a trailing newline!
# This mirrors actual (Mac) DRT behavior but is a bug.
- self._stdout.write(actual_text)
+ self._stdout.write(output.text)
self._stdout.write('#EOF\n')
- if self._options.pixel_tests and test_input.checksum:
+ if self._options.pixel_tests and (test_input.image_hash or is_reftest):
self._stdout.write('\n')
- self._stdout.write('ActualHash: %s\n' % actual_checksum)
- self._stdout.write('ExpectedHash: %s\n' % test_input.checksum)
- if actual_checksum != test_input.checksum:
+ self._stdout.write('ActualHash: %s\n' % output.image_hash)
+ self._stdout.write('ExpectedHash: %s\n' % test_input.image_hash)
+ if output.image_hash != test_input.image_hash:
self._stdout.write('Content-Type: image/png\n')
- self._stdout.write('Content-Length: %s\n' % len(actual_image))
- self._stdout.write(actual_image)
+ self._stdout.write('Content-Length: %s\n' % len(output.image))
+ self._stdout.write(output.image)
self._stdout.write('#EOF\n')
self._stdout.flush()
+ self._stderr.write('#EOF\n')
self._stderr.flush()
-# FIXME: Should probably change this to use DriverInput after
-# https://bugs.webkit.org/show_bug.cgi?id=53004 lands.
-class _ChromiumDRTInput(_DRTInput):
- def __init__(self, line):
+class MockChromiumDRT(MockDRT):
+ def input_from_line(self, line):
vals = line.strip().split()
if len(vals) == 3:
- self.uri, self.timeout, self.checksum = vals
+ uri, timeout, checksum = vals
else:
- self.uri = vals[0]
- self.timeout = vals[1]
- self.checksum = None
+ uri, timeout = vals
+ checksum = None
+ test_name = self._driver.uri_to_test(uri)
+ is_reftest = (self._port.is_reftest(test_name) or
+ test_name.endswith('-expected.html') or
+ test_name.endswith('-mismatch.html'))
-class MockChromiumDRT(MockDRT):
- def parse_input(self, line):
- return _ChromiumDRTInput(line)
+ return DriverInput(test_name, timeout, checksum, is_reftest)
def run_one_test(self, test_input):
- port = self._port
- test_name = self._driver.uri_to_test(test_input.uri)
+ output = self.output_for_test(test_input)
- actual_text = port.expected_text(test_name)
- actual_image = ''
- actual_checksum = ''
- if self._options.pixel_tests and test_input.checksum:
- actual_checksum = port.expected_checksum(test_name)
- if actual_checksum != test_input.checksum:
- actual_image = port.expected_image(test_name)
-
- self._stdout.write("#URL:%s\n" % test_input.uri)
- if self._options.pixel_tests and test_input.checksum:
- self._stdout.write("#MD5:%s\n" % actual_checksum)
+ self._stdout.write("#URL:%s\n" % self._driver.test_to_uri(test_input.test_name))
+ if self._options.pixel_tests and (test_input.image_hash or test_input.is_reftest):
+ self._stdout.write("#MD5:%s\n" % output.image_hash)
self._host.filesystem.write_binary_file(self._options.pixel_path,
- actual_image)
- self._stdout.write(actual_text)
+ output.image)
+ self._stdout.write(output.text)
# FIXME: (See above FIXME as well). Chromium DRT appears to always
# ensure the text output has a trailing newline. Mac DRT does not.
- if not actual_text.endswith('\n'):
+ if not output.text.endswith('\n'):
self._stdout.write('\n')
self._stdout.write('#EOF\n')
self._stdout.flush()
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py (106415 => 106416)
--- trunk/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py 2012-02-01 01:21:32 UTC (rev 106415)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py 2012-02-01 01:41:35 UTC (rev 106416)
@@ -163,7 +163,7 @@
# We use the StringIO.buflist here instead of getvalue() because
# the StringIO might be a mix of unicode/ascii and 8-bit strings.
self.assertEqual(stdout.buflist, drt_output)
- self.assertEqual(stderr.getvalue(), '')
+ self.assertEqual(stderr.getvalue(), '' if options.chromium else '#EOF\n')
def test_main(self):
host = MockSystemHost()
Modified: trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py (106415 => 106416)
--- trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py 2012-02-01 01:21:32 UTC (rev 106415)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests_integrationtest.py 2012-02-01 01:41:35 UTC (rev 106416)
@@ -923,21 +923,5 @@
"/platform/test-mac-leopard/failures/expected/missing_image", [".txt", ".png"], err)
-class DryrunTest(unittest.TestCase):
- # FIXME: it's hard to know which platforms are safe to test; the
- # chromium platforms require a chromium checkout, and the mac platform
- # requires fcntl, so it can't be tested on win32, etc. There is
- # probably a better way of handling this.
- def disabled_test_darwin(self):
- if sys.platform != "darwin":
- return
-
- self.assertTrue(passing_run(['--platform', 'dryrun', 'fast/html'], tests_included=True))
- self.assertTrue(passing_run(['--platform', 'dryrun-mac', 'fast/html'], tests_included=True))
-
- def test_test(self):
- self.assertTrue(passing_run(['--platform', 'dryrun-test', '--pixel-tests']))
-
-
if __name__ == '__main__':
unittest.main()