1# Copyright (c) 2011 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 5import logging 6import time 7 8from autotest_lib.server.cros import vboot_constants as vboot 9from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 10 11 12class firmware_RecoveryButton(FirmwareTest): 13 """ 14 Servo based recovery button test. 15 16 This test requires a USB disk plugged-in, which contains a ChromeOS test 17 image (built by "build_image --test"). On runtime, this test emulates 18 recovery button pressed and reboots. It then triggers recovery mode in 19 two cases: (1) plug in the USB disk before power-on (2) plug in the USB 20 disk after power-on, ideally around the time when INSERT screen shows up. 21 Both cases should lead to successful recovery boot. 22 """ 23 version = 1 24 NEEDS_SERVO_USB = True 25 26 def ensure_normal_boot(self): 27 """Ensure normal mode boot this time. 28 29 If not, it may be a test failure during step 2, try to recover to 30 normal mode by setting no recovery mode and rebooting the machine. 31 """ 32 if not self.checkers.crossystem_checker({ 33 'mainfw_type': ('normal', 'developer') 34 }): 35 self.servo.disable_recovery_mode() 36 self.switcher.mode_aware_reboot() 37 38 def check_recovery_state(self): 39 """Check if this is a recovery boot.""" 40 self.check_state((self.checkers.crossystem_checker, { 41 'mainfw_type': 42 'recovery', 43 'recovery_reason': 44 vboot.RECOVERY_REASON['RO_MANUAL'], 45 })) 46 47 def initialize(self, host, cmdline_args, dev_mode=False, ec_wp=None): 48 super(firmware_RecoveryButton, self).initialize( 49 host, cmdline_args, ec_wp=ec_wp) 50 self.switcher.setup_mode('dev' if dev_mode else 'normal') 51 self.setup_usbkey(usbkey=True, host=False) 52 53 def cleanup(self): 54 try: 55 self.ensure_normal_boot() 56 except Exception as e: 57 logging.error("Caught exception: %s", str(e)) 58 super(firmware_RecoveryButton, self).cleanup() 59 60 def run_once(self, dev_mode=False): 61 """Runs a single iteration of the test.""" 62 logging.info("Reboot to recovery mode with the USB stick plugged.") 63 self.check_state((self.checkers.crossystem_checker, { 64 'mainfw_type': 'developer' if dev_mode else 'normal', 65 })) 66 self.switcher.reboot_to_mode(to_mode="rec") 67 68 logging.info("Expect a recovery boot from the USB stick.") 69 self.check_recovery_state() 70 71 logging.info("Power off, unplug the USB stick and reboot to rec mode.") 72 self.switcher.enable_rec_mode_and_reboot(usb_state='host') 73 74 logging.info("Plug in the USB stick after a delay") 75 time.sleep(self.faft_config.firmware_screen) 76 self.servo.switch_usbkey('dut') 77 logging.info("Expect a recovery boot from the USB stick.") 78 self.switcher.wait_for_client() 79 self.check_recovery_state() 80 81 logging.info("Reboot and then expected normal/dev boot.") 82 self.switcher.mode_aware_reboot() 83 is_jetstream = self.faft_config.mode_switcher_type == \ 84 'jetstream_switcher' 85 self.check_state((self.checkers.crossystem_checker, { 86 'mainfw_type': 87 'developer' if dev_mode and not is_jetstream else 'normal', 88 })) 89