1# Copyright 2014 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 6# TODO(borenet): This module was copied from build.git and heavily modified to 7# remove dependencies on other modules in build.git. It belongs in a different 8# repo. Remove this once it has been moved. 9 10 11import json 12 13DEPS = [ 14 'isolate', 15 'recipe_engine/file', 16 'recipe_engine/json', 17 'recipe_engine/path', 18 'recipe_engine/properties', 19 'recipe_engine/python', 20 'recipe_engine/raw_io', 21 'recipe_engine/step', 22 'swarming', 23 'swarming_client', 24] 25 26from recipe_engine.recipe_api import Property 27 28PROPERTIES = { 29 'platforms': Property(default=('win',)), 30 'show_isolated_out_in_collect_step': Property(default=True), 31 'show_shards_in_collect_step': Property(default=False), 32 'gtest_task': Property(default=False), 33 #'isolated_script_task': Property(default=False), 34 'merge': Property(default=None), 35} 36 37def RunSteps(api, platforms, show_isolated_out_in_collect_step, 38 show_shards_in_collect_step, gtest_task, merge): 39 # Checkout swarming client. 40 api.swarming_client.checkout('master') 41 42 # Ensure swarming_client version is fresh enough. 43 api.swarming.check_client_version(step_test_data=(0, 8, 6)) 44 45 # Configure isolate & swarming modules (this is optional). 46 api.isolate.isolate_server = 'https://isolateserver-dev.appspot.com' 47 api.swarming.swarming_server = 'https://chromium-swarm-dev.appspot.com' 48 api.swarming.add_default_tag('master:tryserver') 49 api.swarming.default_expiration = 60*60 50 api.swarming.default_hard_timeout = 60*60 51 api.swarming.default_io_timeout = 20*60 52 api.swarming.default_idempotent = True 53 api.swarming.default_priority = 30 54 api.swarming.default_user = 'joe' 55 api.swarming.set_default_env('TESTING', '1') 56 api.swarming.verbose = True 57 58 api.swarming.set_default_dimension('inexistent', None) 59 60 api.swarming.show_shards_in_collect_step = show_shards_in_collect_step 61 api.swarming.show_isolated_out_in_collect_step = ( 62 show_isolated_out_in_collect_step) 63 64 try: 65 # Testing ReadOnlyDict.__setattr__() coverage. 66 api.swarming.default_dimensions['invalid'] = 'foo' 67 except TypeError: 68 pass 69 try: 70 api.swarming.default_env['invalid'] = 'foo' 71 except TypeError: 72 pass 73 74 # Create a temp dir to put *.isolated files into. 75 temp_dir = api.path.mkdtemp('hello_isolated_world') 76 77 # Prepare a bunch of swarming tasks to run hello_world on multiple platforms. 78 tasks = [] 79 for platform in platforms: 80 # Isolate example hello_world.isolate from swarming client repo. 81 # TODO(vadimsh): Add a thin wrapper around isolate.py to 'isolate' module? 82 step_result = api.python( 83 'archive for %s' % platform, 84 api.swarming_client.path.join('isolate.py'), 85 [ 86 'archive', 87 '--isolate', api.swarming_client.path.join( 88 'example', 'payload', 'hello_world.isolate'), 89 '--isolated', temp_dir.join('hello_world.isolated'), 90 '--isolate-server', api.isolate.isolate_server, 91 '--config-variable', 'OS', platform, 92 '--verbose', 93 ], stdout=api.raw_io.output_text()) 94 # TODO(vadimsh): Pass result from isolate.py though --output-json option. 95 isolated_hash = step_result.stdout.split()[0].strip() 96 97 # Create a task to run the isolated file on swarming, set OS dimension. 98 # Also generate code coverage for multi-shard case by triggering multiple 99 # shards on Linux. 100 task = api.swarming.task('hello_world', isolated_hash, 101 task_output_dir=temp_dir.join('task_output_dir')) 102 task.dimensions['os'] = api.swarming.prefered_os_dimension(platform) 103 task.shards = 2 if platform == 'linux' else 1 104 task.tags.add('os:' + platform) 105 if api.swarming_client.get_script_version('swarming.py') >= (0, 8, 6): 106 task.cipd_packages = [ 107 ('bin', 'super/awesome/pkg', 'git_revision:deadbeef')] 108 tasks.append(task) 109 110 # Launch all tasks. 111 for task in tasks: 112 step_result = api.swarming.trigger_task(task) 113 assert step_result.swarming_task in tasks 114 115 # Recipe can do something useful here locally while tasks are 116 # running on swarming. 117 api.step('local step', ['echo', 'running something locally']) 118 119 # Wait for all tasks to complete. 120 for task in tasks: 121 step_result = api.swarming.collect_task(task) 122 data = step_result.swarming.summary 123 124 state = data['shards'][0]['state'] 125 if api.swarming.State.COMPLETED == state: 126 state_name = api.swarming.State.to_string(state) 127 assert 'Completed' == state_name, state_name 128 assert step_result.swarming_task in tasks 129 130 # Cleanup. 131 api.file.rmtree('remove temp dir', temp_dir) 132 133 134def GenTests(api): 135 yield ( 136 api.test('basic') + 137 api.step_data( 138 'archive for win', 139 stdout=api.raw_io.output_text('hash_for_win hello_world.isolated')) + 140 api.step_data( 141 'archive for linux', 142 stdout=api.raw_io.output_text( 143 'hash_for_linux hello_world.isolated')) + 144 api.step_data( 145 'archive for mac', 146 stdout=api.raw_io.output_text('hash_for_mac hello_world.isolated')) + 147 api.properties(platforms=('win', 'linux', 'mac'))) 148 149 yield ( 150 api.test('trybot') + 151 api.step_data( 152 'archive for win', 153 stdout=api.raw_io.output_text('hash_for_win hello_world.isolated')) + 154 api.properties( 155 rietveld='https://codereview.chromium.org', 156 issue='123', 157 patchset='1001')) 158 159 yield ( 160 api.test('show_shards_in_collect_step') + 161 api.step_data( 162 'archive for win', 163 stdout=api.raw_io.output_text('hash_for_win hello_world.isolated')) + 164 api.properties( 165 rietveld='https://codereview.chromium.org', 166 issue='123', 167 patchset='1001', 168 show_shards_in_collect_step=True)) 169 170 yield ( 171 api.test('show_isolated_out_in_collect_step') + 172 api.step_data( 173 'archive for win', 174 stdout=api.raw_io.output_text('hash_for_win hello_world.isolated')) + 175 api.properties( 176 rietveld='https://codereview.chromium.org', 177 issue='123', 178 patchset='1001', 179 show_isolated_out_in_collect_step=False)) 180 181 data = { 182 'shards': [ 183 { 184 '': '', 185 } 186 ] 187 } 188 189 data = { 190 'shards': [ 191 { 192 'abandoned_ts': '2014-09-25T01:41:00.123', 193 'bot_id': 'vm30', 194 'completed_ts': None, 195 'created_ts': '2014-09-25T01:41:00.123', 196 'durations': None, 197 'exit_codes': [], 198 'failure': False, 199 'id': '148aa78d7aa0100', 200 'internal_failure': False, 201 'isolated_out': None, 202 'modified_ts': '2014-09-25 01:42:00', 203 'name': 'heartbeat-canary-2014-09-25_01:41:55-os=Windows', 204 'outputs': [], 205 'started_ts': '2014-09-25T01:42:11.123', 206 'state': 0x30, # EXPIRED (old) 207 'try_number': None, 208 'user': 'unknown', 209 } 210 ], 211 } 212 213 yield ( 214 api.test('swarming_expired_old') + 215 api.step_data( 216 'archive for win', 217 stdout=api.raw_io.output_text('hash_for_win hello_world.isolated')) + 218 api.step_data('hello_world on Windows-7-SP1', api.swarming.summary(data))) 219 220 data['shards'][0]['state'] = 'EXPIRED' 221 yield ( 222 api.test('swarming_expired_new') + 223 api.step_data( 224 'archive for win', 225 stdout=api.raw_io.output_text('hash_for_win hello_world.isolated')) + 226 api.step_data('hello_world on Windows-7-SP1', api.swarming.summary(data))) 227 228 data['shards'][0]['state'] = 0x40 # TIMED_OUT (old) 229 yield ( 230 api.test('swarming_timeout_old') + 231 api.step_data( 232 'archive for win', 233 stdout=api.raw_io.output_text('hash_for_win hello_world.isolated')) + 234 api.step_data('hello_world on Windows-7-SP1', api.swarming.summary(data))) 235 236 data['shards'][0]['state'] = 'TIMED_OUT' # TIMED_OUT (old) 237 yield ( 238 api.test('swarming_timeout_new') + 239 api.step_data( 240 'archive for win', 241 stdout=api.raw_io.output_text('hash_for_win hello_world.isolated')) + 242 api.step_data('hello_world on Windows-7-SP1', api.swarming.summary(data))) 243