Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 | 5 |
| 6 # Recipe module for Skia Swarming trigger. | 6 # Recipe module for Skia Swarming trigger. |
| 7 | 7 |
| 8 | 8 |
| 9 import json | 9 import json |
| 10 | 10 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 dimensions['gpu'] = 'none' | 70 dimensions['gpu'] = 'none' |
| 71 # TODO(borenet): Add appropriate CPU dimension(s). | 71 # TODO(borenet): Add appropriate CPU dimension(s). |
| 72 #dimensions['cpu'] = builder_cfg['cpu_or_gpu_value'] | 72 #dimensions['cpu'] = builder_cfg['cpu_or_gpu_value'] |
| 73 else: # pragma: no cover | 73 else: # pragma: no cover |
| 74 dimensions['gpu'] = builder_cfg['cpu_or_gpu_value'] | 74 dimensions['gpu'] = builder_cfg['cpu_or_gpu_value'] |
| 75 else: | 75 else: |
| 76 dimensions['gpu'] = 'none' | 76 dimensions['gpu'] = 'none' |
| 77 return dimensions | 77 return dimensions |
| 78 | 78 |
| 79 | 79 |
| 80 def trigger_task(api, task_name, builder, builder_cfg, got_revision, | |
| 81 infrabots_dir, store_output=False, extra_isolate_hashes=None): | |
| 82 """Trigger the given bot to run as a Swarming task.""" | |
| 83 # TODO(borenet): We're using Swarming directly to run the recipe through | |
| 84 # Kitchen. Once it's possible to track the state of a Buildbucket build, | |
| 85 # we should switch to use the trigger recipe module instead. | |
| 86 | |
| 87 if not extra_isolate_hashes: | |
| 88 extra_isolate_hashes = [] | |
| 89 # Kitchen binaries. | |
| 90 extra_isolate_hashes.append('8ba778e47df2a9b46355cf72c58b58fdb1a7f350') | |
|
rmistry
2016/03/28 12:52:16
Document where you got this hash from?
| |
| 91 | |
| 92 properties = { | |
| 93 'buildername': builder, | |
| 94 'mastername': api.properties['mastername'], | |
| 95 'buildnumber': api.properties['buildnumber'], | |
| 96 'reason': 'Triggered by Skia swarm_trigger Recipe', | |
| 97 'revision': got_revision, | |
| 98 'slavename': api.properties['slavename'], | |
| 99 'swarm_out_dir': '${ISOLATED_OUTDIR}', | |
| 100 } | |
| 101 if builder_cfg['is_trybot']: | |
| 102 properties['issue'] = str(api.properties['issue']) | |
| 103 properties['patchset'] = str(api.properties['patchset']) | |
| 104 properties['rietveld'] = api.properties['rietveld'] | |
| 105 | |
| 106 idempotent = False | |
| 107 store_output = True | |
| 108 if task_name == 'compile': | |
| 109 idempotent = True | |
| 110 store_output = False | |
| 111 | |
| 112 extra_args = [ | |
| 113 'cook', | |
| 114 '-repository', 'https://chromium.googlesource.com/chromium/tools/build', | |
| 115 '-revision', '', | |
| 116 '-recipe', 'skia/swarm_%s' % task_name, | |
| 117 '-properties', json.dumps(properties), | |
| 118 '-workdir', '../../..', | |
| 119 ] | |
| 120 | |
| 121 isolate_base_dir = api.path['slave_build'] | |
| 122 dimensions = swarm_dimensions(builder_cfg) | |
| 123 isolate_blacklist = ['.git', 'out', '*.pyc'] | |
| 124 isolate_vars = {} | |
| 125 | |
| 126 return api.skia_swarming.isolate_and_trigger_task( | |
| 127 infrabots_dir.join('%s_skia.isolate' % task_name), | |
| 128 isolate_base_dir, | |
| 129 '%s_skia' % task_name, | |
| 130 isolate_vars, | |
| 131 dimensions, | |
| 132 isolate_blacklist=isolate_blacklist, | |
| 133 extra_isolate_hashes=extra_isolate_hashes, | |
| 134 idempotent=idempotent, | |
| 135 store_output=store_output, | |
| 136 extra_args=extra_args) | |
| 137 | |
| 138 | |
| 80 def checkout_steps(api): | 139 def checkout_steps(api): |
| 81 """Run the steps to obtain a checkout of Skia.""" | 140 """Run the steps to obtain a checkout of Skia.""" |
| 82 gclient_cfg = api.gclient.make_config(CACHE_DIR=None) | 141 gclient_cfg = api.gclient.make_config(CACHE_DIR=None) |
| 83 skia = gclient_cfg.solutions.add() | 142 skia = gclient_cfg.solutions.add() |
| 84 skia.name = 'skia' | 143 skia.name = 'skia' |
| 85 skia.managed = False | 144 skia.managed = False |
| 86 skia.url = 'https://skia.googlesource.com/skia.git' | 145 skia.url = 'https://skia.googlesource.com/skia.git' |
| 87 skia.revision = api.properties.get('revision') or 'origin/master' | 146 skia.revision = api.properties.get('revision') or 'origin/master' |
| 88 api.skia.update_repo(skia) | 147 api.skia.update_repo(skia) |
| 89 | 148 |
| 90 # Run 'gclient sync'. | 149 # Run 'gclient sync'. |
| 91 gclient_cfg.got_revision_mapping['skia'] = 'got_revision' | 150 gclient_cfg.got_revision_mapping['skia'] = 'got_revision' |
| 92 gclient_cfg.target_os.add('llvm') | 151 gclient_cfg.target_os.add('llvm') |
| 93 update_step = api.gclient.checkout(gclient_config=gclient_cfg) | 152 update_step = api.gclient.checkout(gclient_config=gclient_cfg) |
| 94 | 153 |
| 95 got_revision = update_step.presentation.properties['got_revision'] | 154 got_revision = update_step.presentation.properties['got_revision'] |
| 96 api.tryserver.maybe_apply_issue() | 155 api.tryserver.maybe_apply_issue() |
| 97 return got_revision | 156 return got_revision |
| 98 | 157 |
| 99 | 158 |
| 100 def compile_steps_swarm(api, infrabots_dir, builder_cfg): | 159 def compile_steps_swarm(api, builder_cfg, got_revision, infrabots_dir): |
| 101 builder_name = derive_compile_bot_name(api.properties['buildername'], | 160 builder_name = derive_compile_bot_name(api.properties['buildername'], |
| 102 builder_cfg) | 161 builder_cfg) |
| 103 # Windows bots require a toolchain. | 162 # Windows bots require a toolchain. |
| 104 extra_hashes = None | 163 extra_hashes = None |
| 105 if 'Win' in builder_name: | 164 if 'Win' in builder_name: |
| 106 test_data = '''{ | 165 test_data = '''{ |
| 107 "2013": "705384d88f80da637eb367e5acc6f315c0e1db2f", | 166 "2013": "705384d88f80da637eb367e5acc6f315c0e1db2f", |
| 108 "2015": "38380d77eec9164e5818ae45e2915a6f22d60e85" | 167 "2015": "38380d77eec9164e5818ae45e2915a6f22d60e85" |
| 109 }''' | 168 }''' |
| 110 hash_file = infrabots_dir.join('win_toolchain_hash.json') | 169 hash_file = infrabots_dir.join('win_toolchain_hash.json') |
| 111 j = api.skia._readfile(hash_file, | 170 j = api.skia._readfile(hash_file, |
| 112 name='Read win_toolchain_hash.json', | 171 name='Read win_toolchain_hash.json', |
| 113 test_data=test_data).rstrip() | 172 test_data=test_data).rstrip() |
| 114 hashes = json.loads(j) | 173 hashes = json.loads(j) |
| 115 extra_hashes = [hashes['2013']] | 174 extra_hashes = [hashes['2013']] |
| 116 | 175 |
| 117 # Isolate the inputs and trigger the task. | 176 task = trigger_task( |
| 118 isolate_path = infrabots_dir.join('compile_skia.isolate') | 177 api, |
| 119 isolate_vars = {'BUILDER_NAME': builder_name} | 178 'compile', |
| 120 dimensions = swarm_dimensions(builder_cfg) | 179 builder_name, |
| 121 task = api.skia_swarming.isolate_and_trigger_task( | 180 builder_cfg, |
| 122 isolate_path, infrabots_dir, 'compile_skia', isolate_vars, | 181 got_revision, |
| 123 dimensions, idempotent=True, store_output=False, | 182 infrabots_dir, |
| 124 isolate_blacklist=['.git', 'out', '*.pyc'], | |
| 125 extra_isolate_hashes=extra_hashes) | 183 extra_isolate_hashes=extra_hashes) |
| 126 | 184 |
| 127 # Wait for compile to finish, record the results hash. | 185 # Wait for compile to finish, record the results hash. |
| 128 return api.skia_swarming.collect_swarming_task_isolate_hash(task) | 186 return api.skia_swarming.collect_swarming_task_isolate_hash(task) |
| 129 | 187 |
| 130 | 188 |
| 131 def download_images(api, infrabots_dir): | 189 def download_images(api, infrabots_dir): |
| 132 api.python('Download images', | 190 api.python('Download images', |
| 133 script=infrabots_dir.join('download_images.py'), | 191 script=infrabots_dir.join('download_images.py'), |
| 134 env=api.skia.gsutil_env('chromium-skia-gm.boto')) | 192 env=api.skia.gsutil_env('chromium-skia-gm.boto')) |
| 135 | 193 |
| 136 | 194 |
| 137 def download_skps(api, infrabots_dir): | 195 def download_skps(api, infrabots_dir): |
| 138 api.python('Download SKPs', | 196 api.python('Download SKPs', |
| 139 script=infrabots_dir.join('download_skps.py'), | 197 script=infrabots_dir.join('download_skps.py'), |
| 140 env=api.skia.gsutil_env('chromium-skia-gm.boto')) | 198 env=api.skia.gsutil_env('chromium-skia-gm.boto')) |
| 141 | 199 |
| 142 | 200 |
| 143 def perf_steps_trigger(api, infrabots_dir, compile_hash, dimensions, | 201 def perf_steps_trigger(api, builder_cfg, got_revision, infrabots_dir, |
| 144 got_revision, is_trybot): | 202 compile_hash): |
| 145 """Trigger perf tests via Swarming.""" | 203 """Trigger perf tests via Swarming.""" |
| 146 # Swarm the tests. | 204 return trigger_task( |
| 147 task_name = 'perf_skia' | 205 api, |
| 148 isolate_path = infrabots_dir.join('%s.isolate' % task_name) | 206 'perf', |
| 149 issue = str(api.properties['issue']) if is_trybot else '' | 207 api.properties['buildername'], |
| 150 patchset = str(api.properties['patchset']) if is_trybot else '' | 208 builder_cfg, |
| 151 isolate_vars = { | 209 got_revision, |
| 152 'MASTER_NAME': api.properties['mastername'], | 210 infrabots_dir, |
| 153 'BUILDER_NAME': api.properties['buildername'], | 211 extra_isolate_hashes=[compile_hash]) |
| 154 'BUILD_NUMBER': str(api.properties['buildnumber']), | |
| 155 'SLAVE_NAME': api.properties['slavename'], | |
| 156 'REVISION': got_revision, | |
| 157 'ISSUE': issue, | |
| 158 'PATCHSET': patchset, | |
| 159 } | |
| 160 return api.skia_swarming.isolate_and_trigger_task( | |
| 161 isolate_path, infrabots_dir, task_name, isolate_vars, dimensions, | |
| 162 isolate_blacklist=['.git'], extra_isolate_hashes=[compile_hash]) | |
| 163 | 212 |
| 164 | 213 |
| 165 def perf_steps_collect(api, task, upload_perf_results, got_revision, | 214 def perf_steps_collect(api, task, upload_perf_results, got_revision, |
| 166 is_trybot): | 215 is_trybot): |
| 167 """Wait for perf steps to finish and upload results.""" | 216 """Wait for perf steps to finish and upload results.""" |
| 168 # Wait for nanobench to finish, download the results. | 217 # Wait for nanobench to finish, download the results. |
| 169 api.file.rmtree('results_dir', task.task_output_dir, infra_step=True) | 218 api.file.rmtree('results_dir', task.task_output_dir, infra_step=True) |
| 170 api.skia_swarming.collect_swarming_task(task) | 219 api.skia_swarming.collect_swarming_task(task) |
| 171 | 220 |
| 172 # Upload the results. | 221 # Upload the results. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 193 upload_args.append(api.properties['issue']) | 242 upload_args.append(api.properties['issue']) |
| 194 api.python( | 243 api.python( |
| 195 'Upload perf results', | 244 'Upload perf results', |
| 196 script=api.skia.resource('upload_bench_results.py'), | 245 script=api.skia.resource('upload_bench_results.py'), |
| 197 args=upload_args, | 246 args=upload_args, |
| 198 cwd=api.path['checkout'], | 247 cwd=api.path['checkout'], |
| 199 env=api.skia.gsutil_env('chromium-skia-gm.boto'), | 248 env=api.skia.gsutil_env('chromium-skia-gm.boto'), |
| 200 infra_step=True) | 249 infra_step=True) |
| 201 | 250 |
| 202 | 251 |
| 203 def test_steps_trigger(api, infrabots_dir, compile_hash, dimensions, | 252 def test_steps_trigger(api, builder_cfg, got_revision, infrabots_dir, |
| 204 got_revision, is_trybot): | 253 compile_hash): |
| 205 """Trigger DM via Swarming.""" | 254 """Trigger DM via Swarming.""" |
| 206 # Swarm the tests. | 255 return trigger_task( |
| 207 task_name = 'test_skia' | 256 api, |
| 208 isolate_path = infrabots_dir.join('%s.isolate' % task_name) | 257 'test', |
| 209 issue = str(api.properties['issue']) if is_trybot else '' | 258 api.properties['buildername'], |
| 210 patchset = str(api.properties['patchset']) if is_trybot else '' | 259 builder_cfg, |
| 211 isolate_vars = { | 260 got_revision, |
| 212 'MASTER_NAME': api.properties['mastername'], | 261 infrabots_dir, |
| 213 'BUILDER_NAME': api.properties['buildername'], | 262 extra_isolate_hashes=[compile_hash]) |
| 214 'BUILD_NUMBER': str(api.properties['buildnumber']), | |
| 215 'SLAVE_NAME': api.properties['slavename'], | |
| 216 'REVISION': got_revision, | |
| 217 'ISSUE': issue, | |
| 218 'PATCHSET': patchset, | |
| 219 } | |
| 220 | |
| 221 return api.skia_swarming.isolate_and_trigger_task( | |
| 222 isolate_path, infrabots_dir, task_name, isolate_vars, dimensions, | |
| 223 isolate_blacklist=['.git'], extra_isolate_hashes=[compile_hash]) | |
| 224 | 263 |
| 225 | 264 |
| 226 def test_steps_collect(api, task, upload_dm_results, got_revision, is_trybot): | 265 def test_steps_collect(api, task, upload_dm_results, got_revision, is_trybot): |
| 227 """Collect the DM results from Swarming.""" | 266 """Collect the DM results from Swarming.""" |
| 228 # Wait for tests to finish, download the results. | 267 # Wait for tests to finish, download the results. |
| 229 api.file.rmtree('results_dir', task.task_output_dir, infra_step=True) | 268 api.file.rmtree('results_dir', task.task_output_dir, infra_step=True) |
| 230 api.skia_swarming.collect_swarming_task(task) | 269 api.skia_swarming.collect_swarming_task(task) |
| 231 | 270 |
| 232 # Upload the results. | 271 # Upload the results. |
| 233 if upload_dm_results: | 272 if upload_dm_results: |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 257 got_revision = checkout_steps(api) | 296 got_revision = checkout_steps(api) |
| 258 builder_spec = api.skia.get_builder_spec(api.path['checkout'], | 297 builder_spec = api.skia.get_builder_spec(api.path['checkout'], |
| 259 api.properties['buildername']) | 298 api.properties['buildername']) |
| 260 builder_cfg = builder_spec['builder_cfg'] | 299 builder_cfg = builder_spec['builder_cfg'] |
| 261 infrabots_dir = api.path['checkout'].join('infra', 'bots') | 300 infrabots_dir = api.path['checkout'].join('infra', 'bots') |
| 262 | 301 |
| 263 api.skia_swarming.setup( | 302 api.skia_swarming.setup( |
| 264 api.path['checkout'].join('infra', 'bots', 'tools', 'luci-go'), | 303 api.path['checkout'].join('infra', 'bots', 'tools', 'luci-go'), |
| 265 swarming_rev='') | 304 swarming_rev='') |
| 266 | 305 |
| 267 compile_hash = compile_steps_swarm(api, infrabots_dir, builder_cfg) | 306 compile_hash = compile_steps_swarm(api, builder_cfg, got_revision, |
| 307 infrabots_dir) | |
| 268 | 308 |
| 269 do_test_steps = builder_spec['do_test_steps'] | 309 do_test_steps = builder_spec['do_test_steps'] |
| 270 do_perf_steps = builder_spec['do_perf_steps'] | 310 do_perf_steps = builder_spec['do_perf_steps'] |
| 271 is_trybot = builder_cfg['is_trybot'] | |
| 272 | 311 |
| 273 if not (do_test_steps or do_perf_steps): | 312 if not (do_test_steps or do_perf_steps): |
| 274 return | 313 return |
| 275 | 314 |
| 276 download_skps(api, infrabots_dir) | 315 download_skps(api, infrabots_dir) |
| 277 download_images(api, infrabots_dir) | 316 download_images(api, infrabots_dir) |
| 278 | 317 |
| 279 dimensions = swarm_dimensions(builder_cfg) | 318 dimensions = swarm_dimensions(builder_cfg) |
| 280 | 319 |
| 281 test_task = None | 320 test_task = None |
| 282 perf_task = None | 321 perf_task = None |
| 283 if do_test_steps: | 322 if do_test_steps: |
| 284 test_task = test_steps_trigger(api, infrabots_dir, compile_hash, dimensions, | 323 test_task = test_steps_trigger(api, builder_cfg, got_revision, |
| 285 got_revision, is_trybot) | 324 infrabots_dir, compile_hash) |
| 286 if do_perf_steps: | 325 if do_perf_steps: |
| 287 perf_task = perf_steps_trigger(api, infrabots_dir, compile_hash, dimensions, | 326 perf_task = perf_steps_trigger(api, builder_cfg, got_revision, |
| 288 got_revision, is_trybot) | 327 infrabots_dir, compile_hash) |
| 328 is_trybot = builder_cfg['is_trybot'] | |
| 289 if test_task: | 329 if test_task: |
| 290 test_steps_collect(api, test_task, builder_spec['upload_dm_results'], | 330 test_steps_collect(api, test_task, builder_spec['upload_dm_results'], |
| 291 got_revision, is_trybot) | 331 got_revision, is_trybot) |
| 292 if perf_task: | 332 if perf_task: |
| 293 perf_steps_collect(api, perf_task, builder_spec['upload_perf_results'], | 333 perf_steps_collect(api, perf_task, builder_spec['upload_perf_results'], |
| 294 got_revision, is_trybot) | 334 got_revision, is_trybot) |
| 295 | 335 |
| 296 | 336 |
| 297 def GenTests(api): | 337 def GenTests(api): |
| 298 for mastername, slaves in TEST_BUILDERS.iteritems(): | 338 for mastername, slaves in TEST_BUILDERS.iteritems(): |
| 299 for slavename, builders_by_slave in slaves.iteritems(): | 339 for slavename, builders_by_slave in slaves.iteritems(): |
| 300 for builder in builders_by_slave: | 340 for builder in builders_by_slave: |
| 301 test = ( | 341 test = ( |
| 302 api.test(builder) + | 342 api.test(builder) + |
| 303 api.properties(buildername=builder, | 343 api.properties(buildername=builder, |
| 304 mastername=mastername, | 344 mastername=mastername, |
| 305 slavename=slavename, | 345 slavename=slavename, |
| 306 buildnumber=5, | 346 buildnumber=5, |
| 307 revision='abc123') + | 347 revision='abc123') + |
| 308 api.path.exists( | 348 api.path.exists( |
| 309 api.path['slave_build'].join('skia'), | 349 api.path['slave_build'].join('skia'), |
| 310 api.path['slave_build'].join('tmp', 'uninteresting_hashes.txt') | 350 api.path['slave_build'].join('tmp', 'uninteresting_hashes.txt') |
| 311 ) | 351 ) |
| 312 ) | 352 ) |
| 313 if 'Trybot' in builder: | 353 if 'Trybot' in builder: |
| 314 test += api.properties(issue=500, | 354 test += api.properties(issue=500, |
| 315 patchset=1, | 355 patchset=1, |
| 316 rietveld='https://codereview.chromium.org') | 356 rietveld='https://codereview.chromium.org') |
| 317 if 'Win' in builder: | 357 test += api.step_data( |
| 318 test += api.step_data( | 358 'upload new .isolated file for compile_skia', |
| 319 'upload new .isolated file for compile_skia', | 359 stdout=api.raw_io.output('def456 XYZ.isolated')) |
| 320 stdout=api.raw_io.output('def456 XYZ.isolated')) | |
| 321 if 'Test' in builder: | 360 if 'Test' in builder: |
| 322 test += api.step_data( | 361 test += api.step_data( |
| 323 'upload new .isolated file for test_skia', | 362 'upload new .isolated file for test_skia', |
| 324 stdout=api.raw_io.output('def456 XYZ.isolated')) | 363 stdout=api.raw_io.output('def456 XYZ.isolated')) |
| 325 if ('Test' in builder and 'Debug' in builder) or 'Perf' in builder: | 364 if ('Test' in builder and 'Debug' in builder) or 'Perf' in builder: |
| 326 test += api.step_data( | 365 test += api.step_data( |
| 327 'upload new .isolated file for perf_skia', | 366 'upload new .isolated file for perf_skia', |
| 328 stdout=api.raw_io.output('def456 XYZ.isolated')) | 367 stdout=api.raw_io.output('def456 XYZ.isolated')) |
| 329 | 368 |
| 330 yield test | 369 yield test |
| OLD | NEW |