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