| # Copyright 2019 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 |
| import time |
| |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.server.cros.faft.cr50_test import Cr50Test |
| |
| |
| class firmware_Cr50RddG3(Cr50Test): |
| """Verify Rdd connect and disconnect in G3.""" |
| version = 1 |
| |
| WAIT_FOR_STATE = 10 |
| # Cr50 debounces disconnects. We need to wait before checking Rdd state |
| RDD_DEBOUNCE = 3 |
| |
| def rdd_is_connected(self): |
| """Return True if Cr50 detects Rdd.""" |
| time.sleep(2) |
| return self.cr50.get_ccdstate()['Rdd'] == 'connected' |
| |
| def check_capabilities(self, capabilities): |
| """Returns the matching capability or None.""" |
| if not capabilities: |
| return None |
| for capability in capabilities: |
| if self.check_cr50_capability([capability]): |
| return capability |
| return None |
| |
| |
| def check_rdd_status(self, dts_mode, err_desc, capabilities=None): |
| """Check the rdd state. |
| |
| @param dts_mode: 'on' if Rdd should be connected. 'off' if it should be |
| disconnected. |
| @param err_desc: Description of the rdd error. |
| @param capabilities: ignore err_desc if any of the capabilities from |
| this list are found in the faft board config. |
| @param raises TestFail if rdd state doesn't match the expected rdd state |
| or if it does and the board has the capability set. |
| """ |
| time.sleep(self.RDD_DEBOUNCE) |
| err_msg = None |
| rdd_enabled = self.rdd_is_connected() |
| logging.info('dts: %r rdd: %r', dts_mode, |
| 'connected' if rdd_enabled else 'disconnected') |
| found_cap = self.check_capabilities(capabilities) |
| if rdd_enabled != (dts_mode == 'on'): |
| if found_cap: |
| logging.info('Found %r. %r still applies to board.', |
| found_cap, err_desc) |
| else: |
| err_msg = err_desc |
| elif found_cap: |
| err_msg = 'Found %r, but %r did not occur.' % (found_cap, err_desc) |
| if err_msg: |
| logging.warning(err_msg) |
| self.rdd_failures.append(err_msg) |
| |
| |
| def run_once(self): |
| """Verify Rdd in G3.""" |
| self.rdd_failures = [] |
| if not hasattr(self, 'ec'): |
| raise error.TestNAError('Board does not have an EC.') |
| if not self.servo.dts_mode_is_valid(): |
| raise error.TestNAError('Run with type-c servo v4.') |
| |
| self.servo.set_dts_mode('on') |
| self.check_rdd_status('on', 'Cr50 did not detect Rdd with dts mode on') |
| |
| self.servo.set_dts_mode('off') |
| self.check_rdd_status('off', 'Cr50 did not detect Rdd disconnect in S0') |
| |
| logging.info('Checking Rdd is disconnected with the EC in hibernate') |
| self.faft_client.system.run_shell_command('poweroff') |
| time.sleep(self.WAIT_FOR_STATE) |
| self.ec.send_command('hibernate') |
| time.sleep(self.WAIT_FOR_STATE) |
| |
| self.check_rdd_status('off', 'Rdd connected after EC hibernate', |
| ['rdd_leakage', 'ec_hibernate_breaks_rdd']) |
| |
| logging.info('Checking Rdd can be connected in G3.') |
| self.servo.set_dts_mode('on') |
| self.check_rdd_status('on', 'Cr50 did not detect Rdd connect in G3') |
| |
| # Turn the DUT on, then reenter G3 to make sure the system handles Rdd |
| # while entering G3 ok. |
| self._try_to_bring_dut_up() |
| self.check_rdd_status('on', 'Rdd disconnected entering S0') |
| |
| logging.info('Checking Rdd is connected with the EC in hibernate.') |
| self.faft_client.system.run_shell_command('poweroff') |
| time.sleep(self.WAIT_FOR_STATE) |
| self.ec.send_command('hibernate') |
| time.sleep(self.WAIT_FOR_STATE) |
| |
| self.check_rdd_status('on', 'Rdd disconnected after EC hibernate', |
| ['ec_hibernate_breaks_rdd']) |
| |
| logging.info('Checking Rdd can be disconnected in G3.') |
| self.servo.set_dts_mode('off') |
| self.check_rdd_status('off', 'Cr50 did not detect Rdd disconnect in G3', |
| ['rdd_leakage']) |
| self._try_to_bring_dut_up() |
| if self.rdd_failures: |
| raise error.TestFail('Found Rdd issues: %s' % (self.rdd_failures)) |