| # Copyright 2015 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| PYTHON_VERSION_COMPATIBILITY = 'PY2+3' |
| |
| DEPS = [ |
| 'infra_checkout', |
| 'depot_tools/bot_update', |
| 'depot_tools/gclient', |
| 'depot_tools/git', |
| 'recipe_engine/buildbucket', |
| 'recipe_engine/context', |
| 'recipe_engine/cipd', |
| 'recipe_engine/path', |
| 'recipe_engine/platform', |
| 'recipe_engine/raw_io', |
| 'recipe_engine/step', |
| ] |
| |
| ASSETS_DIFF_FAILURE_MESSAGE = ''' |
| - Please check the diffs in the previous step |
| - Please run `make format` to format files |
| - Please run `make release` to update assets ''' |
| |
| |
| def RunSteps(api): |
| co = api.infra_checkout.checkout( |
| 'luci_py', patch_root='infra/luci', generate_py2_env=True) |
| co.gclient_runhooks() |
| |
| luci_dir = api.path.checkout_dir / 'luci' |
| with api.context(cwd=luci_dir): |
| |
| with api.step.nest('check changes') as presentation: |
| changes = _check_changes(api) |
| presentation.logs['changes'] = [ |
| '%s: %s' % (p, j) for p, j in sorted(changes.items()) |
| ] |
| |
| _step_auth_tests(api, changes) |
| |
| _step_config_tests(api, changes) |
| |
| _step_components_tests(api, changes) |
| |
| _step_client_tests(api, changes) |
| |
| _step_swarming_bot_tests(api, changes) |
| |
| _step_swarming_tests(api, changes) |
| |
| _step_swarming_ui_tests(api, changes) |
| |
| |
| def _check_changes(api): |
| return { |
| 'DEPS': |
| _has_changed_files(api, 'DEPS'), |
| 'vpython': |
| _has_changed_files(api, '.vpython'), |
| 'vpython3': |
| _has_changed_files(api, '.vpython3'), |
| 'client': |
| _has_changed_files(api, 'client'), |
| 'auth_service': |
| _has_changed_files(api, 'appengine/auth_service'), |
| 'config_service': |
| _has_changed_files(api, 'appengine/config_service'), |
| 'components': |
| _has_changed_files(api, 'appengine/components'), |
| 'swarming': |
| _has_changed_files( |
| api, 'appengine/swarming', exclude_dir='appengine/swarming/ui2'), |
| 'swarming_ui': |
| _has_changed_files(api, 'appengine/swarming/ui2'), |
| 'appengine_third_party': |
| _has_changed_files(api, 'appengine/third_party'), |
| } |
| |
| |
| def _has_changed_files(api, path, exclude_dir=None): |
| result = api.m.git( |
| 'diff', |
| '--name-only', |
| '--cached', |
| path, |
| name='get change list on %s' % path, |
| stdout=api.m.raw_io.output_text()) |
| files = result.stdout.splitlines() |
| |
| # exclude files if exclude_dir is specified. |
| if exclude_dir: |
| filtered = [] |
| for f in files: |
| if not f.startswith(exclude_dir): |
| filtered.append(f) |
| files = filtered |
| |
| result.presentation.logs['change list'] = sorted(files) |
| return len(files) > 0 |
| |
| |
| def _step_run_py_tests(api, cwd, python3=False, timeout=None): |
| luci_dir = api.context.cwd |
| with api.context(cwd=cwd): |
| cfg = api.context.cwd / 'unittest.cfg' |
| testpy_args = ['-v', '--conf', cfg] |
| env_path_prefix = [] |
| |
| if python3: |
| venv = luci_dir / '.vpython3' |
| py = 'python3' |
| cmd = ['vpython3'] |
| else: |
| venv = luci_dir / '.vpython' |
| py = 'python2' |
| # Install vpython2.7 to run these tests. |
| vpython_path = api.path.cache_dir.joinpath('builder', 'vpython2.7') |
| env_path_prefix = [vpython_path] |
| ensure_file = api.cipd.EnsureFile().add_package( |
| 'infra/tools/luci/vpython2.7/${platform}', 'latest') |
| api.cipd.ensure(vpython_path, ensure_file) |
| cmd = [vpython_path / 'vpython'] |
| |
| cmd += ['-vpython-spec', venv, '-u', 'test.py'] + testpy_args |
| with api.context(env_prefixes={'PATH': env_path_prefix}): |
| api.step('run tests %s' % py, cmd, timeout=timeout) |
| |
| |
| def _step_auth_tests(api, changes): |
| if not api.platform.is_linux: |
| return |
| |
| deps = ['auth_service', 'components', 'vpython', 'appengine_third_party'] |
| if not any([changes[d] for d in deps]): |
| # skip tests when no changes on the dependencies. |
| return |
| |
| auth_dir = api.path.checkout_dir.joinpath('luci', 'appengine', 'auth_service') |
| with api.step.nest('auth_service'): |
| _step_run_py_tests(api, auth_dir) |
| |
| |
| def _step_components_tests(api, changes): |
| if not api.platform.is_linux: |
| return |
| |
| deps = ['components', 'vpython', 'appengine_third_party'] |
| if not any([changes[d] for d in deps]): |
| # skip tests when no changes on the dependencies. |
| return |
| |
| components_dir = api.path.checkout_dir.joinpath('luci', 'appengine', |
| 'components') |
| with api.step.nest('components'): |
| _step_run_py_tests(api, components_dir) |
| _step_run_py_tests(api, components_dir, python3=True) |
| |
| |
| def _step_config_tests(api, changes): |
| if not api.platform.is_linux: |
| return |
| |
| deps = ['config_service', 'components', 'vpython', 'appengine_third_party'] |
| if not any([changes[d] for d in deps]): |
| # skip tests when no changes on the dependencies. |
| return |
| |
| config_dir = api.path.checkout_dir.joinpath('luci', 'appengine', |
| 'config_service') |
| with api.step.nest('config_service'): |
| _step_run_py_tests(api, config_dir) |
| |
| |
| def _step_client_tests(api, changes): |
| deps = ['client', 'components', 'vpython3', 'vpython'] |
| if not any([changes[d] for d in deps]): |
| # skip tests when no changes on the dependencies. |
| return |
| |
| luci_dir = api.path.checkout_dir / 'luci' |
| with api.step.nest('client'): |
| _step_run_py_tests(api, luci_dir / 'client', python3=True) |
| |
| |
| def _step_swarming_tests(api, changes): |
| deps = [ |
| 'DEPS', 'swarming', 'client', 'components', 'vpython3', 'vpython', |
| 'appengine_third_party', |
| ] |
| if not any([changes[d] for d in deps]): |
| # skip tests when no changes on the dependencies. |
| return |
| if not api.platform.is_linux: |
| # the server runs only on linux. |
| return |
| |
| swarming_dir = api.path.checkout_dir.joinpath('luci', 'appengine', 'swarming') |
| with api.step.nest('swarming'): |
| _step_run_py_tests(api, swarming_dir) |
| |
| |
| def _step_swarming_bot_tests(api, changes): |
| deps = ['DEPS', 'swarming', 'client', 'components', 'vpython3', 'vpython'] |
| if not any([changes[d] for d in deps]): |
| # skip tests when no changes on the dependencies. |
| return |
| |
| bot_dir = api.path.checkout_dir.joinpath('luci', 'appengine', 'swarming', |
| 'swarming_bot') |
| with api.step.nest('swarming bot'): |
| _step_run_py_tests(api, bot_dir, python3=True) |
| |
| |
| def _step_swarming_ui_tests(api, changes): |
| if not api.platform.is_linux: |
| return |
| deps = ['DEPS', 'swarming_ui'] |
| if not any([changes[d] for d in deps]): |
| # skip tests when no changes on the dependencies. |
| return |
| with api.step.nest('swarming-ui'): |
| ui_dir = api.path.checkout_dir.joinpath('luci', 'appengine', 'swarming', |
| 'ui2') |
| node_path = ui_dir.joinpath('nodejs', 'bin') |
| paths_to_add = [api.path.pathsep.join([str(node_path)])] |
| env_prefixes = {'PATH': paths_to_add} |
| with api.context(env_prefixes=env_prefixes, cwd=ui_dir): |
| _steps_check_diffs_on_ui_assets(api) |
| api.step('run tests', ['make', 'test']) |
| |
| |
| def _steps_check_diffs_on_ui_assets(api): |
| api.step('build assets', ['make', 'format'], ok_ret='any') |
| api.step('build assets', ['make', 'release']) |
| diff_check = api.git('diff', '--exit-code', ok_ret='any') |
| if diff_check.retcode != 0: |
| diff_check.presentation.status = 'FAILURE' |
| api.step.empty( |
| 'ASSETS DIFF DETECTED', |
| status=api.step.FAILURE, |
| step_text=ASSETS_DIFF_FAILURE_MESSAGE) |
| |
| |
| def GenTests(api): |
| |
| def _ci_build(): |
| return api.buildbucket.ci_build( |
| project='infra', |
| git_repo='https://chromium.googlesource.com/infra/luci/luci-py') |
| |
| def _try_build(): |
| return api.buildbucket.try_build( |
| project='infra', |
| git_repo='https://chromium.googlesource.com/infra/luci/luci-py') |
| |
| def _step_data_changed_files(directory, files): |
| return api.step_data( |
| 'check changes.get change list on %s' % directory, |
| api.raw_io.stream_output_text('\n'.join(files)), |
| stream='stdout') |
| |
| yield (api.test('ci') + _ci_build() + |
| _step_data_changed_files('client', ['client/foo.py']) + |
| _step_data_changed_files('appengine/auth_service', |
| ['appengine/auth_service/foo.py']) + |
| _step_data_changed_files('appengine/config_service', |
| ['appengine/config_service/foo.py']) + |
| _step_data_changed_files('appengine/components', |
| ['appengine/components/foo.py']) + |
| _step_data_changed_files('appengine/swarming', |
| ['appengine/swarming/foo.py']) + |
| _step_data_changed_files('appengine/swarming/ui2', |
| ['appengine/swarming/ui2/foo.js'])) |
| |
| yield (api.test('try') + _try_build() + |
| _step_data_changed_files('client', ['client/foo.py']) + |
| _step_data_changed_files('appengine/auth_service', |
| ['appengine/auth_service/foo.py']) + |
| _step_data_changed_files('appengine/config_service', |
| ['appengine/config_service/foo.py']) + |
| _step_data_changed_files('appengine/components', |
| ['appengine/components/foo.py']) + |
| _step_data_changed_files( |
| 'appengine/swarming', |
| ['appengine/swarming/foo.py', 'appengine/swarming/ui2/bar.js']) + |
| _step_data_changed_files('appengine/swarming/ui2', |
| ['appengine/swarming/ui2/bar.js'])) |
| |
| yield (api.test('try-mac') + api.platform.name('mac') + _try_build() + |
| _step_data_changed_files('client', ['client/foo.py'])) |
| |
| yield (api.test('try-win') + api.platform.name('win') + _try_build() + |
| _step_data_changed_files('client', ['client/foo.py'])) |
| |
| # test case for failures |
| yield ( |
| api.test('try-ui-diff-check-failure') + _try_build() + |
| _step_data_changed_files( |
| 'appengine/swarming/ui2', |
| ['appengine/swarming/ui2/bar.js']) + |
| api.step_data('swarming-ui.git diff', retcode=1) + |
| api.expect_status('FAILURE')) |
| |
| # test case for skipping test steps. |
| yield api.test('try-skip') + _try_build() |