Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: gm/rebaseline_server/results.py

Issue 232103002: rebaseline_server: allow user to specify which builders to process (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: expose to command line Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 """ 3 """
4 Copyright 2013 Google Inc. 4 Copyright 2013 Google Inc.
5 5
6 Use of this source code is governed by a BSD-style license that can be 6 Use of this source code is governed by a BSD-style license that can be
7 found in the LICENSE file. 7 found in the LICENSE file.
8 8
9 Repackage expected/actual GM results as needed by our HTML rebaseline viewer. 9 Repackage expected/actual GM results as needed by our HTML rebaseline viewer.
10 """ 10 """
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 KEY__HEADER__TYPE = 'type' 52 KEY__HEADER__TYPE = 'type'
53 KEY__NEW_IMAGE_URL = 'newImageUrl' 53 KEY__NEW_IMAGE_URL = 'newImageUrl'
54 KEY__RESULT_TYPE__FAILED = gm_json.JSONKEY_ACTUALRESULTS_FAILED 54 KEY__RESULT_TYPE__FAILED = gm_json.JSONKEY_ACTUALRESULTS_FAILED
55 KEY__RESULT_TYPE__FAILUREIGNORED = gm_json.JSONKEY_ACTUALRESULTS_FAILUREIGNORED 55 KEY__RESULT_TYPE__FAILUREIGNORED = gm_json.JSONKEY_ACTUALRESULTS_FAILUREIGNORED
56 KEY__RESULT_TYPE__NOCOMPARISON = gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON 56 KEY__RESULT_TYPE__NOCOMPARISON = gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON
57 KEY__RESULT_TYPE__SUCCEEDED = gm_json.JSONKEY_ACTUALRESULTS_SUCCEEDED 57 KEY__RESULT_TYPE__SUCCEEDED = gm_json.JSONKEY_ACTUALRESULTS_SUCCEEDED
58 58
59 IMAGE_FILENAME_RE = re.compile(gm_json.IMAGE_FILENAME_PATTERN) 59 IMAGE_FILENAME_RE = re.compile(gm_json.IMAGE_FILENAME_PATTERN)
60 IMAGE_FILENAME_FORMATTER = '%s_%s.png' # pass in (testname, config) 60 IMAGE_FILENAME_FORMATTER = '%s_%s.png' # pass in (testname, config)
61 61
62 # Ignore expectations/actuals for builders matching any of these patterns. 62 DEFAULT_ACTUALS_DIR = '.gm-actuals'
63 DEFAULT_GENERATED_IMAGES_ROOT = os.path.join(
64 PARENT_DIRECTORY, '.generated-images')
65
66 # Define the default set of builders we will process expectations/actuals for.
63 # This allows us to ignore builders for which we don't maintain expectations 67 # This allows us to ignore builders for which we don't maintain expectations
64 # (trybots, Valgrind, ASAN, TSAN), and avoid problems like 68 # (trybots, Valgrind, ASAN, TSAN), and avoid problems like
65 # https://code.google.com/p/skia/issues/detail?id=2036 ('rebaseline_server 69 # https://code.google.com/p/skia/issues/detail?id=2036 ('rebaseline_server
66 # produces error when trying to add baselines for ASAN/TSAN builders') 70 # produces error when trying to add baselines for ASAN/TSAN builders')
67 SKIP_BUILDERS_PATTERN_LIST = [re.compile(p) for p in [ 71 DEFAULT_MATCH_BUILDERS_PATTERN_LIST = ['.*']
68 '.*-Trybot', '.*Valgrind.*', '.*TSAN.*', '.*ASAN.*']] 72 DEFAULT_SKIP_BUILDERS_PATTERN_LIST = [
69 73 '.*-Trybot', '.*Valgrind.*', '.*TSAN.*', '.*ASAN.*']
70 DEFAULT_ACTUALS_DIR = '.gm-actuals'
71 DEFAULT_GENERATED_IMAGES_ROOT = os.path.join(
72 PARENT_DIRECTORY, '.generated-images')
73 74
74 75
75 class BaseComparisons(object): 76 class BaseComparisons(object):
76 """Base class for generating summary of comparisons between two image sets. 77 """Base class for generating summary of comparisons between two image sets.
77 """ 78 """
78 79
79 def __init__(self):
80 raise NotImplementedError('cannot instantiate the abstract base class')
81
82 def get_results_of_type(self, results_type): 80 def get_results_of_type(self, results_type):
83 """Return results of some/all tests (depending on 'results_type' parameter). 81 """Return results of some/all tests (depending on 'results_type' parameter).
84 82
85 Args: 83 Args:
86 results_type: string describing which types of results to include; must 84 results_type: string describing which types of results to include; must
87 be one of the RESULTS_* constants 85 be one of the RESULTS_* constants
88 86
89 Results are returned in a dictionary as output by ImagePairSet.as_dict(). 87 Results are returned in a dictionary as output by ImagePairSet.as_dict().
90 """ 88 """
91 return self._results[results_type] 89 return self._results[results_type]
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 KEY__HEADER__IS_EXPORTED: is_exported, 129 KEY__HEADER__IS_EXPORTED: is_exported,
132 } 130 }
133 return response_dict 131 return response_dict
134 132
135 def get_timestamp(self): 133 def get_timestamp(self):
136 """Return the time at which this object was created, in seconds past epoch 134 """Return the time at which this object was created, in seconds past epoch
137 (UTC). 135 (UTC).
138 """ 136 """
139 return self._timestamp 137 return self._timestamp
140 138
141 @staticmethod 139 _match_builders_pattern_list = [
142 def _ignore_builder(builder): 140 re.compile(p) for p in DEFAULT_MATCH_BUILDERS_PATTERN_LIST]
143 """Returns True if this builder matches any of SKIP_BUILDERS_PATTERN_LIST. 141 _skip_builders_pattern_list = [
142 re.compile(p) for p in DEFAULT_SKIP_BUILDERS_PATTERN_LIST]
143
144 def set_match_builders_pattern_list(self, pattern_list):
145 """Override the default set of builders we should process.
146
147 The default is DEFAULT_MATCH_BUILDERS_PATTERN_LIST .
148
149 Note that skip_builders_pattern_list overrides this; regardless of whether a
150 builder is in the "match" list, if it's in the "skip" list, we will skip it.
151
152 Args:
153 pattern_list: list of regex patterns; process builders that match any
154 entry within this list
155 """
156 if pattern_list == None:
157 pattern_list = []
158 self._match_builders_pattern_list = [re.compile(p) for p in pattern_list]
159
160 def set_skip_builders_pattern_list(self, pattern_list):
161 """Override the default set of builders we should skip while processing.
162
163 The default is DEFAULT_SKIP_BUILDERS_PATTERN_LIST .
164
165 This overrides match_builders_pattern_list; regardless of whether a
166 builder is in the "match" list, if it's in the "skip" list, we will skip it.
167
168 Args:
169 pattern_list: list of regex patterns; skip builders that match any
170 entry within this list
171 """
172 if pattern_list == None:
173 pattern_list = []
174 self._skip_builders_pattern_list = [re.compile(p) for p in pattern_list]
175
176 def _ignore_builder(self, builder):
177 """Returns True if we should skip processing this builder.
144 178
145 Args: 179 Args:
146 builder: name of this builder, as a string 180 builder: name of this builder, as a string
147 181
148 Returns: 182 Returns:
149 True if we should ignore expectations and actuals for this builder. 183 True if we should ignore expectations and actuals for this builder.
150 """ 184 """
151 for pattern in SKIP_BUILDERS_PATTERN_LIST: 185 for pattern in self._skip_builders_pattern_list:
152 if pattern.match(builder): 186 if pattern.match(builder):
153 return True 187 return True
154 return False 188 for pattern in self._match_builders_pattern_list:
189 if pattern.match(builder):
190 return False
191 return True
155 192
156 @staticmethod 193 def _read_dicts_from_root(self, root, pattern='*.json'):
157 def _read_dicts_from_root(root, pattern='*.json'):
158 """Read all JSON dictionaries within a directory tree. 194 """Read all JSON dictionaries within a directory tree.
159 195
160 Args: 196 Args:
161 root: path to root of directory tree 197 root: path to root of directory tree
162 pattern: which files to read within root (fnmatch-style pattern) 198 pattern: which files to read within root (fnmatch-style pattern)
163 199
164 Returns: 200 Returns:
165 A meta-dictionary containing all the JSON dictionaries found within 201 A meta-dictionary containing all the JSON dictionaries found within
166 the directory tree, keyed by the builder name of each dictionary. 202 the directory tree, keyed by the builder name of each dictionary.
167 203
168 Raises: 204 Raises:
169 IOError if root does not refer to an existing directory 205 IOError if root does not refer to an existing directory
170 """ 206 """
171 if not os.path.isdir(root): 207 if not os.path.isdir(root):
172 raise IOError('no directory found at path %s' % root) 208 raise IOError('no directory found at path %s' % root)
173 meta_dict = {} 209 meta_dict = {}
174 for dirpath, dirnames, filenames in os.walk(root): 210 for dirpath, dirnames, filenames in os.walk(root):
175 for matching_filename in fnmatch.filter(filenames, pattern): 211 for matching_filename in fnmatch.filter(filenames, pattern):
176 builder = os.path.basename(dirpath) 212 builder = os.path.basename(dirpath)
177 if BaseComparisons._ignore_builder(builder): 213 if self._ignore_builder(builder):
178 continue 214 continue
179 fullpath = os.path.join(dirpath, matching_filename) 215 fullpath = os.path.join(dirpath, matching_filename)
180 meta_dict[builder] = gm_json.LoadFromFile(fullpath) 216 meta_dict[builder] = gm_json.LoadFromFile(fullpath)
181 return meta_dict 217 return meta_dict
182 218
183 @staticmethod 219 @staticmethod
184 def _create_relative_url(hashtype_and_digest, test_name): 220 def _create_relative_url(hashtype_and_digest, test_name):
185 """Returns the URL for this image, relative to GM_ACTUALS_ROOT_HTTP_URL. 221 """Returns the URL for this image, relative to GM_ACTUALS_ROOT_HTTP_URL.
186 222
187 If we don't have a record of this image, returns None. 223 If we don't have a record of this image, returns None.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 256
221 If this would result in any repeated keys, it will raise an Exception. 257 If this would result in any repeated keys, it will raise an Exception.
222 """ 258 """
223 output_dict = {} 259 output_dict = {}
224 for key, subdict in input_dict.iteritems(): 260 for key, subdict in input_dict.iteritems():
225 for subdict_key, subdict_value in subdict.iteritems(): 261 for subdict_key, subdict_value in subdict.iteritems():
226 if subdict_key in output_dict: 262 if subdict_key in output_dict:
227 raise Exception('duplicate key %s in combine_subdicts' % subdict_key) 263 raise Exception('duplicate key %s in combine_subdicts' % subdict_key)
228 output_dict[subdict_key] = subdict_value 264 output_dict[subdict_key] = subdict_value
229 return output_dict 265 return output_dict
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698