# Copyright 2018 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Wrapper for running suites of tests and waiting for completion.""" from __future__ import absolute_import from __future__ import division from __future__ import print_function import os import sys import logging from lucifer import autotest from skylab_suite import cros_suite from skylab_suite import suite_parser from skylab_suite import suite_runner from skylab_suite import suite_tracking from skylab_suite import swarming_lib PROVISION_SUITE_NAME = 'provision' def _parse_suite_handler_spec(options): provision_num_required = 0 if 'num_required' in options.suite_args: provision_num_required = options.suite_args['num_required'] return cros_suite.SuiteHandlerSpec( suite_name=options.suite_name, wait=not options.create_and_return, suite_id=options.suite_id, timeout_mins=options.timeout_mins, passed_mins=options.passed_mins, test_retry=options.test_retry, max_retries=options.max_retries, provision_num_required=provision_num_required) def _should_run(suite_spec): tags = {'build': suite_spec.test_source_build, 'suite': suite_spec.suite_name} tasks = swarming_lib.query_task_by_tags(tags) current_task_id = suite_tracking.get_task_id_for_task_summaries( os.environ.get('SWARMING_TASK_ID')) logging.info('The current task id is: %s', current_task_id) extra_task_ids = set([]) for t in tasks: if t['task_id'] != current_task_id: extra_task_ids.add(t['task_id']) return extra_task_ids def _run_suite(options): swarming_client = swarming_lib.Client(options.swarming_auth_json) run_suite_common = autotest.load('site_utils.run_suite_common') logging.info('Kicked off suite %s', options.suite_name) suite_spec = suite_parser.parse_suite_spec(options) if options.pre_check: extra_task_ids = _should_run(suite_spec) if extra_task_ids: logging.info( 'The same suites are already run in the past: \n%s', '\n'.join([swarming_lib.get_task_link(tid) for tid in extra_task_ids])) return run_suite_common.SuiteResult( run_suite_common.RETURN_CODES.OK) if options.suite_name == PROVISION_SUITE_NAME: suite_job = cros_suite.ProvisionSuite(suite_spec, swarming_client) else: suite_job = cros_suite.Suite(suite_spec, swarming_client) try: suite_job.prepare() except Exception as e: logging.exception('Infra failure in setting up suite job') return run_suite_common.SuiteResult( run_suite_common.RETURN_CODES.INFRA_FAILURE) suite_handler_spec = _parse_suite_handler_spec(options) suite_handler = cros_suite.SuiteHandler(suite_handler_spec, swarming_client) suite_runner.run(swarming_client, suite_job.test_specs, suite_handler, options.dry_run) if options.create_and_return: suite_tracking.log_create_task(suite_job.suite_name, suite_handler.suite_id) suite_tracking.print_child_test_annotations(suite_handler) return run_suite_common.SuiteResult(run_suite_common.RETURN_CODES.OK) return_code = suite_tracking.log_suite_results( suite_job.suite_name, suite_handler) return run_suite_common.SuiteResult(return_code) def parse_args(): """Parse & validate skylab suite args.""" parser = suite_parser.make_parser() options = parser.parse_args() if options.do_nothing: logging.info('Exit early because --do_nothing requested.') sys.exit(0) if not suite_parser.verify_and_clean_options(options): parser.print_help() sys.exit(1) return options def _setup_env(options): """Set environment variables based on commandline options.""" os.environ['SWARMING_CREDS'] = options.swarming_auth_json def main(): """Entry point.""" autotest.monkeypatch() options = parse_args() _setup_env(options) suite_tracking.setup_logging() result = _run_suite(options) logging.info('Will return from %s with status: %s', os.path.basename(__file__), result.string_code) return result.return_code if __name__ == "__main__": sys.exit(main())