WebKitTools/ChangeLog

 12010-11-16 Hayato Ito <hayato@chromium.org>
 2
 3 Refactor TestTypeBase.compare_output().
 4
 5 Introduce a TestOutput class and update compare_output() of each test
 6 types so that they can take both actual and expected TestOutput objects.
 7
 8 https://bugs.webkit.org/show_bug.cgi?id=49431
 9
 10 * Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py:
 11 * Scripts/webkitpy/layout_tests/layout_package/test_output.py: Added.
 12 * Scripts/webkitpy/layout_tests/port/base.py:
 13 * Scripts/webkitpy/layout_tests/port/chromium.py:
 14 * Scripts/webkitpy/layout_tests/port/dryrun.py:
 15 * Scripts/webkitpy/layout_tests/port/test.py:
 16 * Scripts/webkitpy/layout_tests/port/webkit.py:
 17 * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
 18 * Scripts/webkitpy/layout_tests/test_types/image_diff.py:
 19 * Scripts/webkitpy/layout_tests/test_types/test_type_base.py:
 20 * Scripts/webkitpy/layout_tests/test_types/text_diff.py:
 21
1222010-11-16 Dirk Pranke <dpranke@chromium.org>
223
324 Reviewed by Ojan Vafai.

WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py

@@import time
5151import traceback
5252
5353import test_failures
 54import test_output
5455import test_results
5556
5657_log = logging.getLogger("webkitpy.layout_tests.layout_package."

@@def log_stack(stack):
7475 _log.error(' %s' % line.strip())
7576
7677
 78def _expected_test_output(port, filename):
 79 """Returns an expected TestOutput object."""
 80 return test_output.TestOutput(port.expected_text(filename),
 81 port.expected_image(filename),
 82 port.expected_checksum(filename))
 83
7784def _process_output(port, options, test_input, test_types, test_args,
78  crash, timeout, test_run_time, actual_checksum,
79  output, error):
 85 test_output):
8086 """Receives the output from a DumpRenderTree process, subjects it to a
8187 number of tests, and returns a list of failure types the test produced.
8288

@@def _process_output(port, options, test_input, test_types, test_args,
8793 test_input: Object containing the test filename, uri and timeout
8894 test_types: list of test types to subject the output to
8995 test_args: arguments to be passed to each test
 96 test_output: a actual test_output
9097
9198 Returns: a TestResult object
9299 """
93100 failures = []
94101
95  # Some test args, such as the image hash, may be added or changed on a
96  # test-by-test basis.
97  local_test_args = copy.copy(test_args)
98 
99  local_test_args.hash = actual_checksum
100 
101  if crash:
 102 if test_output.crash:
102103 failures.append(test_failures.FailureCrash())
103  if timeout:
 104 if test_output.timeout:
104105 failures.append(test_failures.FailureTimeout())
105106
106  if crash:
107  _log.debug("Stacktrace for %s:\n%s" % (test_input.filename, error))
 107 if test_output.crash:
 108 _log.debug("Stacktrace for %s:\n%s" % (test_input.filename,
 109 test_output.error))
108110 # Strip off "file://" since RelativeTestFilename expects
109111 # filesystem paths.
110112 filename = os.path.join(options.results_directory,

@@def _process_output(port, options, test_input, test_types, test_args,
113115 filename = os.path.splitext(filename)[0] + "-stack.txt"
114116 port.maybe_make_directory(os.path.split(filename)[0])
115117 with codecs.open(filename, "wb", "utf-8") as file:
116  file.write(error)
117  elif error:
118  _log.debug("Previous test output stderr lines:\n%s" % error)
 118 file.write(test_output.error)
 119 elif test_output.error:
 120 _log.debug("Previous test output stderr lines:\n%s" % test_output.error)
 121
 122 expected_test_output = _expected_test_output(port, test_input.filename)
119123
120124 # Check the output and save the results.
121125 start_time = time.time()

@@def _process_output(port, options, test_input, test_types, test_args,
123127 for test_type in test_types:
124128 start_diff_time = time.time()
125129 new_failures = test_type.compare_output(port, test_input.filename,
126  output, local_test_args,
127  options.configuration)
 130 test_args, test_output,
 131 expected_test_output)
128132 # Don't add any more failures if we already have a crash, so we don't
129133 # double-report those tests. We do double-report for timeouts since
130134 # we still want to see the text and image output.
131  if not crash:
 135 if not test_output.crash:
132136 failures.extend(new_failures)
133137 time_for_diffs[test_type.__class__.__name__] = (
134138 time.time() - start_diff_time)
135139
136140 total_time_for_all_diffs = time.time() - start_diff_time
137  return test_results.TestResult(test_input.filename, failures, test_run_time,
 141 return test_results.TestResult(test_input.filename, failures, test_output.test_time,
138142 total_time_for_all_diffs, time_for_diffs)
139143
140144

@@def _should_fetch_expected_checksum(options):
157161 return options.pixel_tests and not (options.new_baseline or options.reset_results)
158162
159163
 164def _run_single_test(port, options, test_input, test_types, test_args, driver):
 165 # FIXME: Pull this into TestShellThread._run().
 166
 167 # The image hash is used to avoid doing an image dump if the
 168 # checksums match, so it should be set to a blank value if we
 169 # are generating a new baseline. (Otherwise, an image from a
 170 # previous run will be copied into the baseline."""
 171 if _should_fetch_expected_checksum(options):
 172 image_hash_to_driver = port.expected_checksum(test_input.filename)
 173 else:
 174 image_hash_to_driver = None
 175 test_input.uri = port.filename_to_uri(test_input.filename).strip()
 176 test_output = driver.run_test(test_input.uri, test_input.timeout, image_hash_to_driver)
 177 return _process_output(port, options, test_input, test_types, test_args,
 178 test_output)
 179
 180
160181class SingleTestThread(threading.Thread):
161182 """Thread wrapper for running a single test file."""
162183

@@class SingleTestThread(threading.Thread):
185206 def _covered_run(self):
186207 # FIXME: this is a separate routine to work around a bug
187208 # in coverage: see http://bitbucket.org/ned/coveragepy/issue/85.
188 
189  # FIXME: Pull this into TestShellThread._run().
190  test_input = self._test_input
191  test_input.uri = self._port.filename_to_uri(test_input.filename)
192  if _should_fetch_expected_checksum(self._options):
193  test_input.image_checksum = self._port.expected_checksum(test_input.filename)
194 
195  start = time.time()
196209 self._driver = self._port.create_driver(self._test_args.png_path,
197210 self._options)
198211 self._driver.start()
199  crash, timeout, actual_checksum, output, error = \
200  self._driver.run_test(test_input.uri, test_input.timeout,
201  test_input.image_checksum)
202  end = time.time()
203  self._test_result = _process_output(self._port, self._options,
204  test_input, self._test_types, self._test_args,
205  crash, timeout, end - start,
206  actual_checksum, output, error)
 212 self._test_result = _run_single_test(self._port, self._options,
 213 self._test_input, self._test_types,
 214 self._test_args, self._driver)
207215 self._driver.stop()
208216
209217 def get_test_result(self):

@@class TestShellThread(WatchableThread):
501509 Returns: a TestResult object.
502510 """
503511 self._ensure_dump_render_tree_is_running()
504  # The pixel_hash is used to avoid doing an image dump if the
505  # checksums match, so it should be set to a blank value if we
506  # are generating a new baseline. (Otherwise, an image from a
507  # previous run will be copied into the baseline.)
508 
509  # FIXME: Pull this into TestShellThread._run().
510  test_input.uri = self._port.filename_to_uri(test_input.filename)
511  if _should_fetch_expected_checksum(self._options):
512  test_input.image_checksum = self._port.expected_checksum(test_input.filename)
513  start = time.time()
514 
515512 thread_timeout = _milliseconds_to_seconds(
516513 _pad_timeout(int(test_input.timeout)))
517  self._next_timeout = start + thread_timeout
518 
519  crash, timeout, actual_checksum, output, error = \
520  self._driver.run_test(test_input.uri, test_input.timeout, test_input.image_checksum)
521  end = time.time()
522 
523  result = _process_output(self._port, self._options,
524  test_input, self._test_types,
525  self._test_args, crash,
526  timeout, end - start, actual_checksum,
527  output, error)
528  self._test_results.append(result)
529  return result
 514 self._next_timeout = time.time() + thread_timeout
 515 test_result = _run_single_test(self._port, self._options, test_input,
 516 self._test_types, self._test_args,
 517 self._driver)
 518 self._test_results.append(test_result)
 519 return test_result
530520
531521 def _ensure_dump_render_tree_is_running(self):
532522 """Start the shared DumpRenderTree, if it's not running.

WebKitTools/Scripts/webkitpy/layout_tests/layout_package/test_output.py

 1# Copyright (C) 2010 Google Inc. All rights reserved.
 2#
 3# Redistribution and use in source and binary forms, with or without
 4# modification, are permitted provided that the following conditions are
 5# met:
 6#
 7# * Redistributions of source code must retain the above copyright
 8# notice, this list of conditions and the following disclaimer.
 9# * Redistributions in binary form must reproduce the above
 10# copyright notice, this list of conditions and the following disclaimer
 11# in the documentation and/or other materials provided with the
 12# distribution.
 13# * Neither the name of Google Inc. nor the names of its
 14# contributors may be used to endorse or promote products derived from
 15# this software without specific prior written permission.
 16#
 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28
 29
 30class TestOutput(object):
 31 """Groups information about a test output for easy passing of data.
 32
 33 This is used not only for a actual test output, but also for grouping
 34 expected test output.
 35 """
 36
 37 def __init__(self, text, image, image_hash,
 38 crash=None, test_time=None, timeout=None, error=None):
 39 """Initializes a TestOutput object.
 40
 41 Args:
 42 text: a text output
 43 image: an image output
 44 image_hash: a string containing the checksum of the image
 45 crash: a boolean indicating whether the driver crashed on the test
 46 test_time: a time which the test has taken
 47 timeout: a boolean indicating whehter the test timed out
 48 error: any unexpected or additional (or error) text output
 49 """
 50 self.text = text
 51 self.image = image
 52 self.image_hash = image_hash
 53 self.crash = crash
 54 self.test_time = test_time
 55 self.timeout = timeout
 56 self.error = error

WebKitTools/Scripts/webkitpy/layout_tests/port/base.py

@@class Driver:
832832 checksum - if present, the expected checksum for the image for this
833833 test
834834
835  Returns a tuple of the following:
836  crash - a boolean indicating whether the driver crashed on the test
837  timeout - a boolean indicating whehter the test timed out
838  checksum - a string containing the checksum of the image, if
839  present
840  output - any text output
841  error - any unexpected or additional (or error) text output
842 
843  Note that the image itself should be written to the path that was
844  specified in the __init__() call."""
 835 Returns a TestOutput object.
 836 """
845837 raise NotImplementedError('Driver.run_test')
846838
847839 # FIXME: This is static so we can test it w/o creating a Base instance.

WebKitTools/Scripts/webkitpy/layout_tests/port/chromium.py

@@import webbrowser
4646from webkitpy.common.system.executive import Executive
4747from webkitpy.common.system.path import cygpath
4848from webkitpy.layout_tests.layout_package import test_expectations
 49from webkitpy.layout_tests.layout_package import test_output
4950
5051import base
5152import http_server
5253
53 from webkitpy.common.system.executive import Executive
54 from webkitpy.layout_tests.layout_package import test_expectations
55 
5654# Chromium DRT on OSX uses WebKitDriver.
5755if sys.platform == 'darwin':
5856 import webkit

@@class ChromiumDriver(base.Driver):
447445 cmd += "\n"
448446 return cmd
449447
 448 def _output_image(self):
 449 """Returns the image output which driver generated."""
 450 png_path = self._image_path
 451 if png_path and os.path.isfile(png_path):
 452 with open(png_path, 'rb') as image_file:
 453 return image_file.read()
 454 else:
 455 return None
 456
450457 def run_test(self, uri, timeoutms, checksum):
451458 output = []
452459 error = []

@@class ChromiumDriver(base.Driver):
498505
499506 (line, crash) = self._write_command_and_read_line(input=None)
500507
501  return (crash, timeout, actual_checksum, ''.join(output),
502  ''.join(error))
 508 return test_output.TestOutput(
 509 ''.join(output), self._output_image(), actual_checksum,
 510 crash, time.time() - start_time, timeout, ''.join(error))
503511
504512 def stop(self):
505513 if self._proc:

WebKitTools/Scripts/webkitpy/layout_tests/port/dryrun.py

@@from __future__ import with_statement
4848
4949import os
5050import sys
 51import time
 52
 53from webkitpy.layout_tests.layout_package import test_output
5154
5255import base
5356import factory

@@class DryrunDriver(base.Driver):
109112 return None
110113
111114 def run_test(self, uri, timeoutms, image_hash):
 115 start_time = time.time()
112116 test_name = self._port.uri_to_test_name(uri)
113117 path = os.path.join(self._port.layout_tests_dir(), test_name)
114118 text_output = self._port.expected_text(path)
115119
116120 if image_hash is not None:
117121 image = self._port.expected_image(path)
118  if image and self._image_path:
119  with open(self._image_path, 'w') as f:
120  f.write(image)
121122 hash = self._port.expected_checksum(path)
122123 else:
 124 image = None
123125 hash = None
124  return (False, False, hash, text_output, None)
 126 return test_output.TestOutput(text_output, image, hash, False,
 127 time.time() - start_time, False, None)
125128
126129 def start(self):
127130 pass

WebKitTools/Scripts/webkitpy/layout_tests/port/test.py

@@import os
3636import sys
3737import time
3838
 39from webkitpy.layout_tests.layout_package import test_output
 40
3941import base
4042
4143

@@class TestDriver(base.Driver):
289291 return True
290292
291293 def run_test(self, uri, timeoutms, image_hash):
 294 start_time = time.time()
292295 test_name = self._port.uri_to_test_name(uri)
293296 test = self._port._tests[test_name]
294297 if test.keyboard:

@@class TestDriver(base.Driver):
297300 raise ValueError('exception from ' + test_name)
298301 if test.hang:
299302 time.sleep((float(timeoutms) * 4) / 1000.0)
300 
301  if self._port.get_option('pixel_tests') and test.actual_image:
302  with open(self._image_path, 'w') as file:
303  file.write(test.actual_image)
304 
305  return (test.crash, test.timeout, test.actual_checksum,
306  test.actual_text, test.error)
 303 return test_output.TestOutput(test.actual_text, test.actual_image,
 304 test.actual_checksum, test.crash,
 305 time.time() - start_time, test.timeout,
 306 test.error)
307307
308308 def start(self):
309309 pass

WebKitTools/Scripts/webkitpy/layout_tests/port/webkit.py

@@import shutil
4949from webkitpy.common.system.executive import Executive
5050
5151import webkitpy.common.system.ospath as ospath
 52import webkitpy.layout_tests.layout_package.test_output as test_output
5253import webkitpy.layout_tests.port.base as base
5354import webkitpy.layout_tests.port.server_process as server_process
5455

@@class WebKitDriver(base.Driver):
442443 command += "'" + image_hash
443444 command += "\n"
444445
 446 start_time = time.time()
445447 self._server_process.write(command)
446448
447449 have_seen_content_type = False

@@class WebKitDriver(base.Driver):
486488 timeout = deadline - time.time()
487489 line = self._server_process.read_line(timeout)
488490
489  if self._image_path and len(self._image_path):
490  with open(self._image_path, "wb") as image_file:
491  image_file.write(image)
492 
493491 error_lines = self._server_process.error.splitlines()
494492 # FIXME: This is a hack. It is unclear why sometimes
495493 # we do not get any error lines from the server_process

@@class WebKitDriver(base.Driver):
500498 # FIXME: This seems like the wrong section of code to be doing
501499 # this reset in.
502500 self._server_process.error = ""
503  return (self._server_process.crashed,
504  self._server_process.timed_out,
505  actual_image_hash,
506  output,
507  error)
 501 return test_output.TestOutput(output, image, actual_image_hash,
 502 self._server_process.crashed,
 503 time.time() - start_time,
 504 self._server_process.timed_out,
 505 error)
508506
509507 def stop(self):
510508 if self._server_process:

WebKitTools/Scripts/webkitpy/layout_tests/run_webkit_tests.py

@@class TestInput:
101101 """
102102 # FIXME: filename should really be test_name as a relative path.
103103 self.filename = filename
104  # The image checksum is passed to the driver so that the driver can optionally not have
105  # to output the image if the checksums match.
106  self.image_checksum = None
107104 self.timeout = timeout
108105
109106 # FIXME: Maybe the URI shouldn't be part of the TestInput at all?

WebKitTools/Scripts/webkitpy/layout_tests/test_types/image_diff.py

@@_log = logging.getLogger("webkitpy.layout_tests.test_types.image_diff")
5454
5555class ImageDiff(test_type_base.TestTypeBase):
5656
57  def _copy_output_png(self, test_filename, source_image, extension):
58  """Copies result files into the output directory with appropriate
59  names.
60 
61  Args:
62  test_filename: the test filename
63  source_file: path to the image file (either actual or expected)
64  extension: extension to indicate -actual.png or -expected.png
65  """
66  self._make_output_directory(test_filename)
67  dest_image = self.output_filename(test_filename, extension)
68 
69  if os.path.exists(source_image):
70  shutil.copyfile(source_image, dest_image)
71 
72  def _save_baseline_files(self, filename, png_path, checksum,
 57 def _save_baseline_files(self, filename, image, image_hash,
7358 generate_new_baseline):
7459 """Saves new baselines for the PNG and checksum.
7560
7661 Args:
7762 filename: test filename
78  png_path: path to the actual PNG result file
79  checksum: value of the actual checksum result
 63 image: a image output
 64 image_hash: a checksum of the image
8065 generate_new_baseline: whether to generate a new, platform-specific
8166 baseline, or update the existing one
8267 """
83  with open(png_path, "rb") as png_file:
84  png_data = png_file.read()
85  self._save_baseline_data(filename, png_data, ".png", encoding=None,
 68 self._save_baseline_data(filename, image, ".png", encoding=None,
8669 generate_new_baseline=generate_new_baseline)
87  self._save_baseline_data(filename, checksum, ".checksum",
 70 self._save_baseline_data(filename, image_hash, ".checksum",
8871 encoding="ascii",
8972 generate_new_baseline=generate_new_baseline)
9073
91  def _create_image_diff(self, port, filename, configuration):
 74 def _copy_image(self, filename, actual_image, expected_image):
 75 self.write_output_files(filename, '.png',
 76 output=actual_image, expected=expected_image,
 77 encoding=None, print_text_diffs=False)
 78
 79 def _copy_image_hash(self, filename, actual_image_hash, expected_image_hash):
 80 self.write_output_files(filename, '.checksum',
 81 actual_image_hash, expected_image_hash,
 82 encoding="ascii", print_text_diffs=False)
 83
 84 def _create_diff_image(self, port, filename, actual_image, expected_image):
9285 """Creates the visual diff of the expected/actual PNGs.
9386
94  Args:
95  filename: the name of the test
96  configuration: Debug or Release
97  Returns True if the files are different, False if they match
 87 Returns True if the images are different.
9888 """
9989 diff_filename = self.output_filename(filename,
100  self.FILENAME_SUFFIX_COMPARE)
101  actual_filename = self.output_filename(filename,
102  self.FILENAME_SUFFIX_ACTUAL + '.png')
103  expected_filename = self.output_filename(filename,
104  self.FILENAME_SUFFIX_EXPECTED + '.png')
 90 self.FILENAME_SUFFIX_COMPARE)
 91 return port.diff_image(actual_image, expected_image, diff_filename)
10592
106  expected_image = port.expected_image(filename)
107  with codecs.open(actual_filename, 'r+b', None) as file:
108  actual_image = file.read()
109 
110  result = port.diff_image(expected_image, actual_image,
111  diff_filename)
112  return result
113 
114  def compare_output(self, port, filename, output, test_args, configuration):
 93 def compare_output(self, port, filename, test_args, actual_test_output,
 94 expected_test_output):
11595 """Implementation of CompareOutput that checks the output image and
11696 checksum against the expected files from the LayoutTest directory.
11797 """
11898 failures = []
11999
120100 # If we didn't produce a hash file, this test must be text-only.
121  if test_args.hash is None:
 101 if actual_test_output.image_hash is None:
122102 return failures
123103
124104 # If we're generating a new baseline, we pass.
125105 if test_args.new_baseline or test_args.reset_results:
126  self._save_baseline_files(filename, test_args.png_path,
127  test_args.hash, test_args.new_baseline)
 106 self._save_baseline_files(filename, actual_test_output.image_hash,
 107 actual_test_output.image,
 108 test_args.new_baseline)
128109 return failures
129110
130  # Compare hashes.
131  expected_hash = self._port.expected_checksum(filename)
132  expected_png = self._port.expected_image(filename)
133 
134  if not expected_png:
 111 if not expected_test_output.image:
135112 # Report a missing expected PNG file.
136  self.write_output_files(filename, '.checksum',
137  test_args.hash, expected_hash,
138  encoding="ascii",
139  print_text_diffs=False)
140  self._copy_output_png(filename, test_args.png_path, '-actual.png')
 113 self._copy_image(filename, actual_test_output.image, expected_image=None)
 114 self._copy_image_hash(filename, actual_test_output.image_hash,
 115 expected_test_output.image_hash)
141116 failures.append(test_failures.FailureMissingImage())
142117 return failures
143  elif test_args.hash == expected_hash:
 118 if not expected_test_output.image_hash:
 119 # Report a missing expected checksum file.
 120 self._copy_image(filename, actual_test_output.image,
 121 expected_test_output.image)
 122 self._copy_image_hash(filename, actual_test_output.image_hash,
 123 expected_image_hash=None)
 124 failures.append(test_failures.FailureMissingImageHash())
 125 return failures
 126
 127 if actual_test_output.image_hash == expected_test_output.image_hash:
144128 # Hash matched (no diff needed, okay to return).
145129 return failures
146130
147  self.write_output_files(filename, '.checksum',
148  test_args.hash, expected_hash,
149  encoding="ascii",
150  print_text_diffs=False)
151 
152  # FIXME: combine next two lines
153  self._copy_output_png(filename, test_args.png_path, '-actual.png')
154  self.write_output_files(filename, '.png', output=None,
155  expected=expected_png,
156  encoding=None, print_text_diffs=False)
 131 self._copy_image(filename, actual_test_output.image,
 132 expected_test_output.image)
 133 self._copy_image_hash(filename, actual_test_output.image_hash,
 134 expected_test_output.image_hash)
157135
158136 # Even though we only use the result in one codepath below but we
159137 # still need to call CreateImageDiff for other codepaths.
160  images_are_different = self._create_image_diff(port, filename, configuration)
161  if not expected_hash:
162  failures.append(test_failures.FailureMissingImageHash())
163  elif test_args.hash != expected_hash:
164  if images_are_different:
165  failures.append(test_failures.FailureImageHashMismatch())
166  else:
167  failures.append(test_failures.FailureImageHashIncorrect())
 138 images_are_different = self._create_diff_image(port, filename,
 139 actual_test_output.image,
 140 expected_test_output.image)
 141 if not images_are_different:
 142 failures.append(test_failures.FailureImageHashIncorrect())
 143 else:
 144 failures.append(test_failures.FailureImageHashMismatch())
168145
169146 return failures

WebKitTools/Scripts/webkitpy/layout_tests/test_types/test_type_base.py

@@class TestTypeBase(object):
140140 self._port.relative_test_filename(filename))
141141 return os.path.splitext(output_filename)[0] + modifier
142142
143  def compare_output(self, port, filename, output, test_args, configuration):
 143 def compare_output(self, port, filename, test_args, actual_test_output,
 144 expected_test_output):
144145 """Method that compares the output from the test with the
145146 expected value.
146147
147148 This is an abstract method to be implemented by all sub classes.
148149
149150 Args:
 151 port: object implementing port-specific information and methods
150152 filename: absolute filename to test file
151  output: a string containing the output of the test
152153 test_args: a TestArguments object holding optional additional
153154 arguments
154  configuration: Debug or Release
 155 actual_test_output: a TestOutput object which represents actual test
 156 output
 157 expected_test_output: a TestOutput object which represents a expected
 158 test output
155159
156160 Return:
157161 a list of TestFailure objects, empty if the test passes

WebKitTools/Scripts/webkitpy/layout_tests/test_types/text_diff.py

@@class TestTextDiff(test_type_base.TestTypeBase):
5555 "\r\n", "\n")
5656 return norm + "\n"
5757
58  def _get_normalized_expected_text(self, filename):
59  """Given the filename of the test, read the expected output from a file
60  and normalize the text. Returns a string with the expected text, or ''
61  if the expected output file was not found."""
62  return self._port.expected_text(filename)
63 
64  def compare_output(self, port, filename, output, test_args, configuration):
 58 def compare_output(self, port, filename, test_args, actual_test_output,
 59 expected_test_output):
6560 """Implementation of CompareOutput that checks the output text against
6661 the expected text from the LayoutTest directory."""
6762 failures = []

@@class TestTextDiff(test_type_base.TestTypeBase):
7671 return failures
7772
7873 # Normalize text to diff
79  output = self._get_normalized_output_text(output)
80  expected = self._get_normalized_expected_text(filename)
 74 actual_text = self._get_normalized_output_text(actual_test_output.text)
 75 # Assuming expected_text is already normalized.
 76 expected_text = expected_test_output.text
8177
8278 # Write output files for new tests, too.
83  if port.compare_text(output, expected):
 79 if port.compare_text(actual_text, expected_text):
8480 # Text doesn't match, write output files.
85  self.write_output_files(filename, ".txt", output,
86  expected, encoding=None,
 81 self.write_output_files(filename, ".txt", actual_text,
 82 expected_text, encoding=None,
8783 print_text_diffs=True)
8884
89  if expected == '':
 85 if expected_text == '':
9086 failures.append(test_failures.FailureMissingResult())
9187 else:
9288 failures.append(test_failures.FailureTextMismatch())