• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2012 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
5import logging
6import os
7import time
8
9from autotest_lib.client.bin import utils
10from autotest_lib.client.common_lib import error
11from autotest_lib.client.common_lib.cros import chrome
12from autotest_lib.client.cros.graphics import graphics_utils
13from autotest_lib.client.cros.image_comparison import pdiff_image_comparer
14
15def get_percent_difference(file1, file2):
16    """
17    Performs pixel comparison of two files, given by their paths |file1|
18    and |file2| using terminal tool 'perceptualdiff' and returns percentage
19    difference of the total file size.
20
21    @param file1: path to image
22    @param file2: path to secondary image
23    @return: percentage difference of total file size.
24    @raise ValueError: if image dimensions are not the same
25    @raise OSError: if file does not exist or cannot be opened.
26
27    """
28    # Using pdiff image comparer to compare the two images. This class
29    # invokes the terminal tool perceptualdiff.
30    pdi = pdiff_image_comparer.PdiffImageComparer()
31    diff_bytes = pdi.compare(file1, file2)[0]
32    return round(100. * diff_bytes / os.path.getsize(file1))
33
34
35class graphics_VTSwitch(graphics_utils.GraphicsTest):
36    """
37    Verify that VT switching works.
38    """
39    version = 2
40    _WAIT = 5
41    # TODO(crosbug.com/36417): Need to handle more than one display screen.
42
43    @graphics_utils.GraphicsTest.failure_report_decorator('graphics_VTSwitch')
44    def run_once(self,
45                 num_iterations=2,
46                 similarity_percent_threshold=95,
47                 difference_percent_threshold=5):
48
49        # Check for chromebook type devices
50        if not utils.get_board_type() == 'CHROMEBOOK':
51            raise error.TestNAError('DUT is not Chromebook. Test Skipped.')
52
53        self._num_errors = 0
54        keyvals = {}
55
56        # Make sure we start in VT1.
57        self.open_vt1()
58
59        with chrome.Chrome():
60
61            # wait for Chrome to start before taking screenshot
62            time.sleep(10)
63
64            # Take screenshot of browser.
65            vt1_screenshot = self._take_current_vt_screenshot(1)
66
67            keyvals['num_iterations'] = num_iterations
68
69            # Go to VT2 and take a screenshot.
70            self.open_vt2()
71            vt2_screenshot = self._take_current_vt_screenshot(2)
72
73            # Make sure VT1 and VT2 are sufficiently different.
74            diff = get_percent_difference(vt1_screenshot, vt2_screenshot)
75            keyvals['percent_initial_VT1_VT2_difference'] = diff
76            if not diff >= difference_percent_threshold:
77                self._num_errors += 1
78                logging.error('VT1 and VT2 screenshots only differ by ' + \
79                              '%d %%: %s vs %s' %
80                              (diff, vt1_screenshot, vt2_screenshot))
81
82            num_identical_vt1_screenshots = 0
83            num_identical_vt2_screenshots = 0
84            max_vt1_difference_percent = 0
85            max_vt2_difference_percent = 0
86
87            # Repeatedly switch between VT1 and VT2.
88            for iteration in xrange(num_iterations):
89                logging.info('Iteration #%d', iteration)
90
91                # Go to VT1 and take a screenshot.
92                self.open_vt1()
93                current_vt1_screenshot = self._take_current_vt_screenshot(1)
94
95                # Make sure the current VT1 screenshot is the same as (or similar
96                # to) the original login screen screenshot.
97                diff = get_percent_difference(vt1_screenshot,
98                                              current_vt1_screenshot)
99                if not diff < similarity_percent_threshold:
100                    max_vt1_difference_percent = \
101                        max(diff, max_vt1_difference_percent)
102                    self._num_errors += 1
103                    logging.error('VT1 screenshots differ by %d %%: %s vs %s',
104                                  diff, vt1_screenshot,
105                                  current_vt1_screenshot)
106                else:
107                    num_identical_vt1_screenshots += 1
108
109                # Go to VT2 and take a screenshot.
110                self.open_vt2()
111                current_vt2_screenshot = self._take_current_vt_screenshot(2)
112
113                # Make sure the current VT2 screenshot is the same as (or
114                # similar to) the first VT2 screenshot.
115                diff = get_percent_difference(vt2_screenshot,
116                                              current_vt2_screenshot)
117                if not diff <= similarity_percent_threshold:
118                    max_vt2_difference_percent = \
119                        max(diff, max_vt2_difference_percent)
120                    self._num_errors += 1
121                    logging.error(
122                        'VT2 screenshots differ by %d %%: %s vs %s',
123                        diff, vt2_screenshot, current_vt2_screenshot)
124                else:
125                    num_identical_vt2_screenshots += 1
126
127        self.open_vt1()
128
129        keyvals['percent_VT1_screenshot_max_difference'] = \
130            max_vt1_difference_percent
131        keyvals['percent_VT2_screenshot_max_difference'] = \
132            max_vt2_difference_percent
133        keyvals['num_identical_vt1_screenshots'] = num_identical_vt1_screenshots
134        keyvals['num_identical_vt2_screenshots'] = num_identical_vt2_screenshots
135
136        self.write_perf_keyval(keyvals)
137
138        if self._num_errors > 0:
139            raise error.TestFail('Failed: saw %d VT switching errors.' %
140                                  self._num_errors)
141
142    def _take_current_vt_screenshot(self, current_vt):
143        """
144        Captures a screenshot of the current VT screen in PNG format.
145
146        @param current_vt: desired vt for screenshot.
147
148        @returns the path of the screenshot file.
149
150        """
151        return graphics_utils.take_screenshot(self.resultsdir,
152                                              'graphics_VTSwitch_VT%d' % current_vt)
153
154    def cleanup(self):
155        # Return to VT1 when done.  Ideally, the screen should already be in VT1
156        # but the test might fail and terminate while in VT2.
157        self.open_vt1()
158        super(graphics_VTSwitch, self).cleanup()
159