1# Copyright 2016 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, time 6 7from autotest_lib.client.common_lib import error 8from autotest_lib.client.common_lib import utils 9from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 10 11# platform_S0ixCycle test timing constants 12BEFORE_SUSPEND_WAIT_TIME_SECONDS = 10 13BEFORE_RESUME_WAIT_TIME_SECONDS = 2 14SUSPEND_WAIT_TIME_SECONDS = 5 15LIDOPEN_WAIT_TIME_SECONDS = 2 16POWER_STATE_RETRY_COUNT = 10 17 18 19class platform_S0ixCycle(FirmwareTest): 20 ''' 21 Servo based S0ix cycle test and wake source. 22 ''' 23 version = 1 24 25 def initialize(self, host, cmdline_args): 26 dict_args = utils.args_to_dict(cmdline_args) 27 self.faft_iterations = int(dict_args.get('faft_iterations', 1)) 28 super(platform_S0ixCycle, self).initialize(host, cmdline_args) 29 self.switcher.setup_mode('normal') 30 31 def perform_s0ix_cycle(self): 32 """ 33 Perform S0ix suspend/resume cycle and check state transition. 34 """ 35 resume_sources = ['powerbtn', 'lid', 'kbpress'] 36 for resume_source in resume_sources: 37 time.sleep(BEFORE_SUSPEND_WAIT_TIME_SECONDS) 38 self.perform_suspend() 39 self.perform_resume(resume_source) 40 41 def perform_suspend(self): 42 """ 43 Perform suspend to idle and check state transition. 44 """ 45 logging.info('== S0ix suspend and check the state transition ==') 46 # check S0ix state transition 47 if not self.wait_power_state('S0', POWER_STATE_RETRY_COUNT): 48 raise error.TestFail('Platform failed to reach S0 state.') 49 cmd = 'echo freeze > /sys/power/state' 50 block = False 51 self.faft_client.system.run_shell_command(cmd, block) 52 time.sleep(SUSPEND_WAIT_TIME_SECONDS) 53 # check S0ix state transition 54 if not self.wait_power_state('S0ix', POWER_STATE_RETRY_COUNT): 55 raise error.TestFail('Platform failed to reach S0ix state.') 56 57 def perform_resume(self, resume_source): 58 """ 59 Perform resume with selected resume source and check state transition. 60 @param resume_source(string):resume source option. 61 """ 62 logging.info('== S0ix resume and check the state transition ==') 63 time.sleep(BEFORE_RESUME_WAIT_TIME_SECONDS) 64 if resume_source == 'powerbtn': 65 self.ec.send_command('powerbtn') 66 elif resume_source == 'lid': 67 self.ec.send_command('lidclose') 68 time.sleep(LIDOPEN_WAIT_TIME_SECONDS) 69 self.ec.send_command('lidopen') 70 elif resume_source == 'kbpress': 71 self.ec.key_press('<enter>') 72 else: 73 raise error.TestFail('Invalid resume source.') 74 # check S0 state transition 75 if not self.wait_power_state('S0', POWER_STATE_RETRY_COUNT): 76 raise error.TestFail('Platform failed to reach S0 state.') 77 78 def is_skl_board(self): 79 """ 80 Check this device is a SKL based ChromeBook. 81 """ 82 skl_boards = ('kunimitsu', 'lars', 'glados', 'chell', 'sentry') 83 output = self.faft_client.system.get_platform_name() 84 return output.lower() in skl_boards 85 86 def is_s0ix_supported(self): 87 """ 88 Check this device supports suspend to idle. 89 """ 90 cmd = 'cat /var/lib/power_manager/suspend_to_idle' 91 output = self.faft_client.system.run_shell_command_get_output(cmd) 92 if not output: 93 return False 94 else: 95 return int(output[0]) == 1 96 97 def run_once(self): 98 """ 99 Main test logic 100 """ 101 if not self.faft_config.chrome_ec or not self.check_ec_capability(): 102 raise error.TestNAError( 103 'Chrome EC is not supported on this device.') 104 105 if not (self.is_skl_board() and self.is_s0ix_supported()): 106 raise error.TestNAError( 107 'Suspend to idle is not supported on this device.') 108 109 for i in xrange(self.faft_iterations): 110 logging.info('== Running FAFT ITERATION %d/%s ==', i + 1, 111 self.faft_iterations) 112 logging.info( 113 'S0ix suspend/resume back and check state transition.') 114 # wake the display by key press. 115 self.ec.key_press('<enter>') 116 self.switcher.mode_aware_reboot('custom', self.perform_s0ix_cycle) 117 118 def cleanup(self): 119 """ 120 Cleanup after test completes 121 """ 122 self.ec.set_uart_regexp('None') 123 # Test may failed before resume, wake the system. 124 self.ec.send_command('powerbtn') 125 # Perform a warm reboot as part of the cleanup. 126 self._client.reboot() 127 super(platform_S0ixCycle, self).cleanup() 128