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..ef5e7c24973d72305e8e7855d10f2faf1b4f80c5 |
--- /dev/null |
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/update_w3c_test_expectations.py |
@@ -0,0 +1,90 @@ |
+"""TODO(dcampb): DO NOT SUBMIT without one-line documentation for print-layout-test-paths.""" |
qyearsley
2016/07/11 23:17:33
This line can be removed, and at the top of the fi
dcampb
2016/07/12 03:55:55
Corrections made.
|
+from webkitpy.common.net.layouttestresults import LayoutTestResults |
+from webkitpy.layout_tests.models.test_expectations import * |
qyearsley
2016/07/11 23:17:33
It's best to avoid "wildcard imports" like these,
dcampb
2016/07/12 03:55:56
Ahh, never knew that. Changes made.
|
+from webkitpy.common.net.web import Web |
+from webkitpy.common.net import buildbot |
+from webkitpy.common.net import rietveld |
+from webkitpy.common.checkout.scm.git import Git |
qyearsley
2016/07/11 23:17:32
Imports should be sorted, for consistency.
dcampb
2016/07/12 03:55:55
sorted by directory, file name or module name?
qyearsley
2016/07/12 16:43:35
Sorted lexicographically (which ends up to be by d
|
+import logging |
qyearsley
2016/07/12 16:43:35
One more thing about import section format: Standa
|
+ |
+_log = logging.getLogger(__name__) |
+ |
+ |
+TRY_BOTS = ['linux_chromium_rel_ng', 'mac_chromium_rel_ng', 'win_chromium_rel_ng'] |
+ |
+ |
+def Main(): |
qyearsley
2016/07/11 23:17:32
For consistency with most of the other scripts her
dcampb
2016/07/12 03:55:55
done
|
+ json_obj = {} |
qyearsley
2016/07/11 23:17:33
This name can be made more descriptive; how would
dcampb
2016/07/12 03:55:55
Is that the same for local variable names in sub f
dcampb
2016/07/12 03:55:55
Is that the same for local variable names in sub f
qyearsley
2016/07/12 16:43:35
Yep -- there may be some cases where `obj, `data`
|
+ counter = 0 |
+ webo = Web() |
raikiri
2016/07/11 18:46:55
maybe rename webo to something a little more clear
qyearsley
2016/07/11 23:17:33
I'd suggest just calling it web.
dcampb
2016/07/12 03:55:55
done, web_object?
dcampb
2016/07/12 19:57:03
just made it web, per qyearsley@ comment on line 2
|
+ try_jobs_info = get_tryjobs_information(webo) |
+ while counter < len(TRY_BOTS): |
+ failing_paths = get_tryjob_results(try_jobs_info, webo, counter) |
+ json_obj = merge_dicts(json_obj, failing_paths) |
+ counter += 1 |
+ return 0 |
+ |
+ |
+def get_tryjobs_information(web): |
qyearsley
2016/07/11 23:17:33
tryjobs -> try_jobs
I prefer to treat this as two
dcampb
2016/07/12 03:55:55
done
|
+ git_obj = Git('.') |
qyearsley
2016/07/11 23:17:33
You could rename git_obj -> git; the _obj suffix d
dcampb
2016/07/12 03:55:55
makes sense, did the same for the web object.
|
+ issue_number = git_obj.get_issue_number() |
+ info = rietveld.latest_try_jobs(issue_number, TRY_BOTS, web) |
+ return info |
+ |
+ |
+def _generate_results_dict(layout_test_list, test_results_object): |
+ test_dict = {} |
+ builder_name = test_results_object.builder_name() |
+ if test_results_object.builder_name() in TRY_BOTS: |
+ platform = builder_name[:builder_name.find("_")] |
qyearsley
2016/07/11 23:17:33
We can't assume that builder names are always for
dcampb
2016/07/15 00:24:13
taken care of.
|
+ for obj in layout_test_list: |
qyearsley
2016/07/11 23:17:33
The name `obj` can be improved. In this case, it's
dcampb
2016/07/12 03:55:55
done
|
+ test_dict[obj.test_name()] = {platform: {'expected': obj.expected_results(), 'actual': obj.actual_results(), 'bug': 'crbug.com/626703'}} |
+ return test_dict |
+ |
+ |
+def _strip_failing_results(data): |
+ test_object = LayoutTestResults.results_from_string(data) |
+ failing_paths = test_object.didnt_run_as_expected_results() |
+ return _generate_results_dict(failing_paths, test_object) |
+ |
+ |
+def get_tryjob_results(try_jobs_data, web, index): |
qyearsley
2016/07/11 23:17:32
tryjob -> try_job
dcampb
2016/07/12 03:55:55
done
|
+ builder_name = try_jobs_data[index][0] |
+ build_number = try_jobs_data[index][1] |
+ builder = buildbot.Builder(builder_name, buildbot.BuildBot()) |
+ url_components = (builder.results_url(), str(build_number), 'layout-test-results', 'failing_results.json') |
+ results_url = '/'.join(url_components) |
qyearsley
2016/07/11 23:17:32
The results URL can be constructed by methods on t
dcampb
2016/07/12 03:55:56
I believe I tried using it and it was giving me an
|
+ json_data = web.get_binary(results_url) |
+ failing_results_paths = _strip_failing_results(json_data) |
+ return failing_results_paths |
+ |
+ |
+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 = [] |
raikiri
2016/07/11 18:46:55
can also be written:
path = path or []
|
+ 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)]) |
raikiri
2016/07/11 18:46:55
iiuc this line seems to do nothing as you don't ke
dcampb
2016/07/12 03:55:55
this line recursively calls the function with a su
|
+ elif final[key] == temp[key]: |
+ pass |
+ else: |
+ raise Exception('Conflict at %s' % '.'.join(path)) |
+ else: |
+ final[key] = temp[key] |
+ return final |
+ |
+ |
+if __name__ == '__main__': |
+ Main() |