| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 import ast | 5 import ast |
| 6 import collections | 6 import collections |
| 7 import contextlib | 7 import contextlib |
| 8 import copy | 8 import copy |
| 9 import itertools | 9 import itertools |
| 10 import json | 10 import json |
| 11 | 11 |
| 12 from recipe_engine.types import freeze | 12 from recipe_engine.types import freeze |
| 13 from recipe_engine import recipe_api | 13 from recipe_engine import recipe_api |
| 14 from recipe_engine import util as recipe_util | 14 from recipe_engine import util as recipe_util |
| 15 | 15 |
| 16 from . import bot_config_and_test_db as bdb_module |
| 16 from . import builders | 17 from . import builders |
| 17 from . import steps | 18 from . import steps |
| 18 from . import trybots | 19 from . import trybots |
| 19 | 20 |
| 20 | 21 |
| 21 MB_CONFIG_FILENAME = ['tools', 'mb', 'mb_config.pyl'] | 22 MB_CONFIG_FILENAME = ['tools', 'mb', 'mb_config.pyl'] |
| 22 | 23 |
| 23 | 24 |
| 24 # Paths which affect recipe config and behavior in a way that survives | 25 # Paths which affect recipe config and behavior in a way that survives |
| 25 # deapplying user's patch. | 26 # deapplying user's patch. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 return steps | 62 return steps |
| 62 | 63 |
| 63 @property | 64 @property |
| 64 def trybots(self): | 65 def trybots(self): |
| 65 return trybots.TRYBOTS | 66 return trybots.TRYBOTS |
| 66 | 67 |
| 67 def add_builders(self, builders): | 68 def add_builders(self, builders): |
| 68 """Adds builders to our builder map""" | 69 """Adds builders to our builder map""" |
| 69 self._builders.update(builders) | 70 self._builders.update(builders) |
| 70 | 71 |
| 71 def get_bot_config(self, mastername, buildername): | 72 def _get_bot_config(self, mastername, buildername): |
| 72 master_dict = self.builders.get(mastername, {}) | 73 master_dict = self.builders.get(mastername, {}) |
| 73 return freeze(master_dict.get('builders', {}).get(buildername)) | 74 return freeze(master_dict.get('builders', {}).get(buildername)) |
| 74 | 75 |
| 75 def configure_build(self, mastername, buildername, override_bot_type=None): | 76 def configure_build(self, mastername, buildername, override_bot_type=None): |
| 76 master_dict = self.builders.get(mastername, {}) | 77 master_dict = self.builders.get(mastername, {}) |
| 77 bot_config = master_dict.get('builders', {}).get(buildername) | 78 bot_config = master_dict.get('builders', {}).get(buildername) |
| 78 | 79 |
| 79 # Get the buildspec version. It can be supplied as a build property or as | 80 # Get the buildspec version. It can be supplied as a build property or as |
| 80 # a recipe config value. | 81 # a recipe config value. |
| 81 buildspec_version = (self.m.properties.get('buildspec_version') or | 82 buildspec_version = (self.m.properties.get('buildspec_version') or |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 # builds to match also the chromium revision from the builder. | 135 # builds to match also the chromium revision from the builder. |
| 135 component_rev = self.m.properties.get('revision') or 'HEAD' | 136 component_rev = self.m.properties.get('revision') or 'HEAD' |
| 136 if bot_type == 'tester': | 137 if bot_type == 'tester': |
| 137 component_rev = self.m.properties.get( | 138 component_rev = self.m.properties.get( |
| 138 'parent_got_revision', component_rev) | 139 'parent_got_revision', component_rev) |
| 139 dep = bot_config.get('set_component_rev') | 140 dep = bot_config.get('set_component_rev') |
| 140 self.m.gclient.c.revisions[dep['name']] = dep['rev_str'] % component_rev | 141 self.m.gclient.c.revisions[dep['name']] = dep['rev_str'] % component_rev |
| 141 | 142 |
| 142 def ensure_checkout(self, mastername, buildername, | 143 def ensure_checkout(self, mastername, buildername, |
| 143 root_solution_revision=None): | 144 root_solution_revision=None): |
| 144 bot_config = self.get_bot_config(mastername, buildername) | 145 bot_config = self._get_bot_config(mastername, buildername) |
| 145 | 146 |
| 146 if self.m.platform.is_win: | 147 if self.m.platform.is_win: |
| 147 self.m.chromium.taskkill() | 148 self.m.chromium.taskkill() |
| 148 | 149 |
| 149 # Bot Update re-uses the gclient configs. | 150 # Bot Update re-uses the gclient configs. |
| 150 update_step = self.m.bot_update.ensure_checkout( | 151 update_step = self.m.bot_update.ensure_checkout( |
| 151 patch_root=bot_config.get('patch_root'), | 152 patch_root=bot_config.get('patch_root'), |
| 152 root_solution_revision=root_solution_revision, | 153 root_solution_revision=root_solution_revision, |
| 153 clobber=bot_config.get('clobber', False)) | 154 clobber=bot_config.get('clobber', False)) |
| 154 assert update_step.json.output['did_run'] | 155 assert update_step.json.output['did_run'] |
| 155 # HACK(dnj): Remove after 'crbug.com/398105' has landed | 156 # HACK(dnj): Remove after 'crbug.com/398105' has landed |
| 156 self.m.chromium.set_build_properties(update_step.json.output['properties']) | 157 self.m.chromium.set_build_properties(update_step.json.output['properties']) |
| 157 | 158 |
| 158 return update_step | 159 return update_step |
| 159 | 160 |
| 160 def set_up_swarming(self, mastername, buildername): | 161 def set_up_swarming(self, mastername, buildername): |
| 161 bot_config = self.get_bot_config(mastername, buildername) | 162 bot_config = self._get_bot_config(mastername, buildername) |
| 162 | 163 |
| 163 enable_swarming = bot_config.get('enable_swarming') | 164 enable_swarming = bot_config.get('enable_swarming') |
| 164 if enable_swarming: | 165 if enable_swarming: |
| 165 self.m.isolate.set_isolate_environment(self.m.chromium.c) | 166 self.m.isolate.set_isolate_environment(self.m.chromium.c) |
| 166 self.m.swarming.check_client_version() | 167 self.m.swarming.check_client_version() |
| 167 for key, value in bot_config.get('swarming_dimensions', {}).iteritems(): | 168 for key, value in bot_config.get('swarming_dimensions', {}).iteritems(): |
| 168 self.m.swarming.set_default_dimension(key, value) | 169 self.m.swarming.set_default_dimension(key, value) |
| 169 | 170 |
| 170 def runhooks(self, update_step): | 171 def runhooks(self, update_step): |
| 171 if self.m.tryserver.is_tryserver: | 172 if self.m.tryserver.is_tryserver: |
| 172 try: | 173 try: |
| 173 self.m.chromium.runhooks(name='runhooks (with patch)') | 174 self.m.chromium.runhooks(name='runhooks (with patch)') |
| 174 except self.m.step.StepFailure: | 175 except self.m.step.StepFailure: |
| 175 # As part of deapplying patch we call runhooks without the patch. | 176 # As part of deapplying patch we call runhooks without the patch. |
| 176 self.deapply_patch(update_step) | 177 self.deapply_patch(update_step) |
| 177 raise | 178 raise |
| 178 else: | 179 else: |
| 179 self.m.chromium.runhooks() | 180 self.m.chromium.runhooks() |
| 180 | 181 |
| 181 def get_test_spec(self, mastername, buildername): | 182 def get_test_spec(self, mastername, buildername): |
| 182 bot_config = self.get_bot_config(mastername, buildername) | 183 bot_config = self._get_bot_config(mastername, buildername) |
| 183 | 184 |
| 184 test_spec_file = bot_config.get('testing', {}).get( | 185 test_spec_file = bot_config.get('testing', {}).get( |
| 185 'test_spec_file', '%s.json' % mastername) | 186 'test_spec_file', '%s.json' % mastername) |
| 186 | 187 |
| 187 # TODO(phajdan.jr): Bots should have no generators instead. | 188 # TODO(phajdan.jr): Bots should have no generators instead. |
| 188 if bot_config.get('disable_tests'): | 189 if bot_config.get('disable_tests'): |
| 189 return {} | 190 return {} |
| 190 return self.read_test_spec(self.m, test_spec_file) | 191 return self.read_test_spec(self.m, test_spec_file) |
| 191 | 192 |
| 192 def get_master_dict_with_dynamic_tests( | 193 def _get_master_dict_with_dynamic_tests( |
| 193 self, mastername, buildername, test_spec, scripts_compile_targets): | 194 self, mastername, buildername, test_spec, scripts_compile_targets): |
| 194 # We manually thaw the path to the elements we are modifying, since the | 195 # We manually thaw the path to the elements we are modifying, since the |
| 195 # builders are frozen. | 196 # builders are frozen. |
| 196 master_dict = dict(self.builders[mastername]) | 197 master_dict = dict(self.builders[mastername]) |
| 197 builders = master_dict['builders'] = dict(master_dict['builders']) | 198 builders = master_dict['builders'] = dict(master_dict['builders']) |
| 198 bot_config = builders[buildername] | 199 bot_config = builders[buildername] |
| 199 for loop_buildername in builders: | 200 for loop_buildername in builders: |
| 200 builder_dict = builders[loop_buildername] = ( | 201 builder_dict = builders[loop_buildername] = ( |
| 201 dict(builders[loop_buildername])) | 202 dict(builders[loop_buildername])) |
| 202 builders[loop_buildername]['tests'] = ( | 203 builders[loop_buildername]['tests'] = ( |
| 203 self.generate_tests_from_test_spec( | 204 self.generate_tests_from_test_spec( |
| 204 self.m, test_spec, builder_dict, loop_buildername, mastername, | 205 self.m, test_spec, builder_dict, loop_buildername, mastername, |
| 205 # TODO(phajdan.jr): Get enable_swarming value from builder_dict. | 206 # TODO(phajdan.jr): Get enable_swarming value from builder_dict. |
| 206 # Above should remove the need to get bot_config and buildername | 207 # Above should remove the need to get bot_config and buildername |
| 207 # in this method. | 208 # in this method. |
| 208 bot_config.get('enable_swarming', False), | 209 bot_config.get('enable_swarming', False), |
| 209 scripts_compile_targets, builder_dict.get('test_generators', []) | 210 scripts_compile_targets, builder_dict.get('test_generators', []) |
| 210 )) | 211 )) |
| 211 | 212 |
| 212 return freeze(master_dict) | 213 return freeze(master_dict) |
| 213 | 214 |
| 215 def create_bot_db_from_master_dict(self, mastername, master_dict): |
| 216 bot_db = bdb_module.BotConfigAndTestDB() |
| 217 bot_db._add_master_dict_and_test_spec(mastername, master_dict, {}) |
| 218 return bot_db |
| 219 |
| 214 def prepare_checkout(self, mastername, buildername, | 220 def prepare_checkout(self, mastername, buildername, |
| 215 root_solution_revision=None): | 221 root_solution_revision=None): |
| 216 bot_config = self.get_bot_config(mastername, buildername) | 222 bot_config = self._get_bot_config(mastername, buildername) |
| 217 | 223 |
| 218 update_step = self.ensure_checkout(mastername, buildername, | 224 update_step = self.ensure_checkout(mastername, buildername, |
| 219 root_solution_revision) | 225 root_solution_revision) |
| 220 # TODO(robertocn): Remove this hack by the end of Q1/2016. | 226 # TODO(robertocn): Remove this hack by the end of Q1/2016. |
| 221 if (mastername == 'tryserver.chromium.perf' | 227 if (mastername == 'tryserver.chromium.perf' |
| 222 and bot_config.get('bot_type') == 'builder' | 228 and bot_config.get('bot_type') == 'builder' |
| 223 and buildername.endswith('builder')): | 229 and buildername.endswith('builder')): |
| 224 force_legacy_compile = self.should_force_legacy_compiling( | 230 force_legacy_compile = self.should_force_legacy_compiling( |
| 225 mastername, buildername) | 231 mastername, buildername) |
| 226 if force_legacy_compile: | 232 if force_legacy_compile: |
| 227 self.m.chromium.c.project_generator.tool = 'gyp' | 233 self.m.chromium.c.project_generator.tool = 'gyp' |
| 228 | 234 |
| 229 self.set_up_swarming(mastername, buildername) | 235 self.set_up_swarming(mastername, buildername) |
| 230 self.runhooks(update_step) | 236 self.runhooks(update_step) |
| 231 | 237 |
| 232 test_spec = self.get_test_spec(mastername, buildername) | 238 test_spec = self.get_test_spec(mastername, buildername) |
| 233 | 239 |
| 234 # TODO(phajdan.jr): Bots should have no generators instead. | 240 # TODO(phajdan.jr): Bots should have no generators instead. |
| 235 if bot_config.get('disable_tests'): | 241 if bot_config.get('disable_tests'): |
| 236 scripts_compile_targets = {} | 242 scripts_compile_targets = {} |
| 237 else: | 243 else: |
| 238 scripts_compile_targets = \ | 244 scripts_compile_targets = \ |
| 239 self.get_compile_targets_for_scripts().json.output | 245 self.get_compile_targets_for_scripts().json.output |
| 240 | 246 |
| 241 master_dict = self.get_master_dict_with_dynamic_tests( | 247 master_dict = self._get_master_dict_with_dynamic_tests( |
| 242 mastername, buildername, test_spec, scripts_compile_targets) | 248 mastername, buildername, test_spec, scripts_compile_targets) |
| 243 | 249 |
| 244 if self.m.chromium.c.lto and \ | 250 if self.m.chromium.c.lto and \ |
| 245 not self.m.chromium.c.env.LLVM_FORCE_HEAD_REVISION: | 251 not self.m.chromium.c.env.LLVM_FORCE_HEAD_REVISION: |
| 246 self.m.chromium.download_lto_plugin() | 252 self.m.chromium.download_lto_plugin() |
| 247 | 253 |
| 248 return update_step, master_dict, test_spec | 254 bot_db = bdb_module.BotConfigAndTestDB() |
| 255 bot_db._add_master_dict_and_test_spec(mastername, master_dict, test_spec) |
| 256 |
| 257 return update_step, bot_db |
| 249 | 258 |
| 250 def generate_tests_from_test_spec(self, api, test_spec, builder_dict, | 259 def generate_tests_from_test_spec(self, api, test_spec, builder_dict, |
| 251 buildername, mastername, enable_swarming, scripts_compile_targets, | 260 buildername, mastername, enable_swarming, scripts_compile_targets, |
| 252 generators): | 261 generators): |
| 253 tests = builder_dict.get('tests', ()) | 262 tests = builder_dict.get('tests', ()) |
| 254 # TODO(phajdan.jr): Switch everything to scripts generators and simplify. | 263 # TODO(phajdan.jr): Switch everything to scripts generators and simplify. |
| 255 for generator in generators: | 264 for generator in generators: |
| 256 tests = ( | 265 tests = ( |
| 257 tuple(generator(api, mastername, buildername, test_spec, | 266 tuple(generator(api, mastername, buildername, test_spec, |
| 258 enable_swarming=enable_swarming, | 267 enable_swarming=enable_swarming, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 raise | 325 raise |
| 317 | 326 |
| 318 if failed_tests: | 327 if failed_tests: |
| 319 failed_tests_names = [t.name for t in failed_tests] | 328 failed_tests_names = [t.name for t in failed_tests] |
| 320 raise self.m.step.StepFailure( | 329 raise self.m.step.StepFailure( |
| 321 '%d tests failed: %r' % (len(failed_tests), failed_tests_names)) | 330 '%d tests failed: %r' % (len(failed_tests), failed_tests_names)) |
| 322 | 331 |
| 323 return test_runner | 332 return test_runner |
| 324 | 333 |
| 325 def get_compile_targets_and_tests( | 334 def get_compile_targets_and_tests( |
| 326 self, mastername, buildername, master_dict, test_spec, | 335 self, mastername, buildername, bot_db, |
| 327 override_bot_type=None, override_tests=None): | 336 override_bot_type=None, override_tests=None): |
| 328 """Returns a tuple: list of compile targets and list of tests. | 337 """Returns a tuple: list of compile targets and list of tests. |
| 329 | 338 |
| 330 The list of tests includes ones on the triggered testers.""" | 339 The list of tests includes ones on the triggered testers.""" |
| 331 | 340 |
| 332 bot_config = master_dict.get('builders', {}).get(buildername) | 341 assert isinstance(bot_db, bdb_module.BotConfigAndTestDB), \ |
| 342 "bot_db argument %r was not a BotConfigAndTestDB" % (bot_db) |
| 343 bot_config = bot_db.get_bot_config(mastername, buildername) |
| 333 bot_type = override_bot_type or bot_config.get('bot_type', 'builder_tester') | 344 bot_type = override_bot_type or bot_config.get('bot_type', 'builder_tester') |
| 334 | 345 |
| 335 tests = [copy.deepcopy(t) for t in bot_config.get('tests', [])] | 346 tests = [copy.deepcopy(t) for t in bot_config.get('tests', [])] |
| 336 if override_tests is not None: | 347 if override_tests is not None: |
| 337 tests = override_tests | 348 tests = override_tests |
| 338 | 349 |
| 339 if bot_type not in ['builder', 'builder_tester']: | 350 if bot_type not in ['builder', 'builder_tester']: |
| 340 return [], [] | 351 return [], [] |
| 341 | 352 |
| 342 compile_targets = set(bot_config.get('compile_targets', [])) | 353 compile_targets = set(bot_config.get('compile_targets', [])) |
| 343 tests_including_triggered = list(tests) | 354 tests_including_triggered = list(tests) |
| 344 for _, builder_dict in master_dict.get('builders', {}).iteritems(): | 355 for _, test_bot in bot_db.bot_configs_matching_parent_buildername( |
| 345 if builder_dict.get('parent_buildername') == buildername: | 356 mastername, buildername): |
| 346 tests_including_triggered.extend(builder_dict.get('tests', [])) | 357 tests_including_triggered.extend(test_bot.get('tests', [])) |
| 347 | 358 |
| 348 if bot_config.get('add_tests_as_compile_targets', True): | 359 if bot_config.get('add_tests_as_compile_targets', True): |
| 349 for t in tests_including_triggered: | 360 for t in tests_including_triggered: |
| 350 compile_targets.update(t.compile_targets(self.m)) | 361 compile_targets.update(t.compile_targets(self.m)) |
| 351 | 362 |
| 352 # Only add crash_service when we have explicit compile targets. | 363 # Only add crash_service when we have explicit compile targets. |
| 353 if (self.m.platform.is_win and | 364 if (self.m.platform.is_win and |
| 354 compile_targets and | 365 compile_targets and |
| 355 'all' not in compile_targets): | 366 'all' not in compile_targets): |
| 356 compile_targets.add('crash_service') | 367 compile_targets.add('crash_service') |
| 357 | 368 |
| 358 # Lastly, add any targets the checkout-side test spec told us to use. | 369 # Lastly, add any targets the checkout-side test spec told us to use. |
| 359 compile_targets.update(test_spec.get(buildername, {}).get( | 370 compile_targets.update(bot_db.get_test_spec(mastername, buildername).get( |
| 360 'additional_compile_targets', [])) | 371 'additional_compile_targets', [])) |
| 361 | 372 |
| 362 return sorted(compile_targets), tests_including_triggered | 373 return sorted(compile_targets), tests_including_triggered |
| 363 | 374 |
| 364 def transient_check(self, update_step, command): | 375 def transient_check(self, update_step, command): |
| 365 """Runs command, checking for transience if this is a try job. | 376 """Runs command, checking for transience if this is a try job. |
| 366 | 377 |
| 367 * command is a function which takes an argument of type (str -> str), | 378 * command is a function which takes an argument of type (str -> str), |
| 368 which is a test name transformation (it adds "with patch" or "without | 379 which is a test name transformation (it adds "with patch" or "without |
| 369 patch") and runs the command. | 380 patch") and runs the command. |
| 370 * update_step is the bot_update step used for deapplying the patch. | 381 * update_step is the bot_update step used for deapplying the patch. |
| 371 """ | 382 """ |
| 372 if self.m.tryserver.is_tryserver: | 383 if self.m.tryserver.is_tryserver: |
| 373 try: | 384 try: |
| 374 command(lambda name: '%s (with patch)' % name) | 385 command(lambda name: '%s (with patch)' % name) |
| 375 except self.m.step.StepFailure: | 386 except self.m.step.StepFailure: |
| 376 self.deapply_patch(update_step) | 387 self.deapply_patch(update_step) |
| 377 command(lambda name: '%s (without patch)' % name) | 388 command(lambda name: '%s (without patch)' % name) |
| 378 raise | 389 raise |
| 379 else: | 390 else: |
| 380 command(lambda name: name) | 391 command(lambda name: name) |
| 381 | 392 |
| 382 | 393 |
| 383 def compile(self, mastername, buildername, update_step, master_dict, | 394 def compile(self, mastername, buildername, update_step, bot_db, |
| 384 test_spec, mb_mastername=None, mb_buildername=None): | 395 mb_mastername=None, mb_buildername=None): |
| 385 """Runs compile and related steps for given builder.""" | 396 """Runs compile and related steps for given builder.""" |
| 397 assert isinstance(bot_db, bdb_module.BotConfigAndTestDB), \ |
| 398 "bot_db argument %r was not a BotConfigAndTestDB" % (bot_db) |
| 386 compile_targets, tests_including_triggered = \ | 399 compile_targets, tests_including_triggered = \ |
| 387 self.get_compile_targets_and_tests( | 400 self.get_compile_targets_and_tests( |
| 388 mastername, | 401 mastername, |
| 389 buildername, | 402 buildername, |
| 390 master_dict, test_spec) | 403 bot_db) |
| 391 self.compile_specific_targets( | 404 self.compile_specific_targets( |
| 392 mastername, buildername, update_step, master_dict, | 405 mastername, buildername, update_step, bot_db, |
| 393 compile_targets, tests_including_triggered, | 406 compile_targets, tests_including_triggered, |
| 394 mb_mastername=mb_mastername, mb_buildername=mb_buildername) | 407 mb_mastername=mb_mastername, mb_buildername=mb_buildername) |
| 395 | 408 |
| 396 def compile_specific_targets( | 409 def compile_specific_targets( |
| 397 self, mastername, buildername, update_step, master_dict, | 410 self, mastername, buildername, update_step, bot_db, |
| 398 compile_targets, tests_including_triggered, | 411 compile_targets, tests_including_triggered, |
| 399 mb_mastername=None, mb_buildername=None, override_bot_type=None): | 412 mb_mastername=None, mb_buildername=None, override_bot_type=None): |
| 400 """Runs compile and related steps for given builder. | 413 """Runs compile and related steps for given builder. |
| 401 | 414 |
| 402 Allows finer-grained control about exact compile targets used. | 415 Allows finer-grained control about exact compile targets used. |
| 403 | 416 |
| 404 We don't use the given `mastername` and `buildername` to run MB, because | 417 We don't use the given `mastername` and `buildername` to run MB, because |
| 405 they may be the values of the continuous builder the trybot may be | 418 they may be the values of the continuous builder the trybot may be |
| 406 configured to match; instead we need to use the actual mastername and | 419 configured to match; instead we need to use the actual mastername and |
| 407 buildername we're running on (Default to the "mastername" and | 420 buildername we're running on (Default to the "mastername" and |
| 408 "buildername" in the build properties -- self.m.properties, but could be | 421 "buildername" in the build properties -- self.m.properties, but could be |
| 409 overridden by `mb_mastername` and `mb_buildername`), because it may be | 422 overridden by `mb_mastername` and `mb_buildername`), because it may be |
| 410 configured with different MB settings. | 423 configured with different MB settings. |
| 411 | 424 |
| 412 However, recipes used by Findit for culprit finding may still set | 425 However, recipes used by Findit for culprit finding may still set |
| 413 (mb_mastername, mb_buildername) = (mastername, buildername) to exactly match | 426 (mb_mastername, mb_buildername) = (mastername, buildername) to exactly match |
| 414 a given continuous builder.""" | 427 a given continuous builder.""" |
| 415 | 428 |
| 416 bot_config = master_dict.get('builders', {}).get(buildername) | 429 assert isinstance(bot_db, bdb_module.BotConfigAndTestDB), \ |
| 417 master_config = master_dict.get('settings', {}) | 430 "bot_db argument %r was not a BotConfigAndTestDB" % (bot_db) |
| 431 bot_config = bot_db.get_bot_config(mastername, buildername) |
| 432 master_config = bot_db.get_master_settings(mastername) |
| 418 bot_type = override_bot_type or bot_config.get('bot_type', 'builder_tester') | 433 bot_type = override_bot_type or bot_config.get('bot_type', 'builder_tester') |
| 419 | 434 |
| 420 self.m.chromium.cleanup_temp() | 435 self.m.chromium.cleanup_temp() |
| 421 if self.m.chromium.c.TARGET_PLATFORM == 'android': | 436 if self.m.chromium.c.TARGET_PLATFORM == 'android': |
| 422 self.m.chromium_android.clean_local_files() | 437 self.m.chromium_android.clean_local_files() |
| 423 self.m.chromium_android.run_tree_truth() | 438 self.m.chromium_android.run_tree_truth() |
| 424 | 439 |
| 425 if bot_type in ['builder', 'builder_tester']: | 440 if bot_type in ['builder', 'builder_tester']: |
| 426 isolated_targets = [ | 441 isolated_targets = [ |
| 427 t.isolate_target(self.m) | 442 t.isolate_target(self.m) |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 build_url=self._build_gs_archive_url( | 501 build_url=self._build_gs_archive_url( |
| 487 mastername, master_config, buildername), | 502 mastername, master_config, buildername), |
| 488 build_revision=build_revision, | 503 build_revision=build_revision, |
| 489 cros_board=self.m.chromium.c.TARGET_CROS_BOARD, | 504 cros_board=self.m.chromium.c.TARGET_CROS_BOARD, |
| 490 # TODO(machenbach): Make asan a configuration switch. | 505 # TODO(machenbach): Make asan a configuration switch. |
| 491 package_dsym_files=( | 506 package_dsym_files=( |
| 492 self.m.chromium.c.gyp_env.GYP_DEFINES.get('asan') and | 507 self.m.chromium.c.gyp_env.GYP_DEFINES.get('asan') and |
| 493 self.m.chromium.c.HOST_PLATFORM == 'mac'), | 508 self.m.chromium.c.HOST_PLATFORM == 'mac'), |
| 494 ) | 509 ) |
| 495 | 510 |
| 496 for loop_buildername, builder_dict in sorted(master_dict.get( | 511 for loop_buildername, builder_dict in sorted( |
| 497 'builders', {}).iteritems()): | 512 bot_db.bot_configs_matching_parent_buildername( |
| 498 if builder_dict.get('parent_buildername') == buildername: | 513 mastername, buildername)): |
| 499 trigger_spec = { | 514 trigger_spec = { |
| 500 'builder_name': loop_buildername, | 515 'builder_name': loop_buildername, |
| 501 'properties': {}, | 516 'properties': {}, |
| 502 } | 517 } |
| 503 for name, value in update_step.presentation.properties.iteritems(): | 518 for name, value in update_step.presentation.properties.iteritems(): |
| 504 if name.startswith('got_'): | 519 if name.startswith('got_'): |
| 505 trigger_spec['properties']['parent_' + name] = value | 520 trigger_spec['properties']['parent_' + name] = value |
| 506 self.m.trigger(trigger_spec) | 521 self.m.trigger(trigger_spec) |
| 507 | 522 |
| 508 if bot_config.get('archive_build') and not self.m.tryserver.is_tryserver: | 523 if bot_config.get('archive_build') and not self.m.tryserver.is_tryserver: |
| 509 self.m.chromium.archive_build( | 524 self.m.chromium.archive_build( |
| 510 'archive_build', | 525 'archive_build', |
| 511 bot_config['gs_bucket'], | 526 bot_config['gs_bucket'], |
| 512 bot_config.get('gs_acl'), | 527 bot_config.get('gs_acl'), |
| 513 mode='dev' | 528 mode='dev' |
| 514 ) | 529 ) |
| 515 | 530 |
| 516 def run_mb_and_compile(self, compile_targets, isolated_targets, name_suffix, | 531 def run_mb_and_compile(self, compile_targets, isolated_targets, name_suffix, |
| 517 mb_mastername=None, mb_buildername=None): | 532 mb_mastername=None, mb_buildername=None): |
| 518 if self.m.chromium.c.project_generator.tool == 'mb': | 533 if self.m.chromium.c.project_generator.tool == 'mb': |
| 519 mb_mastername = mb_mastername or self.m.properties['mastername'] | 534 mb_mastername = mb_mastername or self.m.properties['mastername'] |
| 520 mb_buildername = mb_buildername or self.m.properties['buildername'] | 535 mb_buildername = mb_buildername or self.m.properties['buildername'] |
| 521 self.m.chromium.run_mb(mb_mastername, mb_buildername, | 536 self.m.chromium.run_mb(mb_mastername, mb_buildername, |
| 522 isolated_targets=isolated_targets, | 537 isolated_targets=isolated_targets, |
| 523 name='generate_build_files%s' % name_suffix) | 538 name='generate_build_files%s' % name_suffix) |
| 524 | 539 |
| 525 self.m.chromium.compile(compile_targets, name='compile%s' % name_suffix) | 540 self.m.chromium.compile(compile_targets, name='compile%s' % name_suffix) |
| 526 | 541 |
| 527 def download_and_unzip_build(self, mastername, buildername, update_step, | 542 def download_and_unzip_build(self, mastername, buildername, update_step, |
| 528 master_dict, build_archive_url=None, | 543 bot_db, build_archive_url=None, |
| 529 build_revision=None, override_bot_type=None): | 544 build_revision=None, override_bot_type=None): |
| 545 assert isinstance(bot_db, bdb_module.BotConfigAndTestDB), \ |
| 546 "bot_db argument %r was not a BotConfigAndTestDB" % (bot_db) |
| 530 # We only want to do this for tester bots (i.e. those which do not compile | 547 # We only want to do this for tester bots (i.e. those which do not compile |
| 531 # locally). | 548 # locally). |
| 532 bot_type = override_bot_type or master_dict.get('builders', {}).get( | 549 bot_type = override_bot_type or bot_db.get_bot_config( |
| 533 buildername, {}).get('bot_type') | 550 mastername, buildername).get('bot_type') |
| 534 if bot_type != 'tester': | 551 if bot_type != 'tester': |
| 535 return | 552 return |
| 536 | 553 |
| 537 # Protect against hard to debug mismatches between directory names | 554 # Protect against hard to debug mismatches between directory names |
| 538 # used to run tests from and extract build to. We've had several cases | 555 # used to run tests from and extract build to. We've had several cases |
| 539 # where a stale build directory was used on a tester, and the extracted | 556 # where a stale build directory was used on a tester, and the extracted |
| 540 # build was not used at all, leading to confusion why source code changes | 557 # build was not used at all, leading to confusion why source code changes |
| 541 # are not taking effect. | 558 # are not taking effect. |
| 542 # | 559 # |
| 543 # The best way to ensure the old build directory is not used is to | 560 # The best way to ensure the old build directory is not used is to |
| 544 # remove it. | 561 # remove it. |
| 545 self.m.file.rmtree( | 562 self.m.file.rmtree( |
| 546 'build directory', | 563 'build directory', |
| 547 self.m.chromium.c.build_dir.join(self.m.chromium.c.build_config_fs)) | 564 self.m.chromium.c.build_dir.join(self.m.chromium.c.build_config_fs)) |
| 548 | 565 |
| 549 legacy_build_url = None | 566 legacy_build_url = None |
| 550 got_revision = update_step.presentation.properties['got_revision'] | 567 got_revision = update_step.presentation.properties['got_revision'] |
| 551 build_revision = build_revision or self.m.properties.get( | 568 build_revision = build_revision or self.m.properties.get( |
| 552 'parent_got_revision') or got_revision | 569 'parent_got_revision') or got_revision |
| 553 build_archive_url = build_archive_url or self.m.properties.get( | 570 build_archive_url = build_archive_url or self.m.properties.get( |
| 554 'parent_build_archive_url') | 571 'parent_build_archive_url') |
| 555 if build_archive_url is None: | 572 if build_archive_url is None: |
| 556 master_config = master_dict.get('settings', {}) | 573 master_config = bot_db.get_master_settings(mastername) |
| 557 legacy_build_url = self._make_legacy_build_url(master_config, mastername) | 574 legacy_build_url = self._make_legacy_build_url(master_config, mastername) |
| 558 | 575 |
| 559 self.m.archive.download_and_unzip_build( | 576 self.m.archive.download_and_unzip_build( |
| 560 step_name='extract build', | 577 step_name='extract build', |
| 561 target=self.m.chromium.c.build_config_fs, | 578 target=self.m.chromium.c.build_config_fs, |
| 562 build_url=legacy_build_url, | 579 build_url=legacy_build_url, |
| 563 build_revision=build_revision, | 580 build_revision=build_revision, |
| 564 build_archive_url=build_archive_url) | 581 build_archive_url=build_archive_url) |
| 565 | 582 |
| 566 def tests_for_builder(self, mastername, buildername, update_step, master_dict, | 583 def tests_for_builder(self, mastername, buildername, update_step, bot_db, |
| 567 override_bot_type=None): | 584 override_bot_type=None): |
| 568 | 585 assert isinstance(bot_db, bdb_module.BotConfigAndTestDB), \ |
| 569 bot_config = master_dict.get('builders', {}).get(buildername) | 586 "bot_db argument %r was not a BotConfigAndTestDB" % (bot_db) |
| 587 bot_config = bot_db.get_bot_config(mastername, buildername) |
| 570 bot_type = override_bot_type or bot_config.get('bot_type', 'builder_tester') | 588 bot_type = override_bot_type or bot_config.get('bot_type', 'builder_tester') |
| 571 # TODO(shinyak): bot_config.get('tests', []) sometimes return tuple. | 589 # TODO(shinyak): bot_config.get('tests', []) sometimes return tuple. |
| 572 tests = [copy.deepcopy(t) for t in bot_config.get('tests', [])] | 590 tests = [copy.deepcopy(t) for t in bot_config.get('tests', [])] |
| 573 | 591 |
| 574 if bot_config.get('goma_canary') or bot_config.get('goma_staging'): | 592 if bot_config.get('goma_canary') or bot_config.get('goma_staging'): |
| 575 tests.insert(0, steps.DiagnoseGomaTest()) | 593 tests.insert(0, steps.DiagnoseGomaTest()) |
| 576 | 594 |
| 577 if bot_type == 'tester': | 595 if bot_type == 'tester': |
| 578 if (self.m.chromium.c.TARGET_PLATFORM == 'android' and | 596 if (self.m.chromium.c.TARGET_PLATFORM == 'android' and |
| 579 bot_config.get('root_devices')): | 597 bot_config.get('root_devices')): |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 result_text = 'MB is enabled for this builder at this revision.' | 893 result_text = 'MB is enabled for this builder at this revision.' |
| 876 log_name = 'Builder MB-ready' | 894 log_name = 'Builder MB-ready' |
| 877 self.m.step.active_result.presentation.logs[log_name] = [result_text] | 895 self.m.step.active_result.presentation.logs[log_name] = [result_text] |
| 878 return False | 896 return False |
| 879 except (self.m.step.StepFailure, KeyError): | 897 except (self.m.step.StepFailure, KeyError): |
| 880 result_text = 'MB is not enabled for this builder at this revision.' | 898 result_text = 'MB is not enabled for this builder at this revision.' |
| 881 log_name = 'Builder NOT MB-ready' | 899 log_name = 'Builder NOT MB-ready' |
| 882 self.m.step.active_result.presentation.logs[log_name] = [result_text] | 900 self.m.step.active_result.presentation.logs[log_name] = [result_text] |
| 883 self.m.step.active_result.presentation.status = self.m.step.WARNING | 901 self.m.step.active_result.presentation.status = self.m.step.WARNING |
| 884 return True | 902 return True |
| OLD | NEW |