| # Copyright 2016 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import logging, time |
| |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.common_lib import utils |
| from autotest_lib.server.cros.faft.firmware_test import FirmwareTest |
| |
| # platform_S0ixCycle test timing constants |
| BEFORE_SUSPEND_WAIT_TIME_SECONDS = 10 |
| BEFORE_RESUME_WAIT_TIME_SECONDS = 2 |
| SUSPEND_WAIT_TIME_SECONDS = 5 |
| LIDOPEN_WAIT_TIME_SECONDS = 2 |
| POWER_STATE_RETRY_COUNT = 10 |
| |
| |
| class platform_S0ixCycle(FirmwareTest): |
| ''' |
| Servo based S0ix cycle test and wake source. |
| ''' |
| version = 1 |
| |
| def initialize(self, host, cmdline_args): |
| dict_args = utils.args_to_dict(cmdline_args) |
| self.faft_iterations = int(dict_args.get('faft_iterations', 1)) |
| super(platform_S0ixCycle, self).initialize(host, cmdline_args) |
| self.switcher.setup_mode('normal') |
| |
| def perform_s0ix_cycle(self): |
| """ |
| Perform S0ix suspend/resume cycle and check state transition. |
| """ |
| resume_sources = ['powerbtn', 'lid', 'kbpress'] |
| for resume_source in resume_sources: |
| time.sleep(BEFORE_SUSPEND_WAIT_TIME_SECONDS) |
| self.perform_suspend() |
| self.perform_resume(resume_source) |
| |
| def perform_suspend(self): |
| """ |
| Perform suspend to idle and check state transition. |
| """ |
| logging.info('== S0ix suspend and check the state transition ==') |
| # check S0ix state transition |
| if not self.wait_power_state('S0', POWER_STATE_RETRY_COUNT): |
| raise error.TestFail('Platform failed to reach S0 state.') |
| cmd = 'echo freeze > /sys/power/state' |
| block = False |
| self.faft_client.system.run_shell_command(cmd, block) |
| time.sleep(SUSPEND_WAIT_TIME_SECONDS) |
| # check S0ix state transition |
| if not self.wait_power_state('S0ix', POWER_STATE_RETRY_COUNT): |
| raise error.TestFail('Platform failed to reach S0ix state.') |
| |
| def perform_resume(self, resume_source): |
| """ |
| Perform resume with selected resume source and check state transition. |
| @param resume_source(string):resume source option. |
| """ |
| logging.info('== S0ix resume and check the state transition ==') |
| time.sleep(BEFORE_RESUME_WAIT_TIME_SECONDS) |
| if resume_source == 'powerbtn': |
| self.ec.send_command('powerbtn') |
| elif resume_source == 'lid': |
| self.ec.send_command('lidclose') |
| time.sleep(LIDOPEN_WAIT_TIME_SECONDS) |
| self.ec.send_command('lidopen') |
| elif resume_source == 'kbpress': |
| self.ec.key_press('<enter>') |
| else: |
| raise error.TestFail('Invalid resume source.') |
| # check S0 state transition |
| if not self.wait_power_state('S0', POWER_STATE_RETRY_COUNT): |
| raise error.TestFail('Platform failed to reach S0 state.') |
| |
| def is_skl_board(self): |
| """ |
| Check this device is a SKL based ChromeBook. |
| """ |
| skl_boards = ('kunimitsu', 'lars', 'glados', 'chell', 'sentry') |
| output = self.faft_client.system.get_platform_name() |
| return output.lower() in skl_boards |
| |
| def is_s0ix_supported(self): |
| """ |
| Check this device supports suspend to idle. |
| """ |
| cmd = 'cat /var/lib/power_manager/suspend_to_idle' |
| output = self.faft_client.system.run_shell_command_get_output(cmd) |
| if not output: |
| return False |
| else: |
| return int(output[0]) == 1 |
| |
| def run_once(self): |
| """ |
| Main test logic |
| """ |
| if not self.faft_config.chrome_ec or not self.check_ec_capability(): |
| raise error.TestNAError( |
| 'Chrome EC is not supported on this device.') |
| |
| if not (self.is_skl_board() and self.is_s0ix_supported()): |
| raise error.TestNAError( |
| 'Suspend to idle is not supported on this device.') |
| |
| for i in xrange(self.faft_iterations): |
| logging.info('== Running FAFT ITERATION %d/%s ==', i + 1, |
| self.faft_iterations) |
| logging.info( |
| 'S0ix suspend/resume back and check state transition.') |
| # wake the display by key press. |
| self.ec.key_press('<enter>') |
| self.switcher.mode_aware_reboot('custom', self.perform_s0ix_cycle) |
| |
| def cleanup(self): |
| """ |
| Cleanup after test completes |
| """ |
| self.ec.set_uart_regexp('None') |
| # Test may failed before resume, wake the system. |
| self.ec.send_command('powerbtn') |
| # Perform a warm reboot as part of the cleanup. |
| self._client.reboot() |
| super(platform_S0ixCycle, self).cleanup() |