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