1# Copyright (c) 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 server side stressing DUT by switching Chameleon EDID."""
6
7import glob
8import logging
9import os
10import xmlrpclib
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.client.cros.chameleon import edid
17from autotest_lib.server import test
18from autotest_lib.server.cros.multimedia import remote_facade_factory
19
20
21class display_EdidStress(test.test):
22    """Server side external display test.
23
24    This test switches Chameleon EDID from among a large pool of EDIDs, tests
25    DUT recognizes the emulated monitor and emits the correct video signal to
26    Chameleon.
27    """
28    version = 1
29
30    _EDID_TYPES = {'HDMI': {'HDMI', 'MHL', 'DVI'},
31                   'DP': {'DP'},
32                   'VGA': {'VGA'}}
33
34    def run_once(self, host, edid_set):
35
36        def _get_edid_type(s):
37            i = s.rfind('_') + 1
38            j = len(s) - len('.txt')
39            return s[i:j].upper()
40
41        edid_path = os.path.join(self.bindir, 'test_data', 'edids',
42                                 edid_set, '*')
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        for chameleon_port in finder.iterate_all_ports():
52            screen_test = chameleon_screen_test.ChameleonScreenTest(
53                host, chameleon_port, display_facade, self.outputdir)
54
55            logging.info('See the display on Chameleon: port %d (%s)',
56                         chameleon_port.get_connector_id(),
57                         chameleon_port.get_connector_type())
58
59            connector = chameleon_port.get_connector_type()
60            supported_types = self._EDID_TYPES[connector]
61
62            failed_edids = []
63            for filepath in glob.glob(edid_path):
64                filename = os.path.basename(filepath)
65                edid_type = _get_edid_type(filename)
66                if edid_type not in supported_types:
67                    logging.info('Skip EDID: %s...', filename)
68                    continue
69
70                logging.info('Use EDID: %s...', filename)
71                try:
72                    with chameleon_port.use_edid(
73                            edid.Edid.from_file(filepath, skip_verify=True)):
74                        resolution = utils.wait_for_value_changed(
75                                display_facade.get_external_resolution,
76                                old_value=None)
77                        if resolution is None:
78                            raise error.TestFail('No external display detected on DUT')
79                        if screen_test.test_resolution(resolution):
80                            raise error.TestFail('Resolution test failed')
81                except (error.TestFail, xmlrpclib.Fault) as e:
82                    logging.warning(e)
83                    logging.error('EDID not supported: %s', filename)
84                    failed_edids.append(filename)
85
86            if failed_edids:
87                message = ('Total %d EDIDs not supported: ' % len(failed_edids)
88                           + ', '.join(failed_edids))
89                logging.error(message)
90                raise error.TestFail(message)
91