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 7import sys 8 9from autotest_lib.client.common_lib import error 10from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 11 12 13class firmware_FwScreenPressPower(FirmwareTest): 14 """ 15 Servo based power button triggered shutdown test during firmware screens. 16 17 This test requires a USB disk plugged-in, which contains a Chrome OS test 18 image (built by "build_image --test"). On runtime, this test triggers 19 firmware screens (developer, remove, insert, yuck, and to_norm screens), 20 and then presses the power button in order to power the machine down. 21 """ 22 version = 1 23 24 SHORT_SHUTDOWN_CONFIRMATION_PERIOD = 0.1 25 26 def wait_fw_screen_and_press_power(self): 27 """Wait for firmware warning screen and press power button.""" 28 time.sleep(self.faft_config.firmware_screen) 29 # While the firmware screen, the power button probing loop sleeps 30 # 0.25 second on every scan. Use the normal delay (1.2 second) for 31 # power press. 32 self.servo.power_normal_press() 33 34 def wait_longer_fw_screen_and_press_power(self): 35 """Wait for firmware screen without timeout and press power button.""" 36 time.sleep(self.faft_config.dev_screen_timeout) 37 self.wait_fw_screen_and_press_power() 38 39 def wait_second_screen_and_press_power(self): 40 """Wait and trigger a second screen and press power button.""" 41 self.switcher.trigger_dev_to_rec() 42 self.wait_longer_fw_screen_and_press_power() 43 44 def wait_yuck_screen_and_press_power(self): 45 """Insert corrupted USB for yuck screen and press power button.""" 46 # This USB stick will be removed in cleanup phase. 47 self.servo.switch_usbkey('dut') 48 time.sleep(self.faft_config.usb_plug) 49 self.wait_longer_fw_screen_and_press_power() 50 51 def initialize(self, host, cmdline_args): 52 super(firmware_FwScreenPressPower, self).initialize(host, cmdline_args) 53 self.assert_test_image_in_usb_disk() 54 self.switcher.setup_mode('dev') 55 self.servo.switch_usbkey('host') 56 usb_dev = self.servo.probe_host_usb_dev() 57 # Corrupt the kernel of USB stick. It is needed for triggering a 58 # yuck screen later. 59 self.corrupt_usb_kernel(usb_dev) 60 61 def cleanup(self): 62 self.servo.switch_usbkey('host') 63 usb_dev = self.servo.probe_host_usb_dev() 64 # Restore the kernel of USB stick which is corrupted on setup phase. 65 self.restore_usb_kernel(usb_dev) 66 super(firmware_FwScreenPressPower, self).cleanup() 67 68 def run_once(self): 69 if self.faft_config.fw_bypasser_type != 'ctrl_d_bypasser': 70 raise error.TestNAError("This test is only valid on devices with " 71 "screens.") 72 if not self.faft_config.has_powerbutton: 73 raise error.TestNAError("This test is only valid on devices with " 74 "power button.") 75 76 logging.info("Expected dev mode and reboot. " 77 "When the next DEVELOPER SCREEN shown, press power button " 78 "to make DUT shutdown.") 79 self.check_state((self.checkers.crossystem_checker, { 80 'devsw_boot': '1', 81 'mainfw_type': 'developer', 82 })) 83 self.switcher.mode_aware_reboot(wait_for_dut_up=False) 84 self.run_shutdown_process(self.wait_fw_screen_and_press_power, 85 post_power_action=self.switcher.bypass_dev_mode) 86 self.switcher.wait_for_client() 87 88 logging.info("Reboot. When the developer screen shown, press " 89 "enter key to trigger either TO_NORM screen (new) or " 90 "RECOVERY INSERT screen (old). Then press power button to " 91 "make DUT shutdown.") 92 self.check_state((self.checkers.crossystem_checker, { 93 'devsw_boot': '1', 94 'mainfw_type': 'developer', 95 })) 96 self.switcher.mode_aware_reboot(wait_for_dut_up=False) 97 self.run_shutdown_process(self.wait_second_screen_and_press_power, 98 post_power_action=self.switcher.bypass_dev_mode, 99 shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD) 100 self.switcher.wait_for_client() 101 102 logging.info("Request recovery boot. When the RECOVERY INSERT " 103 "screen shows, press power button to make DUT shutdown.") 104 self.check_state((self.checkers.crossystem_checker, { 105 'devsw_boot': '1', 106 'mainfw_type': 'developer', 107 })) 108 self.faft_client.system.request_recovery_boot() 109 self.switcher.mode_aware_reboot(wait_for_dut_up=False) 110 self.run_shutdown_process(self.wait_longer_fw_screen_and_press_power, 111 post_power_action=self.switcher.bypass_dev_mode, 112 shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD) 113 self.switcher.wait_for_client() 114 115 logging.info("Request recovery boot again. When the recovery " 116 "insert screen shows, insert a corrupted USB and trigger " 117 "a YUCK SCREEN. Then press power button to " 118 "make DUT shutdown.") 119 self.check_state((self.checkers.crossystem_checker, { 120 'devsw_boot': '1', 121 'mainfw_type': 'developer', 122 })) 123 self.faft_client.system.request_recovery_boot() 124 self.switcher.mode_aware_reboot(wait_for_dut_up=False) 125 self.run_shutdown_process(self.wait_yuck_screen_and_press_power, 126 post_power_action=self.switcher.bypass_dev_mode, 127 shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD) 128 self.switcher.wait_for_client() 129 130 logging.info("Switch back to normal mode.") 131 self.check_state((self.checkers.crossystem_checker, { 132 'devsw_boot': '1', 133 'mainfw_type': 'developer', 134 })) 135 self.switcher.reboot_to_mode(to_mode='normal') 136 137 logging.info("Expected normal mode and request recovery boot. " 138 "Because an USB stick is inserted, a RECOVERY REMOVE " 139 "screen shows. Press power button to make DUT shutdown.") 140 self.check_state((self.checkers.crossystem_checker, { 141 'devsw_boot': '0', 142 'mainfw_type': 'normal', 143 })) 144 self.faft_client.system.request_recovery_boot() 145 self.switcher.mode_aware_reboot(wait_for_dut_up=False) 146 self.run_shutdown_process(self.wait_longer_fw_screen_and_press_power, 147 shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD) 148 self.switcher.wait_for_client() 149 150 logging.info("Check and done.") 151 self.check_state((self.checkers.crossystem_checker, { 152 'devsw_boot': '0', 153 'mainfw_type': 'normal', 154 })) 155