1 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 import logging 6 7 from autotest_lib.server.cros import vboot_constants as vboot 8 from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 9 10 11 class firmware_RollbackFirmware(FirmwareTest): 12 """ 13 Servo based firmware rollback test. 14 15 This test requires a USB disk plugged-in, which contains a Chrome OS test 16 image (built by "build_image --test"). On runtime, this test rollbacks 17 firmware A and results firmware B boot. It then rollbacks firmware B and 18 results recovery boot. 19 """ 20 version = 1 21 22 def initialize(self, host, cmdline_args, dev_mode=False): 23 super(firmware_RollbackFirmware, self).initialize(host, cmdline_args) 24 self.backup_firmware() 25 self.switcher.setup_mode('dev' if dev_mode else 'normal') 26 self.setup_usbkey(usbkey=True, host=False) 27 28 def cleanup(self): 29 try: 30 self.restore_firmware() 31 except Exception as e: 32 logging.error("Caught exception: %s", str(e)) 33 super(firmware_RollbackFirmware, self).cleanup() 34 35 def run_once(self, dev_mode=False): 36 logging.info("Rollback firmware A.") 37 self.check_state((self.checkers.fw_tries_checker, 'A')) 38 self.faft_client.bios.move_version_backward('a') 39 self.switcher.mode_aware_reboot() 40 41 logging.info("Expected firmware B boot and rollback firmware B.") 42 self.check_state((self.checkers.fw_tries_checker, ('B', False))) 43 self.faft_client.bios.move_version_backward('b') 44 45 # Older devices (without BROKEN screen) didn't wait for removal in 46 # dev mode. Make sure the USB key is not plugged in so they won't 47 # start booting immediately and get interrupted by unplug/replug. 48 self.servo.switch_usbkey('host') 49 self.switcher.simple_reboot() 50 self.switcher.bypass_rec_mode() 51 self.switcher.wait_for_client() 52 53 logging.info("Expected recovery boot and restores firmware A and B.") 54 self.check_state((self.checkers.crossystem_checker, { 55 'mainfw_type': 'recovery', 56 'recovery_reason': ( 57 vboot.RECOVERY_REASON['RO_INVALID_RW'], 58 vboot.RECOVERY_REASON['RW_FW_ROLLBACK']), 59 })) 60 self.faft_client.bios.move_version_forward(('a', 'b')) 61 self.switcher.mode_aware_reboot() 62 63 expected_slot = 'B' if self.fw_vboot2 else 'A' 64 logging.info("Expected firmware " + expected_slot + " boot, done.") 65 self.check_state((self.checkers.fw_tries_checker, expected_slot)) 66