Exemplo n.º 1
0
    def update_image(self):
        """Updates the device image and verifies success."""
        autoupdate_cmd = ('%s --update --omaha_url=%s' %
                          (self.updater_ctrl_bin, self.update_url))
        run_args = {'command': autoupdate_cmd, 'timeout': 3600}
        err_prefix = ('Failed to install device image using payload at %s '
                      'on %s. ' % (self.update_url, self.host.hostname))
        logging.info('Updating image via: %s', autoupdate_cmd)
        try:
            to_raise = None
            self._base_update_handler(run_args, err_prefix)
        except Exception as e:
            to_raise = e

        build_name = url_to_image_name(self.update_url)
        try:
            board, build_type, milestone, _ = server_utils.ParseBuildName(
                build_name)
        except server_utils.ParseBuildNameException:
            logging.warning(
                'Unable to parse build name %s for metrics. '
                'Continuing anyway.', build_name)
            board, build_type, milestone = ('', '', '')
        c = metrics.Counter('chromeos/autotest/autoupdater/update')
        f = {
            'dev_server': dev_server.get_hostname(self.update_url),
            'success': to_raise is None,
            'board': board,
            'build_type': build_type,
            'milestone': milestone
        }
        c.increment(fields=f)
        if to_raise:
            raise to_raise
        self._verify_update_completed()
Exemplo n.º 2
0
    def ForceEventsOnceForBuild(self, keywords, build_name):
        """Force events with provided keywords to happen, with given build.

        @param keywords: iterable of event keywords to force
        @param build_name: instead of looking up builds to test, test this one.
        """
        board, type, milestone, manifest = utils.ParseBuildName(build_name)
        branch_builds = {task.PickBranchName(type, milestone): [build_name]}
        logging.info('Testing build R%s-%s on %s', milestone, manifest, board)

        for e in self._events.itervalues():
            if e.keyword in keywords:
                e.Handle(self._scheduler, branch_builds, board, force=True)
Exemplo n.º 3
0
    def _get_metric_fields(self):
        """Return a dict of metric fields.

        This is used for sending autoupdate metrics for this instance.
        """
        build_name = url_to_image_name(self.update_url)
        try:
            board, build_type, milestone, _ = server_utils.ParseBuildName(
                build_name)
        except server_utils.ParseBuildNameException:
            logging.warning(
                'Unable to parse build name %s for metrics. '
                'Continuing anyway.', build_name)
            board, build_type, milestone = ('', '', '')
        return {
            'dev_server': dev_server.get_hostname(self.update_url),
            'board': board,
            'build_type': build_type,
            'milestone': milestone,
        }
Exemplo n.º 4
0
    def trigger_update(self):
        """Triggers a background update.

        @raise RootFSUpdateError or unknown Exception if anything went wrong.
        """
        # If this function is called immediately after reboot (which it is at
        # this time), there is no guarantee that the update service is up and
        # running yet, so wait for it.
        self._wait_for_update_service()

        autoupdate_cmd = ('%s --check_for_update --omaha_url=%s' %
                          (self.updater_ctrl_bin, self.update_url))
        run_args = {'command': autoupdate_cmd}
        err_prefix = 'Failed to trigger an update on %s. ' % self.host.hostname
        logging.info('Triggering update via: %s', autoupdate_cmd)
        try:
            to_raise = None
            self._base_update_handler(run_args, err_prefix)
        except Exception as e:
            to_raise = e

        build_name = url_to_image_name(self.update_url)
        try:
            board, build_type, milestone, _ = server_utils.ParseBuildName(
                build_name)
        except server_utils.ParseBuildNameException:
            logging.warning(
                'Unable to parse build name %s for metrics. '
                'Continuing anyway.', build_name)
            board, build_type, milestone = ('', '', '')
        c = metrics.Counter('chromeos/autotest/autoupdater/trigger')
        f = {
            'dev_server': dev_server.get_hostname(self.update_url),
            'success': to_raise is None,
            'board': board,
            'build_type': build_type,
            'milestone': milestone
        }
        c.increment(fields=f)
        if to_raise:
            raise to_raise
Exemplo n.º 5
0
def _get_metric_fields(update_url):
    """Return a dict of metric fields.

    This is used for sending autoupdate metrics for the given update URL.

    @param update_url  Metrics fields will be calculated from this URL.
    """
    build_name = url_to_image_name(update_url)
    try:
        board, build_type, milestone, _ = server_utils.ParseBuildName(
            build_name)
    except server_utils.ParseBuildNameException:
        logging.warning(
            'Unable to parse build name %s for metrics. '
            'Continuing anyway.', build_name)
        board, build_type, milestone = ('', '', '')
    return {
        'dev_server': dev_server.get_resolved_hostname(update_url),
        'board': board,
        'build_type': build_type,
        'milestone': milestone,
    }
Exemplo n.º 6
0
def create_suite_job(name='',
                     board='',
                     build='',
                     pool='',
                     control_file='',
                     check_hosts=True,
                     num=None,
                     file_bugs=False,
                     timeout=24,
                     timeout_mins=None,
                     priority=priorities.Priority.DEFAULT,
                     suite_args=None,
                     wait_for_results=True,
                     job_retry=False,
                     max_retries=None,
                     max_runtime_mins=None,
                     suite_min_duts=0,
                     offload_failures_only=False,
                     builds={},
                     test_source_build=None,
                     run_prod_code=False,
                     **kwargs):
    """
    Create a job to run a test suite on the given device with the given image.

    When the timeout specified in the control file is reached, the
    job is guaranteed to have completed and results will be available.

    @param name: The test name if control_file is supplied, otherwise the name
                 of the test suite to run, e.g. 'bvt'.
    @param board: the kind of device to run the tests on.
    @param build: unique name by which to refer to the image from now on.
    @param builds: the builds to install e.g.
                   {'cros-version:': 'x86-alex-release/R18-1655.0.0',
                    'fw-version:':  'x86-alex-firmware/R36-5771.50.0',
                    'fwro-version:':  'x86-alex-firmware/R36-5771.49.0'}
                   If builds is given a value, it overrides argument build.
    @param test_source_build: Build that contains the server-side test code.
    @param pool: Specify the pool of machines to use for scheduling
            purposes.
    @param check_hosts: require appropriate live hosts to exist in the lab.
    @param num: Specify the number of machines to schedule across (integer).
                Leave unspecified or use None to use default sharding factor.
    @param file_bugs: File a bug on each test failure in this suite.
    @param timeout: The max lifetime of this suite, in hours.
    @param timeout_mins: The max lifetime of this suite, in minutes. Takes
                         priority over timeout.
    @param priority: Integer denoting priority. Higher is more important.
    @param suite_args: Optional arguments which will be parsed by the suite
                       control file. Used by control.test_that_wrapper to
                       determine which tests to run.
    @param wait_for_results: Set to False to run the suite job without waiting
                             for test jobs to finish. Default is True.
    @param job_retry: Set to True to enable job-level retry. Default is False.
    @param max_retries: Integer, maximum job retries allowed at suite level.
                        None for no max.
    @param max_runtime_mins: Maximum amount of time a job can be running in
                             minutes.
    @param suite_min_duts: Integer. Scheduler will prioritize getting the
                           minimum number of machines for the suite when it is
                           competing with another suite that has a higher
                           priority but already got minimum machines it needs.
    @param offload_failures_only: Only enable gs_offloading for failed jobs.
    @param run_prod_code: If True, the suite will run the test code that
                          lives in prod aka the test code currently on the
                          lab servers. If False, the control files and test
                          code for this suite run will be retrieved from the
                          build artifacts.
    @param kwargs: extra keyword args. NOT USED.

    @raises ControlFileNotFound: if a unique suite control file doesn't exist.
    @raises NoControlFileList: if we can't list the control files at all.
    @raises StageControlFileFailure: If the dev server throws 500 while
                                     staging test_suites.
    @raises ControlFileEmpty: if the control file exists on the server, but
                              can't be read.

    @return: the job ID of the suite; -1 on error.
    """
    if type(num) is not int and num is not None:
        raise error.SuiteArgumentException('Ill specified num argument %r. '
                                           'Must be an integer or None.' % num)
    if num == 0:
        logging.warning("Can't run on 0 hosts; using default.")
        num = None

    # TODO(dshi): crbug.com/496782 Remove argument build and its reference after
    # R45 falls out of stable channel.
    if build and not builds:
        builds = {provision.CROS_VERSION_PREFIX: build}
    # TODO(dshi): crbug.com/497236 Remove this check after firmware ro provision
    # is supported in Autotest.
    if provision.FW_RO_VERSION_PREFIX in builds:
        raise error.SuiteArgumentException(
            'Updating RO firmware is not supported yet.')
    # Default test source build to CrOS build if it's not specified.
    test_source_build = Suite.get_test_source_build(
        builds, test_source_build=test_source_build)

    suite_name = canonicalize_suite_name(name)
    if run_prod_code:
        ds = dev_server.ImageServer.resolve(build)
        keyvals = {}
        getter = control_file_getter.FileSystemGetter([
            _CONFIG.get_config_value('SCHEDULER',
                                     'drone_installation_directory')
        ])
        control_file = getter.get_control_file_contents_by_name(suite_name)
    else:
        (ds, keyvals) = _stage_build_artifacts(test_source_build)
    keyvals[constants.SUITE_MIN_DUTS_KEY] = suite_min_duts

    if not control_file:
        # No control file was supplied so look it up from the build artifacts.
        suite_name = canonicalize_suite_name(name)
        control_file = _get_control_file_contents_by_name(
            test_source_build, ds, suite_name)
        # Do not change this naming convention without updating
        # site_utils.parse_job_name.
        name = '%s-%s' % (test_source_build, suite_name)

    timeout_mins = timeout_mins or timeout * 60
    max_runtime_mins = max_runtime_mins or timeout * 60

    if not board:
        board = utils.ParseBuildName(builds[provision.CROS_VERSION_PREFIX])[0]

    # TODO(dshi): crbug.com/496782 Remove argument build and its reference after
    # R45 falls out of stable channel.
    # Prepend build and board to the control file.
    inject_dict = {
        'board': board,
        'build': builds.get(provision.CROS_VERSION_PREFIX),
        'builds': builds,
        'check_hosts': check_hosts,
        'pool': pool,
        'num': num,
        'file_bugs': file_bugs,
        'timeout': timeout,
        'timeout_mins': timeout_mins,
        'devserver_url': ds.url(),
        'priority': priority,
        'suite_args': suite_args,
        'wait_for_results': wait_for_results,
        'job_retry': job_retry,
        'max_retries': max_retries,
        'max_runtime_mins': max_runtime_mins,
        'offload_failures_only': offload_failures_only,
        'test_source_build': test_source_build,
        'run_prod_code': run_prod_code
    }

    control_file = tools.inject_vars(inject_dict, control_file)

    return rpc_utils.create_job_common(name,
                                       priority=priority,
                                       timeout_mins=timeout_mins,
                                       max_runtime_mins=max_runtime_mins,
                                       control_type='Server',
                                       control_file=control_file,
                                       hostless=True,
                                       keyvals=keyvals)