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 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 raise ValueError(expectation) | 654 raise ValueError(expectation) |
655 | 655 |
656 def remove_expectation_line(self, test): | 656 def remove_expectation_line(self, test): |
657 if not self.has_test(test): | 657 if not self.has_test(test): |
658 return | 658 return |
659 self._clear_expectations_for_test(test) | 659 self._clear_expectations_for_test(test) |
660 del self._test_to_expectation_line[test] | 660 del self._test_to_expectation_line[test] |
661 | 661 |
662 def add_expectation_line(self, expectation_line, | 662 def add_expectation_line(self, expectation_line, |
663 model_all_expectations=False): | 663 model_all_expectations=False): |
| 664 """Returns a list of warnings encountered while matching specifiers.""" |
| 665 |
664 if expectation_line.is_invalid(): | 666 if expectation_line.is_invalid(): |
665 return | 667 return |
666 | 668 |
667 for test in expectation_line.matching_tests: | 669 for test in expectation_line.matching_tests: |
668 lines_involve_rebaseline = False | 670 if self._already_seen_better_match(test, expectation_line): |
669 prev_expectation_line = self.get_expectation_line(test) | 671 continue |
670 | 672 |
671 if prev_expectation_line: | 673 if model_all_expectations: |
672 # The previous path matched more of the test. | 674 expectation_line = TestExpectationLine.merge_expectation_lines(s
elf.get_expectation_line(test), expectation_line, model_all_expectations) |
673 if len(prev_expectation_line.path) > len(expectation_line.path): | |
674 continue | |
675 | |
676 if self._lines_conflict(prev_expectation_line, expectation_line)
: | |
677 continue | |
678 | |
679 lines_involve_rebaseline = self._expects_rebaseline(prev_expecta
tion_line) or self._expects_rebaseline(expectation_line) | |
680 | |
681 # Exact path matches that conflict should be merged, e.g. | |
682 # [ Pass Timeout ] + [ NeedsRebaseline ] ==> [ Pass Timeout NeedsReb
aseline ]. | |
683 if model_all_expectations or lines_involve_rebaseline: | |
684 expectation_line = TestExpectationLine.merge_expectation_lines(p
rev_expectation_line, expectation_line, model_all_expectations) | |
685 | 675 |
686 self._clear_expectations_for_test(test) | 676 self._clear_expectations_for_test(test) |
687 self._test_to_expectation_line[test] = expectation_line | 677 self._test_to_expectation_line[test] = expectation_line |
688 self._add_test(test, expectation_line) | 678 self._add_test(test, expectation_line) |
689 | 679 |
690 def _add_test(self, test, expectation_line): | 680 def _add_test(self, test, expectation_line): |
691 """Sets the expected state for a given test. | 681 """Sets the expected state for a given test. |
692 | 682 |
693 This routine assumes the test has not been added before. If it has, | 683 This routine assumes the test has not been added before. If it has, |
694 use _clear_expectations_for_test() to reset the state prior to | 684 use _clear_expectations_for_test() to reset the state prior to |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 def _remove_from_sets(self, test, dict_of_sets_of_tests): | 718 def _remove_from_sets(self, test, dict_of_sets_of_tests): |
729 """Removes the given test from the sets in the dictionary. | 719 """Removes the given test from the sets in the dictionary. |
730 | 720 |
731 Args: | 721 Args: |
732 test: test to look for | 722 test: test to look for |
733 dict: dict of sets of files""" | 723 dict: dict of sets of files""" |
734 for set_of_tests in dict_of_sets_of_tests.itervalues(): | 724 for set_of_tests in dict_of_sets_of_tests.itervalues(): |
735 if test in set_of_tests: | 725 if test in set_of_tests: |
736 set_of_tests.remove(test) | 726 set_of_tests.remove(test) |
737 | 727 |
738 def _expects_rebaseline(self, expectation_line): | 728 def _already_seen_better_match(self, test, expectation_line): |
739 expectations = expectation_line.parsed_expectations | 729 """Returns whether we've seen a better match already in the file. |
740 return REBASELINE in expectations or NEEDS_REBASELINE in expectations or
NEEDS_MANUAL_REBASELINE in expectations | |
741 | 730 |
742 def _lines_conflict(self, prev_expectation_line, expectation_line): | 731 Returns True if we've already seen a expectation_line.name that matches
more of the test |
743 if prev_expectation_line.path != expectation_line.path: | 732 than this path does |
| 733 """ |
| 734 # FIXME: See comment below about matching test configs and specificity. |
| 735 if not self.has_test(test): |
| 736 # We've never seen this test before. |
744 return False | 737 return False |
745 | 738 |
746 if PASS in expectation_line.parsed_expectations and self._expects_rebase
line(prev_expectation_line): | 739 prev_expectation_line = self._test_to_expectation_line[test] |
| 740 |
| 741 if prev_expectation_line.filename != expectation_line.filename: |
| 742 # We've moved on to a new expectation file, which overrides older on
es. |
747 return False | 743 return False |
748 | 744 |
749 if PASS in prev_expectation_line.parsed_expectations and self._expects_r
ebaseline(expectation_line): | 745 if len(prev_expectation_line.path) > len(expectation_line.path): |
| 746 # The previous path matched more of the test. |
| 747 return True |
| 748 |
| 749 if len(prev_expectation_line.path) < len(expectation_line.path): |
| 750 # This path matches more of the test. |
750 return False | 751 return False |
751 | 752 |
| 753 # At this point we know we have seen a previous exact match on this |
| 754 # base path, so we need to check the two sets of specifiers. |
| 755 |
| 756 # FIXME: This code was originally designed to allow lines that matched |
| 757 # more specifiers to override lines that matched fewer specifiers. |
| 758 # However, we currently view these as errors. |
| 759 # |
| 760 # To use the "more specifiers wins" policy, change the errors for overri
des |
| 761 # to be warnings and return False". |
| 762 |
752 if prev_expectation_line.matching_configurations == expectation_line.mat
ching_configurations: | 763 if prev_expectation_line.matching_configurations == expectation_line.mat
ching_configurations: |
753 expectation_line.warnings.append('Duplicate or ambiguous entry lines
%s:%s and %s:%s.' % ( | 764 expectation_line.warnings.append('Duplicate or ambiguous entry lines
%s:%s and %s:%s.' % ( |
754 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, | 765 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, |
755 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) | 766 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) |
756 return True | 767 return True |
757 | 768 |
758 if prev_expectation_line.matching_configurations >= expectation_line.mat
ching_configurations: | 769 if prev_expectation_line.matching_configurations >= expectation_line.mat
ching_configurations: |
759 expectation_line.warnings.append('More specific entry for %s on line
%s:%s overrides line %s:%s.' % (expectation_line.name, | 770 expectation_line.warnings.append('More specific entry for %s on line
%s:%s overrides line %s:%s.' % (expectation_line.name, |
760 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, | 771 self._shorten_filename(prev_expectation_line.filename), prev_exp
ectation_line.line_numbers, |
761 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) | 772 self._shorten_filename(expectation_line.filename), expectation_l
ine.line_numbers)) |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 # If reconstitute_only_these is an empty list, we want to return ori
ginal_string. | 1137 # If reconstitute_only_these is an empty list, we want to return ori
ginal_string. |
1127 # So we need to compare reconstitute_only_these to None, not just ch
eck if it's falsey. | 1138 # So we need to compare reconstitute_only_these to None, not just ch
eck if it's falsey. |
1128 if reconstitute_only_these is None or expectation_line in reconstitu
te_only_these: | 1139 if reconstitute_only_these is None or expectation_line in reconstitu
te_only_these: |
1129 return expectation_line.to_string(test_configuration_converter) | 1140 return expectation_line.to_string(test_configuration_converter) |
1130 return expectation_line.original_string | 1141 return expectation_line.original_string |
1131 | 1142 |
1132 def nones_out(expectation_line): | 1143 def nones_out(expectation_line): |
1133 return expectation_line is not None | 1144 return expectation_line is not None |
1134 | 1145 |
1135 return "\n".join(filter(nones_out, map(serialize, expectation_lines))) | 1146 return "\n".join(filter(nones_out, map(serialize, expectation_lines))) |
OLD | NEW |