134 lines
5.7 KiB
Python
134 lines
5.7 KiB
Python
# Copyright 2014 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.
|
|
|
|
"""This test remotely emulates noisy HPD line when connecting to an external
|
|
display in extended mode using the Chameleon board."""
|
|
|
|
import logging
|
|
import time
|
|
|
|
from autotest_lib.client.bin import utils
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.client.cros.chameleon import chameleon_port_finder
|
|
from autotest_lib.client.cros.chameleon import chameleon_screen_test
|
|
from autotest_lib.server import test
|
|
from autotest_lib.server.cros.multimedia import remote_facade_factory
|
|
|
|
|
|
class display_HotPlugNoisy(test.test):
|
|
"""Noisy display HPD test.
|
|
|
|
This test talks to a Chameleon board and a DUT to set up, run, and verify
|
|
DUT behavior in response to noisy HPD line.
|
|
"""
|
|
version = 1
|
|
PLUG_CONFIGS = [
|
|
# (plugged_before_noise, plugged_after_noise)
|
|
|
|
(False, False),
|
|
(False, True),
|
|
(True, False),
|
|
(True, True),
|
|
]
|
|
|
|
# pulse segments in msec that end with plugged state
|
|
PULSES_PLUGGED = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
|
|
# pulse segments in msec that end with unplugged state
|
|
PULSES_UNPLUGGED = PULSES_PLUGGED + [2048]
|
|
|
|
REPLUG_DELAY_SEC = 1
|
|
|
|
|
|
def run_once(self, host, test_mirrored=False):
|
|
if test_mirrored and not host.get_board_type() == 'CHROMEBOOK':
|
|
raise error.TestNAError('DUT is not Chromebook. Test Skipped')
|
|
|
|
factory = remote_facade_factory.RemoteFacadeFactory(host)
|
|
display_facade = factory.create_display_facade()
|
|
chameleon_board = host.chameleon
|
|
|
|
chameleon_board.setup_and_reset(self.outputdir)
|
|
finder = chameleon_port_finder.ChameleonVideoInputFinder(
|
|
chameleon_board, display_facade)
|
|
|
|
errors = []
|
|
warns = []
|
|
for chameleon_port in finder.iterate_all_ports():
|
|
screen_test = chameleon_screen_test.ChameleonScreenTest(
|
|
host, chameleon_port, display_facade, self.outputdir)
|
|
|
|
logging.info('See the display on Chameleon: port %d (%s)',
|
|
chameleon_port.get_connector_id(),
|
|
chameleon_port.get_connector_type())
|
|
|
|
logging.info('Set mirrored: %s', test_mirrored)
|
|
display_facade.set_mirrored(test_mirrored)
|
|
|
|
# Keep the original connector name, for later comparison.
|
|
expected_connector = display_facade.get_external_connector_name()
|
|
resolution = display_facade.get_external_resolution()
|
|
logging.info('See the display on DUT: %s %r',
|
|
expected_connector, resolution)
|
|
|
|
for (plugged_before_noise,
|
|
plugged_after_noise) in self.PLUG_CONFIGS:
|
|
logging.info('TESTING THE CASE: %s > noise > %s',
|
|
'plug' if plugged_before_noise else 'unplug',
|
|
'plug' if plugged_after_noise else 'unplug')
|
|
|
|
chameleon_port.set_plug(plugged_before_noise)
|
|
|
|
if screen_test.check_external_display_connected(
|
|
expected_connector if plugged_before_noise else False,
|
|
errors):
|
|
# Skip the following test if an unexpected display detected.
|
|
continue
|
|
|
|
chameleon_port.fire_mixed_hpd_pulses(
|
|
self.PULSES_PLUGGED if plugged_after_noise
|
|
else self.PULSES_UNPLUGGED)
|
|
|
|
if plugged_after_noise:
|
|
chameleon_port.wait_video_input_stable()
|
|
if test_mirrored:
|
|
# Wait for resolution change to make sure the resolution
|
|
# is stable before moving on. This is to deal with the
|
|
# case where DUT may respond slowly after the noise.
|
|
# If the resolution doesn't change, then we are
|
|
# confident that it is stable. Otherwise, a slow
|
|
# response is caught.
|
|
r = display_facade.get_internal_resolution()
|
|
utils.wait_for_value_changed(
|
|
display_facade.get_internal_resolution,
|
|
old_value=r)
|
|
|
|
err = screen_test.check_external_display_connected(
|
|
expected_connector)
|
|
|
|
if not err:
|
|
err = screen_test.test_screen_with_image(
|
|
resolution, test_mirrored)
|
|
if err:
|
|
# When something goes wrong after the noise, a normal
|
|
# user would try to re-plug the cable to recover.
|
|
# We emulate this behavior below and report error if
|
|
# the problem persists.
|
|
logging.warn('Possibly flaky: %s', err)
|
|
warns.append('Possibly flaky: %s' % err)
|
|
logging.info('Replug and retry the screen test...')
|
|
chameleon_port.unplug()
|
|
time.sleep(self.REPLUG_DELAY_SEC)
|
|
chameleon_port.plug()
|
|
chameleon_port.wait_video_input_stable()
|
|
screen_test.test_screen_with_image(
|
|
resolution, test_mirrored, errors)
|
|
else:
|
|
screen_test.check_external_display_connected(False, errors)
|
|
time.sleep(1)
|
|
|
|
if errors:
|
|
raise error.TestFail('; '.join(set(errors)))
|
|
elif warns:
|
|
raise error.TestWarn('; '.join(set(warns)))
|