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 5 import logging 6 import time 7 import sys 8 9 from autotest_lib.client.common_lib import error 10 from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 11 12 13 class 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_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 try: 63 self.servo.switch_usbkey('host') 64 usb_dev = self.servo.probe_host_usb_dev() 65 # Restore the kernel of USB stick which is corrupted on setup phase. 66 self.restore_usb_kernel(usb_dev) 67 except Exception as e: 68 logging.error("Caught exception: %s", str(e)) 69 super(firmware_FwScreenPressPower, self).cleanup() 70 71 def run_once(self): 72 if (self.faft_config.fw_bypasser_type != 'ctrl_d_bypasser' 73 and self.faft_config.fw_bypasser_type != 'tablet_detachable_bypasser'): 74 raise error.TestNAError("This test is only valid on devices with " 75 "screens.") 76 if not self.faft_config.has_powerbutton: 77 raise error.TestNAError("This test is only valid on devices with " 78 "power button.") 79 80 logging.info("Expected dev mode and reboot. " 81 "When the next DEVELOPER SCREEN shown, press power button " 82 "to make DUT shutdown.") 83 self.check_state((self.checkers.crossystem_checker, { 84 'devsw_boot': '1', 85 'mainfw_type': 'developer', 86 })) 87 self.switcher.simple_reboot() 88 self.run_shutdown_process(self.wait_fw_screen_and_press_power, 89 post_power_action=self.switcher.bypass_dev_mode) 90 self.switcher.wait_for_client() 91 92 logging.info("Reboot. When the developer screen shown, press " 93 "enter key to trigger either TO_NORM screen (new) or " 94 "RECOVERY INSERT screen (old). Then press power button to " 95 "make DUT shutdown.") 96 self.check_state((self.checkers.crossystem_checker, { 97 'devsw_boot': '1', 98 'mainfw_type': 'developer', 99 })) 100 self.switcher.simple_reboot() 101 self.run_shutdown_process(self.wait_second_screen_and_press_power, 102 post_power_action=self.switcher.bypass_dev_mode, 103 shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD) 104 self.switcher.wait_for_client() 105 106 logging.info("Request recovery boot. When the RECOVERY INSERT " 107 "screen shows, press power button to make DUT shutdown.") 108 self.check_state((self.checkers.crossystem_checker, { 109 'devsw_boot': '1', 110 'mainfw_type': 'developer', 111 })) 112 self.faft_client.system.request_recovery_boot() 113 self.switcher.simple_reboot() 114 self.run_shutdown_process(self.wait_longer_fw_screen_and_press_power, 115 post_power_action=self.switcher.bypass_dev_mode, 116 shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD) 117 self.switcher.wait_for_client() 118 119 logging.info("Request recovery boot again. When the recovery " 120 "insert screen shows, insert a corrupted USB and trigger " 121 "a YUCK SCREEN. Then press power button to " 122 "make DUT shutdown.") 123 self.check_state((self.checkers.crossystem_checker, { 124 'devsw_boot': '1', 125 'mainfw_type': 'developer', 126 })) 127 self.faft_client.system.request_recovery_boot() 128 self.switcher.simple_reboot() 129 self.run_shutdown_process(self.wait_yuck_screen_and_press_power, 130 post_power_action=self.switcher.bypass_dev_mode, 131 shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD) 132 self.switcher.wait_for_client() 133 134 logging.info("Switch back to normal mode.") 135 self.check_state((self.checkers.crossystem_checker, { 136 'devsw_boot': '1', 137 'mainfw_type': 'developer', 138 })) 139 self.switcher.reboot_to_mode(to_mode='normal') 140 141 logging.info("Expected normal mode and request recovery boot. " 142 "Because an USB stick is inserted, a RECOVERY REMOVE " 143 "screen shows. Press power button to make DUT shutdown.") 144 self.check_state((self.checkers.crossystem_checker, { 145 'devsw_boot': '0', 146 'mainfw_type': 'normal', 147 })) 148 self.faft_client.system.request_recovery_boot() 149 self.switcher.simple_reboot() 150 self.run_shutdown_process(self.wait_longer_fw_screen_and_press_power, 151 shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD) 152 self.switcher.wait_for_client() 153 154 logging.info("Check and done.") 155 self.check_state((self.checkers.crossystem_checker, { 156 'devsw_boot': '0', 157 'mainfw_type': 'normal', 158 })) 159