diff options
Diffstat (limited to 'Tools/Scripts/webkitpy/tool/servers/rebaselineserver.py')
-rw-r--r-- | Tools/Scripts/webkitpy/tool/servers/rebaselineserver.py | 289 |
1 files changed, 0 insertions, 289 deletions
diff --git a/Tools/Scripts/webkitpy/tool/servers/rebaselineserver.py b/Tools/Scripts/webkitpy/tool/servers/rebaselineserver.py deleted file mode 100644 index 41a32ba54..000000000 --- a/Tools/Scripts/webkitpy/tool/servers/rebaselineserver.py +++ /dev/null @@ -1,289 +0,0 @@ -# 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 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. - -import fnmatch -import os -import os.path -import BaseHTTPServer - -from webkitpy.common.host import Host # FIXME: This should not be needed! -from webkitpy.common.system.executive import ScriptError -from webkitpy.port.base import Port -from webkitpy.tool.servers.reflectionhandler import ReflectionHandler - - -STATE_NEEDS_REBASELINE = 'needs_rebaseline' -STATE_REBASELINE_FAILED = 'rebaseline_failed' -STATE_REBASELINE_SUCCEEDED = 'rebaseline_succeeded' - - -def _get_actual_result_files(test_file, test_config): - test_name, _ = os.path.splitext(test_file) - test_directory = os.path.dirname(test_file) - - test_results_directory = test_config.filesystem.join( - test_config.results_directory, test_directory) - actual_pattern = os.path.basename(test_name) + '-actual.*' - actual_files = [] - for filename in test_config.filesystem.listdir(test_results_directory): - if fnmatch.fnmatch(filename, actual_pattern): - actual_files.append(filename) - actual_files.sort() - return tuple(actual_files) - - -def _rebaseline_test(test_file, baseline_target, baseline_move_to, test_config, log): - test_name, _ = os.path.splitext(test_file) - test_directory = os.path.dirname(test_name) - - log('Rebaselining %s...' % test_name) - - actual_result_files = _get_actual_result_files(test_file, test_config) - filesystem = test_config.filesystem - scm = test_config.scm - layout_tests_directory = test_config.layout_tests_directory - results_directory = test_config.results_directory - target_expectations_directory = filesystem.join( - layout_tests_directory, 'platform', baseline_target, test_directory) - test_results_directory = test_config.filesystem.join( - test_config.results_directory, test_directory) - - # If requested, move current baselines out - current_baselines = get_test_baselines(test_file, test_config) - if baseline_target in current_baselines and baseline_move_to != 'none': - log(' Moving current %s baselines to %s' % - (baseline_target, baseline_move_to)) - - # See which ones we need to move (only those that are about to be - # updated), and make sure we're not clobbering any files in the - # destination. - current_extensions = set(current_baselines[baseline_target].keys()) - actual_result_extensions = [ - os.path.splitext(f)[1] for f in actual_result_files] - extensions_to_move = current_extensions.intersection( - actual_result_extensions) - - if extensions_to_move.intersection( - current_baselines.get(baseline_move_to, {}).keys()): - log(' Already had baselines in %s, could not move existing ' - '%s ones' % (baseline_move_to, baseline_target)) - return False - - # Do the actual move. - if extensions_to_move: - if not _move_test_baselines( - test_file, - list(extensions_to_move), - baseline_target, - baseline_move_to, - test_config, - log): - return False - else: - log(' No current baselines to move') - - log(' Updating baselines for %s' % baseline_target) - filesystem.maybe_make_directory(target_expectations_directory) - for source_file in actual_result_files: - source_path = filesystem.join(test_results_directory, source_file) - destination_file = source_file.replace('-actual', '-expected') - destination_path = filesystem.join( - target_expectations_directory, destination_file) - filesystem.copyfile(source_path, destination_path) - try: - scm.add(destination_path) - log(' Updated %s' % destination_file) - except ScriptError, error: - log(' Could not update %s in SCM, exit code %d' % - (destination_file, error.exit_code)) - return False - - return True - - -def _move_test_baselines(test_file, extensions_to_move, source_platform, destination_platform, test_config, log): - test_file_name = os.path.splitext(os.path.basename(test_file))[0] - test_directory = os.path.dirname(test_file) - filesystem = test_config.filesystem - - # Want predictable output order for unit tests. - extensions_to_move.sort() - - source_directory = os.path.join( - test_config.layout_tests_directory, - 'platform', - source_platform, - test_directory) - destination_directory = os.path.join( - test_config.layout_tests_directory, - 'platform', - destination_platform, - test_directory) - filesystem.maybe_make_directory(destination_directory) - - for extension in extensions_to_move: - file_name = test_file_name + '-expected' + extension - source_path = filesystem.join(source_directory, file_name) - destination_path = filesystem.join(destination_directory, file_name) - filesystem.copyfile(source_path, destination_path) - try: - test_config.scm.add(destination_path) - log(' Moved %s' % file_name) - except ScriptError, error: - log(' Could not update %s in SCM, exit code %d' % - (file_name, error.exit_code)) - return False - - return True - - -def get_test_baselines(test_file, test_config): - # FIXME: This seems like a hack. This only seems used to access the Port.expected_baselines logic. - class AllPlatformsPort(Port): - def __init__(self, host): - super(AllPlatformsPort, self).__init__(host, 'mac') - self._platforms_by_directory = dict([(self._webkit_baseline_path(p), p) for p in test_config.platforms]) - - def baseline_search_path(self): - return self._platforms_by_directory.keys() - - def platform_from_directory(self, directory): - return self._platforms_by_directory[directory] - - test_path = test_config.filesystem.join(test_config.layout_tests_directory, test_file) - - # FIXME: This should get the Host from the test_config to be mockable! - host = Host() - host.initialize_scm() - host.filesystem = test_config.filesystem - all_platforms_port = AllPlatformsPort(host) - - all_test_baselines = {} - for baseline_extension in ('.txt', '.checksum', '.png'): - test_baselines = test_config.test_port.expected_baselines(test_file, baseline_extension) - baselines = all_platforms_port.expected_baselines(test_file, baseline_extension, all_baselines=True) - for platform_directory, expected_filename in baselines: - if not platform_directory: - continue - if platform_directory == test_config.layout_tests_directory: - platform = 'base' - else: - platform = all_platforms_port.platform_from_directory(platform_directory) - platform_baselines = all_test_baselines.setdefault(platform, {}) - was_used_for_test = (platform_directory, expected_filename) in test_baselines - platform_baselines[baseline_extension] = was_used_for_test - - return all_test_baselines - - -class RebaselineHTTPServer(BaseHTTPServer.HTTPServer): - def __init__(self, httpd_port, config): - server_name = "" - BaseHTTPServer.HTTPServer.__init__(self, (server_name, httpd_port), RebaselineHTTPRequestHandler) - self.test_config = config['test_config'] - self.results_json = config['results_json'] - self.platforms_json = config['platforms_json'] - - -class RebaselineHTTPRequestHandler(ReflectionHandler): - STATIC_FILE_NAMES = frozenset([ - "index.html", - "loupe.js", - "main.js", - "main.css", - "queue.js", - "util.js", - ]) - - STATIC_FILE_DIRECTORY = os.path.join(os.path.dirname(__file__), "data", "rebaselineserver") - - def results_json(self): - self._serve_json(self.server.results_json) - - def test_config(self): - self._serve_json(self.server.test_config) - - def platforms_json(self): - self._serve_json(self.server.platforms_json) - - def rebaseline(self): - test = self.query['test'][0] - baseline_target = self.query['baseline-target'][0] - baseline_move_to = self.query['baseline-move-to'][0] - test_json = self.server.results_json['tests'][test] - - if test_json['state'] != STATE_NEEDS_REBASELINE: - self.send_error(400, "Test %s is in unexpected state: %s" % (test, test_json["state"])) - return - - log = [] - success = _rebaseline_test( - test, - baseline_target, - baseline_move_to, - self.server.test_config, - log=lambda l: log.append(l)) - - if success: - test_json['state'] = STATE_REBASELINE_SUCCEEDED - self.send_response(200) - else: - test_json['state'] = STATE_REBASELINE_FAILED - self.send_response(500) - - self.send_header('Content-type', 'text/plain') - self.end_headers() - self.wfile.write('\n'.join(log)) - - def test_result(self): - test_name, _ = os.path.splitext(self.query['test'][0]) - mode = self.query['mode'][0] - if mode == 'expected-image': - file_name = test_name + '-expected.png' - elif mode == 'actual-image': - file_name = test_name + '-actual.png' - if mode == 'expected-checksum': - file_name = test_name + '-expected.checksum' - elif mode == 'actual-checksum': - file_name = test_name + '-actual.checksum' - elif mode == 'diff-image': - file_name = test_name + '-diff.png' - if mode == 'expected-text': - file_name = test_name + '-expected.txt' - elif mode == 'actual-text': - file_name = test_name + '-actual.txt' - elif mode == 'diff-text': - file_name = test_name + '-diff.txt' - elif mode == 'diff-text-pretty': - file_name = test_name + '-pretty-diff.html' - - file_path = os.path.join(self.server.test_config.results_directory, file_name) - - # Let results be cached for 60 seconds, so that they can be pre-fetched - # by the UI - self._serve_file(file_path, cacheable_seconds=60) |