| OLD | NEW |
| (Empty) |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import base64 | |
| 6 import collections | |
| 7 import json | |
| 8 | |
| 9 DEPS = [ | |
| 10 'auto_bisect_staging', | |
| 11 'recipe_engine/properties', | |
| 12 'test_utils', | |
| 13 'chromium_tests', | |
| 14 'recipe_engine/raw_io', | |
| 15 'recipe_engine/step', | |
| 16 'halt', | |
| 17 'recipe_engine/json', | |
| 18 ] | |
| 19 | |
| 20 def RunSteps(api): | |
| 21 mastername = api.m.properties.get('mastername') | |
| 22 buildername = api.m.properties.get('buildername') | |
| 23 # TODO(akuegel): Explicitly load the configs for the builders and don't rely | |
| 24 # on builders.py in chromium_tests recipe module. | |
| 25 bot_config = api.chromium_tests.create_bot_config_object( | |
| 26 mastername, buildername) | |
| 27 api.chromium_tests.configure_build(bot_config) | |
| 28 api.m.chromium_tests.prepare_checkout(bot_config) | |
| 29 api.auto_bisect_staging.perform_bisect(do_not_nest_wait_for_revision=True) | |
| 30 | |
| 31 def GenTests(api): | |
| 32 basic_test = api.test('basic') | |
| 33 broken_bad_rev_test = api.test('broken_bad_revision_test') | |
| 34 broken_good_rev_test = api.test('broken_good_revision_test') | |
| 35 return_code_test = api.test('basic_return_code_test') | |
| 36 basic_test += api.properties.generic( | |
| 37 mastername='tryserver.chromium.perf', | |
| 38 buildername='linux_perf_bisect') | |
| 39 broken_bad_rev_test += api.properties.generic( | |
| 40 mastername='tryserver.chromium.perf', | |
| 41 buildername='linux_perf_bisect') | |
| 42 broken_good_rev_test += api.properties.generic( | |
| 43 mastername='tryserver.chromium.perf', | |
| 44 buildername='linux_perf_bisect') | |
| 45 return_code_test += api.properties.generic( | |
| 46 mastername='tryserver.chromium.perf', | |
| 47 buildername='linux_perf_bisect') | |
| 48 | |
| 49 bisect_config = { | |
| 50 'test_type': 'perf', | |
| 51 'command': ('tools/perf/run_benchmark -v ' | |
| 52 '--browser=release page_cycler.intl_ar_fa_he'), | |
| 53 'good_revision': '306475', | |
| 54 'bad_revision': '306478', | |
| 55 'metric': 'warm_times/page_load_time', | |
| 56 'repeat_count': '2', | |
| 57 'max_time_minutes': '5', | |
| 58 'bug_id': '425582', | |
| 59 'gs_bucket': 'chrome-perf', | |
| 60 'builder_host': 'master4.golo.chromium.org', | |
| 61 'builder_port': '8341', | |
| 62 'dummy_initial_confidence': '95', | |
| 63 'poll_sleep': 0, | |
| 64 'dummy_builds': True, | |
| 65 'dummy_tests': True, | |
| 66 'dummy_job_names': True, | |
| 67 'bypass_stats_check': True, | |
| 68 } | |
| 69 invalid_cp_bisect_config = dict(bisect_config) | |
| 70 invalid_cp_bisect_config['good_revision'] = 'XXX' | |
| 71 | |
| 72 basic_test += api.properties(bisect_config=bisect_config) | |
| 73 broken_bad_rev_test += api.properties(bisect_config=bisect_config) | |
| 74 broken_good_rev_test += api.properties(bisect_config=bisect_config) | |
| 75 | |
| 76 # This data represents fake results for a basic scenario, the items in it are | |
| 77 # passed to the `_gen_step_data_for_revision` that patches the necessary steps | |
| 78 # with step_data instances. | |
| 79 def test_data(): | |
| 80 return [ | |
| 81 { | |
| 82 'refrange': True, | |
| 83 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222', | |
| 84 'commit_pos': '306478', | |
| 85 'test_results': { | |
| 86 'results': { | |
| 87 'mean': 20, | |
| 88 'std_err': 1, | |
| 89 'values': [19, 20, 21], | |
| 90 }, | |
| 91 'retcodes':[0], | |
| 92 }, | |
| 93 'cl_info': { | |
| 94 'author': 'DummyAuthor', | |
| 95 'email': 'dummy@nowhere.com', | |
| 96 'subject': 'Some random CL', | |
| 97 'date': '01/01/2015', | |
| 98 'body': ('A long description for a CL.\n' | |
| 99 'Containing multiple lines'), | |
| 100 }, | |
| 101 }, | |
| 102 { | |
| 103 'hash': '00316c9ddfb9d7b4e1ed2fff9fe6d964d2111111', | |
| 104 'commit_pos': '306477', | |
| 105 'test_results': { | |
| 106 'results': { | |
| 107 'mean': 15, | |
| 108 'std_err': 1, | |
| 109 'values': [14, 15, 16], | |
| 110 }, | |
| 111 'retcodes':[0], | |
| 112 } | |
| 113 }, | |
| 114 { | |
| 115 'hash': 'fc6dfc7ff5b1073408499478969261b826441144', | |
| 116 'commit_pos': '306476', | |
| 117 'test_results': { | |
| 118 'results': { | |
| 119 'mean': 70, | |
| 120 'std_err': 2, | |
| 121 'values': [68, 70, 72], | |
| 122 }, | |
| 123 'retcodes':[0], | |
| 124 } | |
| 125 }, | |
| 126 { | |
| 127 'refrange': True, | |
| 128 'hash': 'e28dc0d49c331def2a3bbf3ddd0096eb51551155', | |
| 129 'commit_pos': '306475', | |
| 130 'test_results': { | |
| 131 'results': { | |
| 132 'mean': 80, | |
| 133 'std_err': 10, | |
| 134 'values': [70, 70, 80, 90, 90], | |
| 135 }, | |
| 136 'retcodes':[0], | |
| 137 } | |
| 138 }, | |
| 139 ] | |
| 140 | |
| 141 basic_test_data = test_data() | |
| 142 for revision_data in basic_test_data: | |
| 143 for step_data in _get_step_data_for_revision(api, revision_data): | |
| 144 basic_test += step_data | |
| 145 basic_test += _get_revision_range_step_data(api, basic_test_data) | |
| 146 basic_test += _get_post_bisect_step_data(api) | |
| 147 yield basic_test | |
| 148 | |
| 149 broken_test_data = test_data() | |
| 150 broken_test_data[0].pop('cl_info') | |
| 151 | |
| 152 doctored_data = test_data() | |
| 153 doctored_data[0]['test_results']['results']['errors'] = ['Dummy error.'] | |
| 154 for revision_data in doctored_data: | |
| 155 revision_data.pop('cl_info', None) | |
| 156 skip_results = revision_data in doctored_data[1:-1] | |
| 157 for step_data in _get_step_data_for_revision(api, revision_data, | |
| 158 skip_results=skip_results): | |
| 159 broken_bad_rev_test += step_data | |
| 160 broken_bad_rev_test += _get_revision_range_step_data(api, doctored_data) | |
| 161 broken_bad_rev_test += _get_post_bisect_step_data(api) | |
| 162 yield broken_bad_rev_test | |
| 163 | |
| 164 doctored_data = test_data() | |
| 165 doctored_data[-1]['test_results']['results']['errors'] = ['Dummy error.'] | |
| 166 for revision_data in doctored_data: | |
| 167 revision_data.pop('cl_info', None) | |
| 168 skip_results = revision_data in doctored_data[1:-1] | |
| 169 for step_data in _get_step_data_for_revision(api, revision_data, | |
| 170 skip_results=skip_results): | |
| 171 broken_good_rev_test += step_data | |
| 172 broken_good_rev_test += _get_revision_range_step_data(api, doctored_data) | |
| 173 broken_good_rev_test += _get_post_bisect_step_data(api) | |
| 174 yield broken_good_rev_test | |
| 175 | |
| 176 def return_code_test_data(): | |
| 177 return [ | |
| 178 { | |
| 179 'refrange': True, | |
| 180 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222', | |
| 181 'commit_pos': '306478', | |
| 182 'test_results': { | |
| 183 'results': { | |
| 184 'mean': 1, | |
| 185 'std_err': 0, | |
| 186 'values': [], | |
| 187 }, | |
| 188 'retcodes':[1], | |
| 189 }, | |
| 190 'cl_info': { | |
| 191 'author': 'DummyAuthor', | |
| 192 'email': 'dummy@nowhere.com', | |
| 193 'subject': 'Some random CL', | |
| 194 'date': '01/01/2015', | |
| 195 'body': ('A long description for a CL.\n' | |
| 196 'Containing multiple lines'), | |
| 197 }, | |
| 198 }, | |
| 199 { | |
| 200 'hash': '00316c9ddfb9d7b4e1ed2fff9fe6d964d2111111', | |
| 201 'commit_pos': '306477', | |
| 202 'test_results': { | |
| 203 'results': { | |
| 204 'mean': 1, | |
| 205 'std_err': 0, | |
| 206 'values': [], | |
| 207 }, | |
| 208 'retcodes':[1], | |
| 209 } | |
| 210 }, | |
| 211 { | |
| 212 'hash': 'fc6dfc7ff5b1073408499478969261b826441144', | |
| 213 'commit_pos': '306476', | |
| 214 'test_results': { | |
| 215 'results': { | |
| 216 'mean': 1, | |
| 217 'std_err': 0, | |
| 218 'values': [], | |
| 219 }, | |
| 220 'retcodes':[1], | |
| 221 } | |
| 222 }, | |
| 223 { | |
| 224 'refrange': True, | |
| 225 'hash': 'e28dc0d49c331def2a3bbf3ddd0096eb51551155', | |
| 226 'commit_pos': '306475', | |
| 227 'test_results': { | |
| 228 'results': { | |
| 229 'mean': 0, | |
| 230 'std_err': 0, | |
| 231 'values': [], | |
| 232 }, | |
| 233 'retcodes':[0], | |
| 234 } | |
| 235 }, | |
| 236 ] | |
| 237 | |
| 238 bisect_config_ret_code = bisect_config.copy() | |
| 239 bisect_config_ret_code['test_type'] = 'return_code' | |
| 240 return_code_test += api.properties(bisect_config=bisect_config_ret_code) | |
| 241 return_code_test_data = return_code_test_data() | |
| 242 for revision_data in return_code_test_data: | |
| 243 for step_data in _get_step_data_for_revision(api, revision_data): | |
| 244 return_code_test += step_data | |
| 245 return_code_test += _get_revision_range_step_data(api, return_code_test_data) | |
| 246 return_code_test += _get_post_bisect_step_data(api) | |
| 247 yield return_code_test | |
| 248 | |
| 249 | |
| 250 def _get_revision_range_step_data(api, range_data): | |
| 251 """Gives canned output for fetch_intervening_revisions.py.""" | |
| 252 range_data.sort(key=lambda r: r['commit_pos']) | |
| 253 min_rev = range_data[0]['hash'] | |
| 254 max_rev = range_data[-1]['hash'] | |
| 255 output = [[r['hash'], 'ignored'] for r in range_data[1:]] | |
| 256 step_name = ('Expanding revision range.for revisions %s:%s' % | |
| 257 (min_rev, max_rev)) | |
| 258 return api.step_data(step_name, stdout=api.json.output(output)) | |
| 259 | |
| 260 | |
| 261 def _get_step_data_for_revision(api, revision_data, skip_results=False): | |
| 262 """Generator that produces step patches for fake results.""" | |
| 263 commit_pos_number = revision_data['commit_pos'] | |
| 264 commit_hash = revision_data['hash'] | |
| 265 test_results = revision_data['test_results'] | |
| 266 | |
| 267 if 'refrange' in revision_data: | |
| 268 parent_step = 'Resolving reference range.' | |
| 269 commit_pos = 'refs/heads/master@{#%s}' % commit_pos_number | |
| 270 step_name = parent_step + 'crrev get commit hash for ' + commit_pos | |
| 271 yield api.step_data( | |
| 272 step_name, | |
| 273 stdout=api.json.output({'git_sha': commit_hash})) | |
| 274 | |
| 275 if not skip_results: | |
| 276 step_name = ('gsutil Get test results for build %s') % (commit_hash) | |
| 277 if 'refrange' in revision_data: | |
| 278 parent_step = 'Gathering reference values.' | |
| 279 else: | |
| 280 parent_step = 'Working on revision %s.' % ('chromium@' + commit_hash[:10]) | |
| 281 yield _get_post_bisect_step_data(api, parent_step) | |
| 282 step_name = parent_step + step_name | |
| 283 yield api.step_data(step_name, stdout=api.raw_io.output(json.dumps( | |
| 284 test_results))) | |
| 285 | |
| 286 if 'cl_info' in revision_data: | |
| 287 step_name = 'Reading culprit cl information.' | |
| 288 stdout = api.json.output(revision_data['cl_info']) | |
| 289 yield api.step_data(step_name, stdout=stdout) | |
| 290 | |
| 291 | |
| 292 def _get_post_bisect_step_data(api, parent_step=''): | |
| 293 """Gets step data for perf_dashboard/resource/post_json.py.""" | |
| 294 response = {'status_code': 200} | |
| 295 return api.step_data(parent_step + 'Post bisect results', | |
| 296 stdout=api.json.output(response)) | |
| OLD | NEW |