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