• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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