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