OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 | 2 |
3 # Copyright (c) 2014 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2014 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 | 7 |
8 """Generate new bench expectations from results of trybots on a code review.""" | 8 """Generate new bench expectations from results of trybots on a code review.""" |
9 | 9 |
10 | 10 |
11 import collections | 11 import collections |
12 import compare_codereview | 12 import compare_codereview |
13 import os | 13 import os |
14 import re | 14 import re |
15 import shutil | 15 import shutil |
16 import subprocess | 16 import subprocess |
17 import sys | 17 import sys |
18 | 18 |
19 | 19 |
20 BENCH_DATA_URL = 'gs://chromium-skia-gm/perfdata/%s/%s/*' | 20 BENCH_DATA_URL = 'gs://chromium-skia-gm/perfdata/%s/%s/*' |
21 CHECKOUT_PATH = os.path.realpath(os.path.join( | 21 CHECKOUT_PATH = os.path.realpath(os.path.join( |
22 os.path.dirname(os.path.abspath(__file__)), os.pardir)) | 22 os.path.dirname(os.path.abspath(__file__)), os.pardir)) |
23 TMP_BENCH_DATA_DIR = os.path.join(CHECKOUT_PATH, '.bench_data') | 23 TMP_BENCH_DATA_DIR = os.path.join(CHECKOUT_PATH, '.bench_data') |
24 | 24 |
25 | 25 |
| 26 TryBuild = collections.namedtuple( |
| 27 'TryBuild', ['builder_name', 'build_number', 'is_finished']) |
| 28 |
| 29 |
26 def find_all_builds(codereview_url): | 30 def find_all_builds(codereview_url): |
27 """Finds and returns information about trybot runs for a code review. | 31 """Finds and returns information about trybot runs for a code review. |
28 | 32 |
29 Args: | 33 Args: |
30 codereview_url: URL of the codereview in question. | 34 codereview_url: URL of the codereview in question. |
31 | 35 |
32 Returns: | 36 Returns: |
33 List of NamedTuples: (builder_name, build_number, is_finished) | 37 List of NamedTuples: (builder_name, build_number, is_finished) |
34 """ | 38 """ |
35 results = compare_codereview.CodeReviewHTMLParser().parse(codereview_url) | 39 results = compare_codereview.CodeReviewHTMLParser().parse(codereview_url) |
36 TryBuild = collections.namedtuple( | |
37 'TryBuild', ['builder_name', 'build_number', 'is_finished']) | |
38 try_builds = [] | 40 try_builds = [] |
39 | |
40 for builder, data in results.iteritems(): | 41 for builder, data in results.iteritems(): |
41 if builder.startswith('Perf'): | 42 if builder.startswith('Perf'): |
42 try_builds.append(TryBuild(builder, data.url.split('/')[-1], | 43 build_num = data.url.split('/')[-1] if data.url else None |
| 44 try_builds.append(TryBuild(builder, build_num, |
43 data.status != 'pending')) | 45 data.status != 'pending')) |
44 return try_builds | 46 return try_builds |
45 | 47 |
46 | 48 |
| 49 def _all_trybots_finished(try_builds): |
| 50 """Return True iff all of the given try jobs have finished. |
| 51 |
| 52 Args: |
| 53 try_builds: list of TryBuild instances. |
| 54 |
| 55 Returns: |
| 56 True if all of the given try jobs have finished, otherwise False. |
| 57 """ |
| 58 for try_build in try_builds: |
| 59 if not try_build.is_finished: |
| 60 return False |
| 61 return True |
| 62 |
| 63 |
| 64 def all_trybots_finished(codereview_url): |
| 65 """Return True iff all of the try jobs on the given codereview have finished. |
| 66 |
| 67 Args: |
| 68 codereview_url: string; URL of the codereview. |
| 69 |
| 70 Returns: |
| 71 True if all of the try jobs have finished, otherwise False. |
| 72 """ |
| 73 return _all_trybots_finished(find_all_builds(codereview_url)) |
| 74 |
| 75 |
47 def get_bench_data(builder, build_num, dest_dir): | 76 def get_bench_data(builder, build_num, dest_dir): |
48 """Download the bench data for the given builder at the given build_num. | 77 """Download the bench data for the given builder at the given build_num. |
49 | 78 |
50 Args: | 79 Args: |
51 builder: string; name of the builder. | 80 builder: string; name of the builder. |
52 build_num: string; build number. | 81 build_num: string; build number. |
53 dest_dir: string; destination directory for the bench data. | 82 dest_dir: string; destination directory for the bench data. |
54 """ | 83 """ |
55 url = BENCH_DATA_URL % (builder, build_num) | 84 url = BENCH_DATA_URL % (builder, build_num) |
56 subprocess.check_call(['gsutil', 'cp', '-R', url, dest_dir], | 85 subprocess.check_call(['gsutil', 'cp', '-R', url, dest_dir], |
(...skipping 30 matching lines...) Expand all Loading... |
87 finished trybots and uses them to generate new expectations for their | 116 finished trybots and uses them to generate new expectations for their |
88 waterfall counterparts. | 117 waterfall counterparts. |
89 | 118 |
90 Args: | 119 Args: |
91 url: string; URL of the code review. | 120 url: string; URL of the code review. |
92 error_on_unfinished: bool; throw an error if any trybot has not finished. | 121 error_on_unfinished: bool; throw an error if any trybot has not finished. |
93 """ | 122 """ |
94 try_builds = find_all_builds(codereview_url) | 123 try_builds = find_all_builds(codereview_url) |
95 | 124 |
96 # Verify that all trybots have finished running. | 125 # Verify that all trybots have finished running. |
97 if error_on_unfinished: | 126 if error_on_unfinished and not _all_trybots_finished(try_builds): |
98 for try_build in try_builds: | 127 raise TrybotNotFinishedError('Not all trybots have finished.') |
99 if not try_build.is_finished: | 128 |
100 raise TrybotNotFinishedError('%s: #%s is not finished.' % ( | |
101 try_build.builder_name, | |
102 try_build.build_number)) | |
103 failed_data_pull = [] | 129 failed_data_pull = [] |
104 failed_gen_expectations = [] | 130 failed_gen_expectations = [] |
105 | 131 |
106 if os.path.isdir(TMP_BENCH_DATA_DIR): | 132 if os.path.isdir(TMP_BENCH_DATA_DIR): |
107 shutil.rmtree(TMP_BENCH_DATA_DIR) | 133 shutil.rmtree(TMP_BENCH_DATA_DIR) |
108 | 134 |
109 for try_build in try_builds: | 135 for try_build in try_builds: |
110 try_builder = try_build.builder_name | 136 try_builder = try_build.builder_name |
111 builder = try_builder.replace('-Trybot', '') | 137 builder = try_builder.replace('-Trybot', '') |
112 | 138 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 if failed_gen_expectations: | 171 if failed_gen_expectations: |
146 failure += 'Failed to generate expectations for: %s\n\n' % ','.join( | 172 failure += 'Failed to generate expectations for: %s\n\n' % ','.join( |
147 failed_gen_expectations) | 173 failed_gen_expectations) |
148 if failure: | 174 if failure: |
149 raise Exception(failure) | 175 raise Exception(failure) |
150 | 176 |
151 | 177 |
152 if __name__ == '__main__': | 178 if __name__ == '__main__': |
153 gen_bench_expectations_from_codereview(sys.argv[1]) | 179 gen_bench_expectations_from_codereview(sys.argv[1]) |
154 | 180 |
OLD | NEW |