1# Copyright (c) 2010 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 os 6import logging 7 8from autotest_lib.client.bin import utils 9from autotest_lib.client.common_lib import error 10from autotest_lib.client.common_lib.cros import chrome 11from autotest_lib.client.cros import service_stopper 12from autotest_lib.client.cros.graphics import graphics_utils 13 14# to run this test manually on a test target 15# ssh root@machine 16# cd /usr/local/autotest/deps/glbench 17# stop ui 18# ./windowmanagertest --screenshot1_sec 2 --screenshot2_sec 1 --cooldown_sec 1 \ 19# --screenshot1_cmd \ 20# "/usr/local/autotest/bin/screenshot.py screenshot1_generated.png" \ 21# --screenshot2_cmd \ 22# "/usr/local/autotest/bin/screenshot.py screenshot2_generated.png" 23# start ui 24 25 26class graphics_Sanity(graphics_utils.GraphicsTest): 27 """ 28 This test is meant to be used as a quick sanity check for GL/GLES. 29 """ 30 version = 1 31 32 # None-init vars used by cleanup() here, in case setup() fails 33 _services = None 34 35 def setup(self): 36 self.job.setup_dep(['glbench']) 37 dep = 'glbench' 38 dep_dir = os.path.join(self.autodir, 'deps', dep) 39 self.job.install_pkg(dep, 'dep', dep_dir) 40 41 def cleanup(self): 42 super(graphics_Sanity, self).cleanup() 43 if self._services: 44 self._services.restore_services() 45 46 def test_something_on_screen(self): 47 """Check if something is drawn on screen: i.e. not a black screen. 48 49 @raises TestFail if we cannot determine there was something on screen. 50 """ 51 52 def can_take_screenshot(): 53 """Check that taking a screenshot can succeed. 54 55 There are cases when trying to take a screenshot on the device 56 fails. e.g. the display has gone to sleep, we have logged out and 57 the UI has not come back up yet etc. 58 """ 59 try: 60 graphics_utils.take_screenshot(self.resultsdir, 61 'temp screenshot', '.png') 62 return True 63 except: 64 return False 65 66 utils.poll_for_condition( 67 can_take_screenshot, 68 sleep_interval=1, 69 desc='Failed to take a screenshot. There may be an issue with this ' 70 'ChromeOS image.') 71 72 w, h = graphics_utils.get_internal_resolution() 73 megapixels = (w * h) / 1000000 74 filesize_threshold = 25 * megapixels 75 screenshot1 = graphics_utils.take_screenshot(self.resultsdir, 76 'oobe or signin', '.png') 77 78 with chrome.Chrome() as cr: 79 tab = cr.browser.tabs[0] 80 tab.Navigate('chrome://settings') 81 tab.WaitForDocumentReadyStateToBeComplete() 82 83 screenshot2 = graphics_utils.take_screenshot( 84 self.resultsdir, 'settings page', '.png') 85 86 for screenshot in [screenshot1, screenshot2]: 87 file_size_kb = os.path.getsize(screenshot) / 1000 88 89 # Use compressed file size to tell if anything is on screen. 90 if file_size_kb > filesize_threshold: 91 return 92 93 raise error.TestFail( 94 'Screenshot filesize is very small. This indicates that ' 95 'there is nothing on screen. This ChromeOS image could be ' 96 'unusable. Check the screenshot in the results folder.') 97 98 def test_generated_screenshots_match_expectation(self): 99 """Draws a texture with a soft ellipse twice and captures each image. 100 Compares the output fuzzily against reference images. 101 """ 102 self._services = service_stopper.ServiceStopper(['ui']) 103 self._services.stop_services() 104 105 screenshot1_reference = os.path.join(self.bindir, 106 'screenshot1_reference.png') 107 screenshot1_generated = os.path.join(self.resultsdir, 108 'screenshot1_generated.png') 109 screenshot1_resized = os.path.join(self.resultsdir, 110 'screenshot1_generated_resized.png') 111 screenshot2_reference = os.path.join(self.bindir, 112 'screenshot2_reference.png') 113 screenshot2_generated = os.path.join(self.resultsdir, 114 'screenshot2_generated.png') 115 screenshot2_resized = os.path.join(self.resultsdir, 116 'screenshot2_generated_resized.png') 117 118 exefile = os.path.join(self.autodir, 'deps/glbench/windowmanagertest') 119 120 # Delay before screenshot: 1 second has caused failures. 121 options = ' --screenshot1_sec 2' 122 options += ' --screenshot2_sec 1' 123 options += ' --cooldown_sec 1' 124 # perceptualdiff can handle only 8 bit images. 125 screenshot_cmd = ' "/usr/local/autotest/bin/screenshot.py %s"' 126 options += ' --screenshot1_cmd' + screenshot_cmd % screenshot1_generated 127 options += ' --screenshot2_cmd' + screenshot_cmd % screenshot2_generated 128 129 cmd = exefile + ' ' + options 130 utils.run( 131 cmd, stdout_tee=utils.TEE_TO_LOGS, stderr_tee=utils.TEE_TO_LOGS) 132 133 convert_cmd = ('convert -channel RGB -colorspace RGB -depth 8' 134 " -resize '100x100!' %s %s") 135 utils.system(convert_cmd % (screenshot1_generated, screenshot1_resized)) 136 utils.system(convert_cmd % (screenshot2_generated, screenshot2_resized)) 137 os.remove(screenshot1_generated) 138 os.remove(screenshot2_generated) 139 140 diff_cmd = 'perceptualdiff -verbose %s %s' 141 utils.system(diff_cmd % (screenshot1_reference, screenshot1_resized)) 142 utils.system(diff_cmd % (screenshot2_reference, screenshot2_resized)) 143 144 def run_once(self): 145 if graphics_utils.get_display_resolution() is None: 146 logging.warning('Skipping test because there is no screen') 147 return 148 self.add_failures('graphics_Sanity') 149 self.wake_screen_with_keyboard() 150 self.test_something_on_screen() 151 self.test_generated_screenshots_match_expectation() 152 self.remove_failures('graphics_Sanity') 153