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