blob: b33f6b0bc5a35d6b1fc4aa24d54e361c2ea8cbe2 [file] [log] [blame]
# Copyright 2017 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.
""" The autotest performing Cr50 update."""
import logging
import os
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import cr50_utils
from autotest_lib.server.cros import filesystem_util
from autotest_lib.server.cros.faft.cr50_test import Cr50Test
class provision_Cr50Update(Cr50Test):
"""A test that can provision a machine to the correct cr50 version and
board id.
The value is the image rw version/image board id. The chip board id will be
set to the image board id unless the image board id is empty (''). If it's
empty, the chip board id will be set to the device brand:0x7f80.
value=0.0.23/ZZAF:ffffffff:7f00
value=0.3.25/
"""
version = 1
def initialize(self, host, cmdline_args, full_args, value='',
release_path='', force=False):
"""Initialize get the cr50 update version information"""
super(provision_Cr50Update, self).initialize(host, cmdline_args,
full_args, provision_update=True)
# TODO(mruthven): remove once the test is successfully scheduled.
logging.info('SUCCESSFULLY SCHEDULED PROVISION CR50 UPDATE with %r',
value)
if not force:
return
self.host = host
image_info = None
if os.path.isfile(release_path):
image_info = self.init_local_image(release_path)
else:
# The value is rw_ver/image_bid. The image_bid will also be used for
# the chip board id.
rw_ver, bid = value.split('/')
image_info = self.download_cr50_release_image(rw_ver, bid)
if not image_info:
raise error.TestError('Could not find new cr50 image')
self.local_path, self.image_ver = image_info
self.image_rw = self.image_ver[1]
self.image_bid = self.image_ver[2]
self.chip_bid = cr50_utils.GetChipBIDFromImageBID(
self.image_bid, self.get_device_brand())
def init_local_image(self, release_path):
"""Get the version of the local image.
Args:
release_path: The local path to the cr50 image
Returns:
the local path, image version tuple
"""
ver = cr50_utils.InstallImage(self.host, release_path,
'/tmp/release.bin')[1]
return release_path, ver
def run_once(self, force=False):
"""The method called by the control file to start the update."""
# TODO(mruthven): remove once the test is successfully scheduled.
if not force:
logging.info('skipping update')
return
update_state = {}
update_state['chip_bid'] = self.chip_bid
update_state['prepvt_version'] = self.image_ver
update_state['prod_version'] = self.image_ver
update_state['running_image_bid'] = self.image_ver[2]
# The test can't rollback RO. The newest RO should be running at the end
# of the test. max_ro will be none if the versions are the same. Use the
# running_ro in that case.
running_ro = self.get_saved_cr50_original_version()[0]
max_ro = cr50_utils.GetNewestVersion(running_ro, self.image_ver[0])
update_state['running_image_ver'] = (max_ro or running_ro,
self.image_ver[1],
None)
mismatch = self._check_running_image_and_board_id(update_state)
if not mismatch:
logging.info('No update needed.')
return
filesystem_util.make_rootfs_writable(self.host)
if self._cleanup_required(mismatch, self.DBG_IMAGE):
logging.info('Updating to image %s with chip board id %s',
self.image_ver, '%08x:%08x:%08x' % self.chip_bid)
self.update_cr50_image_and_board_id(self.local_path, self.chip_bid)
# Copy the image onto the DUT. cr50-update uses both cr50.bin.prod and
# cr50.bin.prepvt in /opt/google/cr50/firmware/, so copy it to both
# places. Rootfs verification has to be disabled to do the copy.
cr50_utils.InstallImage(self.host, self.local_path,
cr50_utils.CR50_PREPVT)
cr50_utils.InstallImage(self.host, self.local_path,
cr50_utils.CR50_PROD)
# Verify everything updated correctly
mismatch = self._check_running_image_and_board_id(update_state)
if mismatch:
raise error.TestFail('Failed to update cr50: %s', mismatch)