xref: /aosp_15_r20/external/autotest/server/site_tests/firmware_PDConnect/firmware_PDConnect.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Copyright 2015 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
6
7from autotest_lib.client.common_lib import error
8from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
9from autotest_lib.server.cros.servo import pd_device
10
11
12class firmware_PDConnect(FirmwareTest):
13    """
14    Servo based USB PD connect/disconnect test. If PDTester is not one
15    of the device pair elements, then this test requires that at least
16    one of the devices support dual role mode in order to force a disconnect
17    to connect sequence. The test does not depend on the DUT acting as source
18    or sink, either mode should pass.
19
20    Pass critera is 100%  of connections resulting in successful connections
21    """
22    version = 1
23    CONNECT_ITERATIONS = 10
24    def _test_connect(self, port_pair, dts_mode):
25        """Tests disconnect/connect sequence
26
27        @param port_pair: list of 2 connected PD devices
28        @param dts_mode: the test is under DTS mode?
29        """
30        # Delay in seconds between disconnect and connect commands
31        RECONNECT_DELAY = 10
32        for dev in port_pair:
33            if dts_mode and not dev.is_pdtester:
34                logging.info('If DUT in DTS mode, it is always connected. '
35                             'Unable to set it disconnected; skip this item.')
36                continue
37
38            for attempt in range(self.CONNECT_ITERATIONS):
39                logging.info('Disconnect/Connect iteration %d', attempt)
40                try:
41                    if dev.drp_disconnect_connect(RECONNECT_DELAY) == False:
42                        raise error.TestFail('Disconnect/Connect Failed')
43                except NotImplementedError:
44                    logging.warning('Device does not support disconnect/connect')
45                    break
46
47    def initialize(self, host, cmdline_args, flip_cc=False, dts_mode=False):
48        super(firmware_PDConnect, self).initialize(host, cmdline_args)
49        self.setup_pdtester(flip_cc, dts_mode)
50        # Only run in normal mode
51        self.switcher.setup_mode('normal')
52        self.usbpd.enable_console_channel('usbpd')
53
54
55    def cleanup(self):
56        self.usbpd.send_command('chan 0xffffffff')
57        super(firmware_PDConnect, self).cleanup()
58
59
60    def run_once(self, dts_mode=False):
61        """Exectue disconnect/connect sequence test
62
63        """
64
65        # Create list of available UART consoles
66        consoles = [self.usbpd, self.pdtester]
67        port_partner = pd_device.PDPortPartner(consoles)
68        # Identify a valid test port pair
69        port_pair = port_partner.identify_pd_devices()
70        if not port_pair:
71            raise error.TestFail('No PD connection found!')
72
73        # Test disconnect/connect sequences
74        self._test_connect(port_pair, dts_mode)
75
76        # Swap power roles (if possible). Note the pr swap is attempted
77        # for both devices in the connection. This ensures that a device
78        # such as Plankton, which is dualrole capable, but has this mode
79        # disabled by default, won't prevent the device pair from role swapping.
80        swappable_dev = None;
81        for dev in port_pair:
82            try:
83                if dev.pr_swap():
84                    swappable_dev = dev
85                    break
86            except NotImplementedError:
87                logging.warning('Power role swap not supported on the device')
88
89        if swappable_dev:
90            try:
91                # Power role has been swapped, retest.
92                self._test_connect(port_pair, dts_mode)
93            finally:
94                # Swap power role again, back to the original
95                if not swappable_dev.pr_swap():
96                    logging.error('Failed to swap power role to the original')
97        else:
98            logging.warning('Device pair could not perform power role swap, '
99                         'ending test')
100