blob: 1996d74a1c132bcdd634cddf5a6e31b9441d3750 [file] [log] [blame]
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import time
from autotest_lib.server import test
from autotest_lib.client.common_lib import error
class platform_StageAndRecover(test.test):
"""Installs the same version recovery image onto a servo-connected DUT."""
version = 1
_INSTALL_DELAY_TIMEOUT = 540
_TEST_IMAGE_BOOT_DELAY = 180
_USB_PARTITION = '/dev/sda1'
_MOUNT_PATH = '/media/removable'
_VERIFY_STR = 'ChromeosChrootPostinst complete'
_RECOVERY_LOG = '/recovery_logs*/recovery.log'
_SET_DELAY = 2
def cleanup(self):
""" Clean up by switching servo usb towards servo host. """
self.host.servo.switch_usbkey('host')
def initialize(self, host):
""" Preparing servo to see only DUT_HUB1.
Avoiding peripherals plugged at this servo port.
"""
host.servo.set('prtctl4_pwren','on')
time.sleep(self._SET_DELAY)
host.servo.set('usb_mux_oe3', 'off')
time.sleep(self._SET_DELAY)
host.servo.set('usb_mux_oe1', 'off')
time.sleep(self._SET_DELAY)
# Switch usb_mux_sel1 to enumerate as /dev/sda
host.servo.set('usb_mux_oe1', 'on')
time.sleep(self._SET_DELAY)
host.servo.set('usb_mux_sel1', 'servo_sees_usbkey')
time.sleep(self._SET_DELAY)
try:
host.servo.system('test -e /dev/sda')
host.servo.system('mkdir -p %s' %(self._MOUNT_PATH))
except error.AutoservRunError:
servo_disk = host.servo.system_output('fdisk -l', ignore_status=True )
usb_control = host.servo.system_output('dut-control | grep mux',
ignore_status=True)
logging.info('Servo disk info : %s', servo_disk)
logging.info('Servo USB controls: %s', usb_control)
raise error.TestError('Issue with servo USB mount path %s'
% (self._USB_PARTITION))
def stage_copy_recover_with(self, artifact):
""" Stage image, copy image to servo usb, and 'rec' boot the device.
@param artifact: image type - recovery_image or test_image
"""
# Stage the image on dev server
_, image_path = self.host.stage_image_for_servo(
self.release_builder_path,
artifact=artifact)
logging.info('%s staged at %s', artifact, image_path)
# Reimage servo USB
self.host.servo.image_to_servo_usb(image_path,
make_image_noninteractive=True)
self.host.servo.set('usb_mux_sel1', 'dut_sees_usbkey')
time.sleep(self._SET_DELAY)
# Boot DUT in recovery mode for image to install
self.host.servo.boot_in_recovery_mode()
def wait_for_dut_ping_after(self, process, timeout):
""" Wait for DUT after reimaging or rebooting.
@param process: process to check timeout for
@param timeout: timeout to wait for DUT to answer to ping_wait_up
@raise error.TestFail: if timeout is reached
"""
logging.info('Started %s. Will wait up to %d seconds to complete',
process, timeout)
start_time = time.time()
result = self.host.ping_wait_up(timeout=timeout)
if result:
logging.info('Device came back up successfully in %d seconds.',
time.time() - start_time)
else:
if process.find('TEST_IMAGE') != -1:
logging.info('Host failed to come back after %s '
'in %d seconds.' % (process, timeout))
else:
self.error_messages.append('Host failed to come back after %s '
'in %d seconds.' % (process, timeout))
return result
def verify_recovery_log(self):
""" Mount USB partition to servo and verify the recovery log. """
recovery_info = ''
self.host.servo.set('usb_mux_sel1', 'servo_sees_usbkey')
time.sleep(self._SET_DELAY)
self.host.servo.system('mount -r %s %s'
% (self._USB_PARTITION, self._MOUNT_PATH))
recovery_info = self.host.servo.system_output('cat %s%s'
% (self._MOUNT_PATH, self._RECOVERY_LOG), ignore_status=True)
if recovery_info:
if (recovery_info.find(self._VERIFY_STR) != -1):
logging.info('Recovery log successfully verified.')
else:
log_list = recovery_info.split('\n')
failure_tag = 'Failed Command'
reasons = [line for line in log_list if failure_tag in line]
logging.info('Recovery log:\n%s\n', recovery_info)
self.error_messages.append(' %s ' % (','.join(reasons)))
else:
self.error_messages.append('Recovery log is missing.')
self.host.servo.system('umount %s' % (self._MOUNT_PATH))
def run_once(self, host):
""" Runs the test."""
self.host = host
self.error_messages = []
self.release_builder_path = self.host.get_release_builder_path()
self.stage_copy_recover_with('recovery_image')
self.wait_for_dut_ping_after('RECOVERY', self._INSTALL_DELAY_TIMEOUT)
self.verify_recovery_log()
try:
# Post-recovery exception handling : Test image installation is
# out of scope of the test verification and these failures should
# not be a reason to error out.
self.stage_copy_recover_with('test_image')
# Install the test image back on DUT and reboot
if self.wait_for_dut_ping_after('TEST_IMAGE RECOVERY BOOT FROM USB',
self._TEST_IMAGE_BOOT_DELAY):
self.host.run('chromeos-install --yes', ignore_status=True,
timeout=self._INSTALL_DELAY_TIMEOUT)
self.host.reboot()
except error.AutoservRunError:
pass
if self.error_messages:
raise error.TestFail('Failures: %s' % ' '.join(self.error_messages))