15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# Copyright (c) 2010 Google Inc. All rights reserved. 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# Redistribution and use in source and binary forms, with or without 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# modification, are permitted provided that the following conditions are 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# met: 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# * Redistributions of source code must retain the above copyright 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# notice, this list of conditions and the following disclaimer. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# * Redistributions in binary form must reproduce the above 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# copyright notice, this list of conditions and the following disclaimer 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# in the documentation and/or other materials provided with the 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# distribution. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# * Neither the name of Google Inc. nor the names of its 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# contributors may be used to endorse or promote products derived from 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# this software without specific prior written permission. 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import fnmatch 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import os 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import os.path 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)import BaseHTTPServer 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)from webkitpy.layout_tests.port.base import Port 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)from webkitpy.tool.servers.reflectionhandler import ReflectionHandler 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)STATE_NEEDS_REBASELINE = 'needs_rebaseline' 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)STATE_REBASELINE_FAILED = 'rebaseline_failed' 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)STATE_REBASELINE_SUCCEEDED = 'rebaseline_succeeded' 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)def _get_actual_result_files(test_file, test_config): 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_name, _ = os.path.splitext(test_file) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_directory = os.path.dirname(test_file) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_results_directory = test_config.filesystem.join( 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_config.results_directory, test_directory) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) actual_pattern = os.path.basename(test_name) + '-actual.*' 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) actual_files = [] 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for filename in test_config.filesystem.listdir(test_results_directory): 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if fnmatch.fnmatch(filename, actual_pattern): 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) actual_files.append(filename) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) actual_files.sort() 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return tuple(actual_files) 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)def _rebaseline_test(test_file, baseline_target, baseline_move_to, test_config, log): 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_name, _ = os.path.splitext(test_file) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_directory = os.path.dirname(test_name) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log('Rebaselining %s...' % test_name) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) actual_result_files = _get_actual_result_files(test_file, test_config) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) filesystem = test_config.filesystem 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scm = test_config.scm 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) layout_tests_directory = test_config.layout_tests_directory 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) results_directory = test_config.results_directory 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) target_expectations_directory = filesystem.join( 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) layout_tests_directory, 'platform', baseline_target, test_directory) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_results_directory = test_config.filesystem.join( 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_config.results_directory, test_directory) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) # If requested, move current baselines out 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current_baselines = get_test_baselines(test_file, test_config) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if baseline_target in current_baselines and baseline_move_to != 'none': 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log(' Moving current %s baselines to %s' % 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (baseline_target, baseline_move_to)) 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) # See which ones we need to move (only those that are about to be 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) # updated), and make sure we're not clobbering any files in the 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) # destination. 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current_extensions = set(current_baselines[baseline_target].keys()) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) actual_result_extensions = [ 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) os.path.splitext(f)[1] for f in actual_result_files] 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extensions_to_move = current_extensions.intersection( 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) actual_result_extensions) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if extensions_to_move.intersection( 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) current_baselines.get(baseline_move_to, {}).keys()): 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log(' Already had baselines in %s, could not move existing ' 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) '%s ones' % (baseline_move_to, baseline_target)) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return False 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) # Do the actual move. 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if extensions_to_move: 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if not _move_test_baselines( 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_file, 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) list(extensions_to_move), 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baseline_target, 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baseline_move_to, 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_config, 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log): 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return False 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else: 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log(' No current baselines to move') 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log(' Updating baselines for %s' % baseline_target) 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) filesystem.maybe_make_directory(target_expectations_directory) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for source_file in actual_result_files: 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) source_path = filesystem.join(test_results_directory, source_file) 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destination_file = source_file.replace('-actual', '-expected') 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destination_path = filesystem.join( 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) target_expectations_directory, destination_file) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) filesystem.copyfile(source_path, destination_path) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) exit_code = scm.add(destination_path, return_exit_code=True) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if exit_code: 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log(' Could not update %s in SCM, exit code %d' % 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (destination_file, exit_code)) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return False 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else: 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log(' Updated %s' % destination_file) 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return True 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)def _move_test_baselines(test_file, extensions_to_move, source_platform, destination_platform, test_config, log): 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_file_name = os.path.splitext(os.path.basename(test_file))[0] 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_directory = os.path.dirname(test_file) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) filesystem = test_config.filesystem 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) # Want predictable output order for unit tests. 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extensions_to_move.sort() 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) source_directory = os.path.join( 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_config.layout_tests_directory, 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 'platform', 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) source_platform, 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_directory) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destination_directory = os.path.join( 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_config.layout_tests_directory, 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 'platform', 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destination_platform, 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_directory) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) filesystem.maybe_make_directory(destination_directory) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for extension in extensions_to_move: 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_name = test_file_name + '-expected' + extension 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) source_path = filesystem.join(source_directory, file_name) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destination_path = filesystem.join(destination_directory, file_name) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) filesystem.copyfile(source_path, destination_path) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) exit_code = test_config.scm.add(destination_path, return_exit_code=True) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if exit_code: 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log(' Could not update %s in SCM, exit code %d' % 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (file_name, exit_code)) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return False 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else: 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log(' Moved %s' % file_name) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return True 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)def get_test_baselines(test_file, test_config): 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) # FIXME: This seems like a hack. This only seems used to access the Port.expected_baselines logic. 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) class AllPlatformsPort(Port): 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) def __init__(self, host): 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) super(AllPlatformsPort, self).__init__(host, 'mac') 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self._platforms_by_directory = dict([(self._webkit_baseline_path(p), p) for p in test_config.platforms]) 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) def baseline_search_path(self): 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return self._platforms_by_directory.keys() 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) def platform_from_directory(self, directory): 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return self._platforms_by_directory[directory] 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_path = test_config.filesystem.join(test_config.layout_tests_directory, test_file) 1777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci host = test_config.host 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) all_platforms_port = AllPlatformsPort(host) 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) all_test_baselines = {} 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for baseline_extension in ('.txt', '.checksum', '.png'): 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_baselines = test_config.test_port.expected_baselines(test_file, baseline_extension) 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baselines = all_platforms_port.expected_baselines(test_file, baseline_extension, all_baselines=True) 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for platform_directory, expected_filename in baselines: 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if not platform_directory: 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if platform_directory == test_config.layout_tests_directory: 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platform = 'base' 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else: 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platform = all_platforms_port.platform_from_directory(platform_directory) 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platform_baselines = all_test_baselines.setdefault(platform, {}) 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) was_used_for_test = (platform_directory, expected_filename) in test_baselines 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platform_baselines[baseline_extension] = was_used_for_test 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return all_test_baselines 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class RebaselineHTTPServer(BaseHTTPServer.HTTPServer): 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) def __init__(self, httpd_port, config): 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) server_name = "" 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BaseHTTPServer.HTTPServer.__init__(self, (server_name, httpd_port), RebaselineHTTPRequestHandler) 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self.test_config = config['test_config'] 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self.results_json = config['results_json'] 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self.platforms_json = config['platforms_json'] 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class RebaselineHTTPRequestHandler(ReflectionHandler): 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) STATIC_FILE_NAMES = frozenset([ 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "index.html", 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "loupe.js", 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "main.js", 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "main.css", 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "queue.js", 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "util.js", 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ]) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) STATIC_FILE_DIRECTORY = os.path.join(os.path.dirname(__file__), "data", "rebaselineserver") 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) def results_json(self): 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self._serve_json(self.server.results_json) 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) def test_config(self): 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self._serve_json(self.server.test_config) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) def platforms_json(self): 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self._serve_json(self.server.platforms_json) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) def rebaseline(self): 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test = self.query['test'][0] 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baseline_target = self.query['baseline-target'][0] 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baseline_move_to = self.query['baseline-move-to'][0] 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_json = self.server.results_json['tests'][test] 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if test_json['state'] != STATE_NEEDS_REBASELINE: 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self.send_error(400, "Test %s is in unexpected state: %s" % (test, test_json["state"])) 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log = [] 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) success = _rebaseline_test( 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test, 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baseline_target, 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baseline_move_to, 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self.server.test_config, 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) log=lambda l: log.append(l)) 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if success: 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_json['state'] = STATE_REBASELINE_SUCCEEDED 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self.send_response(200) 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else: 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_json['state'] = STATE_REBASELINE_FAILED 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self.send_response(500) 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self.send_header('Content-type', 'text/plain') 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self.end_headers() 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self.wfile.write('\n'.join(log)) 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) def test_result(self): 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) test_name, _ = os.path.splitext(self.query['test'][0]) 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) mode = self.query['mode'][0] 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if mode == 'expected-image': 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_name = test_name + '-expected.png' 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) elif mode == 'actual-image': 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_name = test_name + '-actual.png' 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if mode == 'expected-checksum': 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_name = test_name + '-expected.checksum' 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) elif mode == 'actual-checksum': 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_name = test_name + '-actual.checksum' 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) elif mode == 'diff-image': 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_name = test_name + '-diff.png' 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if mode == 'expected-text': 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_name = test_name + '-expected.txt' 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) elif mode == 'actual-text': 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_name = test_name + '-actual.txt' 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) elif mode == 'diff-text': 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_name = test_name + '-diff.txt' 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) elif mode == 'diff-text-pretty': 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_name = test_name + '-pretty-diff.html' 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) file_path = os.path.join(self.server.test_config.results_directory, file_name) 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) # Let results be cached for 60 seconds, so that they can be pre-fetched 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) # by the UI 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) self._serve_file(file_path, cacheable_seconds=60) 284