OLD | NEW |
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 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 | 281 |
282 self._baseline_optimizer = self._optimizer_class(tool, port_names) | 282 self._baseline_optimizer = self._optimizer_class(tool, port_names) |
283 self._port = tool.port_factory.get(port_names[0]) | 283 self._port = tool.port_factory.get(port_names[0]) |
284 for test_name in self._port.tests(args): | 284 for test_name in self._port.tests(args): |
285 self._analyze_baseline(options, test_name) | 285 self._analyze_baseline(options, test_name) |
286 | 286 |
287 | 287 |
288 class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): | 288 class AbstractParallelRebaselineCommand(AbstractRebaseliningCommand): |
289 # not overriding execute() - pylint: disable=W0223 | 289 # not overriding execute() - pylint: disable=W0223 |
290 | 290 |
| 291 def __init__(self, options=None): |
| 292 super(AbstractParallelRebaselineCommand, self).__init__(options=options) |
| 293 self._builder_data = {} |
| 294 |
| 295 def builder_data(self): |
| 296 if not self._builder_data: |
| 297 for builder_name in self._release_builders(): |
| 298 builder = self._tool.buildbot_for_builder_name(builder_name).bui
lder_with_name(builder_name) |
| 299 self._builder_data[builder_name] = builder.latest_layout_test_re
sults() |
| 300 return self._builder_data |
| 301 |
291 # The release builders cycle much faster than the debug ones and cover all t
he platforms. | 302 # The release builders cycle much faster than the debug ones and cover all t
he platforms. |
292 def _release_builders(self): | 303 def _release_builders(self): |
293 release_builders = [] | 304 release_builders = [] |
294 for builder_name in builders.all_builder_names(): | 305 for builder_name in builders.all_builder_names(): |
295 port = self._tool.port_factory.get_from_builder_name(builder_name) | 306 port = self._tool.port_factory.get_from_builder_name(builder_name) |
296 if port.test_configuration().build_type == 'release': | 307 if port.test_configuration().build_type == 'release': |
297 release_builders.append(builder_name) | 308 release_builders.append(builder_name) |
298 return release_builders | 309 return release_builders |
299 | 310 |
300 def _run_webkit_patch(self, args, verbose): | 311 def _run_webkit_patch(self, args, verbose): |
(...skipping 29 matching lines...) Expand all Loading... |
330 def _rebaseline_commands(self, test_prefix_list, options): | 341 def _rebaseline_commands(self, test_prefix_list, options): |
331 path_to_webkit_patch = self._tool.path() | 342 path_to_webkit_patch = self._tool.path() |
332 cwd = self._tool.scm().checkout_root | 343 cwd = self._tool.scm().checkout_root |
333 copy_baseline_commands = [] | 344 copy_baseline_commands = [] |
334 rebaseline_commands = [] | 345 rebaseline_commands = [] |
335 port = self._tool.port_factory.get() | 346 port = self._tool.port_factory.get() |
336 | 347 |
337 for test_prefix in test_prefix_list: | 348 for test_prefix in test_prefix_list: |
338 for test in port.tests([test_prefix]): | 349 for test in port.tests([test_prefix]): |
339 for builder in self._builders_to_fetch_from(test_prefix_list[tes
t_prefix]): | 350 for builder in self._builders_to_fetch_from(test_prefix_list[tes
t_prefix]): |
340 suffixes = ','.join(test_prefix_list[test_prefix][builder]) | 351 actual_failures_suffixes = self._suffixes_for_actual_failure
s(test, builder, test_prefix_list[test_prefix][builder]) |
| 352 if not actual_failures_suffixes: |
| 353 continue |
| 354 |
| 355 suffixes = ','.join(actual_failures_suffixes) |
341 cmd_line = ['--suffixes', suffixes, '--builder', builder, '-
-test', test] | 356 cmd_line = ['--suffixes', suffixes, '--builder', builder, '-
-test', test] |
342 if options.results_directory: | 357 if options.results_directory: |
343 cmd_line.extend(['--results-directory', options.results_
directory]) | 358 cmd_line.extend(['--results-directory', options.results_
directory]) |
344 if options.verbose: | 359 if options.verbose: |
345 cmd_line.append('--verbose') | 360 cmd_line.append('--verbose') |
346 copy_baseline_commands.append(tuple([[path_to_webkit_patch,
'copy-existing-baselines-internal'] + cmd_line, cwd])) | 361 copy_baseline_commands.append(tuple([[path_to_webkit_patch,
'copy-existing-baselines-internal'] + cmd_line, cwd])) |
347 rebaseline_commands.append(tuple([[path_to_webkit_patch, 're
baseline-test-internal'] + cmd_line, cwd])) | 362 rebaseline_commands.append(tuple([[path_to_webkit_patch, 're
baseline-test-internal'] + cmd_line, cwd])) |
348 return copy_baseline_commands, rebaseline_commands | 363 return copy_baseline_commands, rebaseline_commands |
349 | 364 |
350 def _files_to_add(self, command_results): | 365 def _files_to_add(self, command_results): |
(...skipping 21 matching lines...) Expand all Loading... |
372 if not file_added: | 387 if not file_added: |
373 _log.debug('Could not add file based off output "%s"' % output) | 388 _log.debug('Could not add file based off output "%s"' % output) |
374 | 389 |
375 return list(files_to_add), lines_to_remove | 390 return list(files_to_add), lines_to_remove |
376 | 391 |
377 def _optimize_baselines(self, test_prefix_list, verbose=False): | 392 def _optimize_baselines(self, test_prefix_list, verbose=False): |
378 # We don't run this in parallel because modifying the SCM in parallel is
unreliable. | 393 # We don't run this in parallel because modifying the SCM in parallel is
unreliable. |
379 for test in test_prefix_list: | 394 for test in test_prefix_list: |
380 all_suffixes = set() | 395 all_suffixes = set() |
381 for builder in self._builders_to_fetch_from(test_prefix_list[test]): | 396 for builder in self._builders_to_fetch_from(test_prefix_list[test]): |
382 all_suffixes.update(test_prefix_list[test][builder]) | 397 all_suffixes.update(self._suffixes_for_actual_failures(test, bui
lder, test_prefix_list[test][builder])) |
383 # FIXME: We should propagate the platform options as well. | 398 # FIXME: We should propagate the platform options as well. |
384 self._run_webkit_patch(['optimize-baselines', '--suffixes', ','.join
(all_suffixes), test], verbose) | 399 self._run_webkit_patch(['optimize-baselines', '--suffixes', ','.join
(all_suffixes), test], verbose) |
385 | 400 |
386 def _update_expectations_files(self, lines_to_remove): | 401 def _update_expectations_files(self, lines_to_remove): |
387 for test in lines_to_remove: | 402 for test in lines_to_remove: |
388 for builder in lines_to_remove[test]: | 403 for builder in lines_to_remove[test]: |
389 port = self._tool.port_factory.get_from_builder_name(builder) | 404 port = self._tool.port_factory.get_from_builder_name(builder) |
390 path = port.path_to_generic_test_expectations_file() | 405 path = port.path_to_generic_test_expectations_file() |
391 expectations = TestExpectations(port, include_overrides=False) | 406 expectations = TestExpectations(port, include_overrides=False) |
392 for test_configuration in port.all_test_configurations(): | 407 for test_configuration in port.all_test_configurations(): |
(...skipping 20 matching lines...) Expand all Loading... |
413 for builder, suffixes in sorted(builders_to_check.items()): | 428 for builder, suffixes in sorted(builders_to_check.items()): |
414 _log.debug(" %s: %s" % (builder, ",".join(suffixes))) | 429 _log.debug(" %s: %s" % (builder, ",".join(suffixes))) |
415 | 430 |
416 copy_baseline_commands, rebaseline_commands = self._rebaseline_commands(
test_prefix_list, options) | 431 copy_baseline_commands, rebaseline_commands = self._rebaseline_commands(
test_prefix_list, options) |
417 self._run_in_parallel_and_update_scm(copy_baseline_commands) | 432 self._run_in_parallel_and_update_scm(copy_baseline_commands) |
418 self._run_in_parallel_and_update_scm(rebaseline_commands) | 433 self._run_in_parallel_and_update_scm(rebaseline_commands) |
419 | 434 |
420 if options.optimize: | 435 if options.optimize: |
421 self._optimize_baselines(test_prefix_list, options.verbose) | 436 self._optimize_baselines(test_prefix_list, options.verbose) |
422 | 437 |
| 438 def _suffixes_for_actual_failures(self, test, builder_name, existing_suffixe
s): |
| 439 actual_results = self.builder_data()[builder_name].actual_results(test) |
| 440 if not actual_results: |
| 441 return set() |
| 442 return set(existing_suffixes) & TestExpectations.suffixes_for_actual_exp
ectations_string(actual_results) |
| 443 |
423 | 444 |
424 class RebaselineJson(AbstractParallelRebaselineCommand): | 445 class RebaselineJson(AbstractParallelRebaselineCommand): |
425 name = "rebaseline-json" | 446 name = "rebaseline-json" |
426 help_text = "Rebaseline based off JSON passed to stdin. Intended to only be
called from other scripts." | 447 help_text = "Rebaseline based off JSON passed to stdin. Intended to only be
called from other scripts." |
427 | 448 |
428 def __init__(self,): | 449 def __init__(self,): |
429 super(RebaselineJson, self).__init__(options=[ | 450 super(RebaselineJson, self).__init__(options=[ |
430 self.no_optimize_option, | 451 self.no_optimize_option, |
431 self.results_directory_option, | 452 self.results_directory_option, |
432 ]) | 453 ]) |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 # FIXME: http://crbug.com/263676 Obviously we should fix the uploader here. | 560 # FIXME: http://crbug.com/263676 Obviously we should fix the uploader here. |
540 MAX_LINES_TO_REBASELINE = 200 | 561 MAX_LINES_TO_REBASELINE = 200 |
541 | 562 |
542 def __init__(self): | 563 def __init__(self): |
543 super(AutoRebaseline, self).__init__(options=[ | 564 super(AutoRebaseline, self).__init__(options=[ |
544 # FIXME: Remove this option. | 565 # FIXME: Remove this option. |
545 self.no_optimize_option, | 566 self.no_optimize_option, |
546 # FIXME: Remove this option. | 567 # FIXME: Remove this option. |
547 self.results_directory_option, | 568 self.results_directory_option, |
548 ]) | 569 ]) |
549 self._builder_data = {} | |
550 | |
551 def builder_data(self): | |
552 if not self._builder_data: | |
553 for builder_name in self._release_builders(): | |
554 builder = self._tool.buildbot_for_builder_name(builder_name).bui
lder_with_name(builder_name) | |
555 self._builder_data[builder_name] = builder.latest_layout_test_re
sults() | |
556 return self._builder_data | |
557 | 570 |
558 def latest_revision_processed_on_all_bots(self): | 571 def latest_revision_processed_on_all_bots(self): |
559 revisions = [] | 572 revisions = [] |
560 for result in self.builder_data().values(): | 573 for result in self.builder_data().values(): |
561 if result.run_was_interrupted(): | 574 if result.run_was_interrupted(): |
562 _log.error("Can't rebaseline. The latest run on %s did not compl
ete." % builder_name) | 575 _log.error("Can't rebaseline. The latest run on %s did not compl
ete." % builder_name) |
563 return 0 | 576 return 0 |
564 revisions.append(result.blink_revision()) | 577 revisions.append(result.blink_revision()) |
565 return int(min(revisions)) | 578 return int(min(revisions)) |
566 | 579 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 return """Auto-rebaseline for r%s | 628 return """Auto-rebaseline for r%s |
616 | 629 |
617 %s | 630 %s |
618 | 631 |
619 %sTBR=%s | 632 %sTBR=%s |
620 """ % (revision, self.link_to_patch(revision), bug_string, author) | 633 """ % (revision, self.link_to_patch(revision), bug_string, author) |
621 | 634 |
622 def get_test_prefix_list(self, tests): | 635 def get_test_prefix_list(self, tests): |
623 test_prefix_list = {} | 636 test_prefix_list = {} |
624 lines_to_remove = {} | 637 lines_to_remove = {} |
625 builder_data = self.builder_data() | |
626 | 638 |
627 for builder_name in self._release_builders(): | 639 for builder_name in self._release_builders(): |
628 port_name = builders.port_name_for_builder_name(builder_name) | 640 port_name = builders.port_name_for_builder_name(builder_name) |
629 port = self._tool.port_factory.get(port_name) | 641 port = self._tool.port_factory.get(port_name) |
630 expectations = TestExpectations(port, include_overrides=True) | 642 expectations = TestExpectations(port, include_overrides=True) |
631 for test in expectations.get_needs_rebaseline_failures(): | 643 for test in expectations.get_needs_rebaseline_failures(): |
632 if test not in tests: | 644 if test not in tests: |
633 continue | 645 continue |
634 | 646 |
635 if test not in lines_to_remove: | 647 if test not in test_prefix_list: |
636 lines_to_remove[test] = [] | 648 lines_to_remove[test] = [] |
| 649 test_prefix_list[test] = {} |
637 lines_to_remove[test].append(builder_name) | 650 lines_to_remove[test].append(builder_name) |
638 | 651 test_prefix_list[test][builder_name] = BASELINE_SUFFIX_LIST |
639 actual_results = builder_data[builder_name].actual_results(test) | |
640 if not actual_results: | |
641 continue | |
642 | |
643 suffixes = TestExpectations.suffixes_for_actual_expectations_str
ing(actual_results) | |
644 if not suffixes: | |
645 continue | |
646 | |
647 if test not in test_prefix_list: | |
648 test_prefix_list[test] = {} | |
649 test_prefix_list[test][builder_name] = suffixes | |
650 | 652 |
651 return test_prefix_list, lines_to_remove | 653 return test_prefix_list, lines_to_remove |
652 | 654 |
653 def _run_git_cl_command(self, options, command): | 655 def _run_git_cl_command(self, options, command): |
654 subprocess_command = ['git', 'cl'] + command | 656 subprocess_command = ['git', 'cl'] + command |
655 if options.verbose: | 657 if options.verbose: |
656 subprocess_command.append('--verbose') | 658 subprocess_command.append('--verbose') |
657 # Use call instead of run_command so that stdout doesn't get swallowed. | 659 # Use call instead of run_command so that stdout doesn't get swallowed. |
658 self._tool.executive.call(subprocess_command) | 660 self._tool.executive.call(subprocess_command) |
659 | 661 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 | 738 |
737 def execute(self, options, args, tool): | 739 def execute(self, options, args, tool): |
738 while True: | 740 while True: |
739 tool.executive.run_command(['git', 'pull']) | 741 tool.executive.run_command(['git', 'pull']) |
740 rebaseline_command = [tool.filesystem.join(tool.scm().checkout_root,
'Tools', 'Scripts', 'webkit-patch'), 'auto-rebaseline'] | 742 rebaseline_command = [tool.filesystem.join(tool.scm().checkout_root,
'Tools', 'Scripts', 'webkit-patch'), 'auto-rebaseline'] |
741 if options.verbose: | 743 if options.verbose: |
742 rebaseline_command.append('--verbose') | 744 rebaseline_command.append('--verbose') |
743 # Use call instead of run_command so that stdout doesn't get swallow
ed. | 745 # Use call instead of run_command so that stdout doesn't get swallow
ed. |
744 tool.executive.call(rebaseline_command) | 746 tool.executive.call(rebaseline_command) |
745 time.sleep(self.SLEEP_TIME_IN_SECONDS) | 747 time.sleep(self.SLEEP_TIME_IN_SECONDS) |
OLD | NEW |