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 client side graphics stress test.""" 6 7import logging, os, time 8 9from autotest_lib.client.bin import test 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 14BIG_BUCK_BUNNY_VM_URL = 'http://vimeo.com/1084537' 15BIG_BUCK_BUNNY_YT_URL = 'https://www.youtube.com/watch?v=YE7VzlLtp-4' 16GMAPS_MTV_URL = 'https://www.google.com/maps/@37.4249155,-122.072205,13z?force=webgl' 17WEBGL_AQUARIUM_URL = \ 18 'http://webglsamples.org/aquarium/aquarium.html' 19WEBGL_BLOB_URL = 'http://webglsamples.org/blob/blob.html' 20WEBGL_SPIRITBOX_URL = \ 21 'http://www.webkit.org/blog-files/webgl/SpiritBox.html' 22VIMEO_COUCHMODE_URL = 'http://vimeo.com/couchmode/' 23 24 25class graphics_Stress(graphics_utils.GraphicsTest): 26 """Graphics stress test.""" 27 version = 1 28 29 def setup(self): 30 self.job.setup_dep(['graphics']) 31 32 33 def new_chrome(self): 34 browser_args = ['--disable-features=PreferHtmlOverPlugins'] 35 return chrome.Chrome(extra_browser_args=browser_args, 36 extension_paths=self.ext_paths, 37 logged_in=True, 38 autotest_ext=True) 39 40 41 def create_window(self, cr, url): 42 cmd = 'chrome.windows.create( { url: \'%s\' } )' % ( url ) 43 cr.autotest_ext.ExecuteJavaScript(cmd) 44 tab = cr.browser.tabs[-1] 45 return tab 46 47 48 def open_urls(self, cr, url_list, window=True): 49 """Opens a list of the given urls. 50 @param browser: The Browser object to run the test with. 51 @param url_list: The list of URLs to open. 52 """ 53 tabs = [] 54 first = True 55 cr.browser.tabs[0].WaitForDocumentReadyStateToBeComplete() 56 57 for url in url_list: 58 tab = None 59 if first: 60 tab = cr.browser.tabs[0] 61 tab.Navigate(url) 62 else: 63 if window: 64 tab = self.create_window(cr, url) 65 else: 66 tab = cr.browser.tabs.New() 67 tab.Navigate(url) 68 69 logging.info('Opening URL %s', url) 70 first = False 71 tab.WaitForDocumentReadyStateToBeComplete() 72 tab.Activate() 73 tabs.append(tab) 74 return tabs 75 76 77 def maps_zoom_cycle(self): 78 """Performs one cycle of the maps zooming.""" 79 # Zoom in on purpose once more than out. 80 for _ in range(1, 11): 81 graphics_utils.press_keys(['KEY_KPPLUS']) 82 time.sleep(0.1) 83 time.sleep(0.5) 84 for _ in range(1, 10): 85 graphics_utils.press_keys(['KEY_KPMINUS']) 86 time.sleep(0.1) 87 time.sleep(0.5) 88 89 90 def fifty_spirits_test(self): 91 """ Open 50 tabs of WebGL SpiritBox, and let them run for a while. """ 92 with self.new_chrome() as cr: 93 tabs = self.open_urls(cr, [WEBGL_SPIRITBOX_URL] * 50, 94 window=False) 95 time.sleep(self._test_duration_secs - (time.time() - self._start_time)) 96 for tab in tabs: 97 tab.Close() 98 99 100 def blob_aquarium_yt_test(self): 101 """ Open WebGL Blob, WebGL Aquarium, and Youtube video, 102 and switch between tabs, pausing for 2 seconds at each tab, for the 103 duration of the test. """ 104 with self.new_chrome() as cr: 105 tabs = self.open_urls(cr, 106 [WEBGL_BLOB_URL, 107 WEBGL_AQUARIUM_URL, 108 BIG_BUCK_BUNNY_YT_URL], 109 window=False) 110 111 tabidx = 0 112 while time.time() - self._start_time < self._test_duration_secs: 113 cr.browser.tabs[tabidx].Activate() 114 tabidx = (tabidx + 1) % len(cr.browser.tabs) 115 time.sleep(2) 116 117 for tab in tabs: 118 tab.Close() 119 120 121 def gmaps_test(self): 122 """ Google Maps test. Load maps and zoom in and out. """ 123 with self.new_chrome() as cr: 124 tabs = self.open_urls(cr, [GMAPS_MTV_URL]) 125 126 # Click into the map area to achieve focus. 127 time.sleep(5) 128 graphics_utils.click_mouse() 129 130 # Do the stress test. 131 cycle = 0 132 while time.time() - self._start_time < self._test_duration_secs: 133 logging.info('Maps zoom cycle %d', cycle) 134 cycle += 1 135 self.maps_zoom_cycle() 136 137 for tab in tabs: 138 tab.Close() 139 140 141 def restart_test(self): 142 """ Restart UI, excercises X server startup and shutdown and related 143 kernel paths. """ 144 # Ui respawn will reboot us if we restart ui too many times, so stop 145 # it for the duration of the test. 146 stopped_services = service_stopper.ServiceStopper(['ui-respawn']) 147 stopped_services.stop_services() 148 149 while time.time() - self._start_time < self._test_duration_secs: 150 stopped_ui = service_stopper.ServiceStopper(['ui']) 151 stopped_ui.stop_services() 152 time.sleep(1) 153 stopped_ui.restore_services() 154 155 stopped_services.restore_services() 156 157 158 def tab_open_close_test(self): 159 """ Open 10 tabs of WebGL SpiritBox, close them, repeat. """ 160 with self.new_chrome() as cr: 161 while time.time() - self._start_time < self._test_duration_secs: 162 tabs = self.open_urls(cr, 163 [WEBGL_SPIRITBOX_URL] * 10, 164 window=False) 165 for tab in tabs: 166 tab.Close() 167 time.sleep(1) 168 169 170 def yt_vimeo_webgl_test(self): 171 """ Youtube + Vimeo + WebGL, just running at the same time. """ 172 with self.new_chrome() as cr: 173 tabs = self.open_urls(cr, 174 [BIG_BUCK_BUNNY_YT_URL, 175 VIMEO_COUCHMODE_URL, 176 WEBGL_AQUARIUM_URL]) 177 time.sleep(self._test_duration_secs - (time.time() - self._start_time)) 178 for tab in tabs: 179 tab.Close() 180 181 182 subtests = { 183 '50spirit' : fifty_spirits_test, 184 'blob+aquarium+yt' : blob_aquarium_yt_test, 185 'gmaps' : gmaps_test, 186 'restart' : restart_test, 187 'tabopenclose' : tab_open_close_test, 188 'yt+vimeo+webgl' : yt_vimeo_webgl_test 189 } 190 191 192 def run_once(self, test_duration_secs=600, fullscreen=True, subtest='gmaps'): 193 """Finds a browser with telemetry, and runs the test. 194 195 @param test_duration_secs: The test duration in seconds. 196 @param fullscreen: Whether to run the test in fullscreen. 197 """ 198 self._start_time = time.time() 199 self._test_duration_secs = test_duration_secs 200 self._fullscreeen = fullscreen 201 202 self.ext_paths = [] 203 if fullscreen: 204 self.ext_paths.append( 205 os.path.join(self.autodir, 'deps', 'graphics', 206 'graphics_test_extension')) 207 208 self._test_failure_description = 'Failures_%s' % subtest 209 self.add_failures(subtest) 210 self.subtests[subtest](self) 211 self.remove_failures(subtest) 212 213