Home | History | Annotate | Download | only in display_HotPlugAtSuspend
      1 # Copyright 2014 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 
      5 """This is a display hot-plug and suspend test using the Chameleon board."""
      6 
      7 import logging
      8 import time
      9 
     10 from autotest_lib.client.bin import utils
     11 from autotest_lib.client.common_lib import error
     12 from autotest_lib.client.cros.chameleon import chameleon_port_finder
     13 from autotest_lib.client.cros.chameleon import chameleon_screen_test
     14 from autotest_lib.server import test
     15 from autotest_lib.server.cros.multimedia import remote_facade_factory
     16 
     17 
     18 class display_HotPlugAtSuspend(test.test):
     19     """Display hot-plug and suspend test.
     20 
     21     This test talks to a Chameleon board and a DUT to set up, run, and verify
     22     DUT behavior response to different configuration of hot-plug during
     23     suspend/resume.
     24     """
     25     version = 1
     26     # Duration of suspend, in second.
     27     SUSPEND_DURATION = 30
     28     # Allowed timeout for the transition of suspend.
     29     SUSPEND_TIMEOUT = 20
     30     # Allowed timeout for the transition of resume.
     31     RESUME_TIMEOUT = 60
     32     # Time margin to do plug/unplug before resume.
     33     TIME_MARGIN_BEFORE_RESUME = 5
     34     # Timeout of waiting DUT mirrored.
     35     TIMEOUT_WAITING_MIRRORED = 5
     36 
     37 
     38     def run_once(self, host, plug_status, test_mirrored=False):
     39         if test_mirrored and not host.get_board_type() == 'CHROMEBOOK':
     40             raise error.TestNAError('DUT is not Chromebook. Test Skipped')
     41 
     42         factory = remote_facade_factory.RemoteFacadeFactory(host)
     43         display_facade = factory.create_display_facade()
     44         chameleon_board = host.chameleon
     45 
     46         chameleon_board.setup_and_reset(self.outputdir)
     47         finder = chameleon_port_finder.ChameleonVideoInputFinder(
     48                 chameleon_board, display_facade)
     49 
     50         errors = []
     51         is_display_failure = False
     52         for chameleon_port in finder.iterate_all_ports():
     53             screen_test = chameleon_screen_test.ChameleonScreenTest(
     54                     host, chameleon_port, display_facade, self.outputdir)
     55 
     56             logging.info('See the display on Chameleon: port %d (%s)',
     57                          chameleon_port.get_connector_id(),
     58                          chameleon_port.get_connector_type())
     59 
     60             logging.info('Set mirrored: %s', test_mirrored)
     61             display_facade.set_mirrored(test_mirrored)
     62 
     63             # Keep the original connector name, for later comparison.
     64             expected_connector = display_facade.get_external_connector_name()
     65             resolution = display_facade.get_external_resolution()
     66             logging.info('See the display on DUT: %s %r',
     67                          expected_connector, resolution)
     68 
     69             for (plugged_before_suspend, plugged_after_suspend,
     70                  plugged_before_resume) in plug_status:
     71                 test_case = ('TEST CASE: %s > SUSPEND > %s > %s > RESUME' %
     72                     ('PLUG' if plugged_before_suspend else 'UNPLUG',
     73                      'PLUG' if plugged_after_suspend else 'UNPLUG',
     74                      'PLUG' if plugged_before_resume else 'UNPLUG'))
     75                 logging.info(test_case)
     76                 boot_id = host.get_boot_id()
     77                 chameleon_port.set_plug(plugged_before_suspend)
     78 
     79                 if screen_test.check_external_display_connected(
     80                         expected_connector if plugged_before_suspend else False,
     81                         errors):
     82                     is_display_failure = True
     83                     # Skip the following test if an unexpected display detected.
     84                     continue
     85 
     86                 logging.info('GOING TO SUSPEND FOR %d SECONDS...',
     87                              self.SUSPEND_DURATION)
     88                 time_before_suspend = time.time()
     89                 display_facade.suspend_resume_bg(self.SUSPEND_DURATION)
     90 
     91                 # Confirm DUT suspended.
     92                 logging.info('WAITING FOR SUSPEND...')
     93                 try:
     94                     host.test_wait_for_sleep(self.SUSPEND_TIMEOUT)
     95                 except error.TestFail, ex:
     96                     errors.append("%s - %s" % (test_case, str(ex)))
     97                 if plugged_after_suspend is not plugged_before_suspend:
     98                     chameleon_port.set_plug(plugged_after_suspend)
     99 
    100                 current_time = time.time()
    101                 sleep_time = (self.SUSPEND_DURATION -
    102                               (current_time - time_before_suspend) -
    103                               self.TIME_MARGIN_BEFORE_RESUME)
    104                 if sleep_time > 0:
    105                     logging.info('- Sleep for %.2f seconds...', sleep_time)
    106                     time.sleep(sleep_time)
    107                 if plugged_before_resume is not plugged_after_suspend:
    108                     chameleon_port.set_plug(plugged_before_resume)
    109                 time.sleep(self.TIME_MARGIN_BEFORE_RESUME)
    110 
    111                 logging.info('WAITING FOR RESUME...')
    112                 try:
    113                     host.test_wait_for_resume(boot_id, self.RESUME_TIMEOUT)
    114                 except error.TestFail, ex:
    115                     errors.append("%s - %s" % (test_case, str(ex)))
    116 
    117                 logging.info('Resumed back')
    118 
    119                 if screen_test.check_external_display_connected(
    120                         expected_connector if plugged_before_resume else False,
    121                         errors):
    122                     # Skip the following test if an unexpected display detected.
    123                     continue
    124 
    125                 if plugged_before_resume:
    126                     if test_mirrored and (not utils.wait_for_value(
    127                             display_facade.is_mirrored_enabled, True,
    128                             timeout_sec=self.TIMEOUT_WAITING_MIRRORED)):
    129                         error_message = 'Error: not resumed to mirrored mode'
    130                         errors.append("%s - %s" % (test_case, error_message))
    131                         logging.error(error_message)
    132                         logging.info('Set mirrored: %s', True)
    133                         display_facade.set_mirrored(True)
    134                     elif screen_test.test_screen_with_image(
    135                                 resolution, test_mirrored, errors):
    136                         is_display_failure = True
    137 
    138         if errors:
    139             if is_display_failure:
    140                 raise error.TestFail('; '.join(set(errors)))
    141             else:
    142                 raise error.TestError('; '.join(set(errors)))
    143