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

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

Issue 2136723002: Create test expectations line automatically from failing test results (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Create list of test expectations lines from failing test tree Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Tools/Scripts/webkitpy/w3c/update_w3c_test_expectations.py
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/update_w3c_test_expectations.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/update_w3c_test_expectations.py
new file mode 100644
index 0000000000000000000000000000000000000000..18aa37354d2ccca6ca8e4d7d6f163316c1b2cb68
--- /dev/null
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/update_w3c_test_expectations.py
@@ -0,0 +1,163 @@
+# Coppyright 2016 The Chromium Authors. All rights reserved.
qyearsley 2016/07/12 23:00:15 Coppyright -> Copyright
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+
+from webkitpy.common.checkout.scm.git import Git
+from webkitpy.common.net import buildbot
+from webkitpy.common.net import rietveld
+from webkitpy.common.net.web import Web
+from webkitpy.layout_tests.builder_list import BuilderList
+from webkitpy.common.config.builders import BUILDERS as Builders_list_dict
+import logging
+
+
+# This script is designed to output a list of Test Expectations lines to be added to TestExpectations.py by
+# retrieving the latest try_job results for the current cl issue connected to the local branch and parsing it
+# to develop a dictionary of dictionaries that contain:
+# {Test Name: {Platform: {'actual': 'foo', 'expected': 'foo', 'bug':'crbug.com/#####'}}}
qyearsley 2016/07/12 23:00:15 Good - module-level descriptions with examples of
+
+_log = logging.getLogger(__name__)
+
+
+TRY_BOTS = ['linux_chromium_rel_ng', 'mac_chromium_rel_ng', 'win_chromium_rel_ng']
+
+
+def main():
+ line_expectations_dict = {}
+ line_list = []
+ counter = 0
+ web = Web()
+ try_jobs_info = get_try_jobs_information(web)
+ while counter < len(TRY_BOTS):
+ try:
+ platform_results_dict = get_try_job_results(try_jobs_info, counter)
+ line_expectations_dict = merge_dicts(line_expectations_dict, platform_results_dict)
+ counter += 1
+ except IndexError:
+ print "no tryjob info was collected"
+ return 1
+ line_expectations_dict = update_platforms(line_expectations_dict)
+ line_list = create_line_list(line_expectations_dict)
+ return line_list
+
+# This function will return only tryjobs with failing results.
+# If no failing results, try_job info will not be returned. If one try server
+# has two try jobs, it will return both.
+
+
+def get_try_jobs_information(web):
+ git = Git('.')
+ issue_number = git.get_issue_number()
+ info = rietveld.latest_try_jobs(issue_number, TRY_BOTS, web)
+ return info
+
+
+def _generate_results_dict(layout_test_list):
+ test_dict = {}
+ builder_list = BuilderList(Builders_list_dict)
+ builder_name = layout_test_list.builder_name()
+ platform = builder_list.port_name_for_builder_name(builder_name)
+ dash = platform.find("-")
+ if dash != -1:
+ platform = platform[dash + 1:].capitalize()
+ for result in layout_test_list.didnt_run_as_expected_results():
+ test_dict[result.test_name()] = {platform: {'expected': result.expected_results(), 'actual': result.actual_results(), 'bug': 'crbug.com/626703'}}
+ return test_dict
+
+
+def get_try_job_results(try_jobs_data, index):
+ builder_name = try_jobs_data[index][0]
+ build_number = try_jobs_data[index][1]
+ builder = buildbot.Builder(builder_name, buildbot.BuildBot())
+ build = buildbot.Build(builder, build_number)
+ layout_test_results = builder.fetch_layout_test_results(build.results_url())
+ failing_results_dict = _generate_results_dict(layout_test_results)
+ return failing_results_dict
+
+
+def _remove_duplicates(failing_paths):
+ seen = set()
+ new_list = []
+ for dictionary in failing_paths:
+ path = tuple(dictionary.items())
+ if path not in seen:
+ seen.add(path)
+ new_list.append(dict(path))
+ return new_list
+
+
+def merge_dicts(final, temp, path=None):
+ if path is None:
+ path = []
+ for key in temp:
+ if key in final:
+ if (isinstance(final[key], dict)) and isinstance(temp[key], dict):
+ merge_dicts(final[key], temp[key], path + [str(key)])
+ elif final[key] == temp[key]:
+ pass
+ else:
+ raise Exception('conflict at %s' % '.'.join(path))
+ else:
+ final[key] = temp[key]
+ return final
+
+# note this function may break if there are more than 3 inner_keys.
+# as of right now, the inner_keys should only be [win, linux, mac]
+
+
+def update_platforms(final):
+ for value in final.values():
+ platform = [set()]
+ inner_keys = value.keys()
+ tuple_result = {}
+ for i, item in enumerate(inner_keys):
+ if (i + 1) < len(inner_keys):
+ if value[item] == value[inner_keys[i + 1]]:
+ tuple_result = value[item]
+ platform[0].add(item)
+ if (i + 2) == len(inner_keys):
+ platform[0].add(inner_keys[i + 1])
+ elif (i == 0) and (value[item] == value[inner_keys[len(inner_keys) - 1]]):
+ platform[0].add(item)
+ platform[0].add(inner_keys[len(inner_keys) - 1])
+ if len(platform[0]) == 0:
+ continue
+ else:
+ value[tuple(platform[0])] = tuple_result
+ for i in platform[0]:
+ value.pop(i)
+ return final
qyearsley 2016/07/12 23:00:15 On first look, I'm having difficulty understanding
+
+
+def get_expectations(results):
+ expectations = []
+ failure_expectations = ['TEXT', 'FAIL', 'IMAGE+TEXT', 'IMAGE']
+ pass_crash_timeout = ['TIMEOUT', 'CRASH', 'PASS']
+ if results['expected'] in pass_crash_timeout and results['actual'] in failure_expectations:
+ expectations.append('Failure')
+ if results['expected'] in failure_expectations and results['actual'] in pass_crash_timeout:
+ expectations.append(results['actual'].capitalize())
+ if results['expected'] in pass_crash_timeout and results['actual'] in pass_crash_timeout:
+ expectations.append(results['actual'].capitalize())
+ expectations.append(results['expected'].capitalize())
+ return expectations
+
+
+def create_line_list(dictionary):
+ line_list = []
+ for key, value in dictionary.iteritems():
+ test_name = key
+ for key2 in value:
+ platform = []
+ bug = []
+ expectations = []
+ if isinstance(key2, tuple):
+ platform = list(key2)
+ else:
+ platform.append(key2)
+ bug.append(value[key2]['bug'])
+ expectations = get_expectations(value[key2])
+ line = '%s [ %s ] %s [ %s ]' % (bug[0], ' '.join(platform), test_name, ' '.join(expectations))
+ line_list.append(line)
+ return line_list

Powered by Google App Engine
This is Rietveld 408576698