OLD | NEW |
---|---|
(Empty) | |
1 # Coppyright 2016 The Chromium Authors. All rights reserved. | |
qyearsley
2016/07/12 23:00:15
Coppyright -> Copyright
| |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 | |
6 from webkitpy.common.checkout.scm.git import Git | |
7 from webkitpy.common.net import buildbot | |
8 from webkitpy.common.net import rietveld | |
9 from webkitpy.common.net.web import Web | |
10 from webkitpy.layout_tests.builder_list import BuilderList | |
11 from webkitpy.common.config.builders import BUILDERS as Builders_list_dict | |
12 import logging | |
13 | |
14 | |
15 # This script is designed to output a list of Test Expectations lines to be adde d to TestExpectations.py by | |
16 # retrieving the latest try_job results for the current cl issue connected to th e local branch and parsing it | |
17 # to develop a dictionary of dictionaries that contain: | |
18 # {Test Name: {Platform: {'actual': 'foo', 'expected': 'foo', 'bug':'crbug.com/# ####'}}} | |
qyearsley
2016/07/12 23:00:15
Good - module-level descriptions with examples of
| |
19 | |
20 _log = logging.getLogger(__name__) | |
21 | |
22 | |
23 TRY_BOTS = ['linux_chromium_rel_ng', 'mac_chromium_rel_ng', 'win_chromium_rel_ng '] | |
24 | |
25 | |
26 def main(): | |
27 line_expectations_dict = {} | |
28 line_list = [] | |
29 counter = 0 | |
30 web = Web() | |
31 try_jobs_info = get_try_jobs_information(web) | |
32 while counter < len(TRY_BOTS): | |
33 try: | |
34 platform_results_dict = get_try_job_results(try_jobs_info, counter) | |
35 line_expectations_dict = merge_dicts(line_expectations_dict, platfor m_results_dict) | |
36 counter += 1 | |
37 except IndexError: | |
38 print "no tryjob info was collected" | |
39 return 1 | |
40 line_expectations_dict = update_platforms(line_expectations_dict) | |
41 line_list = create_line_list(line_expectations_dict) | |
42 return line_list | |
43 | |
44 # This function will return only tryjobs with failing results. | |
45 # If no failing results, try_job info will not be returned. If one try server | |
46 # has two try jobs, it will return both. | |
47 | |
48 | |
49 def get_try_jobs_information(web): | |
50 git = Git('.') | |
51 issue_number = git.get_issue_number() | |
52 info = rietveld.latest_try_jobs(issue_number, TRY_BOTS, web) | |
53 return info | |
54 | |
55 | |
56 def _generate_results_dict(layout_test_list): | |
57 test_dict = {} | |
58 builder_list = BuilderList(Builders_list_dict) | |
59 builder_name = layout_test_list.builder_name() | |
60 platform = builder_list.port_name_for_builder_name(builder_name) | |
61 dash = platform.find("-") | |
62 if dash != -1: | |
63 platform = platform[dash + 1:].capitalize() | |
64 for result in layout_test_list.didnt_run_as_expected_results(): | |
65 test_dict[result.test_name()] = {platform: {'expected': result.expected_ results(), 'actual': result.actual_results(), 'bug': 'crbug.com/626703'}} | |
66 return test_dict | |
67 | |
68 | |
69 def get_try_job_results(try_jobs_data, index): | |
70 builder_name = try_jobs_data[index][0] | |
71 build_number = try_jobs_data[index][1] | |
72 builder = buildbot.Builder(builder_name, buildbot.BuildBot()) | |
73 build = buildbot.Build(builder, build_number) | |
74 layout_test_results = builder.fetch_layout_test_results(build.results_url()) | |
75 failing_results_dict = _generate_results_dict(layout_test_results) | |
76 return failing_results_dict | |
77 | |
78 | |
79 def _remove_duplicates(failing_paths): | |
80 seen = set() | |
81 new_list = [] | |
82 for dictionary in failing_paths: | |
83 path = tuple(dictionary.items()) | |
84 if path not in seen: | |
85 seen.add(path) | |
86 new_list.append(dict(path)) | |
87 return new_list | |
88 | |
89 | |
90 def merge_dicts(final, temp, path=None): | |
91 if path is None: | |
92 path = [] | |
93 for key in temp: | |
94 if key in final: | |
95 if (isinstance(final[key], dict)) and isinstance(temp[key], dict): | |
96 merge_dicts(final[key], temp[key], path + [str(key)]) | |
97 elif final[key] == temp[key]: | |
98 pass | |
99 else: | |
100 raise Exception('conflict at %s' % '.'.join(path)) | |
101 else: | |
102 final[key] = temp[key] | |
103 return final | |
104 | |
105 # note this function may break if there are more than 3 inner_keys. | |
106 # as of right now, the inner_keys should only be [win, linux, mac] | |
107 | |
108 | |
109 def update_platforms(final): | |
110 for value in final.values(): | |
111 platform = [set()] | |
112 inner_keys = value.keys() | |
113 tuple_result = {} | |
114 for i, item in enumerate(inner_keys): | |
115 if (i + 1) < len(inner_keys): | |
116 if value[item] == value[inner_keys[i + 1]]: | |
117 tuple_result = value[item] | |
118 platform[0].add(item) | |
119 if (i + 2) == len(inner_keys): | |
120 platform[0].add(inner_keys[i + 1]) | |
121 elif (i == 0) and (value[item] == value[inner_keys[len(inner_key s) - 1]]): | |
122 platform[0].add(item) | |
123 platform[0].add(inner_keys[len(inner_keys) - 1]) | |
124 if len(platform[0]) == 0: | |
125 continue | |
126 else: | |
127 value[tuple(platform[0])] = tuple_result | |
128 for i in platform[0]: | |
129 value.pop(i) | |
130 return final | |
qyearsley
2016/07/12 23:00:15
On first look, I'm having difficulty understanding
| |
131 | |
132 | |
133 def get_expectations(results): | |
134 expectations = [] | |
135 failure_expectations = ['TEXT', 'FAIL', 'IMAGE+TEXT', 'IMAGE'] | |
136 pass_crash_timeout = ['TIMEOUT', 'CRASH', 'PASS'] | |
137 if results['expected'] in pass_crash_timeout and results['actual'] in failur e_expectations: | |
138 expectations.append('Failure') | |
139 if results['expected'] in failure_expectations and results['actual'] in pass _crash_timeout: | |
140 expectations.append(results['actual'].capitalize()) | |
141 if results['expected'] in pass_crash_timeout and results['actual'] in pass_c rash_timeout: | |
142 expectations.append(results['actual'].capitalize()) | |
143 expectations.append(results['expected'].capitalize()) | |
144 return expectations | |
145 | |
146 | |
147 def create_line_list(dictionary): | |
148 line_list = [] | |
149 for key, value in dictionary.iteritems(): | |
150 test_name = key | |
151 for key2 in value: | |
152 platform = [] | |
153 bug = [] | |
154 expectations = [] | |
155 if isinstance(key2, tuple): | |
156 platform = list(key2) | |
157 else: | |
158 platform.append(key2) | |
159 bug.append(value[key2]['bug']) | |
160 expectations = get_expectations(value[key2]) | |
161 line = '%s [ %s ] %s [ %s ]' % (bug[0], ' '.join(platform), test_nam e, ' '.join(expectations)) | |
162 line_list.append(line) | |
163 return line_list | |
OLD | NEW |