xref: /aosp_15_r20/external/autotest/server/site_tests/firmware_PDResetSoft/firmware_PDResetSoft.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Copyright 2016 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.firmware_test import FirmwareTest
10from autotest_lib.server.cros.servo import pd_device
11
12class firmware_PDResetSoft(FirmwareTest):
13    """
14    Servo based USB PD soft reset test.
15
16    Soft resets are issued by both ends of the connection. If the DUT
17    is dualrole capable, then a power role swap is executed, and the
18    test is repeated with the DUT in the opposite power role. Pass
19    criteria is that all attempted soft resets are successful.
20
21    """
22
23    version = 1
24    RESET_ITERATIONS = 5
25    PD_CONNECT_DELAY = 10
26
27    def _test_soft_reset(self, port_pair):
28        """Tests soft reset initated by both PDTester and the DUT
29
30        @param port_pair: list of 2 connected PD devices
31        """
32        for dev in port_pair:
33            for _ in range(self.RESET_ITERATIONS):
34                try:
35                    time.sleep(self.PD_CONNECT_DELAY)
36                    if dev.soft_reset() == False:
37                        raise error.TestFail('Soft Reset Failed')
38                except NotImplementedError:
39                    logging.warning('Device cant soft reset ... skipping')
40                    break
41
42    def initialize(self, host, cmdline_args, flip_cc=False, dts_mode=False,
43                   init_power_mode=None):
44        super(firmware_PDResetSoft, self).initialize(host, cmdline_args)
45        self.setup_pdtester(flip_cc, dts_mode, min_batt_level=10)
46        # Only run in normal mode
47        self.switcher.setup_mode('normal')
48        if init_power_mode:
49            # Set the DUT to suspend or shutdown mode
50            self.set_ap_off_power_mode(init_power_mode)
51        # Turn off console prints, except for USBPD.
52        self.usbpd.enable_console_channel('usbpd')
53
54    def cleanup(self):
55        self.usbpd.send_command('chan 0xffffffff')
56        self.restore_ap_on_power_mode()
57        super(firmware_PDResetSoft, self).cleanup()
58
59    def run_once(self):
60        """Execute Power Role swap test.
61
62        1. Verify that pd console is accessible
63        2. Verify that DUT has a valid PD contract
64        3. Make sure dualrole mode is enabled on both ends
65        4. Test Soft Reset initiated by both ends of connection
66        5. Attempt to change power roles
67           If power role changed, then retest soft resets
68           Else end test.
69
70        """
71        # Create list of available UART consoles
72        consoles = [self.usbpd, self.pdtester]
73        port_partner = pd_device.PDPortPartner(consoles)
74
75        # Identify a valid test port pair
76        port_pair = port_partner.identify_pd_devices()
77        if not port_pair:
78            raise error.TestFail('No PD connection found!')
79
80        # Test soft resets initiated by both ends
81        self._test_soft_reset(port_pair)
82
83        # Swap power roles (if possible). Note the pr swap is attempted
84        # for both devices in the connection. This ensures that a device
85        # such as Plankton, which is dualrole capable, but has this mode
86        # disabled by default, won't prevent the device pair from role swapping.
87        swappable_dev = None;
88        for dev in port_pair:
89            try:
90                if dev.pr_swap():
91                    swappable_dev = dev
92                    break
93            except NotImplementedError:
94                logging.warning('Power role swap not supported on the device')
95
96        if swappable_dev:
97            try:
98                # Power role has been swapped, retest.
99                self._test_soft_reset(port_pair)
100            finally:
101                # Swap power role again, back to the original
102                if not swappable_dev.pr_swap():
103                    logging.error('Failed to swap power role to the original')
104        else:
105            logging.warning('Device pair could not perform power role swap, '
106                         'ending test')
107