1# Lint as: python2, python3 2# Copyright (c) 2018 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import logging 7import time 8 9from contextlib import contextmanager 10 11from autotest_lib.client.bin import test 12from autotest_lib.client.bin import utils 13from autotest_lib.client.common_lib import error 14from autotest_lib.client.cros.power import power_suspend 15from autotest_lib.client.cros.power import power_status 16from autotest_lib.client.cros.power import power_utils 17 18 19class power_SuspendToIdle(test.test): 20 """class for power_SuspendToIdle test.""" 21 version = 1 22 _pch_powergating_max_retry = 5 23 _pch_powergating_retry_delay_secs = 1 24 25 @contextmanager 26 def _log_error_message(self): 27 """Suppress exception and log the message.""" 28 try: 29 yield 30 except Exception as e: 31 self._error_count += 1 32 self._error_message.append(str(e)) 33 34 def run_once(self, force_suspend_to_idle=False): 35 """Main test method. 36 """ 37 if utils.get_cpu_arch() != 'x86_64': 38 raise error.TestNAError('This test only supports x86_64 CPU.') 39 40 if power_utils.get_sleep_state() != 'freeze': 41 if not force_suspend_to_idle: 42 raise error.TestNAError( 43 'System default config is not suspend to idle.') 44 else: 45 logging.info('System default config is suspend to ram. ' 46 'Force suspend to idle') 47 48 self._error_count = 0 49 self._error_message = [] 50 dmc_firmware_stats = None 51 s0ix_residency_stats = None 52 cpu_packages_stats = None 53 rc6_residency_stats = None 54 55 with self._log_error_message(): 56 dmc_firmware_stats = power_status.DMCFirmwareStats() 57 if not dmc_firmware_stats.check_fw_loaded(): 58 raise error.TestFail('DMC firmware not loaded.') 59 60 with self._log_error_message(): 61 pch_powergating_stats = power_status.PCHPowergatingStats() 62 63 on_pch = None 64 # Allow |_pch_powergating_max_retry| tries of PCH powergating 65 # because we check this in S0 idle instead of S0ix and background 66 # process may make this flakiness. 67 for try_count in range(1, self._pch_powergating_max_retry + 1): 68 pch_powergating_stats.read_pch_powergating_info() 69 on_pch = pch_powergating_stats.check_s0ix_requirement() 70 if not on_pch: 71 break 72 logging.info('PCH powergating check#%d failed: %s', try_count, 73 ', '.join(on_pch)) 74 time.sleep(self._pch_powergating_retry_delay_secs) 75 else: 76 raise error.TestFail('PCH powergating check failed: ', 77 ', '.join(on_pch)) 78 79 with self._log_error_message(): 80 s0ix_residency_stats = power_status.S0ixResidencyStats() 81 82 with self._log_error_message(): 83 cpu_packages_stats = power_status.CPUPackageStats() 84 85 with self._log_error_message(): 86 rc6_residency_stats = power_status.RC6ResidencyStats() 87 88 with self._log_error_message(): 89 suspender = power_suspend.Suspender(self.resultsdir, 90 suspend_state='freeze') 91 suspender.suspend() 92 93 with self._log_error_message(): 94 if (dmc_firmware_stats and 95 dmc_firmware_stats.is_dc6_supported() and 96 dmc_firmware_stats.get_accumulated_dc6_entry() <= 0): 97 raise error.TestFail('DC6 entry check failed.') 98 99 with self._log_error_message(): 100 if (s0ix_residency_stats and 101 s0ix_residency_stats.get_accumulated_residency_secs() <= 0): 102 raise error.TestFail('S0ix residency check failed.') 103 104 with self._log_error_message(): 105 if (cpu_packages_stats and 106 cpu_packages_stats.refresh().get('C10', 0) <= 0): 107 raise error.TestFail('C10 state check failed.') 108 109 with self._log_error_message(): 110 if (rc6_residency_stats and 111 rc6_residency_stats.get_accumulated_residency_msecs() <= 0): 112 raise error.TestFail('RC6 residency check failed.') 113 114 if self._error_count > 0: 115 raise error.TestFail('Found %d errors: ' % self._error_count, 116 ', '.join(self._error_message)) 117