1# Copyright 2019 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.server.cros.faft.cr50_test import Cr50Test 10 11 12class firmware_Cr50RddG3(Cr50Test): 13 """Verify Rdd connect and disconnect in G3.""" 14 version = 1 15 16 WAIT_FOR_STATE = 10 17 # Cr50 debounces disconnects. We need to wait before checking Rdd state 18 RDD_DEBOUNCE = 3 19 20 def initialize(self, host, cmdline_args, full_args): 21 """Initialize the test""" 22 super(firmware_Cr50RddG3, self).initialize(host, cmdline_args, 23 full_args) 24 25 # TODO(b/186535695): EC hibernate puts cr50 into reset, so the test 26 # can't verify cr50 behavior while the EC is hibernate. 27 if 'c2d2' in self.servo.get_servo_type(): 28 raise error.TestNAError('Cannot run test with c2d2') 29 30 def rdd_is_connected(self): 31 """Return True if Cr50 detects Rdd.""" 32 time.sleep(2) 33 return self.cr50.get_ccdstate()['Rdd'] == 'connected' 34 35 def check_capabilities(self, capabilities): 36 """Returns the matching capability or None.""" 37 if not capabilities: 38 return None 39 for capability in capabilities: 40 if self.check_cr50_capability([capability]): 41 return capability 42 return None 43 44 45 def check_rdd_status(self, dts_mode, err_desc, capabilities=None): 46 """Check the rdd state. 47 48 @param dts_mode: 'on' if Rdd should be connected. 'off' if it should be 49 disconnected. 50 @param err_desc: Description of the rdd error. 51 @param capabilities: ignore err_desc if any of the capabilities from 52 this list are found in the faft board config. 53 @param raises TestFail if rdd state doesn't match the expected rdd state 54 or if it does and the board has the capability set. 55 """ 56 time.sleep(self.RDD_DEBOUNCE) 57 err_msg = None 58 rdd_enabled = self.rdd_is_connected() 59 logging.info('dts: %r rdd: %r', dts_mode, 60 'connected' if rdd_enabled else 'disconnected') 61 board_cap = self.check_capabilities(capabilities) 62 if rdd_enabled != (dts_mode == 'on'): 63 if board_cap: 64 logging.info('Board has %r. %r still applies to board.', 65 board_cap, err_desc) 66 else: 67 err_msg = err_desc 68 elif board_cap: 69 # Log a warning if the board has a Rdd issue, but it didn't show up 70 # during this test run. 71 logging.warning( 72 'Irregular Cap behavior: Board has %r, but %r did ' 73 'not occur.', board_cap, err_desc) 74 err_msg = None 75 if err_msg: 76 logging.warning(err_msg) 77 self.rdd_failures.append(err_msg) 78 79 80 def run_once(self): 81 """Verify Rdd in G3.""" 82 self.rdd_failures = [] 83 if not hasattr(self, 'ec'): 84 raise error.TestNAError('Board does not have an EC.') 85 if not self.servo.dts_mode_is_valid(): 86 raise error.TestNAError('Run with type-c servo v4.') 87 88 self.servo.set_dts_mode('on') 89 self.check_rdd_status('on', 'Cr50 did not detect Rdd with dts mode on') 90 91 self.servo.set_dts_mode('off') 92 self.check_rdd_status('off', 'Cr50 did not detect Rdd disconnect in S0') 93 94 logging.info('Checking Rdd is disconnected with the EC in hibernate') 95 self.faft_client.system.run_shell_command('poweroff') 96 time.sleep(self.WAIT_FOR_STATE) 97 self.ec.send_command('hibernate') 98 time.sleep(self.WAIT_FOR_STATE) 99 100 self.check_rdd_status('off', 'Rdd connected after EC hibernate', 101 ['rdd_leakage', 'ec_hibernate_breaks_rdd']) 102 103 logging.info('Checking Rdd can be connected in G3.') 104 self.servo.set_dts_mode('on') 105 self.check_rdd_status('on', 'Cr50 did not detect Rdd connect in G3') 106 107 # Turn the DUT on, then reenter G3 to make sure the system handles Rdd 108 # while entering G3 ok. 109 self._try_to_bring_dut_up() 110 self.check_rdd_status('on', 'Rdd disconnected entering S0') 111 112 logging.info('Checking Rdd is connected with the EC in hibernate.') 113 self.faft_client.system.run_shell_command('poweroff') 114 time.sleep(self.WAIT_FOR_STATE) 115 self.ec.send_command('hibernate') 116 time.sleep(self.WAIT_FOR_STATE) 117 118 self.check_rdd_status('on', 'Rdd disconnected after EC hibernate', 119 ['rdd_off_in_g3', 'ec_hibernate_breaks_rdd']) 120 121 logging.info('Checking Rdd can be disconnected in G3.') 122 self.servo.set_dts_mode('off') 123 self.check_rdd_status('off', 124 'Cr50 did not detect Rdd disconnect in G3', 125 ['rdd_leakage']) 126 self._try_to_bring_dut_up() 127 if self.rdd_failures: 128 raise error.TestFail('Found Rdd issues: %s' % (self.rdd_failures)) 129