#!/usr/bin/python
#
# Copyright (c) 2012 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.


"""Tool for running suites of tests and waiting for completion.

The desired test suite will be scheduled with autotest. By default,
this tool will block until the job is complete, printing a summary
at the end.  Error conditions result in exceptions.

This is intended for use only with Chrome OS test suits that leverage the
dynamic suite infrastructure in server/cros/dynamic_suite.py.

This script exits with one of the following codes:
0 - OK: Suite finished successfully
1 - ERROR: Test(s) failed, or hits its own timeout
2 - WARNING: Test(s) raised a warning or passed on retry, none failed/timed out.
3 - INFRA_FAILURE: Infrastructure related issues, e.g.
    * Lab is down
    * Too many duts (defined as a constant) in repair failed status
    * Suite job issues, like bug in dynamic suite,
      user aborted the suite, lose a drone/all devservers/rpc server,
      0 tests ran, etc.
    * provision failed
      TODO(fdeng): crbug.com/413918, reexamine treating all provision
                   failures as INFRA failures.
4 - SUITE_TIMEOUT: Suite timed out, some tests ran,
    none failed by the time the suite job was aborted. This will cover,
    but not limited to, the following cases:
    * A devserver failure that manifests as a timeout
    * No DUTs available midway through a suite
    * Provision/Reset/Cleanup took longer time than expected for new image
    * A regression in scheduler tick time.
5- BOARD_NOT_AVAILABLE: If there is no host for the requested board/pool.
6- INVALID_OPTIONS: If options are not valid.
"""

import argparse
import ast
import collections
from datetime import datetime
from datetime import timedelta
import functools
import getpass
import json
import logging
import os
import re
import sys
import time
import warnings

import common
from chromite.lib import buildbot_annotations as annotations
from chromite.lib import cros_build_lib
from chromite.lib import gs
from chromite.lib import osutils

from django.core import exceptions as django_exceptions

try:
    from suite_scheduler import config_reader
    from suite_scheduler import skylab
except ImportError:
    # For unittest
    config_reader = None
    skylab = None

from autotest_lib.client.common_lib import control_data
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.common_lib import priorities
from autotest_lib.client.common_lib import time_utils
from autotest_lib.client.common_lib.cros import retry
from autotest_lib.frontend.afe import rpc_client_lib
from autotest_lib.frontend.afe.json_rpc import proxy
from autotest_lib.server import site_utils
from autotest_lib.server import utils
from autotest_lib.server.cros import provision
from autotest_lib.server.cros.dynamic_suite import constants
from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
from autotest_lib.server.cros.dynamic_suite import reporting_utils
from autotest_lib.server.cros.dynamic_suite import suite_common
from autotest_lib.server.cros.dynamic_suite import tools
try:
    from autotest_lib.site_utils import diagnosis_utils
except django_exceptions.ImproperlyConfigured as e:
    if 'Error loading MySQLdb module: libmariadbclient' in str(e):
        logging.error('Unable to import a necessary MySQLdb module. This is '
                      'commonly caused by running a command inside[outside] '
                      'of the chroot but having autotest utility packages '
                      'that were build outside[inside] the chroot. '
                      'Please re-run utils/build_externals.py inside[outside] '
                      'of the chroot accordingly.')
    raise

from autotest_lib.site_utils import paygen
from autotest_lib.site_utils import run_suite_common

CONFIG = global_config.global_config

_DEFAULT_AUTOTEST_INSTANCE = CONFIG.get_config_value(
        'SERVER', 'hostname', type=str)
_URL_PATTERN = CONFIG.get_config_value('CROS', 'log_url_pattern', type=str)
_ENABLE_RUN_SUITE_TRAMPOLINE = CONFIG.get_config_value(
        'CROS', 'enable_run_suite_trampoline', type=bool, default=False)

_SKYLAB_TOOL = '/opt/infra-tools/skylab'
_SKYLAB_SERVICE_ACCOUNT = '/creds/service_accounts/skylab_swarming.json'
_MIGRATION_CONFIG_FILE = 'migration_config.ini'
_MIGRATION_CONFIG_BUCKET = 'suite-scheduler.google.com.a.appspot.com'
_TRAMPOLINE_CONFIG = 'gs://%s/%s' % (_MIGRATION_CONFIG_BUCKET,
                                     _MIGRATION_CONFIG_FILE)

# Minimum RPC timeout setting for calls expected to take long time, e.g.,
# create_suite_job. If default socket time (socket.getdefaulttimeout()) is
# None or greater than this value, the default will be used.
# The value here is set to be the same as the timeout for the RetryingAFE object
# so long running RPCs can wait long enough before being aborted.
_MIN_RPC_TIMEOUT = 600

# Number of days back to search for existing job.
_SEARCH_JOB_MAX_DAYS = 14

_PROVISION_SUITE = 'provision'

# Only special tasks can have a priority lower than 50.
_SKYLAB_PRIORITY_MIN = 50
# Mandated by Swarming.
_SKYLAB_PRIORITY_MAX = 255


@functools.total_ordering
class _ReturnResult(object):
    """Represents overall result of run_suite operation.

    _ReturnResult instances sort based on priority (the order in
    _RETURN_RESULTS).

    Furthermore, _ReturnResult instances can be combined by bitwise or
    ("union"), which returns the instance with the higher priority
    between the two (the instance with higher priority is a "superset"
    of the other).

    Do not create new instances of this; use _RETURN_RESULTS instead.
    """

    def __init__(self, return_code, message):
        self.return_code = return_code
        self.message = message

    def __repr__(self):
        return '<{cls} {key}, {this.return_code}, {this.message}>'.format(
            cls=type(self).__name__,
            key=self._getkey(),
            this=self)

    def __gt__(self, other):
        if isinstance(other, type(self)):
            return self._getkey() > other._getkey()
        else:
            return NotImplemented

    def __eq__(self, other):
        if isinstance(other, type(self)):
            return (self.return_code == other.return_code
                    and self.message == other.message)
        else:
            return NotImplemented

    def __hash__(self):
        return hash(self.return_code) ^ hash(self.message)

    def __or__(self, other):
        if isinstance(other, type(self)):
            if self > other:
                return self
            else:
                return other
        else:
            return NotImplemented

    def _getkey(self):
        """Return sort key."""
        return _RETURN_RESULTS_LIST.index(self)

    def suite_result(self, output_dict=None):
        """Make a SuiteResult using this _ReturnResult.

        @param output_dict: output_dict to merge into SuiteResult.
        """
        if output_dict is None:
            output_dict = dict()
        else:
            output_dict = output_dict.copy()
        if self.message:
            output_dict['return_message'] = self.message
        return run_suite_common.SuiteResult(self.return_code, output_dict)


_RETURN_RESULTS = collections.OrderedDict([
    ('ok', _ReturnResult(run_suite_common.RETURN_CODES.OK, '')),

    ('test_warning', _ReturnResult(
        run_suite_common.RETURN_CODES.WARNING, 'Test job raised warning.')),
    ('suite_warning', _ReturnResult(
        run_suite_common.RETURN_CODES.WARNING, 'Suite job raised warning.')),
    ('test_retry', _ReturnResult(
        run_suite_common.RETURN_CODES.WARNING, 'Tests were retried.')),

    ('test_aborted_prestart', _ReturnResult(
        run_suite_common.RETURN_CODES.SUITE_TIMEOUT,
        'Tests were aborted before running; suite must have timed out.')),
    # This really indicates a user action or an infra failure. But, suite
    # timeouts cause similar fauilres in the individual tests, so we must
    # classify these lower than suite_timeout. In case of a suite_timeout, the
    # result from the suite job will promote the result to suite_timeout.
    ('test_aborted_mystery',
     _ReturnResult(
             run_suite_common.RETURN_CODES.SUITE_TIMEOUT,
             'Tests were aborted after running, but before timeout; '
             'Test was manually aborted or parsing results failed: '
             'crbug.com/796348.')),
    ('suite_timeout', _ReturnResult(
        run_suite_common.RETURN_CODES.SUITE_TIMEOUT, 'Suite job timed out.')),

    ('test_views_missing', _ReturnResult(
        run_suite_common.RETURN_CODES.INFRA_FAILURE, 'No test views found.')),
    ('suite_failed', _ReturnResult(
        run_suite_common.RETURN_CODES.INFRA_FAILURE, 'Suite job failed.')),
    ('provision_failed', _ReturnResult(
        run_suite_common.RETURN_CODES.INFRA_FAILURE, 'Provisioning failed.')),

    ('test_failure', _ReturnResult(
        run_suite_common.RETURN_CODES.ERROR, 'Tests failed.')),
])
_RETURN_RESULTS_LIST = list(_RETURN_RESULTS.values())


def bool_str(x):
    """Boolean string type for option arguments.

    @param x: string representation of boolean value.

    """
    if x == 'True':
        return True
    elif x == 'False':
        return False
    else:
        raise argparse.ArgumentTypeError(
            '%s is not one of True or False' % (x,))


def _get_priority_value(x):
    """Convert a priority representation to its int value.

    Priorities can be described either by an int value (possibly as a string)
    or a name string.  This function coerces both forms to an int value.

    This function is intended for casting command line arguments during
    parsing.

    @param x: priority value as an int, int string, or name string

    @returns: int value of priority
    """
    try:
        return int(x)
    except ValueError:
        try:
            return priorities.Priority.get_value(x)
        except AttributeError:
            raise argparse.ArgumentTypeError(
                'Unknown priority level %s.  Try one of %s.'
                % (x, ', '.join(priorities.Priority.names)))


def skylab_priority_for(afe_priority):
  """Convert AFE priority to Skylab priority.

  Args:
    afe_priority: An integer get from _get_priority_value().

  Returns:
    An integer representing Skylab priority.
  """
  skylab_priority = 260 - 3 * int(afe_priority)
  skylab_priority = min(skylab_priority, _SKYLAB_PRIORITY_MAX)
  skylab_priority = max(skylab_priority, _SKYLAB_PRIORITY_MIN)
  return skylab_priority


def make_parser():
    """Make ArgumentParser instance for run_suite.py."""
    parser = argparse.ArgumentParser(
        usage="%(prog)s [options]")
    parser.add_argument("-b", "--board", dest="board")
    parser.add_argument(
            "--model",
            help="The device model to run tests against. For non-unified "
                 "builds, model and board are synonymous, but board is more "
                 "accurate in some cases. Only pass this option if your build "
                 "is a unified build.",
    )
    parser.add_argument("-i", "--build", dest="build")
    parser.add_argument(
        "-w", "--web", dest="web", default=None,
        help="Address of a webserver to receive suite requests.")
    parser.add_argument(
        '--cheets_build', dest='cheets_build', default=None,
        help='ChromeOS Android build to be installed on dut.')
    parser.add_argument(
        '--firmware_rw_build', dest='firmware_rw_build', default=None,
        help='Firmware build to be installed in dut RW firmware.')
    parser.add_argument(
        '--firmware_ro_build', dest='firmware_ro_build', default=None,
        help='Firmware build to be installed in dut RO firmware.')
    parser.add_argument(
        '--test_source_build', dest='test_source_build', default=None,
        help=('Build that contains the test code, '
              'e.g., it can be the value of `--build`, '
              '`--firmware_rw_build` or `--firmware_ro_build` '
              'arguments. Default is None, that is, use the test '
              'code from `--build` (CrOS image)'))
    #  This should just be a boolean flag, but the autotest "proxy" code
    #  can't handle flags that don't take arguments.
    parser.add_argument(
        "-n", "--no_wait", dest="no_wait", default=False, type=bool_str,
        help='Must pass "True" or "False" if used.')
    # If you really want no pool, --pool="" will do it. USE WITH CARE.
    parser.add_argument("-p", "--pool", dest="pool", default="suites")
    parser.add_argument("-s", "--suite_name", dest="name")
    parser.add_argument("-a", "--afe_timeout_mins", type=int,
                        dest="afe_timeout_mins", default=30)
    parser.add_argument("-t", "--timeout_mins", type=int,
                        dest="timeout_mins", default=1440)
    parser.add_argument("-x", "--max_runtime_mins", type=int,
                        dest="max_runtime_mins", default=1440)
    parser.add_argument("-d", "--delay_sec", type=int,
                        dest="delay_sec", default=10)
    parser.add_argument("-m", "--mock_job_id", dest="mock_job_id",
                        help="Attach to existing job id for already running "
                        "suite, and creates report.")
    # NOTE(akeshet): This looks similar to --no_wait, but behaves differently.
    # --no_wait is passed in to the suite rpc itself and affects the suite,
    # while this does not.
    parser.add_argument("-c", "--create_and_return", dest="create_and_return",
                        action="store_true",
                        help="Create the suite and print the job id, then "
                        "finish immediately.")
    parser.add_argument("-u", "--num", dest="num", type=int, default=None,
                        help="Deprecated, does nothing.")
    #  Same boolean flag issue applies here.
    parser.add_argument(
        "-f", "--file_bugs", dest="file_bugs", default=False, type=bool_str,
        help=('File bugs on test failures. Must pass "True" or '
              '"False" if used.'))
    parser.add_argument("-l", "--bypass_labstatus", dest="bypass_labstatus",
                        action="store_true", help='Bypass lab status check.')
    # We allow either a number or a string for the priority.  This way, if you
    # know what you're doing, one can specify a custom priority level between
    # other levels.
    parser.add_argument("-r", "--priority", dest="priority",
                        type=_get_priority_value,
                        default=priorities.Priority.DEFAULT,
                        action="store",
                        help="Priority of suite. Either numerical value, or "
                        "one of (" + ", ".join(priorities.Priority.names)
                        + ").")
    parser.add_argument(
        '--retry', dest='retry', default=False, type=bool_str, action='store',
        help='Enable test retry.  Must pass "True" or "False" if used.')
    parser.add_argument('--max_retries', dest='max_retries', default=None,
                        type=int, action='store', help='Maximum retries'
                        'allowed at suite level. No limit if not specified.')
    parser.add_argument('--minimum_duts', dest='minimum_duts', type=int,
                        default=0, action='store',
                        help='Check that the pool has at least such many '
                        'healthy machines, otherwise suite will not run. '
                        'Default to 0.')
    parser.add_argument('--suite_min_duts', dest='suite_min_duts', type=int,
                        default=0, action='store',
                        help='Preferred minimum number of machines. Scheduler '
                        'will prioritize on getting such many machines for '
                        'the suite when it is competing with another suite '
                        'that has a higher priority but already got minimum '
                        'machines it needs. Default to 0.')
    parser.add_argument("--suite_args", dest="suite_args",
                        type=ast.literal_eval,
                        default=None, action="store",
                        help="A dict of args passed to the suite control file.")
    parser.add_argument('--offload_failures_only',
                        dest='offload_failures_only', type=bool_str,
                        action='store', default=False,
                        help='Only enable gs_offloading for failed tests. '
                        'Successful tests will be deleted. Must pass "True"'
                        ' or "False" if used.')
    parser.add_argument('--use_suite_attr', dest='use_suite_attr',
                        action='store_true', default=False,
                        help='Advanced. Run the suite based on ATTRIBUTES of '
                        'control files, rather than SUITE.')
    parser.add_argument('--json_dump', dest='json_dump', action='store_true',
                        default=False,
                        help='Dump the output of run_suite to stdout.')
    parser.add_argument(
        '--run_prod_code', dest='run_prod_code',
        action='store_true', default=False,
        help='Run the test code that lives in prod aka the test '
        'code currently on the lab servers.')
    parser.add_argument(
        '--delay_minutes', type=int, default=0,
        help=('Delay the creation of test jobs for a given '
              'number of minutes. This argument can be used to '
              'force provision jobs being delayed, which helps '
              'to distribute loads across devservers.'))
    parser.add_argument(
        '--skip_duts_check', dest='skip_duts_check', action='store_true',
        default=False, help='If True, skip minimum available DUTs check')
    parser.add_argument(
        '--job_keyvals', dest='job_keyvals', type=ast.literal_eval,
        action='store', default=None,
        help='A dict of job keyvals to be inject to suite control file')
    parser.add_argument(
        '--test_args', dest='test_args', type=ast.literal_eval,
        action='store', default=None,
        help=('A dict of args passed all the way to each individual test that '
              'will be actually ran.'))
    parser.add_argument(
        '--require_logfile', action='store_true',
        help=('Stream logs of run_suite.py to a local file named '
              'run_suite-<build name>.log.'))

    # Used for monitoring purposes, to measure no-op swarming proxy latency.
    parser.add_argument('--do_nothing', action='store_true',
                        help=argparse.SUPPRESS)

    # Used when lab/job status checking is needed. Currently its only user is
    # suite scheduler v2.
    parser.add_argument(
        '--pre_check', action='store_true',
        help=('Check lab and job status before kicking off a suite. Used by '
              'suite scheduler v2.'))

    # TODO(crbug.com/763207): This is to support calling old moblab RPC
    # with ToT code.  This does not need to be supported after M62.
    parser.add_argument('--oldrpc', action='store_true',
                        help='Use old AFE RPC.')

    return parser


def verify_and_clean_options(options):
    """Verify the validity of options.

    @param options: The parsed options to verify.

    @returns: True if verification passes, False otherwise.

    """
    if options.mock_job_id and (
            not options.build or not options.name or not options.board):
        print ('When using -m, need to specify build, board and suite '
               'name which you have used for creating the original job')
        return False
    else:
        if not options.build:
            print 'Need to specify which build to use'
            return False
        if not options.board:
            print 'Need to specify board'
            return False
        if not options.name:
            print 'Need to specify suite name'
            return False
    if options.num is not None:
        warnings.warn('-u/--num option is deprecated; it does nothing.')
    del options.num
    if not options.retry and options.max_retries is not None:
        print 'max_retries can only be used with --retry=True'
        return False
    if options.use_suite_attr and options.suite_args is not None:
        print ('The new suite control file cannot parse the suite_args: %s.'
               'Please not specify any suite_args here.' % options.suite_args)
        return False
    if options.no_wait and options.retry:
        print 'Test retry is not available when using --no_wait=True'
    # Default to use the test code in CrOS build.
    if not options.test_source_build and options.build:
        options.test_source_build = options.build
    options.child_dependencies = _make_child_dependencies(options)
    base_dependencies = ('board:%s' % options.board,
                         'pool:%s' % options.pool)
    options.dependencies = base_dependencies + options.child_dependencies
    return True


def change_options_for_suite_attr(options):
    """Change options to be prepared to run the suite_attr_wrapper.

    If specify 'use_suite_attr' from the cmd line, it indicates to run the
    new style suite control file, suite_attr_wrapper. Then, change the
    options.name to 'suite_attr_wrapper', change the options.suite_args to
    include the arguments needed by suite_attr_wrapper.

    @param options: The verified options.

    @returns: The changed options.

    """
    # Convert the suite_name to attribute boolean expression.
    if type(options.name) is str:
        attr_filter_val = 'suite:%s' % options.name
    else:
        attr_filter_val = ' or '.join(['suite:%s' % x for x in options.name])

    # change the suite_args to be a dict of arguments for suite_attr_wrapper
    # if suite_args is not None, store the values in 'other_args' of the dict
    args_dict = {}
    args_dict['attr_filter'] = attr_filter_val
    options.suite_args = args_dict
    options.name = 'suite_attr_wrapper'

    return options


class TestResult(object):

    """Represents the result of a TestView."""

    def __init__(self, test_view, retry_count=0):
        """Initialize instance.

        @param test_view: TestView instance.
        @param retry_count: Retry count for test.  Optional.
        """
        self.name = test_view.get_testname()
        self.status = test_view['status']
        self.reason = test_view['reason']
        self.retry_count = retry_count

    _PRETTY_STATUS_MAP = {
        'GOOD':    '[ PASSED ]',
        'TEST_NA': '[  INFO  ]',
    }

    @property
    def _pretty_status(self):
        """Pretty status string."""
        return self._PRETTY_STATUS_MAP.get(self.status, '[ FAILED ]')

    def log_using(self, log_function, name_column_width):
        """Log the test result using the given log function.

        @param log_function: Log function to use.  Example: logging.info
        @param name_column_width: Width of name column for formatting.
        """
        padded_name = self.name.ljust(name_column_width)
        log_function('%s%s', padded_name, self._pretty_status)
        if self.status != 'GOOD':
            log_function('%s  %s: %s', padded_name, self.status, self.reason)
        if self.retry_count > 0:
            log_function('%s  retry_count: %s', padded_name, self.retry_count)


def get_original_suite_name(suite_name, suite_args):
    """Get the original suite name when running suite_attr_wrapper.

    @param suite_name: the name of the suite launched in afe. When it is
                       suite_attr_wrapper, the suite that actually running is
                       specified in the suite_args.
    @param suite_args: dict of suite args from argument parsing.

    @returns: the original suite name.

    """
    if suite_name == 'suite_attr_wrapper':
        attrs = suite_args.get('attr_filter', '')
        suite_list = ([x[6:] for x in re.split('[() ]', attrs)
                       if x and x.startswith('suite:')])
        return suite_list[0] if suite_list else suite_name
    return suite_name


class LogLink(object):
    """Information needed to record a link in the logs.

    Depending on context and the information provided at
    construction time, the link may point to either to log files for
    a job, or to a bug filed for a failure in the job.

    @var anchor  The link text.
    @var url     The link url.
    @var bug_id  Id of a bug to link to, or None.
    """

    # A list of tests that don't get retried so skip the dashboard.
    _SKIP_RETRY_DASHBOARD = ['provision']

    _BUG_LINK_PREFIX = 'Auto-Bug'
    _LOG_LINK_PREFIX = 'Test-Logs'


    def __init__(self, anchor, server, job_string, bug_info=None, reason=None,
                 retry_count=0, testname=None, sponge_url=None):
        """Initialize the LogLink by generating the log URL.

        @param anchor      The link text.
        @param server      The hostname of the server this suite ran on.
        @param job_string  The job whose logs we'd like to link to.
        @param bug_info    Info about the bug, if one was filed.
        @param reason      A string representing the reason of failure if any.
        @param retry_count How many times the test has been retried.
        @param testname    Optional Arg that supplies the testname.
        @param sponge_url  url to Sponge result.
        """
        self.anchor = anchor
        self.url = _URL_PATTERN % (rpc_client_lib.add_protocol(server),
                                   job_string)
        self.reason = reason
        self.retry_count = retry_count
        self.testname = testname
        self.sponge_url = sponge_url
        if bug_info:
            self.bug_id, self.bug_count = bug_info
        else:
            self.bug_id = None
            self.bug_count = None


    @property
    def bug_url(self):
        """URL of associated bug."""
        if self.bug_id:
            return reporting_utils.link_crbug(self.bug_id)
        else:
            return None


    @property
    def _bug_count_text(self):
        """Return bug count as human friendly text."""
        if self.bug_count is None:
            bug_info = 'unknown number of reports'
        elif self.bug_count == 1:
            bug_info = 'new report'
        else:
            bug_info = '%s reports' % self.bug_count
        return bug_info


    def GenerateBuildbotLinks(self):
        """Generate a link formatted to meet buildbot expectations.

        If there is a bug associated with this link, report a link to the bug
        and a link to the job logs; otherwise report a link to the job logs.

        @return A generator of links formatted for the buildbot log annotator.
        """
        if self.bug_url:
            yield self._get_link_to_bug()
        yield self._get_link_to_job_logs()


    def _get_link_to_bug(self):
        """Return buildbot link to bug.

        @return A link formatted for the buildbot log annotator.
        """
        info_strings = self._get_info_strings()
        info_strings.append(self._bug_count_text)
        anchor_text = self._format_anchor_text(self._BUG_LINK_PREFIX,
                                               info_strings)
        return annotations.StepLink(anchor_text, self.bug_url)


    def _get_link_to_job_logs(self):
        """Return buildbot link to job logs.

        @return A link formatted for the buildbot log annotator.
        """
        anchor_text = self._format_anchor_text(self._LOG_LINK_PREFIX,
                                               self._get_info_strings())
        return annotations.StepLink(anchor_text, self.url)


    def _get_info_strings(self):
        """Return a list of info strings for _format_anchor_text()."""
        info_strings = []
        if self.retry_count > 0:
            info_strings.append('retry_count: %d' % self.retry_count)
        if self.reason:
            info_strings.append(self.reason)
        return info_strings


    def _format_anchor_text(self, prefix, info_strings):
        """Format anchor text given a prefix and info strings.

        @param prefix        The prefix of the anchor text.
        @param info_strings  Iterable of strings.
        @return A anchor_text with the right prefix and info strings.
        """
        return '[{prefix}]: {anchor}: {info}'.format(
            prefix=prefix,
            anchor=self.anchor.strip(),
            info=', '.join(info_strings))

    @property
    def text_link(self):
        """Link to the job's logs, for consumption by a human.

        @return A link formatted for human readability.
        """
        return '%s %s' % (self.anchor, self.url)

    def GenerateRetryLink(self):
        """Generate a link to the retry dashboard.

        @return A link formatted for the buildbot log annotator.
        """
        if not self.testname or self.testname in self._SKIP_RETRY_DASHBOARD:
            return None

        # TODO(xixuan): Return the right flake dashboard later.
        return None

    def GenerateHistoryLink(self):
        """Generate a link to the test history dashboard.

        @return A link formatted for the buildbot log annotator.
        """
        if not self.testname or self.testname in self._SKIP_RETRY_DASHBOARD:
            return None
        return annotations.StepLink(
            text='[Test-History]: %s' % self.testname,
            url=reporting_utils.link_test_history(self.testname))


class Timings(object):
    """Timings for important events during a suite.

    All timestamps are datetime.datetime objects.

    @var suite_job_id: the afe job id of the suite job for which
                       we are recording the timing for.
    @var download_start_time: the time the devserver starts staging
                              the build artifacts. Recorded in create_suite_job.
    @var payload_end_time: the time when the artifacts only necessary to start
                           installsing images onto DUT's are staged.
                           Recorded in create_suite_job.
    @var artifact_end_time: the remaining artifacts are downloaded after we kick
                            off the reimaging job, at which point we record
                            artifact_end_time. Recorded in dynamic_suite.py.
    @var suite_start_time: the time the suite started.
    @var tests_start_time: the time the first test started running.
    @var tests_end_time: the time the last test finished running.
    """

    def __init__(self, suite_job_id):
        self.suite_job_id = suite_job_id
        # Timings related to staging artifacts on devserver.
        self.download_start_time = None
        self.payload_end_time = None
        self.artifact_end_time = None

        # The test_start_time, but taken off the view that corresponds to the
        # suite instead of an individual test.
        self.suite_start_time = None

        # Earliest and Latest tests in the set of TestViews passed to us.
        self.tests_start_time = None
        self.tests_end_time = None


    def RecordTiming(self, view):
        """Given a test report view, extract and record pertinent time info.

        get_detailed_test_views() returns a list of entries that provide
        info about the various parts of a suite run.  This method can take
        any one of these entries and look up timestamp info we might want
        and record it.

        If timestamps are unavailable, datetime.datetime.min/max will be used.

        @param view: A TestView object.
        """
        start_candidate = datetime.min
        end_candidate = datetime.max
        if view['test_started_time']:
            start_candidate = time_utils.time_string_to_datetime(
                    view['test_started_time'])
        if view['test_finished_time']:
            end_candidate = time_utils.time_string_to_datetime(
                    view['test_finished_time'])

        if view.get_testname() == TestView.SUITE_JOB:
            self.suite_start_time = start_candidate
        else:
            self._UpdateFirstTestStartTime(start_candidate)
            self._UpdateLastTestEndTime(end_candidate)
        if view['afe_job_id'] == self.suite_job_id and 'job_keyvals' in view:
            keyvals = view['job_keyvals']
            self.download_start_time = time_utils.time_string_to_datetime(
                    keyvals.get(constants.DOWNLOAD_STARTED_TIME),
                    handle_type_error=True)

            self.payload_end_time = time_utils.time_string_to_datetime(
                    keyvals.get(constants.PAYLOAD_FINISHED_TIME),
                    handle_type_error=True)

            self.artifact_end_time = time_utils.time_string_to_datetime(
                    keyvals.get(constants.ARTIFACT_FINISHED_TIME),
                    handle_type_error=True)


    def _UpdateFirstTestStartTime(self, candidate):
        """Update self.tests_start_time, iff candidate is an earlier time.

        @param candidate: a datetime.datetime object.
        """
        if not self.tests_start_time or candidate < self.tests_start_time:
            self.tests_start_time = candidate


    def _UpdateLastTestEndTime(self, candidate):
        """Update self.tests_end_time, iff candidate is a later time.

        @param candidate: a datetime.datetime object.
        """
        if not self.tests_end_time or candidate > self.tests_end_time:
            self.tests_end_time = candidate


    def __str__(self):
        return ('\n'
                'Suite timings:\n'
                'Downloads started at %s\n'
                'Payload downloads ended at %s\n'
                'Suite started at %s\n'
                'Artifact downloads ended (at latest) at %s\n'
                'Testing started at %s\n'
                'Testing ended at %s\n' % (self.download_start_time,
                                           self.payload_end_time,
                                           self.suite_start_time,
                                           self.artifact_end_time,
                                           self.tests_start_time,
                                           self.tests_end_time))


def instance_for_pool(pool_name):
    """
    Return the hostname of the server that should be used to service a suite
    for the specified pool.

    @param pool_name: The pool (without 'pool:' to schedule the suite against.
    @return: The correct host that should be used to service this suite run.
    """
    return CONFIG.get_config_value(
            'POOL_INSTANCE_SHARDING', pool_name,
            default=_DEFAULT_AUTOTEST_INSTANCE)


class TestView(object):
    """Represents a test view and provides a set of helper functions."""


    SUITE_JOB = 'Suite job'


    def __init__(self, view, afe_job, suite_name, build, user,
                 solo_test_run=False):
        """Init a TestView object representing a tko test view.

        @param view: A dictionary representing a tko test view.
        @param afe_job: An instance of frontend.afe.models.Job
                        representing the job that kicked off the test.
        @param suite_name: The name of the suite
                           that the test belongs to.
        @param build: The build for which the test is run.
        @param user: The user for which the test is run.
        @param solo_test_run: This is a solo test run not part of a suite.
        """
        self.view = view
        self.afe_job = afe_job
        self.suite_name = suite_name
        self.build = build
        self.is_suite_view = afe_job.parent_job is None and not solo_test_run
        # This is the test name that will be shown in the output.
        self.testname = None
        self.user = user

        # The case that a job was aborted before it got a chance to run
        # usually indicates suite has timed out (unless aborted by user).
        # In this case, the abort reason will be None.
        # Update the reason with proper information.
        if (self.is_relevant_suite_view() and
                not self.get_testname() == self.SUITE_JOB and
                self.view['status'] == 'ABORT' and
                not self.view['reason']):
            self.view['reason'] = 'Timed out, did not run.'


    def __getitem__(self, key):
        """Overload __getitem__ so that we can still use []

        @param key: A key of the tko test view.

        @returns: The value of an attribute in the view.

        """
        return self.view[key]


    def __iter__(self):
        """Overload __iter__ so that it supports 'in' operator."""
        return iter(self.view)


    def get_testname(self):
        """Get test name that should be shown in the output.

        Formalize the test_name we got from the test view.

        Remove 'build/suite' prefix if any.

        If one runs a test in control file via the following code,
           job.runtest('my_Test', tag='tag')
        for most of the cases, view['test_name'] would look like 'my_Test.tag'.
        If this is the case, this method will just return the original
        test name, i.e. 'my_Test.tag'.

        There are four special cases.
        1) A test view is for the suite job's SERVER_JOB.
           In this case, this method will return 'Suite job'.

        2) A test view is of a child job or a solo test run not part of a
           suite, and for a SERVER_JOB or CLIENT_JOB.
           In this case, we will take the job name, remove the build/suite
           prefix from the job name, and append the rest to 'SERVER_JOB'
           or 'CLIENT_JOB' as a prefix. So the names returned by this
           method will look like:
             'dummy_Pass_SERVER_JOB'
             'dummy_Fail_SERVER_JOB'

        3) A test view is of a suite job and its status is ABORT.
           In this case, the view['test_name'] is the child job's name.
           For instance,
             'lumpy-release/R35-5712.0.0/dummy/dummy_Pass'
             'lumpy-release/R35-5712.0.0/dummy/dummy_Fail'
           The above names will be converted to the following:
             'dummy_Pass'
             'dummy_Fail'

        4) A test view's status is of a suite job and its status is TEST_NA.
           In this case, the view['test_name'] is the NAME field of the control
           file. For instance,
             'dummy_Pass'
             'dummy_Fail'
           This method will not modify these names.

        @returns: Test name after normalization.

        """
        if self.testname is not None:
            return self.testname

        if (self.is_suite_view and
                self.view['test_name'].startswith('SERVER_JOB')):
            # Rename suite job's SERVER_JOB to 'Suite job'.
            self.testname = self.SUITE_JOB
            return self.testname

        if (self.view['test_name'].startswith('SERVER_JOB') or
                self.view['test_name'].startswith('CLIENT_JOB')):
            # Append job name as a prefix for SERVER_JOB and CLIENT_JOB
            testname= '%s_%s' % (self.view['job_name'], self.view['test_name'])
        else:
            testname = self.view['test_name']
        # Remove the build and suite name from testname if any.
        self.testname = tools.get_test_name(
                self.build, self.suite_name, testname)
        return self.testname


    def is_relevant_suite_view(self):
        """Checks whether this is a suite view we should care about.

        @returns: True if it is relevant. False otherwise.
        """
        return (self.get_testname() == self.SUITE_JOB or
                (self.is_suite_view and
                    not self.view['test_name'].startswith('CLIENT_JOB') and
                    not self.view['subdir']))


    def is_test(self):
        """Return whether the view is for an actual test.

        @returns True if the view is for an actual test.
                 False if the view is for SERVER_JOB or CLIENT_JOB.

        """
        return not (self.view['test_name'].startswith('SERVER_JOB') or
                self.view['test_name'].startswith('CLIENT_JOB'))


    def is_retry(self):
        """Check whether the view is for a retry.

        @returns: True, if the view is for a retry; False otherwise.

        """
        return self.view['job_keyvals'].get('retry_original_job_id') is not None


    def hit_timeout(self):
        """Check whether the corresponding job has hit its own timeout.

        Note this method should not be called for those test views
        that belongs to a suite job and are determined as irrelevant
        by is_relevant_suite_view.  This is because they are associated
        to the suite job, whose job start/finished time make no sense
        to an irrelevant test view.

        @returns: True if the corresponding afe job has hit timeout.
                  False otherwise.
        """
        if (self.is_relevant_suite_view() and
                self.get_testname() != self.SUITE_JOB):
            # Any relevant suite test view except SUITE_JOB
            # did not hit its own timeout because it was not ever run.
            return False
        start = (datetime.strptime(
                self.view['job_started_time'], time_utils.TIME_FMT)
                if self.view['job_started_time'] else None)
        end = (datetime.strptime(
                self.view['job_finished_time'], time_utils.TIME_FMT)
                if self.view['job_finished_time'] else None)
        if not start or not end:
            return False
        else:
            return ((end - start).total_seconds()/60.0
                        > self.afe_job.max_runtime_mins)


    def is_aborted(self):
        """Check if the view was aborted.

        For suite job and child job test views, we check job keyval
        'aborted_by' and test status.

        For relevant suite job test views, we only check test status
        because the suite job keyval won't make sense to individual
        test views.

        @returns: True if the test was as aborted, False otherwise.

        """

        if (self.is_relevant_suite_view() and
                self.get_testname() != self.SUITE_JOB):
            return self.view['status'] == 'ABORT'
        else:
            return (bool(self.view['job_keyvals'].get('aborted_by')) and
                    self.view['status'] in ['ABORT', 'RUNNING'])


    def is_in_fail_status(self):
        """Check if the given test's status corresponds to a failure.

        @returns: True if the test's status is FAIL or ERROR. False otherwise.

        """
        # All the statuses tests can have when they fail.
        return self.view['status'] in ['FAIL', 'ERROR', 'ABORT']


    def is_provision(self):
        """Check whether this is a provision test."""
        return self.get_testname() == 'provision'


    def get_buildbot_link_reason(self):
        """Generate the buildbot link reason for the test.

        @returns: A string representing the reason.

        """
        return ('%s: %s' % (self.view['status'], self.view['reason'])
                if self.view['reason'] else self.view['status'])


    def get_job_id_owner_str(self):
        """Generate the job_id_owner string for a test.

        @returns: A string which looks like 135036-username

        """
        return '%s-%s' % (self.view['afe_job_id'], self.user)


    def get_bug_info(self, suite_job_keyvals):
        """Get the bug info from suite_job_keyvals.

        If a bug has been filed for the test, its bug info (bug id and counts)
        will be stored in the suite job's keyvals. This method attempts to
        retrieve bug info of the test from |suite_job_keyvals|. It will return
        None if no bug info is found. No need to check bug info if the view is
        SUITE_JOB.

        @param suite_job_keyvals: The job keyval dictionary of the suite job.
                All the bug info about child jobs are stored in
                suite job's keyvals.

        @returns: None if there is no bug info, or a pair with the
                  id of the bug, and the count of the number of
                  times the bug has been seen.

        """
        if self.get_testname() == self.SUITE_JOB:
            return None
        if (self.view['test_name'].startswith('SERVER_JOB') or
                self.view['test_name'].startswith('CLIENT_JOB')):
            # Append job name as a prefix for SERVER_JOB and CLIENT_JOB
            testname= '%s_%s' % (self.view['job_name'], self.view['test_name'])
        else:
            testname = self.view['test_name']

        return tools.get_test_failure_bug_info(
                suite_job_keyvals, self.view['afe_job_id'],
                testname)


    def should_display_buildbot_link(self):
        """Check whether a buildbot link should show for this view.

        For suite job view, show buildbot link if it fails.
        For normal test view,
            show buildbot link if it is a retry
            show buildbot link if it hits its own timeout.
            show buildbot link if it fails. This doesn't
            include the case where it was aborted but has
            not hit its own timeout (most likely it was aborted because
            suite has timed out).

        @returns: True if we should show the buildbot link.
                  False otherwise.
        """
        is_bad_status = (self.view['status'] != 'GOOD' and
                         self.view['status'] != 'TEST_NA')
        if self.get_testname() == self.SUITE_JOB:
            return is_bad_status
        else:
            if self.is_retry():
                return True
            if is_bad_status:
                return not self.is_aborted() or self.hit_timeout()


    def get_control_file_attributes(self):
        """Get the attributes from the control file of the test.

        @returns: A list of test attribute or None.
        """
        control_file = self.afe_job.control_file
        attributes = None
        if control_file:
            cd = control_data.parse_control_string(control_file)
            attributes = list(cd.attributes)
        return attributes


    def override_afe_job_id(self, afe_job_id):
        """Overrides the AFE job id for the test.

        @param afe_job_id: The new AFE job id to use.
        """
        self.view['afe_job_id'] = afe_job_id


def log_buildbot_links(log_func, links):
    """Output buildbot links to log.

    @param log_func: Logging function to use.
    @param links: Iterable of LogLink instances.
    """
    for link in links:
        for generated_link in link.GenerateBuildbotLinks():
            log_func(generated_link)
        retry_link = link.GenerateRetryLink()
        if retry_link:
            log_func(retry_link)
        history_link = link.GenerateHistoryLink()
        if history_link:
            log_func(history_link)


class _ReturnCodeComputer(object):
    """This is responsible for returning the _ReturnResult for a suite."""

    def __call__(self, test_views):
        """Compute the exit code based on test results."""
        result = _RETURN_RESULTS['ok']

        for v in test_views:
            if v.get_testname() == TestView.SUITE_JOB:
                result |= self._get_suite_result(v)
            else:
                result |= self._get_test_result(v)
        return result

    def _get_suite_result(self, test_view):
        """Return the _ReturnResult for the given suite job."""
        # The order of checking each case is important.
        if test_view.is_aborted() and test_view.hit_timeout():
            return _RETURN_RESULTS['suite_timeout']
        elif test_view.is_in_fail_status():
            return _RETURN_RESULTS['suite_failed']
        elif test_view['status'] == 'WARN':
            return _RETURN_RESULTS['suite_warning']
        else:
            return _RETURN_RESULTS['ok']

    def _get_test_result(self, test_view):
        """Return the _ReturnResult for the given test job."""
        # The order of checking each case is important.
        if test_view.is_aborted() and test_view.is_relevant_suite_view():
            # The test was aborted before started
            # This gurantees that the suite has timed out.
            return _RETURN_RESULTS['test_aborted_prestart']
        elif test_view.is_aborted() and not test_view.hit_timeout():
            # The test was aborted, but
            # not due to a timeout. This is most likely
            # because the suite has timed out, but may
            # also because it was aborted by the user.
            # Since suite timing out is determined by checking
            # the suite job view, we simply ignore this view here.
            return _RETURN_RESULTS['test_aborted_mystery']
        elif test_view.is_in_fail_status():  # The test job failed
            if test_view.is_provision():
                return _RETURN_RESULTS['provision_failed']
            else:
                return _RETURN_RESULTS['test_failure']
        elif test_view['status'] == 'WARN':
            return _RETURN_RESULTS['test_warning']
        elif test_view.is_retry():
            # The test is a passing retry.
            return _RETURN_RESULTS['test_retry']
        else:
            return _RETURN_RESULTS['ok']


class _ProvisionReturnCodeComputer(_ReturnCodeComputer):
    """This is used for returning the _ReturnResult for provision suites."""

    def __init__(self, num_required):
        """Initialize instance.

        num_required is the number of passing provision jobs needed.
        """
        super(_ProvisionReturnCodeComputer, self).__init__()
        self._num_required = num_required
        self._num_successful = 0

    def __call__(self, test_views):
        result = super(_ProvisionReturnCodeComputer, self).__call__(test_views)
        if self._num_successful >= self._num_required:
            logging.info('Return result upgraded from %r'
                         ' due to enough ok provisions',
                         result)
            return _RETURN_RESULTS['ok']
        else:
            return result

    def _get_test_result(self, test_view):
        result = (super(_ProvisionReturnCodeComputer, self)
                  ._get_test_result(test_view))
        if result in {_RETURN_RESULTS[s] for s in ('ok', 'test_retry')}:
            self._num_successful += 1
        return result


class ResultCollector(object):
    """Collect test results of a suite or a single test run.

    Once a suite job has finished, use this class to collect test results.
    `run` is the core method that is to be called first. Then the caller
    could retrieve information like return code, return message, is_aborted,
    and timings by accessing the collector's public attributes. And output
    the test results and links by calling the 'output_*' methods.

    Here is a overview of what `run` method does.

    1) Collect the suite job's results from tko_test_view_2.
    For the suite job, we only pull test views without a 'subdir'.
    A NULL subdir indicates that the test was _not_ executed. This could be
    that no child job was scheduled for this test or the child job got
    aborted before starts running.
    (Note 'SERVER_JOB'/'CLIENT_JOB' are handled specially)

    2) Collect the child jobs' results from tko_test_view_2.
    For child jobs, we pull all the test views associated with them.
    (Note 'SERVER_JOB'/'CLIENT_JOB' are handled specially)

    3) Generate web and buildbot links.
    4) Compute timings of the suite run.
    5) Compute the return code based on test results.

    @var _instance_server: The hostname of the server that is used
                           to service the suite.
    @var _afe: The afe rpc client.
    @var _tko: The tko rpc client.
    @var _build: The build for which the suite is run,
                 e.g. 'lumpy-release/R35-5712.0.0'
    @var _suite_name: The suite name, e.g. 'bvt', 'dummy'.
    @var _suite_job_id: The job id of the suite for which we are going to
                        collect results.
    @var _original_suite_name: The suite name we record timing would be
                               different from _suite_name when running
                               suite_attr_wrapper.
    @var _return_code_function: Called to return what the overall result of
                                the suite is.
    @var _suite_views: A list of TestView objects, representing relevant
                       test views of the suite job.
    @var _child_views: A list of TestView objects, representing test views
                       of the child jobs.
    @var _test_views: A list of TestView objects, representing all test views
                      from _suite_views and _child_views.
    @var _web_links: A list of web links pointing to the results of jobs.
    @var buildbot_links: A list of buildbot links for non-passing tests.
    @var _solo_test_run: True if this is a single test run.
    @var return_result: The _ReturnResult of the suite run.
    @var is_aborted: Whether the suite was aborted or not.
                     True, False or None (aborting status is unknown yet)
    @var timings: A Timing object that records the suite's timings.

    """


    def __init__(self, instance_server, afe, tko, build,
                 suite_name, suite_job_id, return_code_function,
                 original_suite_name=None,
                 user=None, solo_test_run=False):
        self._instance_server = instance_server
        self._afe = afe
        self._tko = tko
        self._build = build
        self._suite_name = suite_name
        self._suite_job_id = suite_job_id
        self._original_suite_name = original_suite_name or suite_name
        self._return_code_function = return_code_function
        self._suite_views = []
        self._child_views = []
        self._test_views = []
        self._retry_counts = {}
        self._missing_results = {}
        self._web_links = []
        self.buildbot_links = []
        self._num_child_jobs = 0
        self.return_result = None
        self.is_aborted = None
        self.timings = None
        self._user = user or getpass.getuser()
        self._solo_test_run = solo_test_run


    def _fetch_relevant_test_views_of_suite(self):
        """Fetch relevant test views of the suite job.

        For the suite job, there will be a test view for SERVER_JOB, and views
        for results of its child jobs. For example, assume we've created
        a suite job (afe_job_id: 40) that runs dummy_Pass, dummy_Fail,
        dummy_Pass.bluetooth. Assume dummy_Pass was aborted before running while
        dummy_Path.bluetooth got TEST_NA as no duts have bluetooth.
        So the suite job's test views would look like
        _____________________________________________________________________
        test_idx| job_idx|test_name           |subdir      |afe_job_id|status
        10      | 1000   |SERVER_JOB          |----        |40        |GOOD
        11      | 1000   |dummy_Pass          |NULL        |40        |ABORT
        12      | 1000   |dummy_Fail.Fail     |41-onwer/...|40        |FAIL
        13      | 1000   |dummy_Fail.Error    |42-owner/...|40        |ERROR
        14      | 1000   |dummy_Pass.bluetooth|NULL        |40        |TEST_NA

        For a suite job, we only care about
        a) The test view for the suite job's SERVER_JOB
        b) The test views for real tests without a subdir. A NULL subdir
           indicates that a test didn't get executed.
        So, for the above example, we only keep test views whose test_idxs
        are 10, 11, 14.

        @returns: A list of TestView objects, representing relevant
                  test views of the suite job.

        """
        suite_job = self._afe.get_jobs(id=self._suite_job_id)[0]
        views = self._tko.run(call='get_detailed_test_views',
                              afe_job_id=self._suite_job_id)
        relevant_views = []
        for v in views:
            v = TestView(v, suite_job, self._suite_name, self._build, self._user,
                         solo_test_run=self._solo_test_run)
            if v.is_relevant_suite_view():
                # If the test doesn't have results in TKO and is being
                # displayed in the suite view instead of the child view,
                # then afe_job_id is incorrect and from the suite.
                # Override it based on the AFE job id which was missing
                # results.
                # TODO: This is likely inaccurate if a test has multiple
                # tries which all fail TKO parse stage.
                if v['test_name'] in self._missing_results:
                    v.override_afe_job_id(
                            self._missing_results[v['test_name']][0])
                relevant_views.append(v)
        return relevant_views


    def _compute_retry_count(self, view):
        """Return how many times the test has been retried.

        @param view: A TestView instance.
        @returns: An int value indicating the retry count.

        """
        old_job = view['job_keyvals'].get('retry_original_job_id')
        count = 0
        while old_job:
            count += 1
            views = self._tko.run(
                call='get_detailed_test_views', afe_job_id=old_job)
            old_job = (views[0]['job_keyvals'].get('retry_original_job_id')
                       if views else None)
        return count


    def _fetch_test_views_of_child_jobs(self, jobs=None):
        """Fetch test views of child jobs.

        @returns: A tuple (child_views, retry_counts, missing_results)
                  child_views is list of TestView objects, representing
                  all valid views.
                  retry_counts is a dictionary that maps test_idx to retry
                  counts. It only stores retry counts that are greater than 0.
                  missing_results is a dictionary that maps test names to
                  lists of job ids.

        """
        child_views = []
        retry_counts = {}
        missing_results = {}
        child_jobs = jobs or self._afe.get_jobs(parent_job_id=self._suite_job_id)
        if child_jobs:
            self._num_child_jobs = len(child_jobs)
        for job in child_jobs:
            views = [TestView(v, job, self._suite_name, self._build, self._user)
                     for v in self._tko.run(
                         call='get_detailed_test_views', afe_job_id=job.id,
                         invalid=0)]
            if len(views) == 0:
                missing_results.setdefault(job.name, []).append(job.id)
            contains_test_failure = any(
                    v.is_test() and v['status'] != 'GOOD' for v in views)
            for v in views:
                if (v.is_test() or
                        v['status'] != 'GOOD' and not contains_test_failure):
                    # For normal test view, just keep it.
                    # For SERVER_JOB or CLIENT_JOB, only keep it
                    # if it fails and no other test failure.
                    child_views.append(v)
                    retry_count = self._compute_retry_count(v)
                    if retry_count > 0:
                        retry_counts[v['test_idx']] = retry_count
        return child_views, retry_counts, missing_results


    def _generate_web_and_buildbot_links(self):
        """Generate web links and buildbot links."""
        # TODO(fdeng): If a job was aborted before it reaches Running
        # state, we read the test view from the suite job
        # and thus this method generates a link pointing to the
        # suite job's page for the aborted job. Need a fix.
        self._web_links = []
        self.buildbot_links = []

        # Bug info are stored in the suite job's keyvals.
        if self._solo_test_run:
            suite_job_keyvals = {}
        elif not self._suite_views:
            suite_job_keyvals = {}
        else:
            suite_job_keyvals = self._suite_views[0]['job_keyvals']

        for v in self._test_views:
            retry_count = self._retry_counts.get(v['test_idx'], 0)
            bug_info = v.get_bug_info(suite_job_keyvals)
            job_id_owner = v.get_job_id_owner_str()
            link = LogLink(
                    anchor=v.get_testname(),
                    server=self._instance_server,
                    job_string=job_id_owner,
                    bug_info=bug_info, retry_count=retry_count,
                    testname=v.get_testname(),
                    sponge_url=suite_job_keyvals.get('sponge_url'))
            self._web_links.append(link)

            if v.should_display_buildbot_link():
                link.reason = v.get_buildbot_link_reason()
                self.buildbot_links.append(link)


    def _record_timings(self):
        """Record suite timings."""
        self.timings = Timings(self._suite_job_id)
        for v in self._test_views:
            self.timings.RecordTiming(v)


    def _compute_return_code(self):
        """Compute the exit code based on test results."""
        self.return_result = self._return_code_function(self._test_views)


    def _make_test_results(self):
        """Make TestResults for collected tests.

        @returns: List of TestResult instances.
        """
        test_results = []
        for test_view in self._test_views:
            test_result = TestResult(
                test_view=test_view,
                retry_count=self._retry_counts.get(test_view['test_idx'], 0))
            test_results.append(test_result)
        return test_results


    def output_results(self):
        """Output test results, timings and web links."""
        # Output test results
        test_results = self._make_test_results()
        if len(test_results) == 0:
            max_name_length = 0
        else:
            max_name_length = max(len(t.name) for t in test_results)
        for test_result in test_results:
            test_result.log_using(logging.info, max_name_length + 3)
        # Output suite timings
        logging.info(self.timings)
        # Output links to test logs
        logging.info('\nLinks to test logs:')
        for link in self._web_links:
            logging.info(link.text_link)
        logging.info('\n')


    def get_results_dict(self):
        """Write test results, timings and web links into a dict.

        @returns: A dict of results in the format like:
                  {
                  'tests': {
                        'test_1': {'status': 'PASSED', 'attributes': [1,2], ...}
                        'test_2': {'status': 'FAILED', 'attributes': [1],...}
                  }
                  'suite_timings': {
                        'download_start': '1998-07-17 00:00:00',
                        'payload_download_end': '1998-07-17 00:00:05',
                        ...
                  }
                  }
        """
        output_dict = {}
        tests_dict = output_dict.setdefault('tests', {})
        for v in self._test_views:
            test_name = v.get_testname()
            test_info = tests_dict.setdefault(test_name, {})
            test_info.update({
                'status': v['status'],
                'attributes': v.get_control_file_attributes() or list(),
                'reason': v['reason'],
                'retry_count': self._retry_counts.get(v['test_idx'], 0),
                })
            # For aborted test, the control file will not be parsed and thus
            # fail to get the attributes info. Therefore, the subsystems the
            # abort test testing will be missing. For this case, we will assume
            # the aborted test will test all subsystems, set subsystem:default.
            if (test_info['status'] == 'ABORT' and
                not any('subsystem:' in a for a in test_info['attributes'])):
                test_info['attributes'].append('subsystem:default')

        # Write the links to test logs into the |tests_dict| of |output_dict|.
        # For test whose status is not 'GOOD', the link is also buildbot_link.
        for link in self._web_links:
            test_name = link.anchor.strip()
            test_info = tests_dict.get(test_name)
            if test_info:
                test_info['link_to_logs'] = link.url
                test_info['sponge_url'] = link.sponge_url
                # Write the retry dashboard link into the dict.
                if link in self.buildbot_links and link.testname:
                    test_info['retry_dashboard_link'] \
                        = reporting_utils.link_retry_url(link.testname)
                    # Always write the wmatrix link for compatibility.
                    test_info['wmatrix_link'] \
                        = reporting_utils.link_wmatrix_retry_url(link.testname)
                # Write the bug url into the dict.
                if link.bug_id:
                    test_info['bug_url'] = link.bug_url

        # Write the suite timings into |output_dict|
        timings = self.timings
        if timings is not None:
            time_dict = output_dict.setdefault('suite_timings', {})
            time_dict.update({
                'download_start' : str(timings.download_start_time),
                'payload_download_end' : str(timings.payload_end_time),
                'suite_start' : str(timings.suite_start_time),
                'artifact_download_end' : str(timings.artifact_end_time),
                'tests_start' : str(timings.tests_start_time),
                'tests_end' : str(timings.tests_end_time),
                })

        output_dict['suite_job_id'] = self._suite_job_id

        return output_dict


    def run(self):
        """Collect test results.

        This method goes through the following steps:
            Fetch relevent test views of the suite job.
            Fetch test views of child jobs
            Check whether the suite was aborted.
            Generate links.
            Calculate suite timings.
            Compute return code based on the test result.

        """
        if self._solo_test_run:
            self._test_views, self._retry_counts, self._missing_results = (
                  self._fetch_test_views_of_child_jobs(
                          jobs=self._afe.get_jobs(id=self._suite_job_id)))
        else:
            self._child_views, self._retry_counts, self._missing_results = (
                    self._fetch_test_views_of_child_jobs())
            self._suite_views = self._fetch_relevant_test_views_of_suite()
            self._test_views = self._suite_views + self._child_views
        # For hostless job in Starting status, there is no test view associated.
        # This can happen when a suite job in Starting status is aborted. When
        # the scheduler hits some limit, e.g., max_hostless_jobs_per_drone,
        # max_jobs_started_per_cycle, a suite job can stays in Starting status.
        if not self._test_views:
            self.return_result = _RETURN_RESULTS['test_views_missing']
            return
        self.is_aborted = any([view['job_keyvals'].get('aborted_by')
                               for view in self._suite_views])
        self._generate_web_and_buildbot_links()
        self._record_timings()
        self._compute_return_code()


    def gather_timing_stats(self):
        """Collect timing related statistics."""
        # Record suite runtime in metadata db.
        # Some failure modes can leave times unassigned, report sentinel value
        # in that case.
        runtime_in_secs = -1
        if (self.timings.tests_end_time is not None and
            self.timings.suite_start_time is not None):
            runtime_in_secs = (self.timings.tests_end_time -
                    self.timings.suite_start_time).total_seconds()


def _make_child_dependencies(options):
    """Creates a list of extra dependencies for child jobs.

    @param options: Parsed arguments to run_suite.

    @returns: A list of label strings if any dependencies should be added. None
            otherwise.
    """
    if not options.model:
        return ()
    return ('model:%s' % options.model,)


@retry.retry(error.StageControlFileFailure, timeout_min=10)
def create_suite(afe, options):
    """Create a suite with retries.

    @param afe: The afe object to insert the new suite job into.
    @param options: The options to use in creating the suite.

    @return: The afe_job_id of the new suite job.
    """
    logging.info('%s Submitted create_suite_job rpc',
                 diagnosis_utils.JobTimer.format_time(datetime.now()))

    # TODO(crbug.com/763207): This is to support calling old moblab RPC
    # with ToT code.  This does not need to be supported after M62.
    if options.oldrpc:
        suite_args = options.suite_args
        if 'tests' in suite_args:
            # This is for test_that_wrapper
            suite_args = ' '.join([':lab:'] + suite_args['tests'])
        else:
            # This is for suite_attr_wrapper
            suite_args = repr(suite_args)
        options.suite_args = suite_args

    return afe.run(
        'create_suite_job',
        name=options.name,
        board=options.board,
        builds=suite_common.make_builds_from_options(options),
        test_source_build=options.test_source_build,
        check_hosts=not options.no_wait,
        pool=options.pool,
        file_bugs=options.file_bugs,
        priority=options.priority,
        suite_args=options.suite_args,
        wait_for_results=not options.no_wait,
        timeout_mins=options.timeout_mins + options.delay_minutes,
        max_runtime_mins=options.max_runtime_mins + options.delay_minutes,
        job_retry=options.retry,
        max_retries=options.max_retries,
        suite_min_duts=options.suite_min_duts,
        offload_failures_only=options.offload_failures_only,
        run_prod_code=options.run_prod_code,
        delay_minutes=options.delay_minutes,
        job_keyvals=options.job_keyvals,
        test_args=options.test_args,
        child_dependencies=options.child_dependencies,
    )


def _run_suite(options):
    """
    run_suite script without exception handling.

    @param options: The parsed options.

    @returns: A tuple contains the return_code of run_suite and the dictionary
              of the output.

    """
    # If indicate to use the new style suite control file, convert the args
    if options.use_suite_attr:
        options = change_options_for_suite_attr(options)

    log_name = _get_log_name(options)
    utils.setup_logging(logfile=log_name)

    if not options.bypass_labstatus and not options.web:
        utils.check_lab_status(options.build)

    afe = _create_afe(options)
    instance_server = afe.server

    rpc_helper = diagnosis_utils.RPCHelper(afe)
    is_real_time = True
    if options.mock_job_id:
        job_id = int(options.mock_job_id)
        existing_job = afe.get_jobs(id=job_id, finished=True)
        if existing_job:
            is_real_time = False
        else:
            existing_job = afe.get_jobs(id=job_id)
        if existing_job:
            job_created_on = time_utils.date_string_to_epoch_time(
                    existing_job[0].created_on)
        else:
            raise utils.TestLabException('Failed to retrieve job: %d' % job_id)
    else:
        try:
            rpc_helper.check_dut_availability(options.dependencies,
                                              options.minimum_duts,
                                              options.skip_duts_check)
            job_id = create_suite(afe, options)
            job_created_on = time.time()
        except (error.CrosDynamicSuiteException,
                error.RPCException, proxy.JSONRPCException) as e:
            logging.exception('Error Message: %s', e)
            return run_suite_common.SuiteResult(
                    run_suite_common.RETURN_CODES.INFRA_FAILURE,
                    {'return_message': str(e)})
        except AttributeError as e:
            logging.exception('Error Message: %s', e)
            return run_suite_common.SuiteResult(
                    run_suite_common.RETURN_CODES.INVALID_OPTIONS)

    job_timer = diagnosis_utils.JobTimer(
            job_created_on, float(options.timeout_mins))
    job_url = reporting_utils.link_job(job_id,
                                       instance_server=instance_server)
    _log_create_task(job_timer, job_url, job_id)

    if options.create_and_return:
        msg = '--create_and_return was specified, terminating now.'
        logging.info(msg)
        return run_suite_common.SuiteResult(
                run_suite_common.RETURN_CODES.OK,
                {'return_message': msg})

    if options.no_wait:
        return _handle_job_nowait(job_id, options, instance_server)
    else:
        return _handle_job_wait(afe, job_id, options, job_timer, is_real_time)


def _get_log_name(options):
    """Return local log file's name.

    @param options:         Parsed options.

    @return log_name, a string file name.
    """
    if options.require_logfile:
        # options.build is verified to exist in verify_options.
        # convert build name from containing / to containing only _.
        log_name = 'run_suite-%s.log' % options.build.replace('/', '_')
        log_dir = os.path.join(common.autotest_dir, 'logs')
        if os.path.exists(log_dir):
            log_name = os.path.join(log_dir, log_name)

        return log_name
    else:
        return None


def _create_afe(options):
    """Return an afe instance based on options.

    @param options          Parsed options.

    @return afe, an AFE instance.
    """
    instance_server = (options.web if options.web else
                       instance_for_pool(options.pool))
    afe = frontend_wrappers.RetryingAFE(server=instance_server,
                                        timeout_min=options.afe_timeout_mins,
                                        delay_sec=options.delay_sec)
    logging.info('Autotest instance created: %s', instance_server)
    return afe


def _handle_job_wait(afe, job_id, options, job_timer, is_real_time):
    """Handle suite job synchronously.

    @param afe              AFE instance.
    @param job_id           Suite job id.
    @param options          Parsed options.
    @param job_timer        JobTimer for suite job.
    @param is_real_time     Whether or not to handle job timeout.

    @return SuiteResult of suite job.
    """
    rpc_helper = diagnosis_utils.RPCHelper(afe)
    instance_server = afe.server
    while not afe.get_jobs(id=job_id, finished=True):
        _poke_buildbot_with_output(afe, job_id, job_timer)
        if job_timer.debug_output_timer.poll():
            logging.info('The suite job has another %s till timeout.',
                         job_timer.timeout_hours - job_timer.elapsed_time())
        time.sleep(10)
    logging.info('%s Suite job is finished.',
                 diagnosis_utils.JobTimer.format_time(datetime.now()))
    # For most cases, ResultCollector should be able to determine whether
    # a suite has timed out by checking information in the test view.
    # However, occationally tko parser may fail on parsing the
    # job_finished time from the job's keyval file. So we add another
    # layer of timeout check in run_suite. We do the check right after
    # the suite finishes to make it as accurate as possible.
    # There is a minor race condition here where we might have aborted
    # for some reason other than a timeout, and the job_timer thinks
    # it's a timeout because of the jitter in waiting for results.
    # The consequence would be that run_suite exits with code
    # SUITE_TIMEOUT while it should  have returned INFRA_FAILURE
    # instead, which should happen very rarely.
    # Note the timeout will have no sense when using -m option.
    is_suite_timeout = job_timer.is_suite_timeout()

    # Extract the original suite name to record timing.
    original_suite_name = get_original_suite_name(options.name,
                                                  options.suite_args)
    # Start collecting test results.
    logging.info('%s Start collecting test results and dump them to json.',
                 diagnosis_utils.JobTimer.format_time(datetime.now()))
    TKO = frontend_wrappers.RetryingTKO(server=instance_server,
                                        timeout_min=options.afe_timeout_mins,
                                        delay_sec=options.delay_sec)
    # TODO(crbug.com/672348): It needs to be possible for provision
    # suite to pass if only a few tests fail.  Otherwise, a single
    # failing test will be reported as failure even if the suite reports
    # success.
    if options.name == _PROVISION_SUITE:
        # TODO(crbug.com/672348): Creating the suite job requires that
        # suite_args contains num_required.
        return_code_function = _ProvisionReturnCodeComputer(
            num_required=options.suite_args['num_required'])
    else:
        return_code_function = _ReturnCodeComputer()
    collector = ResultCollector(instance_server=instance_server,
                                afe=afe, tko=TKO, build=options.build,
                                suite_name=options.name,
                                suite_job_id=job_id,
                                return_code_function=return_code_function,
                                original_suite_name=original_suite_name)
    collector.run()
    # Dump test outputs into json.
    output_dict = collector.get_results_dict()
    output_dict['autotest_instance'] = instance_server
    if not options.json_dump:
        collector.output_results()
    result = collector.return_result
    if is_real_time:
        # Do not record stats if the suite was aborted (either by a user
        # or through the golo rpc).
        # Also do not record stats if is_aborted is None, indicating
        # aborting status is unknown yet.
        if collector.is_aborted == False:
            logging.info('%s Gathering timing stats for the suite job.',
                         diagnosis_utils.JobTimer.format_time(datetime.now()))
            collector.gather_timing_stats()

        if collector.is_aborted == True and is_suite_timeout:
            # There are two possible cases when a suite times out.
            # 1. the suite job was aborted due to timing out
            # 2. the suite job succeeded, but some child jobs
            #    were already aborted before the suite job exited.
            # The case 2 was handled by ResultCollector,
            # here we handle case 1.
            result |= _RETURN_RESULTS['suite_timeout']
        logging.info('\n %s Attempting to display pool info: %s',
                     diagnosis_utils.JobTimer.format_time(datetime.now()),
                     options.pool)
        try:
            # Add some jitter to make up for any latency in
            # aborting the suite or checking for results.
            cutoff = job_timer.timeout_hours + timedelta(hours=0.3)
            rpc_helper.diagnose_pool(options.dependencies, cutoff)
        except proxy.JSONRPCException:
            logging.warning('Unable to display pool info.')

    # And output return message.
    if result.message:
        logging.info('Reason: %s', result.message)

    logging.info('\n %s Output below this line is for buildbot consumption:',
                 diagnosis_utils.JobTimer.format_time(datetime.now()))
    log_buildbot_links(logging.info, collector.buildbot_links)
    return result.suite_result(output_dict)


def _handle_job_nowait(job_id, options, instance_server):
    """Handle suite job asynchronously.

    @param job_id           Suite job id.
    @param options          Parsed options.
    @param instance_server  Autotest instance hostname.

    @return SuiteResult of suite job.
    """
    logging.info('Created suite job: %r', job_id)
    link = LogLink(options.name, instance_server,
                   '%s-%s' % (job_id, getpass.getuser()))
    for generate_link in link.GenerateBuildbotLinks():
        logging.info(generate_link)
    logging.info('--no_wait specified; Exiting.')
    return run_suite_common.SuiteResult(
            run_suite_common.RETURN_CODES.OK,
            {'return_message': '--no_wait specified; Exiting.'})


def _should_run(options):
    """Check whether the suite should be run based on lab/job status checking.

    @param options          Parsed options.
    """
    try:
        site_utils.check_lab_status(options.test_source_build)
    except site_utils.TestLabException as ex:
        logging.exception('Lab is closed or build is blocked. Skipping '
                          'suite %s, board %s, build %s:  %s',
                          options.name, options.board,
                          options.test_source_build, str(ex))
        return False

    start_time = str(datetime.now() -
                     timedelta(days=_SEARCH_JOB_MAX_DAYS))
    afe = _create_afe(options)
    afe_jobs = afe.get_jobs(
            name__istartswith=options.test_source_build,
            name__iendswith='control.'+options.name,
            created_on__gte=start_time,
            min_rpc_timeout=_MIN_RPC_TIMEOUT)
    if options.model:
        model_tag = 'model:%s' % options.model
        filtered_jobs = [j for j in afe_jobs if model_tag in j.control_file]
    else:
        filtered_jobs = afe_jobs

    if filtered_jobs:
        logging.info('Found duplicate suite %s scheduled in past.',
                     filtered_jobs)
        return False

    return True


def _poke_buildbot_with_output(afe, job_id, job_timer):
    """Poke buildbot so it doesn't timeout from silence.

    @param afe              AFE instance.
    @param job_id           Suite job id.
    @param job_timer        JobTimer for suite job.
    """
    rpc_helper = diagnosis_utils.RPCHelper(afe)
    # Note that this call logs output, preventing buildbot's
    # 9000 second silent timeout from kicking in. Let there be no
    # doubt, this is a hack. The timeout is from upstream buildbot and
    # this is the easiest work around.
    if job_timer.first_past_halftime():
        rpc_helper.diagnose_job(job_id, afe.server)



def _run_task(options):
    """Perform this script's function minus setup.

    Boilerplate like argument parsing, logging, output formatting happen
    elsewhere.

    Returns a SuiteResult instance.

    TODO(ayatane): The try/except should be moved into _run_suite().
    Good luck trying to figure out which function calls are supposed to
    raise which of the exceptions.
    """
    try:
        return _run_suite(options)
    except diagnosis_utils.DUTsNotAvailableError as e:
        result = run_suite_common.SuiteResult(
            run_suite_common.RETURN_CODES.BOARD_NOT_AVAILABLE,
            {'return_message': 'Skipping testing: %s' % e.message})
        logging.info(result.output_dict['return_message'])
        return result
    except utils.TestLabException as e:
        result = run_suite_common.SuiteResult(
            run_suite_common.RETURN_CODES.INFRA_FAILURE,
            {'return_message': 'TestLabException: %s' % e})
        logging.exception(result.output_dict['return_message'])
        return result


class _ExceptionHandler(object):
    """Global exception handler replacement."""

    def __init__(self, dump_json):
        """Initialize instance.

        @param dump_json: Whether to print a JSON dump of the result dict to
                          stdout.
        """
        self._should_dump_json = dump_json

    def __call__(self, exc_type, value, traceback):
        if self._should_dump_json:
            run_suite_common.dump_json(
                    {'return_message': ('Unhandled run_suite exception: %s'
                                        % value)})
        sys.exit(run_suite_common.RETURN_CODES.INFRA_FAILURE)


def _log_create_task(job_timer, job_url, job_id):
    """Logging for task creation."""
    logging.info('%s Created suite job: %s',
                 job_timer.format_time(job_timer.job_created_time),
                 job_url)
    logging.info(annotations.StepLink(text='Link to suite', url=job_url))
    # For task id parsing of chromite HWTestStage.
    logging.info('Created task id: %s', job_id)


def _if_run_in_skylab(options):
    """Detect whether to run suite in skylab.

    Returns:
        A tuple of (bool, string, string) to indicate
            (if_use_skylab, override_pool, override_qs_account)
    """
    # An autotest job id is a number of at least 9 digits, e.g. 296843118.
    # A skylab task id is of 16 chars, e.g. 43cabbb4e118ea10.
    if len(str(options.mock_job_id)) >= 16:
        # No override info is needed if mock_job_id is specified.
        return True, '', ''

    if not _ENABLE_RUN_SUITE_TRAMPOLINE:
        logging.info('trampoline to skylab is not enabled.')
        return False, '', ''

    task_info = 'suite:%s, board:%s, model:%s, pool:%s' % (
            options.name, options.board, options.model, options.pool)
    ctx = gs.GSContext()
    with osutils.TempDir(prefix='trampoline_') as tempdir:
        temp_file = os.path.join(tempdir, _MIGRATION_CONFIG_FILE)
        ctx.Copy(_TRAMPOLINE_CONFIG, temp_file)
        _migration_config = config_reader.MigrationConfig(
                config_reader.ConfigReader(temp_file))

        logging.info('Checking whether to run in skylab: Task(%s)', task_info)
        if skylab.should_run_in_skylab(_migration_config,
                                       options.board,
                                       options.model,
                                       options.name,
                                       options.pool):
            logging.info('Task (%s) Should run in skylab', task_info)
            override_pool, override_qs_account = skylab.get_override_info(
                    _migration_config,
                    options.board,
                    options.model,
                    options.name,
                    options.pool)
            return True, override_pool, override_qs_account

    logging.info('Task (%s) Should run in autotest', task_info)
    return False, '', ''


def _get_skylab_suite_result(child_tasks):
    """Parse skylab task result to get final result for the suite.

    @param child_tasks: A list of json dict of task result object, whose format
        is: {
                'name': ...,
                'state': ...,
                'failure': ...
            }.
    """
    _final_suite_states = run_suite_common.get_final_skylab_suite_states()
    for ct in child_tasks:
        logging.info('Parsing test %r', ct)
        state = run_suite_common.get_final_skylab_task_state(ct)

        if (state not in run_suite_common.IGNORED_TEST_STATE and
            state in _final_suite_states):
            return _final_suite_states[state][1]

    return run_suite_common.RETURN_CODES.OK


def _log_skylab_for_buildbot(stdout):
    """Output skylab logs to buildbot.

    @param stdout: A string.
    """
    logging.info('\n %s Output below this line is for buildbot consumption:',
                 diagnosis_utils.JobTimer.format_time(datetime.now()))
    logging.info(stdout)


def _run_paygen_with_skylab(options, override_pool, override_qs_account):
    """Run paygen suites with skylab."""
    builds = suite_common.make_builds_from_options(options)
    skylab_tool = os.environ.get('SKYLAB_TOOL') or _SKYLAB_TOOL
    test_source_build = suite_common.get_test_source_build(builds)
    pool = ('DUT_POOL_%s' % options.pool.upper()
            if not override_pool else override_pool)
    paygen_tests = paygen.get_paygen_tests(test_source_build, options.name)
    for test in paygen_tests:
        cmd = [skylab_tool, 'create-test']
        cmd += paygen.paygen_skylab_args(
                test, options.name, test_source_build, pool, options.board,
                options.model, options.timeout_mins,
                override_qs_account, _SKYLAB_SERVICE_ACCOUNT)
        job_created_on = time.time()
        try:
            res = cros_build_lib.RunCommand(cmd, capture_output=True)
        except cros_build_lib.RunCommandError as e:
            logging.error(str(e))
            return run_suite_common.SuiteResult(
                    run_suite_common.RETURN_CODES.INFRA_FAILURE)

        logging.info(res.output)
        job_url = res.output.split()[-1]
        job_id = job_url.split('id=')[-1]
        job_timer = diagnosis_utils.JobTimer(
                job_created_on, float(options.timeout_mins))
        _log_create_task(job_timer, job_url, job_id)

    return run_suite_common.SuiteResult(run_suite_common.RETURN_CODES.OK)


def _run_with_skylab(options, override_pool, override_qs_account):
    """Run suite inside skylab."""
    if paygen.is_paygen_suite(options.name):
        return _run_paygen_with_skylab(options, override_pool,
                                       override_qs_account)

    builds = suite_common.make_builds_from_options(options)
    skylab_tool = os.environ.get('SKYLAB_TOOL') or _SKYLAB_TOOL
    pool = override_pool or options.pool
    if options.mock_job_id:
        taskID = options.mock_job_id
        cmd = [skylab_tool, 'wait-suite',
               '-timeout-mins', str(options.timeout_mins),
               '-service-account-json', _SKYLAB_SERVICE_ACCOUNT,
               taskID]
        try:
            res = cros_build_lib.RunCommand(cmd, capture_output=True)
        except cros_build_lib.RunCommandError as e:
            logging.error(str(e))
            return run_suite_common.SuiteResult(
                    run_suite_common.RETURN_CODES.INFRA_FAILURE)

        output = json.loads(res.output)
        child_tasks = output['child-results']
        task_stdout = output['stdout']

        return_code = _get_skylab_suite_result(child_tasks)
        _log_skylab_for_buildbot(task_stdout)
        return run_suite_common.SuiteResult(return_code)
    else:
        cmd = [skylab_tool, 'create-suite',
               '-board', options.board,
               '-image', builds[provision.CROS_VERSION_PREFIX],
               '-pool', pool,
               '-timeout-mins', str(options.timeout_mins),
               '-priority', str(skylab_priority_for(options.priority)),
               '-service-account-json', _SKYLAB_SERVICE_ACCOUNT]
        if override_qs_account:
            cmd.extend(['-qs-account', override_qs_account])

        if options.max_retries is not None:
            cmd.extend(['-max-retries', str(options.max_retries)])

        if options.model is not None:
            cmd.extend(['-model', options.model])

        tags = ['skylab:run_suite_trampoline']
        for t in tags:
            cmd.extend(['-tag', t])

        unsupported_skylab_keyvals = ['datastore_parent_key']
        if options.job_keyvals is not None:
            for k, v in options.job_keyvals.iteritems():
                if k in unsupported_skylab_keyvals:
                    continue

                cmd.extend(['-keyval', '%s:%s' % (k, v)])

        cmd.extend([options.name])
        job_created_on = time.time()
        res = cros_build_lib.RunCommand(cmd, capture_output=True)
        # TODO (xixuan): The parsing will change with crbug.com/935244.
        logging.info(res.output)
        job_url = res.output.split()[-1]
        job_id = job_url.split('id=')[-1]
        job_timer = diagnosis_utils.JobTimer(
                job_created_on, float(options.timeout_mins))
        _log_create_task(job_timer, job_url, job_id)
        return run_suite_common.SuiteResult(run_suite_common.RETURN_CODES.OK)


def _run_with_autotest(options):
    """Run suite inside autotest."""
    if options.pre_check and not _should_run(options):
        logging.info('Suite %s-%s is terminated: Lab is closed, OR build is '
                     'blocked, OR this suite has already been kicked off '
                     'once in past %d days.',
                     options.test_source_build, options.name,
                     _SEARCH_JOB_MAX_DAYS)
        result = run_suite_common.SuiteResult(
            run_suite_common.RETURN_CODES.ERROR,
            {'return_message': ("Lab is closed OR other reason"
                                " (see code, it's complicated)")})
    else:
        result = _run_task(options)

    if options.json_dump:
        run_suite_common.dump_json(result.output_dict)

    return result


def main():
    """Entry point."""
    utils.verify_not_root_user()

    parser = make_parser()
    options = parser.parse_args()
    if options.do_nothing:
        return 0

    sys.exceptionhandler = _ExceptionHandler(dump_json=options.json_dump)
    if options.json_dump:
        logging.disable(logging.CRITICAL)

    options_okay = verify_and_clean_options(options)
    # Set StreamHandler first to capture error messages if suite is not run.
    utils.setup_logging()
    if not options_okay:
        parser.print_help()
        result = run_suite_common.SuiteResult(
                run_suite_common.RETURN_CODES.INVALID_OPTIONS)
    else:
        try:
            is_skylab, ovrd_pool, ovrd_qs_account = _if_run_in_skylab(options)
        except Exception as e:
            logging.exception(str(e))
            logging.info('fall back to Autotest due to trampoline errors')
            is_skylab = False
            ovrd_pool = ''
            ovrd_qs_account = ''

        if is_skylab:
            result = _run_with_skylab(options, ovrd_pool, ovrd_qs_account)
        else:
            result = _run_with_autotest(options)

    logging.info('Will return from run_suite with status: %s',
                  run_suite_common.RETURN_CODES.get_string(result.return_code))
    return result.return_code


if __name__ == "__main__":
    sys.exit(main())
