1f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.com#!/usr/bin/python 2f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.com 39fb6c8ac9ce7dd5d3319b4e3affd5f1e051162a2epoger@google.com""" 4f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.comCopyright 2013 Google Inc. 5f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.com 6f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.comUse of this source code is governed by a BSD-style license that can be 7f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.comfound in the LICENSE file. 8f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.com 9f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.comRepackage expected/actual GM results as needed by our HTML rebaseline viewer. 109fb6c8ac9ce7dd5d3319b4e3affd5f1e051162a2epoger@google.com""" 11f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.com 12f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.com# System-level imports 1331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.orgimport fnmatch 14f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.comimport os 15f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.comimport re 16f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.com 17b4edbffd7c09ca172f95fc30381671962e22dee0epoger# Must fix up PYTHONPATH before importing from within Skia 183b5c86c7a2db25f82a8415b6c79d1ac580fc64aestephanaimport rs_fixpypath # pylint: disable=W0611 19b4edbffd7c09ca172f95fc30381671962e22dee0epoger 20f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.com# Imports from within Skia 21f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.comimport gm_json 2231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.orgimport imagepairset 2316f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.org 2416f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.org# Keys used to link an image to a particular GM test. 2516f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.org# NOTE: Keep these in sync with static/constants.js 265c4b137592a7937b4d02d72a976fa783f8d3675aepogerVALUE__HEADER__SCHEMA_VERSION = 5 2716f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.orgKEY__EXPECTATIONS__BUGS = gm_json.JSONKEY_EXPECTEDRESULTS_BUGS 2816f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.orgKEY__EXPECTATIONS__IGNOREFAILURE = gm_json.JSONKEY_EXPECTEDRESULTS_IGNOREFAILURE 2916f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.orgKEY__EXPECTATIONS__REVIEWED = gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED 3068a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.orgKEY__EXTRACOLUMNS__BUILDER = 'builder' 3168a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.orgKEY__EXTRACOLUMNS__CONFIG = 'config' 3268a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.orgKEY__EXTRACOLUMNS__RESULT_TYPE = 'resultType' 3368a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.orgKEY__EXTRACOLUMNS__TEST = 'test' 347498d95bde16eeaa4b20643fb930b6a3be7face1commit-bot@chromium.orgKEY__HEADER__DATAHASH = 'dataHash' 357498d95bde16eeaa4b20643fb930b6a3be7face1commit-bot@chromium.orgKEY__HEADER__IS_EDITABLE = 'isEditable' 367498d95bde16eeaa4b20643fb930b6a3be7face1commit-bot@chromium.orgKEY__HEADER__IS_EXPORTED = 'isExported' 377498d95bde16eeaa4b20643fb930b6a3be7face1commit-bot@chromium.orgKEY__HEADER__IS_STILL_LOADING = 'resultsStillLoading' 3816f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.orgKEY__HEADER__RESULTS_ALL = 'all' 3916f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.orgKEY__HEADER__RESULTS_FAILURES = 'failures' 40ea770f155e72f88e66a4d9c652552517d46a8605commit-bot@chromium.orgKEY__HEADER__SCHEMA_VERSION = 'schemaVersion' 415c4b137592a7937b4d02d72a976fa783f8d3675aepogerKEY__HEADER__SET_A_DESCRIPTIONS = 'setA' 425c4b137592a7937b4d02d72a976fa783f8d3675aepogerKEY__HEADER__SET_B_DESCRIPTIONS = 'setB' 437498d95bde16eeaa4b20643fb930b6a3be7face1commit-bot@chromium.orgKEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE = 'timeNextUpdateAvailable' 447498d95bde16eeaa4b20643fb930b6a3be7face1commit-bot@chromium.orgKEY__HEADER__TIME_UPDATED = 'timeUpdated' 457498d95bde16eeaa4b20643fb930b6a3be7face1commit-bot@chromium.orgKEY__HEADER__TYPE = 'type' 4616f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.orgKEY__RESULT_TYPE__FAILED = gm_json.JSONKEY_ACTUALRESULTS_FAILED 4716f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.orgKEY__RESULT_TYPE__FAILUREIGNORED = gm_json.JSONKEY_ACTUALRESULTS_FAILUREIGNORED 4816f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.orgKEY__RESULT_TYPE__NOCOMPARISON = gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON 4916f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.orgKEY__RESULT_TYPE__SUCCEEDED = gm_json.JSONKEY_ACTUALRESULTS_SUCCEEDED 505c4b137592a7937b4d02d72a976fa783f8d3675aepogerKEY__SET_DESCRIPTIONS__DIR = 'dir' 515c4b137592a7937b4d02d72a976fa783f8d3675aepogerKEY__SET_DESCRIPTIONS__REPO_REVISION = 'repoRevision' 525c4b137592a7937b4d02d72a976fa783f8d3675aepogerKEY__SET_DESCRIPTIONS__SECTION = 'section' 5316f418080ff6751e15e0193263149412de9c848acommit-bot@chromium.org 54f9d134da93b8c78e7127efd84c9a26f99a73527eepoger@google.comIMAGE_FILENAME_RE = re.compile(gm_json.IMAGE_FILENAME_PATTERN) 55eb832599b631a09b180ea3615347adba6bd5e363epoger@google.comIMAGE_FILENAME_FORMATTER = '%s_%s.png' # pass in (testname, config) 5631d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 57b144271179aaf82cb1151e9dfd8e866747402594epogerPARENT_DIRECTORY = os.path.dirname(os.path.realpath(__file__)) 58defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.orgDEFAULT_ACTUALS_DIR = '.gm-actuals' 59defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.orgDEFAULT_GENERATED_IMAGES_ROOT = os.path.join( 60defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org PARENT_DIRECTORY, '.generated-images') 61defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org 62defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org# Define the default set of builders we will process expectations/actuals for. 6331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org# This allows us to ignore builders for which we don't maintain expectations 6431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org# (trybots, Valgrind, ASAN, TSAN), and avoid problems like 6531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org# https://code.google.com/p/skia/issues/detail?id=2036 ('rebaseline_server 6631d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org# produces error when trying to add baselines for ASAN/TSAN builders') 67defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.orgDEFAULT_MATCH_BUILDERS_PATTERN_LIST = ['.*'] 68defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.orgDEFAULT_SKIP_BUILDERS_PATTERN_LIST = [ 69defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org '.*-Trybot', '.*Valgrind.*', '.*TSAN.*', '.*ASAN.*'] 7031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 7131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 7231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.orgclass BaseComparisons(object): 7331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """Base class for generating summary of comparisons between two image sets. 7431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """ 7531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 765c4b137592a7937b4d02d72a976fa783f8d3675aepoger def __init__(self): 775c4b137592a7937b4d02d72a976fa783f8d3675aepoger """Base constructor; most subclasses will override.""" 785c4b137592a7937b4d02d72a976fa783f8d3675aepoger self._setA_descriptions = None 795c4b137592a7937b4d02d72a976fa783f8d3675aepoger self._setB_descriptions = None 805c4b137592a7937b4d02d72a976fa783f8d3675aepoger 8131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org def get_results_of_type(self, results_type): 8231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """Return results of some/all tests (depending on 'results_type' parameter). 8331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 8431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org Args: 8531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org results_type: string describing which types of results to include; must 8631d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org be one of the RESULTS_* constants 8731d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 8831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org Results are returned in a dictionary as output by ImagePairSet.as_dict(). 8931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """ 9031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org return self._results[results_type] 9131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 9231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org def get_packaged_results_of_type(self, results_type, reload_seconds=None, 9331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org is_editable=False, is_exported=True): 9431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """Package the results of some/all tests as a complete response_dict. 9531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 9631d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org Args: 9731d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org results_type: string indicating which set of results to return; 9831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org must be one of the RESULTS_* constants 9931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org reload_seconds: if specified, note that new results may be available once 10031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org these results are reload_seconds old 10131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org is_editable: whether clients are allowed to submit new baselines 10231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org is_exported: whether these results are being made available to other 10331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org network hosts 10431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """ 10531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org response_dict = self._results[results_type] 10631d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org time_updated = self.get_timestamp() 1075c4b137592a7937b4d02d72a976fa783f8d3675aepoger header_dict = { 10831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org KEY__HEADER__SCHEMA_VERSION: ( 10968a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.org VALUE__HEADER__SCHEMA_VERSION), 11031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 11131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org # Timestamps: 11231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org # 1. when this data was last updated 11331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org # 2. when the caller should check back for new data (if ever) 11431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org KEY__HEADER__TIME_UPDATED: time_updated, 11531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE: ( 11631d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org (time_updated+reload_seconds) if reload_seconds else None), 11731d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 11831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org # The type we passed to get_results_of_type() 11931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org KEY__HEADER__TYPE: results_type, 12031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 12131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org # Hash of dataset, which the client must return with any edits-- 12231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org # this ensures that the edits were made to a particular dataset. 12331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org KEY__HEADER__DATAHASH: str(hash(repr( 12468a3815401f461976f76891d0477cb1440fa0abacommit-bot@chromium.org response_dict[imagepairset.KEY__ROOT__IMAGEPAIRS]))), 12531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 12631d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org # Whether the server will accept edits back. 12731d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org KEY__HEADER__IS_EDITABLE: is_editable, 12831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 12931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org # Whether the service is accessible from other hosts. 13031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org KEY__HEADER__IS_EXPORTED: is_exported, 13131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org } 1325c4b137592a7937b4d02d72a976fa783f8d3675aepoger if self._setA_descriptions: 1335c4b137592a7937b4d02d72a976fa783f8d3675aepoger header_dict[KEY__HEADER__SET_A_DESCRIPTIONS] = self._setA_descriptions 1345c4b137592a7937b4d02d72a976fa783f8d3675aepoger if self._setB_descriptions: 1355c4b137592a7937b4d02d72a976fa783f8d3675aepoger header_dict[KEY__HEADER__SET_B_DESCRIPTIONS] = self._setB_descriptions 1365c4b137592a7937b4d02d72a976fa783f8d3675aepoger response_dict[imagepairset.KEY__ROOT__HEADER] = header_dict 13731d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org return response_dict 13831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 13931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org def get_timestamp(self): 14031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """Return the time at which this object was created, in seconds past epoch 14131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org (UTC). 14231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """ 14331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org return self._timestamp 14431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 145defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org _match_builders_pattern_list = [ 146defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org re.compile(p) for p in DEFAULT_MATCH_BUILDERS_PATTERN_LIST] 147defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org _skip_builders_pattern_list = [ 148defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org re.compile(p) for p in DEFAULT_SKIP_BUILDERS_PATTERN_LIST] 149defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org 150defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org def set_match_builders_pattern_list(self, pattern_list): 151defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org """Override the default set of builders we should process. 152defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org 153defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org The default is DEFAULT_MATCH_BUILDERS_PATTERN_LIST . 154defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org 155defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org Note that skip_builders_pattern_list overrides this; regardless of whether a 156defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org builder is in the "match" list, if it's in the "skip" list, we will skip it. 157defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org 158defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org Args: 159defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org pattern_list: list of regex patterns; process builders that match any 160defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org entry within this list 161defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org """ 162defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org if pattern_list == None: 163defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org pattern_list = [] 164defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org self._match_builders_pattern_list = [re.compile(p) for p in pattern_list] 165defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org 166defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org def set_skip_builders_pattern_list(self, pattern_list): 167defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org """Override the default set of builders we should skip while processing. 168defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org 169defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org The default is DEFAULT_SKIP_BUILDERS_PATTERN_LIST . 170defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org 171defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org This overrides match_builders_pattern_list; regardless of whether a 172defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org builder is in the "match" list, if it's in the "skip" list, we will skip it. 173defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org 174defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org Args: 175defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org pattern_list: list of regex patterns; skip builders that match any 176defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org entry within this list 177defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org """ 178defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org if pattern_list == None: 179defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org pattern_list = [] 180defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org self._skip_builders_pattern_list = [re.compile(p) for p in pattern_list] 181defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org 182defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org def _ignore_builder(self, builder): 183defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org """Returns True if we should skip processing this builder. 18431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 18531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org Args: 18631d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org builder: name of this builder, as a string 18731d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 18831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org Returns: 18931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org True if we should ignore expectations and actuals for this builder. 19031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """ 191defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org for pattern in self._skip_builders_pattern_list: 19231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org if pattern.match(builder): 19331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org return True 194defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org for pattern in self._match_builders_pattern_list: 195defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org if pattern.match(builder): 196defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org return False 197defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org return True 19831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 1997418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org def _read_builder_dicts_from_root(self, root, pattern='*.json'): 20031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """Read all JSON dictionaries within a directory tree. 20131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 2027418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org Skips any dictionaries belonging to a builder we have chosen to ignore. 2037418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org 20431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org Args: 20531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org root: path to root of directory tree 20631d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org pattern: which files to read within root (fnmatch-style pattern) 20731d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 20831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org Returns: 20931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org A meta-dictionary containing all the JSON dictionaries found within 2107418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org the directory tree, keyed by builder name (the basename of the directory 2117418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org where each JSON dictionary was found). 21231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 21331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org Raises: 21431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org IOError if root does not refer to an existing directory 21531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """ 2162c4352bb9db02db70b829f96f397faa80fade220epoger # I considered making this call read_dicts_from_root(), but I decided 2177418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org # it was better to prune out the ignored builders within the os.walk(). 21831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org if not os.path.isdir(root): 21931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org raise IOError('no directory found at path %s' % root) 22031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org meta_dict = {} 221b4edbffd7c09ca172f95fc30381671962e22dee0epoger for dirpath, _, filenames in os.walk(root): 22231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org for matching_filename in fnmatch.filter(filenames, pattern): 22331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org builder = os.path.basename(dirpath) 224defe6fdbc8edb2df0887c007450a8d8cc446f420commit-bot@chromium.org if self._ignore_builder(builder): 22531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org continue 2267418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org full_path = os.path.join(dirpath, matching_filename) 2277418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org meta_dict[builder] = gm_json.LoadFromFile(full_path) 2287418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org return meta_dict 2297418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org 2302c4352bb9db02db70b829f96f397faa80fade220epoger @staticmethod 2312c4352bb9db02db70b829f96f397faa80fade220epoger def read_dicts_from_root(root, pattern='*.json'): 2327418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org """Read all JSON dictionaries within a directory tree. 2337418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org 2342c4352bb9db02db70b829f96f397faa80fade220epoger TODO(stephana): Factor this out into a utility module, as a standalone 2352c4352bb9db02db70b829f96f397faa80fade220epoger function (not part of a class). 2362c4352bb9db02db70b829f96f397faa80fade220epoger 2377418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org Args: 2387418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org root: path to root of directory tree 2397418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org pattern: which files to read within root (fnmatch-style pattern) 2407418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org 2417418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org Returns: 2427418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org A meta-dictionary containing all the JSON dictionaries found within 2437418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org the directory tree, keyed by the pathname (relative to root) of each JSON 2447418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org dictionary. 2457418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org 2467418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org Raises: 2477418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org IOError if root does not refer to an existing directory 2487418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org """ 2497418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org if not os.path.isdir(root): 2507418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org raise IOError('no directory found at path %s' % root) 2517418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org meta_dict = {} 252b4edbffd7c09ca172f95fc30381671962e22dee0epoger for abs_dirpath, _, filenames in os.walk(root): 2537418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org rel_dirpath = os.path.relpath(abs_dirpath, root) 2547418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org for matching_filename in fnmatch.filter(filenames, pattern): 2557418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org abs_path = os.path.join(abs_dirpath, matching_filename) 2567418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org rel_path = os.path.join(rel_dirpath, matching_filename) 2577418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org meta_dict[rel_path] = gm_json.LoadFromFile(abs_path) 25831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org return meta_dict 25931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 26031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org @staticmethod 2614cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org def _read_noncomment_lines(path): 2624cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org """Return a list of all noncomment lines within a file. 2634cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org 2644cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org (A "noncomment" line is one that does not start with a '#'.) 2654cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org 2664cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org Args: 2674cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org path: path to file 2684cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org """ 2694cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org lines = [] 2704cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org with open(path, 'r') as fh: 2714cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org for line in fh: 2724cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org if not line.startswith('#'): 2734cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org lines.append(line.strip()) 2744cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org return lines 2754cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org 2764cef1be82193a9d527f7b1f873197c443d0dde2ecommit-bot@chromium.org @staticmethod 27731d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org def _create_relative_url(hashtype_and_digest, test_name): 27831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """Returns the URL for this image, relative to GM_ACTUALS_ROOT_HTTP_URL. 27931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 28031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org If we don't have a record of this image, returns None. 28131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org 28231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org Args: 28331d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org hashtype_and_digest: (hash_type, hash_digest) tuple, or None if we 28431d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org don't have a record of this image 28531d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org test_name: string; name of the GM test that created this image 28631d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org """ 28731d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org if not hashtype_and_digest: 28831d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org return None 28931d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org return gm_json.CreateGmRelativeUrl( 29031d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org test_name=test_name, 29131d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org hash_type=hashtype_and_digest[0], 29231d0b3d806a1aa86b7edaa442b3821f5d548e184commit-bot@chromium.org hash_digest=hashtype_and_digest[1]) 2933eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org 2943eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org @staticmethod 2953eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org def combine_subdicts(input_dict): 2963eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org """ Flatten out a dictionary structure by one level. 2973eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org 2983eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org Input: 2993eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org { 3007418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org KEY_A1 : { 3017418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org KEY_B1 : VALUE_B1, 3023eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org }, 3037418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org KEY_A2 : { 3047418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org KEY_B2 : VALUE_B2, 3053eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org } 3063eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org } 3073eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org 3083eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org Output: 3093eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org { 3107418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org KEY_B1 : VALUE_B1, 3117418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org KEY_B2 : VALUE_B2, 3123eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org } 3133eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org 3143eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org If this would result in any repeated keys, it will raise an Exception. 3153eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org """ 3163eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org output_dict = {} 317b4edbffd7c09ca172f95fc30381671962e22dee0epoger for subdict in input_dict.values(): 3183eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org for subdict_key, subdict_value in subdict.iteritems(): 3193eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org if subdict_key in output_dict: 3203eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org raise Exception('duplicate key %s in combine_subdicts' % subdict_key) 3213eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org output_dict[subdict_key] = subdict_value 3223eb77e4d5a381fa55197f6bd03c599e709146069commit-bot@chromium.org return output_dict 3237418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org 3247418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org @staticmethod 3250b7127635d8245de7ac704080d722d06e47621d0epoger def get_default(input_dict, default_value, *keys): 3260b7127635d8245de7ac704080d722d06e47621d0epoger """Returns input_dict[key1][key2][...], or default_value. 3270b7127635d8245de7ac704080d722d06e47621d0epoger 3280b7127635d8245de7ac704080d722d06e47621d0epoger If input_dict is None, or any key is missing along the way, this returns 3290b7127635d8245de7ac704080d722d06e47621d0epoger default_value. 3300b7127635d8245de7ac704080d722d06e47621d0epoger 3310b7127635d8245de7ac704080d722d06e47621d0epoger Args: 3320b7127635d8245de7ac704080d722d06e47621d0epoger input_dict: dictionary to look within 3330b7127635d8245de7ac704080d722d06e47621d0epoger key: key indicating which value to return from input_dict 3340b7127635d8245de7ac704080d722d06e47621d0epoger default_value: value to return if input_dict is None or any key cannot 3350b7127635d8245de7ac704080d722d06e47621d0epoger be found along the way 3367418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org """ 3370b7127635d8245de7ac704080d722d06e47621d0epoger if input_dict == None: 3380b7127635d8245de7ac704080d722d06e47621d0epoger return default_value 3397418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org for key in keys: 3407418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org input_dict = input_dict.get(key, None) 3410b7127635d8245de7ac704080d722d06e47621d0epoger if input_dict == None: 3420b7127635d8245de7ac704080d722d06e47621d0epoger return default_value 3437418bd8cad3576294b48dd8e5015301e184c6af1commit-bot@chromium.org return input_dict 344