1# Copyright 2015 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.client.common_lib import error 9from autotest_lib.client.common_lib import utils 10from autotest_lib.server.cros import vboot_constants as vboot 11from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 12from autotest_lib.server.cros.faft.firmware_test import ConnectionError 13 14 15class firmware_ConsecutiveBoot(FirmwareTest): 16 """ 17 Servo based consecutive boot test via power button to turn on DUT and 18 /sbin/shutdown command to turn off DUT. 19 20 This test is intended to be run with many iterations to ensure that the DUT 21 does boot into ChromeOS and then does power off later. 22 23 The iteration should be specified by the parameter -a "faft_iterations=10". 24 """ 25 version = 1 26 # Number of power button press to boot before declare test fail. 27 POWER_ON_RETRY = 3 28 29 30 def initialize(self, host, cmdline_args, dev_mode=False): 31 # Parse arguments from command line 32 dict_args = utils.args_to_dict(cmdline_args) 33 self.faft_iterations = int(dict_args.get('faft_iterations', 1)) 34 self.faft_waitup_time = int(dict_args.get('faft_waitup_time', 0)) 35 self.faft_localrun = int(dict_args.get('faft_localrun', 0)) 36 super(firmware_ConsecutiveBoot, self).initialize(host, cmdline_args) 37 self.console_checker() 38 self.switcher.setup_mode('dev' if dev_mode else 'normal', 39 allow_gbb_force=True) 40 if dev_mode: 41 self.clear_set_gbb_flags(0, vboot.GBB_FLAG_DEV_SCREEN_SHORT_DELAY) 42 self.setup_usbkey(usbkey=False) 43 44 def console_checker(self): 45 """Verify EC console is available if using Chrome EC.""" 46 if not self.check_ec_capability(suppress_warning=True): 47 # Not Chrome EC. Nothing to check. 48 return True 49 try: 50 if self.ec.get_version(): 51 return True 52 except: 53 pass 54 55 raise error.TestFail( 56 "Failed EC console check. Maybe CCD close. Please check ccd open state." 57 ) 58 59 def wait_for_client_aux(self): 60 """Use test specific timeout to wait for system to come up, 61 otherwise use default (180s). 62 """ 63 logging.info('wait_for_client %d start.', self.faft_waitup_time) 64 if self.faft_waitup_time: 65 self.switcher.wait_for_client(self.faft_waitup_time) 66 else: 67 self.switcher.wait_for_client() 68 69 def shutdown_power_on(self): 70 """ 71 Use /sbin/shutdown to turn off device follow by power button press to 72 turn on device. Do not want to call full_power_off_and_on since we 73 are testing firmware and mainly want to focus on power on sequence. 74 """ 75 boot_id = self.get_bootid() 76 77 # Call shutdown instead of long press the power key, since we're 78 # testing the firmware, not the power manager and button handling. 79 logging.info("Sending /sbin/shutdown -P now") 80 self.run_shutdown_cmd() 81 logging.info('Wait for client to go offline') 82 self.switcher.wait_for_client_offline(timeout=100, orig_boot_id=boot_id) 83 if self.check_ec_capability(['x86'], suppress_warning=True): 84 self.check_shutdown_power_state( 85 self.POWER_STATE_G3, pwr_retries=13, orig_boot_id=boot_id) 86 87 # Retry in case power_short_press was not registered. 88 for i in range(self.POWER_ON_RETRY): 89 logging.info("sleep %d, tap power key to boot.", 90 self.faft_config.powerup_ready) 91 time.sleep(self.faft_config.powerup_ready) 92 self.servo.power_key(self.faft_config.hold_pwr_button_poweron) 93 try: 94 self.wait_for_client_aux() 95 except ConnectionError: 96 logging.error('wait_for_client exception %d.', i) 97 else: 98 logging.info('wait_for_client online done %d.', i) 99 return 100 raise ConnectionError() 101 102 def cleanup(self): 103 try: 104 # Restore the GBB flag in developer mode test. 105 self.clear_set_gbb_flags(vboot.GBB_FLAG_DEV_SCREEN_SHORT_DELAY, 0) 106 except Exception as e: 107 logging.error("Caught exception: %s", str(e)) 108 super(firmware_ConsecutiveBoot, self).cleanup() 109 110 def run_once(self, host, dev_mode=False): 111 """Runs a single iteration of the test.""" 112 for i in range(self.faft_iterations): 113 logging.info('======== Running FAFT ITERATION %d/%s ========', 114 i+1, self.faft_iterations) 115 logging.info("Expected boot fine, full power off DUT and on.") 116 self.check_state((self.checkers.crossystem_checker, { 117 'mainfw_type': 'developer' if dev_mode else 'normal', 118 })) 119 self.shutdown_power_on() 120 121 logging.info("Expected boot fine.") 122 self.check_state((self.checkers.crossystem_checker, { 123 'mainfw_type': 'developer' if dev_mode else 'normal', 124 })) 125