From f5003089817ff9c07ee3f3e64abf4df5903b406c Mon Sep 17 00:00:00 2001 From: "dpranke@chromium.org" Date: Wed, 26 Jan 2011 20:45:39 +0000 Subject: [PATCH] 2011-01-26 Dirk Pranke Reviewed by Tony Chang. new-run-webkit-tests: add a "mock DRT" port implementation and a separate class that emulates what we expect the DumpRenderTree behavior to be. This will eventually replace port/dryrun.py and allow us to get better test coverage of the new-run-webkit-tests code as well as a reference for what new-run-webkit-tests expects from DRT. This is the first attempt at this, and it is pretty bare-boned. It really only has been tested on the 'mac' port (and a little on the 'chromium-mac' port. https://bugs.webkit.org/show_bug.cgi?id=53126 * Scripts/webkitpy/layout_tests/port/mock_drt.py: Added. * Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py: Added. * Scripts/webkitpy/layout_tests/port/factory.py: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76709 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Tools/ChangeLog | 22 ++ .../webkitpy/layout_tests/port/factory.py | 5 +- .../webkitpy/layout_tests/port/mock_drt.py | 207 ++++++++++++++++++ .../layout_tests/port/mock_drt_unittest.py | 115 ++++++++++ 4 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py create mode 100644 Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py diff --git a/Tools/ChangeLog b/Tools/ChangeLog index 58659e69c65d..1a0fcdfb8e62 100644 --- a/Tools/ChangeLog +++ b/Tools/ChangeLog @@ -1,3 +1,25 @@ +2011-01-26 Dirk Pranke + + Reviewed by Tony Chang. + + new-run-webkit-tests: add a "mock DRT" port implementation + and a separate class that emulates what we expect the + DumpRenderTree behavior to be. + + This will eventually replace port/dryrun.py and allow us to get + better test coverage of the new-run-webkit-tests code as well as + a reference for what new-run-webkit-tests expects from DRT. + + This is the first attempt at this, and it is pretty bare-boned. It + really only has been tested on the 'mac' port (and a little on + the 'chromium-mac' port. + + https://bugs.webkit.org/show_bug.cgi?id=53126 + + * Scripts/webkitpy/layout_tests/port/mock_drt.py: Added. + * Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py: Added. + * Scripts/webkitpy/layout_tests/port/factory.py: + 2011-01-26 Xianzhu Wang Reviewed by Tony Chang. diff --git a/Tools/Scripts/webkitpy/layout_tests/port/factory.py b/Tools/Scripts/webkitpy/layout_tests/port/factory.py index 675e0c096889..051565933887 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/factory.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/factory.py @@ -32,7 +32,7 @@ import sys -ALL_PORT_NAMES = ['test', 'dryrun', 'mac', 'win', 'gtk', 'qt', 'chromium-mac', +ALL_PORT_NAMES = ['test', 'dryrun', 'mock', 'mac', 'win', 'gtk', 'qt', 'chromium-mac', 'chromium-linux', 'chromium-win', 'google-chrome-win', 'google-chrome-mac', 'google-chrome-linux32', 'google-chrome-linux64'] @@ -76,6 +76,9 @@ def _get_kwargs(**kwargs): elif port_to_use.startswith('dryrun'): import dryrun maker = dryrun.DryRunPort + elif port_to_use.startswith('mock'): + import mock_drt + maker = mock_drt.MockDRTPort elif port_to_use.startswith('mac'): import mac maker = mac.MacPort diff --git a/Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py b/Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py new file mode 100644 index 000000000000..36c4f7125592 --- /dev/null +++ b/Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python +# Copyright (C) 2011 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 an implementation of the Port interface that overrides other +ports and changes the Driver binary to "MockDRT". +""" + +import logging +import optparse +import os +import sys + +from webkitpy.layout_tests.port import base +from webkitpy.layout_tests.port import factory + +_log = logging.getLogger(__name__) + + +class MockDRTPort(object): + """MockPort implementation of the Port interface.""" + + def __init__(self, **kwargs): + prefix = 'mock-' + if 'port_name' in kwargs: + if kwargs['port_name'].startswith(prefix): + kwargs['port_name'] = kwargs['port_name'][len(prefix):] + else: + kwargs['port_name'] = None + self.__delegate = factory.get(**kwargs) + + def __getattr__(self, name): + return getattr(self.__delegate, name) + + def check_build(self, needs_http): + return True + + def check_sys_deps(self, needs_http): + return True + + def driver_cmd_line(self): + driver = self.create_driver(0) + return driver.cmd_line() + + def _path_to_driver(self): + return os.path.abspath(__file__) + + 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. + + # FIXME: This doesn't yet work for Chromium test_shell ports. + def overriding_cmd_line(): + cmd = self.__original_driver_cmd_line() + index = cmd.index(self.__delegate._path_to_driver()) + cmd[index:index + 1] = [sys.executable, self._path_to_driver(), + '--platform', self.name()] + return cmd + + 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 + + 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 main(argv, stdin, stdout, stderr): + """Run the tests.""" + + options, args = parse_options(argv) + drt = MockDRT(options, args, stdin, stdout, stderr) + return drt.run() + + +def parse_options(argv): + # FIXME: We need to figure out how to handle variants that have + # different command-line conventions. + option_list = [ + optparse.make_option('--platform', action='store', + help='platform to emulate'), + optparse.make_option('--layout-tests', action='store_true', + default=True, help='run layout tests'), + optparse.make_option('--pixel-tests', action='store_true', + default=False, + help='output image for pixel tests'), + ] + option_parser = optparse.OptionParser(option_list=option_list) + return option_parser.parse_args(argv) + + +class MockDRT(object): + def __init__(self, options, args, stdin, stdout, stderr): + self._options = options + self._args = args + self._stdout = stdout + self._stdin = stdin + self._stderr = stderr + + port_name = None + if options.platform: + port_name = options.platform + self._port = factory.get(port_name, options=options) + self._exit_status = 0 + + def run(self): + try: + while True: + line = self._stdin.readline() + if not line: + break + + url, expected_checksum = self.parse_input(line) + self.run_one_test(url, expected_checksum) + except ValueError, e: + self._stderr.write("MockDRT exiting, ValueError raised: '%s'\n" + % str(e)) + self._exit_status = 1 + except Exception, e: + self._stderr.write("MockDRT exiting, unexpected exception: '%s'\n" + % str(e)) + self._exit_status = -1 + + return self._exit_status + + def parse_input(self, line): + line = line.strip() + if "'" in line: + return line.split("'", 1) + return (line, None) + + def run_one_test(self, url, expected_checksum): + port = self._port + if url.startswith('file:///') or url.startswith('http'): + test_name = port.uri_to_test_name(url) + test_path = port.path_from_webkit_base('LayoutTests', test_name) + else: + test_path = url + + actual_text = port.expected_text(test_path) + if self._options.pixel_tests and expected_checksum: + actual_checksum = port.expected_checksum(test_path) + actual_image = port.expected_image(test_path) + + self._stdout.write("Content-Type: text/plain\n") + self._stdout.write(actual_text) + self._stdout.write("#EOF\n") + + if self._options.pixel_tests and expected_checksum: + self._stdout.write("\n") + self._stdout.write("ActualHash: %s\n" % actual_checksum) + self._stdout.write("ExpectedHash: %s\n" % expected_checksum) + if actual_checksum != expected_checksum: + self._stdout.write("Content-Length: %s\n\n" % len(actual_image)) + self._stdout.write(actual_image) + self._stdout.write("#EOF\n") + self._stdout.flush() + self._stderr.flush() + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:], sys.stdin, sys.stdout, sys.stderr)) diff --git a/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py b/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py new file mode 100644 index 000000000000..fbe911cb52e4 --- /dev/null +++ b/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# Copyright (C) 2011 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 name of Google Inc. 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. + +"""Unit tests for MockDRT.""" + +import unittest + +from webkitpy.common import newstringio + +from webkitpy.layout_tests.port import mock_drt +from webkitpy.layout_tests.port import factory +from webkitpy.layout_tests.port import port_testcase + + +class MockDRTPortTest(port_testcase.PortTestCase): + def make_port(self): + return mock_drt.MockDRTPort() + + +class MockDRTTest(unittest.TestCase): + def setUp(self): + # We base our tests on the mac-snowleopard port. + self._port = factory.get('mac-snowleopard') + self._layout_tests_dir = self._port.layout_tests_dir() + + def to_path(self, test_name): + return self._port._filesystem.join(self._layout_tests_dir, test_name) + + def input_line(self, test_name, checksum=None): + url = self._port.filename_to_uri(self.to_path(test_name)) + if checksum: + return url + "'" + checksum + '\n' + return url + '\n' + + def make_drt(self, input_string, args=None, extra_args=None): + args = args or ['--platform', 'mac-snowleopard', '-'] + extra_args = extra_args or [] + args += extra_args + stdin = newstringio.StringIO(input_string) + stdout = newstringio.StringIO() + stderr = newstringio.StringIO() + options, args = mock_drt.parse_options(args) + drt = mock_drt.MockDRT(options, args, stdin, stdout, stderr) + return (drt, stdout, stderr) + + def make_input_output(self, test_name, pixel_tests): + path = self.to_path(test_name) + expected_checksum = None + if pixel_tests: + expected_checksum = self._port.expected_checksum(path) + drt_input = self.input_line(test_name, expected_checksum) + text_output = self._port.expected_text(path) + + if pixel_tests: + drt_output = ( + "Content-Type: text/plain\n" + "%s#EOF\n" + "\n" + "ActualHash: %s\n" + "ExpectedHash: %s\n" + "#EOF\n") % (text_output, expected_checksum, expected_checksum) + else: + drt_output = ( + "Content-Type: text/plain\n" + "%s#EOF\n" + "#EOF\n") % text_output + + return (drt_input, drt_output) + + def assertTest(self, test_name, pixel_tests): + drt_input, drt_output = self.make_input_output(test_name, pixel_tests) + extra_args = [] + if pixel_tests: + extra_args = ['--pixel-tests'] + drt, stdout, stderr = self.make_drt(drt_input, extra_args) + res = drt.run() + self.assertEqual(res, 0) + self.assertEqual(stdout.getvalue(), drt_output) + self.assertEqual(stderr.getvalue(), '') + + def test_pixeltest(self): + self.assertTest('fast/html/keygen.html', True) + + def test_textonly(self): + self.assertTest('fast/html/article-element.html', False) + + +if __name__ == '__main__': + unittest.main() -- 2.36.0