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

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py

Issue 2397573002: Don't track SCM changes in rebaseline commands. (Closed)
Patch Set: Rebased Created 4 years, 2 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 # Copyright (c) 2010 Google Inc. All rights reserved. 1 # Copyright (c) 2010 Google Inc. All rights reserved.
2 # 2 #
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer 10 # copyright notice, this list of conditions and the following disclaimer
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 platform_options = factory.platform_options(use_globs=True) 56 platform_options = factory.platform_options(use_globs=True)
57 57
58 results_directory_option = optparse.make_option("--results-directory", help= "Local results directory to use.") 58 results_directory_option = optparse.make_option("--results-directory", help= "Local results directory to use.")
59 59
60 suffixes_option = optparse.make_option("--suffixes", default=','.join(BASELI NE_SUFFIX_LIST), action="store", 60 suffixes_option = optparse.make_option("--suffixes", default=','.join(BASELI NE_SUFFIX_LIST), action="store",
61 help="Comma-separated-list of file ty pes to rebaseline.") 61 help="Comma-separated-list of file ty pes to rebaseline.")
62 62
63 def __init__(self, options=None): 63 def __init__(self, options=None):
64 super(AbstractRebaseliningCommand, self).__init__(options=options) 64 super(AbstractRebaseliningCommand, self).__init__(options=options)
65 self._baseline_suffix_list = BASELINE_SUFFIX_LIST 65 self._baseline_suffix_list = BASELINE_SUFFIX_LIST
66 self._scm_changes = ChangeSet() 66 self.expectation_line_changes = ChangeSet()
67 self._tool = None 67 self._tool = None
68 68
69 def _print_scm_changes(self): 69 def _print_expectation_line_changes(self):
70 print(json.dumps(self._scm_changes.to_dict())) 70 print(json.dumps(self.expectation_line_changes.to_dict()))
71 71
72 72
73 class ChangeSet(object): 73 class ChangeSet(object):
74 """A record of added and deleted files and TestExpectation lines to remove. 74 """A record of TestExpectation lines to remove.
75 75
76 This class groups two kinds of changes together: 76 TODO(qyearsley): Remove this class, track list of lines to remove directly
77 (1) files that have been added or removed. 77 in an attribute of AbstractRebaseliningCommand.
78 (2) lines to remove from TestExpectations.
79
80 The reason for keeping track of these changes together is that after rebasel ining
81 many tests in parallel by subprocesses, we can update the git staged files l ist
82 and the TestExpectations all at once at the end.
83
84 Each subprocess can communicate some set of changes by outputting JSON lines ,
85 and another process can aggregate the changes.
86
87 TODO(qyearsley): Refactor this so that lines to remove are only tracked in o ne format.
88 """ 78 """
89 def __init__(self, files_to_add=None, files_to_delete=None, lines_to_remove= None): 79 def __init__(self, lines_to_remove=None):
90 self.files_to_add = files_to_add or []
91 self.files_to_delete = files_to_delete or []
92 self.lines_to_remove = lines_to_remove or {} 80 self.lines_to_remove = lines_to_remove or {}
93 81
94 def add_file(self, path):
95 self.files_to_add.append(path)
96
97 def delete_file(self, path):
98 self.files_to_delete.append(path)
99
100 def remove_line(self, test, builder): 82 def remove_line(self, test, builder):
101 if test not in self.lines_to_remove: 83 if test not in self.lines_to_remove:
102 self.lines_to_remove[test] = [] 84 self.lines_to_remove[test] = []
103 self.lines_to_remove[test].append(builder) 85 self.lines_to_remove[test].append(builder)
104 86
105 def to_dict(self): 87 def to_dict(self):
106 remove_lines = [] 88 remove_lines = []
107 for test in self.lines_to_remove: 89 for test in self.lines_to_remove:
108 for builder in self.lines_to_remove[test]: 90 for builder in self.lines_to_remove[test]:
109 remove_lines.append({'test': test, 'builder': builder}) 91 remove_lines.append({'test': test, 'builder': builder})
110 return { 92 return {'remove-lines': remove_lines}
111 'add': list(self.files_to_add),
112 'delete': list(self.files_to_delete),
113 'remove-lines': remove_lines,
114 }
115 93
116 @staticmethod 94 @staticmethod
117 def from_dict(change_dict): 95 def from_dict(change_dict):
118 files_to_add = set()
119 files_to_delete = set()
120 lines_to_remove = {} 96 lines_to_remove = {}
121 if 'add' in change_dict:
122 files_to_add.update(change_dict['add'])
123 if 'delete' in change_dict:
124 files_to_delete.update(change_dict['delete'])
125 if 'remove-lines' in change_dict: 97 if 'remove-lines' in change_dict:
126 for line_to_remove in change_dict['remove-lines']: 98 for line_to_remove in change_dict['remove-lines']:
127 test = line_to_remove['test'] 99 test = line_to_remove['test']
128 builder = line_to_remove['builder'] 100 builder = line_to_remove['builder']
129 if test not in lines_to_remove: 101 if test not in lines_to_remove:
130 lines_to_remove[test] = [] 102 lines_to_remove[test] = []
131 lines_to_remove[test].append(builder) 103 lines_to_remove[test].append(builder)
132 return ChangeSet( 104 return ChangeSet(lines_to_remove=lines_to_remove)
133 files_to_add=list(files_to_add),
134 files_to_delete=list(files_to_delete),
135 lines_to_remove=lines_to_remove)
136 105
137 def update(self, other): 106 def update(self, other):
138 assert isinstance(other, ChangeSet) 107 assert isinstance(other, ChangeSet)
139 assert type(other.lines_to_remove) is dict 108 assert type(other.lines_to_remove) is dict
140 self.files_to_add.extend(other.files_to_add)
141 self.files_to_delete.extend(other.files_to_delete)
142 for test in other.lines_to_remove: 109 for test in other.lines_to_remove:
143 if test not in self.lines_to_remove: 110 if test not in self.lines_to_remove:
144 self.lines_to_remove[test] = [] 111 self.lines_to_remove[test] = []
145 self.lines_to_remove[test].extend(other.lines_to_remove[test]) 112 self.lines_to_remove[test].extend(other.lines_to_remove[test])
146 113
147 114
148 class BaseInternalRebaselineCommand(AbstractRebaseliningCommand): 115 class BaseInternalRebaselineCommand(AbstractRebaseliningCommand):
149 """Base class for rebaseline-related commands that are intended to be used b y other commands.""" 116 """Base class for rebaseline-related commands that are intended to be used b y other commands."""
150 # Not overriding execute() - pylint: disable=abstract-method 117 # Not overriding execute() - pylint: disable=abstract-method
151 118
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 old_baselines.append(old_baseline) 198 old_baselines.append(old_baseline)
232 new_baselines.append(new_baseline) 199 new_baselines.append(new_baseline)
233 200
234 for i in range(len(old_baselines)): 201 for i in range(len(old_baselines)):
235 old_baseline = old_baselines[i] 202 old_baseline = old_baselines[i]
236 new_baseline = new_baselines[i] 203 new_baseline = new_baselines[i]
237 204
238 _log.debug("Copying baseline from %s to %s.", old_baseline, new_base line) 205 _log.debug("Copying baseline from %s to %s.", old_baseline, new_base line)
239 self._tool.filesystem.maybe_make_directory(self._tool.filesystem.dir name(new_baseline)) 206 self._tool.filesystem.maybe_make_directory(self._tool.filesystem.dir name(new_baseline))
240 self._tool.filesystem.copyfile(old_baseline, new_baseline) 207 self._tool.filesystem.copyfile(old_baseline, new_baseline)
241 if not self._tool.scm().exists(new_baseline):
242 self._scm_changes.add_file(new_baseline)
243 208
244 def execute(self, options, args, tool): 209 def execute(self, options, args, tool):
245 self._tool = tool 210 self._tool = tool
246 for suffix in options.suffixes.split(','): 211 for suffix in options.suffixes.split(','):
247 self._copy_existing_baseline(options.builder, options.test, suffix) 212 self._copy_existing_baseline(options.builder, options.test, suffix)
248 self._print_scm_changes()
249 213
250 214
251 class RebaselineTest(BaseInternalRebaselineCommand): 215 class RebaselineTest(BaseInternalRebaselineCommand):
252 name = "rebaseline-test-internal" 216 name = "rebaseline-test-internal"
253 help_text = "Rebaseline a single test from a buildbot. Only intended for use by other webkit-patch commands." 217 help_text = "Rebaseline a single test from a buildbot. Only intended for use by other webkit-patch commands."
254 218
255 def _save_baseline(self, data, target_baseline): 219 def _save_baseline(self, data, target_baseline):
256 if not data: 220 if not data:
257 _log.debug("No baseline data to save.") 221 _log.debug("No baseline data to save.")
258 return 222 return
259 223
260 filesystem = self._tool.filesystem 224 filesystem = self._tool.filesystem
261 filesystem.maybe_make_directory(filesystem.dirname(target_baseline)) 225 filesystem.maybe_make_directory(filesystem.dirname(target_baseline))
262 filesystem.write_binary_file(target_baseline, data) 226 filesystem.write_binary_file(target_baseline, data)
263 if not self._tool.scm().exists(target_baseline):
264 self._scm_changes.add_file(target_baseline)
265 227
266 def _rebaseline_test(self, builder_name, test_name, suffix, results_url): 228 def _rebaseline_test(self, builder_name, test_name, suffix, results_url):
267 baseline_directory = self._baseline_directory(builder_name) 229 baseline_directory = self._baseline_directory(builder_name)
268 230
269 source_baseline = "%s/%s" % (results_url, self._file_name_for_actual_res ult(test_name, suffix)) 231 source_baseline = "%s/%s" % (results_url, self._file_name_for_actual_res ult(test_name, suffix))
270 target_baseline = self._tool.filesystem.join(baseline_directory, self._f ile_name_for_expected_result(test_name, suffix)) 232 target_baseline = self._tool.filesystem.join(baseline_directory, self._f ile_name_for_expected_result(test_name, suffix))
271 233
272 _log.debug("Retrieving source %s for target %s.", source_baseline, targe t_baseline) 234 _log.debug("Retrieving source %s for target %s.", source_baseline, targe t_baseline)
273 self._save_baseline(self._tool.web.get_binary(source_baseline, convert_4 04_to_None=True), 235 self._save_baseline(self._tool.web.get_binary(source_baseline, convert_4 04_to_None=True),
274 target_baseline) 236 target_baseline)
275 237
276 def _rebaseline_test_and_update_expectations(self, options): 238 def _rebaseline_test_and_update_expectations(self, options):
277 self._baseline_suffix_list = options.suffixes.split(',') 239 self._baseline_suffix_list = options.suffixes.split(',')
278 240
279 port = self._tool.port_factory.get_from_builder_name(options.builder) 241 port = self._tool.port_factory.get_from_builder_name(options.builder)
280 if port.reference_files(options.test): 242 if port.reference_files(options.test):
281 if 'png' in self._baseline_suffix_list: 243 if 'png' in self._baseline_suffix_list:
282 _log.warning("Cannot rebaseline image result for reftest: %s", o ptions.test) 244 _log.warning("Cannot rebaseline image result for reftest: %s", o ptions.test)
283 return 245 return
284 assert self._baseline_suffix_list == ['txt'] 246 assert self._baseline_suffix_list == ['txt']
285 247
286 if options.results_directory: 248 if options.results_directory:
287 results_url = 'file://' + options.results_directory 249 results_url = 'file://' + options.results_directory
288 else: 250 else:
289 results_url = self._tool.buildbot.results_url(options.builder, build _number=options.build_number) 251 results_url = self._tool.buildbot.results_url(options.builder, build _number=options.build_number)
290 252
291 for suffix in self._baseline_suffix_list: 253 for suffix in self._baseline_suffix_list:
292 self._rebaseline_test(options.builder, options.test, suffix, results _url) 254 self._rebaseline_test(options.builder, options.test, suffix, results _url)
293 self._scm_changes.remove_line(test=options.test, builder=options.builder ) 255 self.expectation_line_changes.remove_line(test=options.test, builder=opt ions.builder)
294 256
295 def execute(self, options, args, tool): 257 def execute(self, options, args, tool):
296 self._tool = tool 258 self._tool = tool
297 self._rebaseline_test_and_update_expectations(options) 259 self._rebaseline_test_and_update_expectations(options)
298 self._print_scm_changes() 260 self._print_expectation_line_changes()
299 261
300 262
301 class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): 263 class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand):
302 """Base class for rebaseline commands that do some tasks in parallel.""" 264 """Base class for rebaseline commands that do some tasks in parallel."""
303 # Not overriding execute() - pylint: disable=abstract-method 265 # Not overriding execute() - pylint: disable=abstract-method
304 266
305 def __init__(self, options=None): 267 def __init__(self, options=None):
306 super(AbstractParallelRebaselineCommand, self).__init__(options=options) 268 super(AbstractParallelRebaselineCommand, self).__init__(options=options)
307 269
308 def _release_builders(self): 270 def _release_builders(self):
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 cmd_line.extend(['--results-directory', options.results_ directory]) 356 cmd_line.extend(['--results-directory', options.results_ directory])
395 if options.verbose: 357 if options.verbose:
396 cmd_line.append('--verbose') 358 cmd_line.append('--verbose')
397 copy_baseline_commands.append( 359 copy_baseline_commands.append(
398 tuple([[self._tool.executable, path_to_webkit_patch, 'co py-existing-baselines-internal'] + cmd_line, cwd])) 360 tuple([[self._tool.executable, path_to_webkit_patch, 'co py-existing-baselines-internal'] + cmd_line, cwd]))
399 rebaseline_commands.append( 361 rebaseline_commands.append(
400 tuple([[self._tool.executable, path_to_webkit_patch, 're baseline-test-internal'] + cmd_line, cwd])) 362 tuple([[self._tool.executable, path_to_webkit_patch, 're baseline-test-internal'] + cmd_line, cwd]))
401 return copy_baseline_commands, rebaseline_commands, lines_to_remove 363 return copy_baseline_commands, rebaseline_commands, lines_to_remove
402 364
403 @staticmethod 365 @staticmethod
404 def _extract_scm_changes(command_results): 366 def _extract_expectation_line_changes(command_results):
405 """Parses the JSON lines from sub-command output and returns the result as a ChangeSet.""" 367 """Parses the JSON lines from sub-command output and returns the result as a ChangeSet."""
406 change_set = ChangeSet() 368 change_set = ChangeSet()
407 for _, stdout, _ in command_results: 369 for _, stdout, _ in command_results:
408 updated = False 370 updated = False
409 for line in filter(None, stdout.splitlines()): 371 for line in filter(None, stdout.splitlines()):
410 try: 372 try:
411 parsed_line = json.loads(line) 373 parsed_line = json.loads(line)
412 change_set.update(ChangeSet.from_dict(parsed_line)) 374 change_set.update(ChangeSet.from_dict(parsed_line))
413 updated = True 375 updated = True
414 except ValueError: 376 except ValueError:
(...skipping 11 matching lines...) Expand all
426 for build in sorted(test_prefix_list[test]): 388 for build in sorted(test_prefix_list[test]):
427 if build.builder_name not in builders_to_fetch_from: 389 if build.builder_name not in builders_to_fetch_from:
428 break 390 break
429 all_suffixes.update(self._suffixes_for_actual_failures(test, bui ld, test_prefix_list[test][build])) 391 all_suffixes.update(self._suffixes_for_actual_failures(test, bui ld, test_prefix_list[test][build]))
430 392
431 # No need to optimize baselines for a test with no failures. 393 # No need to optimize baselines for a test with no failures.
432 if not all_suffixes: 394 if not all_suffixes:
433 continue 395 continue
434 396
435 # FIXME: We should propagate the platform options as well. 397 # FIXME: We should propagate the platform options as well.
436 cmd_line = ['--no-modify-scm', '--suffixes', ','.join(all_suffixes), test] 398 cmd_line = ['--suffixes', ','.join(all_suffixes), test]
437 if verbose: 399 if verbose:
438 cmd_line.append('--verbose') 400 cmd_line.append('--verbose')
439 401
440 path_to_webkit_patch = self._tool.path() 402 path_to_webkit_patch = self._tool.path()
441 cwd = self._tool.scm().checkout_root 403 cwd = self._tool.scm().checkout_root
442 optimize_commands.append(tuple([[self._tool.executable, path_to_webk it_patch, 'optimize-baselines'] + cmd_line, cwd])) 404 optimize_commands.append(tuple([[self._tool.executable, path_to_webk it_patch, 'optimize-baselines'] + cmd_line, cwd]))
443 return optimize_commands 405 return optimize_commands
444 406
445 def _update_expectations_files(self, lines_to_remove): 407 def _update_expectations_files(self, lines_to_remove):
446 # FIXME: This routine is way too expensive. We're creating O(n ports) Te stExpectations objects. 408 # FIXME: This routine is way too expensive. We're creating O(n ports) Te stExpectations objects.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 def _port_skips_test(port, test, generic_expectations, full_expectations): 442 def _port_skips_test(port, test, generic_expectations, full_expectations):
481 fs = port.host.filesystem 443 fs = port.host.filesystem
482 if port.default_smoke_test_only(): 444 if port.default_smoke_test_only():
483 smoke_test_filename = fs.join(port.layout_tests_dir(), 'SmokeTests') 445 smoke_test_filename = fs.join(port.layout_tests_dir(), 'SmokeTests')
484 if fs.exists(smoke_test_filename) and test not in fs.read_text_file( smoke_test_filename): 446 if fs.exists(smoke_test_filename) and test not in fs.read_text_file( smoke_test_filename):
485 return True 447 return True
486 448
487 return (SKIP in full_expectations.get_expectations(test) and 449 return (SKIP in full_expectations.get_expectations(test) and
488 SKIP not in generic_expectations.get_expectations(test)) 450 SKIP not in generic_expectations.get_expectations(test))
489 451
490 def _run_in_parallel(self, commands, update_scm=True): 452 def _run_in_parallel(self, commands):
491 if not commands: 453 if not commands:
492 return {} 454 return {}
493 455
494 command_results = self._tool.executive.run_in_parallel(commands) 456 command_results = self._tool.executive.run_in_parallel(commands)
495 for _, _, stderr in command_results: 457 for _, _, stderr in command_results:
496 if stderr: 458 if stderr:
497 _log.error(stderr) 459 _log.error(stderr)
498 460
499 change_set = self._extract_scm_changes(command_results) 461 change_set = self._extract_expectation_line_changes(command_results)
500
501 # TODO(qyearsley): Instead of updating the SCM state here, aggregate cha nges
502 # and update once in rebaseline. See http://crbug.com/639410.
503 if update_scm:
504 if change_set.files_to_delete:
505 self._tool.scm().delete_list(change_set.files_to_delete)
506 if change_set.files_to_add:
507 self._tool.scm().add_list(change_set.files_to_add)
508 462
509 return change_set.lines_to_remove 463 return change_set.lines_to_remove
510 464
511 def rebaseline(self, options, test_prefix_list, update_scm=True): 465 def rebaseline(self, options, test_prefix_list):
512 """Downloads new baselines in parallel, then updates expectations files 466 """Downloads new baselines in parallel, then updates expectations files
513 and optimizes baselines. 467 and optimizes baselines.
514 468
515 Args: 469 Args:
516 options: An object with the options passed to the current command. 470 options: An object with the options passed to the current command.
517 test_prefix_list: A map of test names to Build objects to file suffi xes 471 test_prefix_list: A map of test names to Build objects to file suffi xes
518 for new baselines. For example: 472 for new baselines. For example:
519 { 473 {
520 "some/test.html": {Build("builder-1", 412): ["txt"], Build(" builder-2", 100): ["txt"]}, 474 "some/test.html": {Build("builder-1", 412): ["txt"], Build(" builder-2", 100): ["txt"]},
521 "some/other.html": {Build("builder-1", 412): ["txt"]} 475 "some/other.html": {Build("builder-1", 412): ["txt"]}
522 } 476 }
523 This would mean that new text baselines should be downloaded for 477 This would mean that new text baselines should be downloaded for
524 "some/test.html" on both builder-1 (build 412) and builder-2 478 "some/test.html" on both builder-1 (build 412) and builder-2
525 (build 100), and new text baselines should be downloaded for 479 (build 100), and new text baselines should be downloaded for
526 "some/other.html" but only from builder-1. 480 "some/other.html" but only from builder-1.
527 TODO(qyearsley): Replace test_prefix_list everywhere with some 481 TODO(qyearsley): Replace test_prefix_list everywhere with some
528 sort of class that contains the same data. 482 sort of class that contains the same data.
529 update_scm: If True, commands like `git add` and `git rm` will be ru n.
530 """ 483 """
531 for test, builds_to_check in sorted(test_prefix_list.items()): 484 for test, builds_to_check in sorted(test_prefix_list.items()):
532 _log.info("Rebaselining %s", test) 485 _log.info("Rebaselining %s", test)
533 for build, suffixes in sorted(builds_to_check.items()): 486 for build, suffixes in sorted(builds_to_check.items()):
534 _log.debug(" %s: %s", build, ",".join(suffixes)) 487 _log.debug(" %s: %s", build, ",".join(suffixes))
535 488
536 copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = sel f._rebaseline_commands( 489 copy_baseline_commands, rebaseline_commands, extra_lines_to_remove = sel f._rebaseline_commands(
537 test_prefix_list, options) 490 test_prefix_list, options)
538 lines_to_remove = {} 491 lines_to_remove = {}
539 492
540 self._run_in_parallel(copy_baseline_commands, update_scm=update_scm) 493 self._run_in_parallel(copy_baseline_commands)
541 lines_to_remove = self._run_in_parallel(rebaseline_commands, update_scm= update_scm) 494 lines_to_remove = self._run_in_parallel(rebaseline_commands)
542 495
543 for test in extra_lines_to_remove: 496 for test in extra_lines_to_remove:
544 if test in lines_to_remove: 497 if test in lines_to_remove:
545 lines_to_remove[test] = lines_to_remove[test] + extra_lines_to_r emove[test] 498 lines_to_remove[test] = lines_to_remove[test] + extra_lines_to_r emove[test]
546 else: 499 else:
547 lines_to_remove[test] = extra_lines_to_remove[test] 500 lines_to_remove[test] = extra_lines_to_remove[test]
548 501
549 if lines_to_remove: 502 if lines_to_remove:
550 self._update_expectations_files(lines_to_remove) 503 self._update_expectations_files(lines_to_remove)
551 504
552 if options.optimize: 505 if options.optimize:
553 # TODO(wkorman): Consider changing temporary branch to base off of H EAD rather than 506 # TODO(wkorman): Consider changing temporary branch to base off of H EAD rather than
554 # origin/master to ensure we run baseline optimization processes wit h the same code as 507 # origin/master to ensure we run baseline optimization processes wit h the same code as
555 # auto-rebaseline itself. 508 # auto-rebaseline itself.
556 self._run_in_parallel(self._optimize_baselines(test_prefix_list, opt ions.verbose), update_scm=update_scm) 509 self._run_in_parallel(self._optimize_baselines(test_prefix_list, opt ions.verbose))
510
511 self._tool.scm().add_all()
557 512
558 def _suffixes_for_actual_failures(self, test, build, existing_suffixes): 513 def _suffixes_for_actual_failures(self, test, build, existing_suffixes):
559 """Gets the baseline suffixes for actual mismatch failures in some resul ts. 514 """Gets the baseline suffixes for actual mismatch failures in some resul ts.
560 515
561 Args: 516 Args:
562 test: A full test path string. 517 test: A full test path string.
563 build: A Build object. 518 build: A Build object.
564 existing_suffixes: A collection of all suffixes to consider. 519 existing_suffixes: A collection of all suffixes to consider.
565 520
566 Returns: 521 Returns:
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 for test in args: 638 for test in args:
684 if test not in test_prefix_list: 639 if test not in test_prefix_list:
685 test_prefix_list[test] = {} 640 test_prefix_list[test] = {}
686 build = Build(builder) 641 build = Build(builder)
687 test_prefix_list[test][build] = suffixes_to_update 642 test_prefix_list[test][build] = suffixes_to_update
688 643
689 if options.verbose: 644 if options.verbose:
690 _log.debug("rebaseline-json: " + str(test_prefix_list)) 645 _log.debug("rebaseline-json: " + str(test_prefix_list))
691 646
692 self.rebaseline(options, test_prefix_list) 647 self.rebaseline(options, test_prefix_list)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698