diff options
Diffstat (limited to 'Tools/Scripts/webkitpy/layout_tests/port')
11 files changed, 129 insertions, 50 deletions
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/base.py b/Tools/Scripts/webkitpy/layout_tests/port/base.py index 247a260..dea126f 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/base.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/base.py @@ -30,6 +30,8 @@ """Abstract base class of Port-specific entrypoints for the layout tests test infrastructure (the Port and Driver classes).""" +from __future__ import with_statement + import cgi import difflib import errno @@ -44,20 +46,19 @@ try: except ImportError: multiprocessing = None -import apache_http_server -import config as port_config -import http_lock -import http_server -import test_files -import websocket_server - from webkitpy.common import system from webkitpy.common.system import filesystem from webkitpy.common.system import logutils from webkitpy.common.system import path from webkitpy.common.system.executive import Executive, ScriptError from webkitpy.common.system.user import User - +from webkitpy.layout_tests import read_checksum_from_png +from webkitpy.layout_tests.port import apache_http_server +from webkitpy.layout_tests.port import config as port_config +from webkitpy.layout_tests.port import http_lock +from webkitpy.layout_tests.port import http_server +from webkitpy.layout_tests.port import test_files +from webkitpy.layout_tests.port import websocket_server _log = logutils.get_logger(__file__) @@ -139,7 +140,9 @@ class Port(object): return self._executive.cpu_count() def default_worker_model(self): - return 'old-threads' + if self._multiprocessing_is_available: + return 'processes' + return 'threads' def baseline_path(self): """Return the absolute path to the directory to store new baselines @@ -323,10 +326,17 @@ class Port(object): def expected_checksum(self, test): """Returns the checksum of the image we expect the test to produce, or None if it is a text-only test.""" - path = self.expected_filename(test, '.checksum') - if not self.path_exists(path): - return None - return self._filesystem.read_binary_file(path) + png_path = self.expected_filename(test, '.png') + checksum_path = self._filesystem.splitext(png_path)[0] + '.checksum' + + if self.path_exists(checksum_path): + return self._filesystem.read_binary_file(checksum_path) + + if self.path_exists(png_path): + with self._filesystem.open_binary_file_for_reading(png_path) as filehandle: + return read_checksum_from_png.read_checksum(filehandle) + + return None def expected_image(self, test): """Returns the image we expect the test to produce.""" @@ -347,6 +357,14 @@ class Port(object): text = self._filesystem.read_binary_file(path) return text.replace("\r\n", "\n") + def reftest_expected_filename(self, filename): + """Return the filename of reference we expect the test matches.""" + return self.expected_filename(filename, '.html') + + def reftest_expected_mismatch_filename(self, filename): + """Return the filename of reference we don't expect the test matches.""" + return self.expected_filename(filename, '-mismatch.html') + def filename_to_uri(self, filename): """Convert a test file (which is an absolute path) to a URI.""" LAYOUTTEST_HTTP_DIR = "http/tests/" @@ -498,6 +516,9 @@ class Port(object): def script_path(self, script_name): return self._config.script_path(script_name) + def script_shell_command(self, script_name): + return self._config.script_shell_command(script_name) + def path_to_test_expectations_file(self): """Update the test expectations to the passed-in string. diff --git a/Tools/Scripts/webkitpy/layout_tests/port/chromium_linux.py b/Tools/Scripts/webkitpy/layout_tests/port/chromium_linux.py index a8e1bb2..2cd2435 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/chromium_linux.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/chromium_linux.py @@ -114,11 +114,6 @@ class ChromiumLinuxPort(chromium.ChromiumPort): 'LinuxBuildInstructions') return result - def default_worker_model(self): - if self._multiprocessing_is_available: - return 'processes' - return 'old-threads' - def test_platform_name(self): # We use 'linux' instead of 'chromium-linux' in test_expectations.txt. return 'linux' diff --git a/Tools/Scripts/webkitpy/layout_tests/port/chromium_mac.py b/Tools/Scripts/webkitpy/layout_tests/port/chromium_mac.py index 78a6682..141b587 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/chromium_mac.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/chromium_mac.py @@ -46,11 +46,25 @@ class ChromiumMacPort(chromium.ChromiumPort): SUPPORTED_OS_VERSIONS = ('leopard', 'snowleopard') FALLBACK_PATHS = { - 'leopard': ['chromium-mac-leopard', 'chromium-mac-snowleopard', 'chromium-mac', 'chromium', - 'mac-leopard', 'mac-snowleopard', 'mac'], - 'snowleopard': ['chromium-mac-snowleopard', 'chromium-mac', 'chromium', - 'mac-snowleopard', 'mac'], - '': ['chromium-mac', 'chromium', 'mac'], + 'leopard': [ + 'chromium-mac-leopard', + 'chromium-mac', + 'chromium', + 'mac-leopard', + 'mac-snowleopard', + 'mac', + ], + 'snowleopard': [ + 'chromium-mac', + 'chromium', + 'mac-snowleopard', + 'mac', + ], + '': [ + 'chromium-mac', + 'chromium', + 'mac', + ], } def __init__(self, port_name=None, os_version_string=None, rebaselining=False, **kwargs): @@ -100,22 +114,12 @@ class ChromiumMacPort(chromium.ChromiumPort): return result def default_child_processes(self): - if self.get_option('worker_model') == 'old-threads': - # FIXME: we need to run single-threaded for now. See - # https://bugs.webkit.org/show_bug.cgi?id=38553. Unfortunately this - # routine is called right before the logger is configured, so if we - # try to _log.warning(), it gets thrown away. - import sys - sys.stderr.write("Defaulting to one child - see https://bugs.webkit.org/show_bug.cgi?id=38553\n") + if not self._multiprocessing_is_available: + # Running multiple threads in Mac Python is unstable (See + # https://bugs.webkit.org/show_bug.cgi?id=38553 for more info). return 1 - return chromium.ChromiumPort.default_child_processes(self) - def default_worker_model(self): - if self._multiprocessing_is_available: - return 'processes' - return 'old-threads' - def driver_name(self): return "DumpRenderTree" diff --git a/Tools/Scripts/webkitpy/layout_tests/port/chromium_win.py b/Tools/Scripts/webkitpy/layout_tests/port/chromium_win.py index e7c6e49..d0908df 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/chromium_win.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/chromium_win.py @@ -129,6 +129,10 @@ class ChromiumWinPort(chromium.ChromiumPort): 'build-instructions-windows') return result + def default_worker_model(self): + # FIXME: should use base class method instead. See bug 55163. + return 'old-threads' + def relative_test_filename(self, filename): path = filename[len(self.layout_tests_dir()) + 1:] return path.replace('\\', '/') diff --git a/Tools/Scripts/webkitpy/layout_tests/port/dryrun.py b/Tools/Scripts/webkitpy/layout_tests/port/dryrun.py index 6b3bd51..20aa776 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/dryrun.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/dryrun.py @@ -118,12 +118,26 @@ class DryrunDriver(base.Driver): def run_test(self, driver_input): start_time = time.time() - text_output = self._port.expected_text(driver_input.filename) - - if driver_input.image_hash is not None: + fs = self._port._filesystem + if fs.exists(self._port.reftest_expected_filename(driver_input.filename)) or \ + fs.exists(self._port.reftest_expected_mismatch_filename(driver_input.filename)): + text_output = 'test-text' + image = 'test-image' + hash = 'test-checksum' + elif driver_input.filename.endswith('-expected.html'): + text_output = 'test-text' + image = 'test-image' + hash = 'test-checksum' + elif driver_input.filename.endswith('-expected-mismatch.html'): + text_output = 'test-text-mismatch' + image = 'test-image-mismatch' + hash = 'test-checksum-mismatch' + elif driver_input.image_hash is not None: + text_output = self._port.expected_text(driver_input.filename) image = self._port.expected_image(driver_input.filename) hash = self._port.expected_checksum(driver_input.filename) else: + text_output = self._port.expected_text(driver_input.filename) image = None hash = None return base.DriverOutput(text_output, image, hash, False, diff --git a/Tools/Scripts/webkitpy/layout_tests/port/http_server.py b/Tools/Scripts/webkitpy/layout_tests/port/http_server.py index 752b099..1753aee 100755 --- a/Tools/Scripts/webkitpy/layout_tests/port/http_server.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/http_server.py @@ -55,7 +55,7 @@ class HttpdNotStarted(Exception): class Lighttpd(http_server_base.HttpServerBase): def __init__(self, port_obj, output_dir, background=False, port=None, - root=None, run_background=None): + root=None, run_background=None, layout_tests_dir=None): """Args: output_dir: the absolute path to the layout test result directory """ @@ -66,16 +66,21 @@ class Lighttpd(http_server_base.HttpServerBase): self._port = port self._root = root self._run_background = run_background + self._layout_tests_dir = layout_tests_dir + if self._port: self._port = int(self._port) + if not self._layout_tests_dir: + self._layout_tests_dir = self._port_obj.layout_tests_dir() + try: self._webkit_tests = os.path.join( - self._port_obj.layout_tests_dir(), 'http', 'tests') + self._layout_tests_dir, 'http', 'tests') self._js_test_resource = os.path.join( - self._port_obj.layout_tests_dir(), 'fast', 'js', 'resources') + self._layout_tests_dir, 'fast', 'js', 'resources') self._media_resource = os.path.join( - self._port_obj.layout_tests_dir(), 'media') + self._layout_tests_dir, 'media') except: self._webkit_tests = None diff --git a/Tools/Scripts/webkitpy/layout_tests/port/mac.py b/Tools/Scripts/webkitpy/layout_tests/port/mac.py index 0168ec7..4315543 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/mac.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/mac.py @@ -88,14 +88,14 @@ class MacPort(WebKitPort): # four threads in parallel. # See https://bugs.webkit.org/show_bug.cgi?id=36622 child_processes = WebKitPort.default_child_processes(self) - if self.get_option('worker_model') == 'old-threads' and child_processes > 4: + if not self._multiprocessing_is_available and child_processes > 4: return 4 return child_processes def default_worker_model(self): if self._multiprocessing_is_available: return 'processes' - return 'old-threads' + return 'threads' def baseline_search_path(self): return map(self._webkit_baseline_path, self.FALLBACK_PATHS[self._version]) diff --git a/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py b/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py index 71de14b..b6f6e8a 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py @@ -207,6 +207,9 @@ class MockDRTTest(unittest.TestCase): def test_textonly(self): self.assertTest('passes/image.html', False) + def test_checksum_in_png(self): + self.assertTest('passes/checksum_in_image.html', True) + class MockChromiumDRTTest(MockDRTTest): def extra_args(self, pixel_tests): diff --git a/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py b/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py index d37fdc0..649e33c 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py @@ -73,7 +73,7 @@ class PortTestCase(unittest.TestCase): if multiprocessing: self.assertEqual(port.default_worker_model(), 'processes') else: - self.assertEqual(port.default_worker_model(), 'old-threads') + self.assertEqual(port.default_worker_model(), 'threads') def test_driver_cmd_line(self): port = self.make_port() diff --git a/Tools/Scripts/webkitpy/layout_tests/port/test.py b/Tools/Scripts/webkitpy/layout_tests/port/test.py index d323ed5..392818d 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/test.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/test.py @@ -50,6 +50,7 @@ class TestInstance: self.keyboard = False self.error = '' self.timeout = False + self.is_reftest = False # The values of each field are treated as raw byte strings. They # will be converted to unicode strings where appropriate using @@ -78,6 +79,13 @@ class TestList: test.__dict__[key] = value self.tests[name] = test + def add_reftest(self, name, reference_name, same_image): + self.add(name, actual_checksum='xxx', actual_image='XXX', is_reftest=True) + if same_image: + self.add(reference_name, actual_checksum='xxx', actual_image='XXX', is_reftest=True) + else: + self.add(reference_name, actual_checksum='yyy', actual_image='YYY', is_reftest=True) + def keys(self): return self.tests.keys() @@ -104,7 +112,9 @@ def unit_test_list(): actual_checksum='image_checksum_fail-checksum', actual_image='image_checksum_fail-png') tests.add('failures/expected/keyboard.html', keyboard=True) - tests.add('failures/expected/missing_check.html', expected_checksum=None) + tests.add('failures/expected/missing_check.html', + expected_checksum=None, + expected_image=None) tests.add('failures/expected/missing_image.html', expected_image=None) tests.add('failures/expected/missing_text.html', expected_text=None) tests.add('failures/expected/newlines_leading.html', @@ -120,15 +130,29 @@ def unit_test_list(): actual_checksum='text-image-checksum_fail-checksum') tests.add('failures/unexpected/timeout.html', timeout=True) tests.add('http/tests/passes/text.html') + tests.add('http/tests/passes/image.html') tests.add('http/tests/ssl/text.html') tests.add('passes/error.html', error='stuff going to stderr') tests.add('passes/image.html') tests.add('passes/platform_image.html') + tests.add('passes/checksum_in_image.html', + expected_checksum=None, + expected_image='tEXtchecksum\x00checksum_in_image-checksum') # Text output files contain "\r\n" on Windows. This may be # helpfully filtered to "\r\r\n" by our Python/Cygwin tooling. tests.add('passes/text.html', expected_text='\nfoo\n\n', actual_text='\nfoo\r\n\r\r\n') + + # For reftests. + tests.add_reftest('passes/reftest.html', 'passes/reftest-expected.html', same_image=True) + tests.add_reftest('passes/mismatch.html', 'passes/mismatch-expected-mismatch.html', same_image=False) + tests.add_reftest('failures/expected/reftest.html', 'failures/expected/reftest-expected.html', same_image=False) + tests.add_reftest('failures/expected/mismatch.html', 'failures/expected/mismatch-expected-mismatch.html', same_image=True) + tests.add_reftest('failures/unexpected/reftest.html', 'failures/unexpected/reftest-expected.html', same_image=False) + tests.add_reftest('failures/unexpected/mismatch.html', 'failures/unexpected/mismatch-expected-mismatch.html', same_image=True) + # FIXME: Add a reftest which crashes. + tests.add('websocket/tests/passes/text.html') return tests @@ -158,6 +182,8 @@ def unit_test_filesystem(files=None): # Add each test and the expected output, if any. for test in test_list.tests.values(): add_file(files, test, '.html', '') + if test.is_reftest: + continue add_file(files, test, '-expected.txt', test.expected_text) add_file(files, test, '-expected.checksum', test.expected_checksum) add_file(files, test, '-expected.png', test.expected_image) @@ -169,12 +195,14 @@ WONTFIX : failures/expected/crash.html = CRASH // This one actually passes because the checksums will match. WONTFIX : failures/expected/image.html = PASS WONTFIX : failures/expected/image_checksum.html = IMAGE +WONTFIX : failures/expected/mismatch.html = IMAGE WONTFIX : failures/expected/missing_check.html = MISSING PASS WONTFIX : failures/expected/missing_image.html = MISSING PASS WONTFIX : failures/expected/missing_text.html = MISSING PASS WONTFIX : failures/expected/newlines_leading.html = TEXT WONTFIX : failures/expected/newlines_trailing.html = TEXT WONTFIX : failures/expected/newlines_with_excess_CR.html = TEXT +WONTFIX : failures/expected/reftest.html = IMAGE WONTFIX : failures/expected/text.html = TEXT WONTFIX : failures/expected/timeout.html = TIMEOUT WONTFIX SKIP : failures/expected/hang.html = TIMEOUT @@ -222,6 +250,12 @@ class TestPort(base.Port): def baseline_search_path(self): return [self.baseline_path()] + def default_child_processes(self): + return 1 + + def default_worker_model(self): + return 'inline' + def check_build(self, needs_http): return True diff --git a/Tools/Scripts/webkitpy/layout_tests/port/test_files.py b/Tools/Scripts/webkitpy/layout_tests/port/test_files.py index 534462a..fbbbea5 100644 --- a/Tools/Scripts/webkitpy/layout_tests/port/test_files.py +++ b/Tools/Scripts/webkitpy/layout_tests/port/test_files.py @@ -105,11 +105,10 @@ def _has_supported_extension(filesystem, filename): return extension in _supported_file_extensions -def _is_reference_html_file(filename): +def is_reference_html_file(filename): """Return true if the filename points to a reference HTML file.""" if (filename.endswith('-expected.html') or filename.endswith('-expected-mismatch.html')): - _log.warn("Reftests are not supported - ignoring %s" % filename) return True return False @@ -117,4 +116,4 @@ def _is_reference_html_file(filename): def _is_test_file(filesystem, dirname, filename): """Return true if the filename points to a test file.""" return (_has_supported_extension(filesystem, filename) and - not _is_reference_html_file(filename)) + not is_reference_html_file(filename)) |