| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import logging | |
| 6 import os | |
| 7 | |
| 8 from layout_package import json_results_generator | |
| 9 from layout_package import path_utils | |
| 10 from layout_package import test_expectations | |
| 11 from layout_package import test_failures | |
| 12 | |
| 13 | |
| 14 class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGenerator): | |
| 15 """A JSON results generator for layout tests.""" | |
| 16 | |
| 17 LAYOUT_TESTS_PATH = "LayoutTests" | |
| 18 | |
| 19 # Additional JSON fields. | |
| 20 WONTFIX = "wontfixCounts" | |
| 21 DEFERRED = "deferredCounts" | |
| 22 | |
| 23 def __init__(self, builder_name, build_name, build_number, | |
| 24 results_file_base_path, builder_base_url, | |
| 25 test_timings, expectations, result_summary, all_tests): | |
| 26 """Modifies the results.json file. Grabs it off the archive directory | |
| 27 if it is not found locally. | |
| 28 | |
| 29 Args: | |
| 30 result_summary: ResultsSummary object storing the summary of the test | |
| 31 results. | |
| 32 (see the comment of JSONResultsGenerator.__init__ for other Args) | |
| 33 """ | |
| 34 | |
| 35 self._builder_name = builder_name | |
| 36 self._build_name = build_name | |
| 37 self._build_number = build_number | |
| 38 self._builder_base_url = builder_base_url | |
| 39 self._results_file_path = os.path.join(results_file_base_path, | |
| 40 self.RESULTS_FILENAME) | |
| 41 self._expectations = expectations | |
| 42 | |
| 43 # We don't use self._skipped_tests and self._passed_tests as we | |
| 44 # override _InsertFailureSummaries. | |
| 45 | |
| 46 # We want relative paths to LayoutTest root for JSON output. | |
| 47 path_to_name = self._GetPathRelativeToLayoutTestRoot | |
| 48 self._result_summary = result_summary | |
| 49 self._failures = dict( | |
| 50 (path_to_name(test), test_failures.DetermineResultType(failures)) | |
| 51 for (test, failures) in result_summary.failures.iteritems()) | |
| 52 self._all_tests = [path_to_name(test) for test in all_tests] | |
| 53 self._test_timings = dict( | |
| 54 (path_to_name(test_tuple.filename), test_tuple.test_run_time) | |
| 55 for test_tuple in test_timings) | |
| 56 | |
| 57 self._GenerateJSONOutput() | |
| 58 | |
| 59 def _GetPathRelativeToLayoutTestRoot(self, test): | |
| 60 """Returns the path of the test relative to the layout test root. | |
| 61 For example, for: | |
| 62 src/third_party/WebKit/LayoutTests/fast/forms/foo.html | |
| 63 We would return | |
| 64 fast/forms/foo.html | |
| 65 """ | |
| 66 index = test.find(self.LAYOUT_TESTS_PATH) | |
| 67 if index is not -1: | |
| 68 index += len(self.LAYOUT_TESTS_PATH) | |
| 69 | |
| 70 if index is -1: | |
| 71 # Already a relative path. | |
| 72 relativePath = test | |
| 73 else: | |
| 74 relativePath = test[index + 1:] | |
| 75 | |
| 76 # Make sure all paths are unix-style. | |
| 77 return relativePath.replace('\\', '/') | |
| 78 | |
| 79 # override | |
| 80 def _ConvertJSONToCurrentVersion(self, results_json): | |
| 81 archive_version = None | |
| 82 if self.VERSION_KEY in results_json: | |
| 83 archive_version = results_json[self.VERSION_KEY] | |
| 84 | |
| 85 super(JSONLayoutResultsGenerator, self)._ConvertJSONToCurrentVersion( | |
| 86 results_json) | |
| 87 | |
| 88 # version 2->3 | |
| 89 if archive_version == 2: | |
| 90 for results_for_builder in results_json.itervalues(): | |
| 91 try: | |
| 92 test_results = results_for_builder[self.TESTS] | |
| 93 except: | |
| 94 continue | |
| 95 | |
| 96 for test in test_results: | |
| 97 # Make sure all paths are relative | |
| 98 test_path = self._GetPathRelativeToLayoutTestRoot(test) | |
| 99 if test_path != test: | |
| 100 test_results[test_path] = test_results[test] | |
| 101 del test_results[test] | |
| 102 | |
| 103 # override | |
| 104 def _InsertFailureSummaries(self, results_for_builder): | |
| 105 summary = self._result_summary | |
| 106 | |
| 107 self._InsertItemIntoRawList(results_for_builder, | |
| 108 len((set(summary.failures.keys()) | | |
| 109 summary.tests_by_expectation[test_expectations.SKIP]) & | |
| 110 summary.tests_by_timeline[test_expectations.NOW]), | |
| 111 self.FIXABLE_COUNT) | |
| 112 self._InsertItemIntoRawList(results_for_builder, | |
| 113 self._GetFailureSummaryEntry(test_expectations.NOW), | |
| 114 self.FIXABLE) | |
| 115 self._InsertItemIntoRawList(results_for_builder, | |
| 116 len(self._expectations.GetTestsWithTimeline( | |
| 117 test_expectations.NOW)), self.ALL_FIXABLE_COUNT) | |
| 118 self._InsertItemIntoRawList(results_for_builder, | |
| 119 self._GetFailureSummaryEntry(test_expectations.DEFER), | |
| 120 self.DEFERRED) | |
| 121 self._InsertItemIntoRawList(results_for_builder, | |
| 122 self._GetFailureSummaryEntry(test_expectations.WONTFIX), | |
| 123 self.WONTFIX) | |
| 124 | |
| 125 # override | |
| 126 def _NormalizeResultsJSON(self, test, test_name, tests): | |
| 127 super(JSONLayoutResultsGenerator, self)._NormalizeResultsJSON( | |
| 128 test, test_name, tests) | |
| 129 | |
| 130 # Remove tests that don't exist anymore. | |
| 131 full_path = os.path.join(path_utils.LayoutTestsDir(), test_name) | |
| 132 full_path = os.path.normpath(full_path) | |
| 133 if not os.path.exists(full_path): | |
| 134 del tests[test_name] | |
| 135 | |
| 136 def _GetFailureSummaryEntry(self, timeline): | |
| 137 """Creates a summary object to insert into the JSON. | |
| 138 | |
| 139 Args: | |
| 140 summary ResultSummary object with test results | |
| 141 timeline current test_expectations timeline to build entry for | |
| 142 (e.g., test_expectations.NOW, etc.) | |
| 143 """ | |
| 144 entry = {} | |
| 145 summary = self._result_summary | |
| 146 timeline_tests = summary.tests_by_timeline[timeline] | |
| 147 entry[self.SKIP_RESULT] = len( | |
| 148 summary.tests_by_expectation[test_expectations.SKIP] & | |
| 149 timeline_tests) | |
| 150 entry[self.PASS_RESULT] = len( | |
| 151 summary.tests_by_expectation[test_expectations.PASS] & | |
| 152 timeline_tests) | |
| 153 for failure_type in summary.tests_by_expectation.keys(): | |
| 154 if failure_type not in self.FAILURE_TO_CHAR: | |
| 155 continue | |
| 156 count = len(summary.tests_by_expectation[failure_type] & | |
| 157 timeline_tests) | |
| 158 entry[self.FAILURE_TO_CHAR[failure_type]] = count | |
| 159 return entry | |
| OLD | NEW |