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

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/w3c/update_w3c_test_expectations.py

Issue 2183913002: Removes build and builder object refrences along with minor bug fixes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removes build and builder object refrences along with minor bug fixes Created 4 years, 4 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
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/w3c/update_w3c_test_expectations_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2016 The Chromium Authors. All rights reserved. 1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """A script to modify TestExpectations lines based layout test failures in try j obs. 5 """A script to modify TestExpectations lines based layout test failures in try j obs.
6 6
7 This script outputs a list of test expectation lines to add to a 'TestExpectatio ns' file 7 This script outputs a list of test expectation lines to add to a 'TestExpectatio ns' file
8 by retrieving the try job results for the current CL. 8 by retrieving the try job results for the current CL.
9 """ 9 """
10 10
11 import logging 11 import logging
12 12
13 from webkitpy.common.net import buildbot 13 from webkitpy.common.net.buildbot import BuildBot
14 from webkitpy.common.net import rietveld 14 from webkitpy.common.net import rietveld
15 15
16 16
17 _log = logging.getLogger(__name__) 17 _log = logging.getLogger(__name__)
18 18
19 19
20 def main(host, port): 20 def main(host, port):
21 expectations_file = port.path_to_generic_test_expectations_file() 21 expectations_file = port.path_to_generic_test_expectations_file()
22 expectations_line_adder = W3CExpectationsLineAdder(host) 22 expectations_line_adder = W3CExpectationsLineAdder(host)
23 issue_number = expectations_line_adder.get_issue_number() 23 issue_number = expectations_line_adder.get_issue_number()
24 try_bots = expectations_line_adder.get_try_bots() 24 try_bots = expectations_line_adder.get_try_bots()
25 try_jobs = rietveld.latest_try_jobs(issue_number, try_bots, host.web) 25 try_jobs = rietveld.latest_try_jobs(issue_number, try_bots, host.web)
26 line_expectations_dict = {} 26 test_expectations_dict = {}
27 if not try_jobs: 27 if not try_jobs:
28 print 'No Try Job information was collected.' 28 print 'No Try Job information was collected.'
29 return 1 29 return 1
30 for try_job in try_jobs: 30 for try_job in try_jobs:
31 builder_name = try_job[0] 31 builder_name = try_job[0]
32 build_number = try_job[1] 32 build_number = try_job[1]
33 builder = buildbot.Builder(builder_name, host.buildbot) 33 buildbot = BuildBot()
34 build = buildbot.Build(builder, build_number) 34 platform_results_dict = expectations_line_adder.get_failing_results_dict (buildbot, builder_name, build_number)
qyearsley 2016/07/26 21:40:35 Somewhat unrelated to this CL: An alternative way
dcampb 2016/07/26 22:08:35 suggestions noted and changed made.
35 platform_results_dict = expectations_line_adder.get_failing_results_dict (builder, build) 35 test_expectations_dict = expectations_line_adder.merge_dicts(test_expect ations_dict, platform_results_dict)
36 line_expectations_dict = expectations_line_adder.merge_dicts(line_expect ations_dict, platform_results_dict) 36 for test_name, platform_results_dicts in test_expectations_dict.iteritems():
37 for platform_results_dicts in line_expectations_dict.values():
38 platform_results_dicts = expectations_line_adder.merge_same_valued_keys( platform_results_dicts) 37 platform_results_dicts = expectations_line_adder.merge_same_valued_keys( platform_results_dicts)
39 line_list = expectations_line_adder.create_line_list(line_expectations_dict) 38 test_expectations_dict[test_name] = platform_results_dicts
39 line_list = expectations_line_adder.create_line_list(test_expectations_dict)
40 expectations_line_adder.write_to_test_expectations(host, expectations_file, line_list) 40 expectations_line_adder.write_to_test_expectations(host, expectations_file, line_list)
41 41
42 42
43 class W3CExpectationsLineAdder(object): 43 class W3CExpectationsLineAdder(object):
44 44
45 def __init__(self, host): 45 def __init__(self, host):
46 self._host = host 46 self._host = host
47 self.filesystem = host.filesystem 47 self.filesystem = host.filesystem
48 48
49 def get_issue_number(self): 49 def get_issue_number(self):
50 return self._host.scm().get_issue_number() 50 return self._host.scm().get_issue_number()
51 51
52 def get_try_bots(self): 52 def get_try_bots(self):
53 return self._host.builders.all_try_builder_names() 53 return self._host.builders.all_try_builder_names()
54 54
55 def _generate_results_dict(self, platform, result_list): 55 def _generate_results_dict(self, platform, result_list):
56 test_dict = {} 56 test_dict = {}
57 if '-' in platform: 57 if '-' in platform:
58 platform = platform[platform.find('-') + 1:].capitalize() 58 platform = platform[platform.find('-') + 1:].capitalize()
59 for result in result_list: 59 for result in result_list:
60 test_dict[result.test_name()] = { 60 test_dict[result.test_name()] = {
61 platform: { 61 platform: {
62 'expected': result.expected_results(), 62 'expected': result.expected_results(),
63 'actual': result.actual_results(), 63 'actual': result.actual_results(),
64 'bug': 'crbug.com/626703' 64 'bug': 'crbug.com/626703'
65 }} 65 }}
66 return test_dict 66 return test_dict
67 67
68 def get_failing_results_dict(self, builder, build): 68 def get_failing_results_dict(self, buildbot, builder_name, build_number):
69 """Returns a nested dict of failing test results. 69 """Returns a nested dict of failing test results.
70 70
71 Retrieves a full list of layout test results from a builder result URL. Collects 71 Retrieves a full list of layout test results from a builder result URL. Collects
72 the builder name, platform and a list of tests that did not run as expec ted. 72 the builder name, platform and a list of tests that did not run as expec ted.
73 73
74 Args: 74 Args:
75 builder: A Builder object. 75 builder: A Builder object.
76 build: A Build object. 76 build: A Build object.
77 77
78 Returns: 78 Returns:
79 A dictionary with the structure: { 79 A dictionary with the structure: {
80 'key': { 80 'key': {
81 'expected': 'TIMEOUT', 81 'expected': 'TIMEOUT',
82 'actual': 'CRASH', 82 'actual': 'CRASH',
83 'bug': 'crbug.com/11111' 83 'bug': 'crbug.com/11111'
84 } 84 }
85 } 85 }
86 """ 86 """
87 layout_test_results = builder.fetch_layout_test_results(build.results_ur l()) 87 results_url = buildbot.results_url(builder_name, build_number)
88 builder_name = layout_test_results.builder_name() 88 layout_test_results = buildbot.fetch_layout_test_results(results_url)
qyearsley 2016/07/26 21:40:35 Side note: In a subsequent CL (after this CL is la
dcampb 2016/07/26 22:08:35 sounds good.
89 platform = self._host.builders.port_name_for_builder_name(builder_name) 89 platform = self._host.builders.port_name_for_builder_name(builder_name)
90 result_list = layout_test_results.didnt_run_as_expected_results() 90 result_list = layout_test_results.didnt_run_as_expected_results()
91 failing_results_dict = self._generate_results_dict(platform, result_list ) 91 failing_results_dict = self._generate_results_dict(platform, result_list )
92 return failing_results_dict 92 return failing_results_dict
93 93
94 def merge_dicts(self, target, source, path=None): 94 def merge_dicts(self, target, source, path=None):
95 """Recursively merge nested dictionaries, returning the target dictionar y 95 """Recursively merge nested dictionaries, returning the target dictionar y
96 96
97 Merges the keys and values from the source dict into the target dict. 97 Merges the keys and values from the source dict into the target dict.
98 98
(...skipping 23 matching lines...) Expand all
122 """Merges keys in dictionary with same value. 122 """Merges keys in dictionary with same value.
123 123
124 Traverses through a dict and compares the values of keys to one another. 124 Traverses through a dict and compares the values of keys to one another.
125 If the values match, the keys are combined to a tuple and the previous k eys 125 If the values match, the keys are combined to a tuple and the previous k eys
126 are removed from the dict. 126 are removed from the dict.
127 127
128 Args: 128 Args:
129 dictionary: A dictionary with a dictionary as the value. 129 dictionary: A dictionary with a dictionary as the value.
130 130
131 Returns: 131 Returns:
132 A dictionary with updated keys to reflect matching values of keys. 132 A new dictionary with updated keys to reflect matching values of key s.
133 Example: { 133 Example: {
134 'one': {'foo': 'bar'}, 134 'one': {'foo': 'bar'},
135 'two': {'foo': 'bar'}, 135 'two': {'foo': 'bar'},
136 'three': {'foo': bar'} 136 'three': {'foo': bar'}
qyearsley 2016/07/26 21:40:35 Unrelated to this CL, but there's a quote missing
dcampb 2016/07/26 22:08:35 ahh, nice eye. done
137 } 137 }
138 is converted to {('one', 'two', 'three'): {'foo': 'bar'}} 138 is converted to a new dictionary with that contains
139 {('one', 'two', 'three'): {'foo': 'bar'}}
139 """ 140 """
141 merged_dict = {}
140 matching_value_keys = set() 142 matching_value_keys = set()
141 keys = dictionary.keys() 143 keys = sorted(dictionary.keys())
qyearsley 2016/07/26 21:40:35 Same as `keys = sorted(dictionary)` (both are OK).
dcampb 2016/07/26 22:08:35 noted
142 is_last_item = False 144 while keys:
143 for index, item in enumerate(keys): 145 current_key = keys[0]
144 if is_last_item: 146 found_match = False
147 if current_key == keys[-1]:
148 merged_dict[current_key] = dictionary[current_key]
149 keys.remove(current_key)
145 break 150 break
146 for i in range(index + 1, len(keys)): 151 for i in range(1, len(keys)):
147 next_item = keys[i] 152 next_item = keys[i]
qyearsley 2016/07/26 21:40:36 If `i` isn't used below, then maybe you could also
dcampb 2016/07/26 22:08:35 nicee, noted.
148 if dictionary[item] == dictionary[next_item]: 153 if dictionary[current_key] == dictionary[next_item]:
149 matching_value_keys.update([item, next_item]) 154 found_match = True
150 dictionary[tuple(matching_value_keys)] = dictionary[item] 155 matching_value_keys.update([current_key, next_item])
151 is_last_item = next_item == keys[-1] 156 if next_item == keys[-1]:
152 del dictionary[item] 157 if found_match:
153 del dictionary[next_item] 158 merged_dict[tuple(matching_value_keys)] = dictionary[cur rent_key]
154 return dictionary 159 for key in matching_value_keys:
160 keys.remove(key)
qyearsley 2016/07/26 21:40:35 For many short for loops, you can sometimes write
dcampb 2016/07/26 22:08:35 nice tip, thanks. done
161 else:
162 merged_dict[current_key] = dictionary[current_key]
163 keys.remove(current_key)
164 matching_value_keys = set()
165 return merged_dict
155 166
156 def get_expectations(self, results): 167 def get_expectations(self, results):
157 """Returns a list of test expectations for a given test dict. 168 """Returns a list of test expectations for a given test dict.
158 169
159 Returns a list of one or more test expectations based on the expected 170 Returns a list of one or more test expectations based on the expected
160 and actual results of a given test name. 171 and actual results of a given test name.
161 172
162 Args: 173 Args:
163 results: A dictionary that maps one test to its results. Example: { 174 results: A dictionary that maps one test to its results. Example: {
164 'test_name': { 175 'test_name': {
165 'expected': 'PASS', 176 'expected': 'PASS',
166 'actual': 'FAIL', 177 'actual': 'FAIL',
167 'bug': 'crbug.com/11111' 178 'bug': 'crbug.com/11111'
168 } 179 }
169 } 180 }
170 181
171 Returns: 182 Returns:
172 A list of one or more test expectations with the first letter capita lized. Example: 183 A list of one or more test expectations with the first letter capita lized. Example:
173 ['Failure', 'Timeout'] 184 ['Failure', 'Timeout']
174 """ 185 """
175 expectations = [] 186 expectations = set()
176 failure_expectations = ['TEXT', 'FAIL', 'IMAGE+TEXT', 'IMAGE'] 187 failure_expectations = ['TIMEOUT', 'CRASH', 'SLOW', 'TEXT', 'FAIL', 'IMA GE+TEXT', 'IMAGE']
177 pass_crash_timeout = ['TIMEOUT', 'CRASH', 'PASS'] 188 pass_crash_timeout = ['TIMEOUT', 'CRASH', 'PASS']
178 if results['expected'] in pass_crash_timeout and results['actual'] in fa ilure_expectations: 189 for expected in results['expected'].split():
179 expectations.append('Failure') 190 for actual in results['actual'].split():
qyearsley 2016/07/26 21:40:35 For this change, I think it will be good to have u
dcampb 2016/07/26 22:08:35 working on this now.
180 if results['expected'] in failure_expectations and results['actual'] in pass_crash_timeout: 191 if expected in pass_crash_timeout and actual in failure_expectat ions:
181 expectations.append(results['actual'].capitalize()) 192 expectations.update(['Failure'])
182 if results['expected'] in pass_crash_timeout and results['actual'] in pa ss_crash_timeout: 193 if expected in failure_expectations and actual in pass_crash_tim eout:
183 expectations.append(results['actual'].capitalize()) 194 expectations.update([actual.capitalize()])
184 expectations.append(results['expected'].capitalize()) 195 if expected in pass_crash_timeout and actual in pass_crash_timeo ut:
196 expectations.update([actual.capitalize()])
197 expectations.update([expected.capitalize()])
qyearsley 2016/07/26 21:40:35 For sets, if you're adding only one item, you can
dcampb 2016/07/26 22:08:35 noted and done.
185 return expectations 198 return expectations
186 199
187 def create_line_list(self, merged_results): 200 def create_line_list(self, merged_results):
188 """Creates list of test expectations lines. 201 """Creates list of test expectations lines.
189 202
190 Traverses through a merged_results and parses the value to create a test 203 Traverses through a merged_results and parses the value to create a test
191 expectations line per key. 204 expectations line per key.
192 205
193 Args: 206 Args:
194 merged_results: A merged_results with the format { 207 merged_results: A merged_results with the format {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 all_lines += str(line) + '\n' 266 all_lines += str(line) + '\n'
254 all_lines = all_lines[:-1] 267 all_lines = all_lines[:-1]
255 if w3c_comment_line_index == -1: 268 if w3c_comment_line_index == -1:
256 file_contents += '\n%s\n' % comment_line 269 file_contents += '\n%s\n' % comment_line
257 file_contents += all_lines 270 file_contents += all_lines
258 else: 271 else:
259 end_of_comment_line = (file_contents[w3c_comment_line_index:].find(' \n')) + w3c_comment_line_index 272 end_of_comment_line = (file_contents[w3c_comment_line_index:].find(' \n')) + w3c_comment_line_index
260 new_data = file_contents[: end_of_comment_line + 1] + all_lines + fi le_contents[end_of_comment_line:] 273 new_data = file_contents[: end_of_comment_line + 1] + all_lines + fi le_contents[end_of_comment_line:]
261 file_contents = new_data 274 file_contents = new_data
262 host.filesystem.write_text_file(path, file_contents) 275 host.filesystem.write_text_file(path, file_contents)
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Tools/Scripts/webkitpy/w3c/update_w3c_test_expectations_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698