100 lines
3.9 KiB
Python
100 lines
3.9 KiB
Python
# Copyright 2015 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
|
|
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
|
|
from autotest_lib.server.cros.servo import pd_device
|
|
|
|
|
|
class firmware_PDConnect(FirmwareTest):
|
|
"""
|
|
Servo based USB PD connect/disconnect test. If PDTester is not one
|
|
of the device pair elements, then this test requires that at least
|
|
one of the devices support dual role mode in order to force a disconnect
|
|
to connect sequence. The test does not depend on the DUT acting as source
|
|
or sink, either mode should pass.
|
|
|
|
Pass critera is 100% of connections resulting in successful connections
|
|
"""
|
|
version = 1
|
|
CONNECT_ITERATIONS = 10
|
|
def _test_connect(self, port_pair, dts_mode):
|
|
"""Tests disconnect/connect sequence
|
|
|
|
@param port_pair: list of 2 connected PD devices
|
|
@param dts_mode: the test is under DTS mode?
|
|
"""
|
|
# Delay in seconds between disconnect and connect commands
|
|
RECONNECT_DELAY = 10
|
|
for dev in port_pair:
|
|
if dts_mode and not dev.is_pdtester:
|
|
logging.info('If DUT in DTS mode, it is always connected. '
|
|
'Unable to set it disconnected; skip this item.')
|
|
continue
|
|
|
|
for attempt in xrange(self.CONNECT_ITERATIONS):
|
|
logging.info('Disconnect/Connect iteration %d', attempt)
|
|
try:
|
|
if dev.drp_disconnect_connect(RECONNECT_DELAY) == False:
|
|
raise error.TestFail('Disconnect/Connect Failed')
|
|
except NotImplementedError:
|
|
logging.warn('Device does not support disconnect/connect')
|
|
break
|
|
|
|
def initialize(self, host, cmdline_args, flip_cc=False, dts_mode=False):
|
|
super(firmware_PDConnect, self).initialize(host, cmdline_args)
|
|
self.setup_pdtester(flip_cc, dts_mode)
|
|
# Only run in normal mode
|
|
self.switcher.setup_mode('normal')
|
|
self.usbpd.enable_console_channel('usbpd')
|
|
|
|
|
|
def cleanup(self):
|
|
self.usbpd.send_command('chan 0xffffffff')
|
|
super(firmware_PDConnect, self).cleanup()
|
|
|
|
|
|
def run_once(self, dts_mode=False):
|
|
"""Exectue disconnect/connect sequence test
|
|
|
|
"""
|
|
|
|
# Create list of available UART consoles
|
|
consoles = [self.usbpd, self.pdtester]
|
|
port_partner = pd_device.PDPortPartner(consoles)
|
|
# Identify a valid test port pair
|
|
port_pair = port_partner.identify_pd_devices()
|
|
if not port_pair:
|
|
raise error.TestFail('No PD connection found!')
|
|
|
|
# Test disconnect/connect sequences
|
|
self._test_connect(port_pair, dts_mode)
|
|
|
|
# Swap power roles (if possible). Note the pr swap is attempted
|
|
# for both devices in the connection. This ensures that a device
|
|
# such as Plankton, which is dualrole capable, but has this mode
|
|
# disabled by default, won't prevent the device pair from role swapping.
|
|
swappable_dev = None;
|
|
for dev in port_pair:
|
|
try:
|
|
if dev.pr_swap():
|
|
swappable_dev = dev
|
|
break
|
|
except NotImplementedError:
|
|
logging.warn('Power role swap not supported on the device')
|
|
|
|
if swappable_dev:
|
|
try:
|
|
# Power role has been swapped, retest.
|
|
self._test_connect(port_pair, dts_mode)
|
|
finally:
|
|
# Swap power role again, back to the original
|
|
if not swappable_dev.pr_swap():
|
|
logging.error('Failed to swap power role to the original')
|
|
else:
|
|
logging.warn('Device pair could not perform power role swap, '
|
|
'ending test')
|