• 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    'http://webglsamples.org/aquarium/aquarium.html'
21WEBGL_BLOB_URL = 'http://webglsamples.org/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(graphics_utils.GraphicsTest):
28    """Graphics stress test."""
29    version = 1
30
31    def setup(self):
32        self.job.setup_dep(['graphics'])
33
34
35    def new_chrome(self):
36        return chrome.Chrome(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 peacekeeper_test(self):
142        """ Run Futuremark Peacekeeper benchmark. """
143        with self.new_chrome() as cr:
144            tabs = self.open_urls(cr, [PEACEKEEPER_URL])
145            time.sleep(self._test_duration_secs - (time.time() - self._start_time))
146            for tab in tabs:
147                tab.Close()
148
149
150    def restart_test(self):
151        """ Restart UI, excercises X server startup and shutdown and related
152        kernel paths. """
153        # Ui respawn will reboot us if we restart ui too many times, so stop
154        # it for the duration of the test.
155        stopped_services = service_stopper.ServiceStopper(['ui-respawn'])
156        stopped_services.stop_services()
157
158        while time.time() - self._start_time < self._test_duration_secs:
159            stopped_ui = service_stopper.ServiceStopper(['ui'])
160            stopped_ui.stop_services()
161            time.sleep(1)
162            stopped_ui.restore_services()
163
164        stopped_services.restore_services()
165
166
167    def tab_open_close_test(self):
168        """ Open 10 tabs of WebGL SpiritBox, close them, repeat. """
169        with self.new_chrome() as cr:
170            while time.time() - self._start_time < self._test_duration_secs:
171                tabs = self.open_urls(cr,
172                                      [WEBGL_SPIRITBOX_URL] * 10,
173                                      window=False)
174                for tab in tabs:
175                    tab.Close()
176                time.sleep(1)
177
178
179    def yt_vimeo_webgl_test(self):
180        """ Youtube + Vimeo + WebGL, just running at the same time. """
181        with self.new_chrome() as cr:
182            tabs = self.open_urls(cr,
183                                  [BIG_BUCK_BUNNY_YT_URL,
184                                   VIMEO_COUCHMODE_URL,
185                                   WEBGL_AQUARIUM_URL])
186            time.sleep(self._test_duration_secs - (time.time() - self._start_time))
187            for tab in tabs:
188                tab.Close()
189
190
191    subtests = {
192        '50spirit' : fifty_spirits_test,
193        'blob+aquarium+yt' : blob_aquarium_yt_test,
194        'gmaps' : gmaps_test,
195        'peacekeeper' : peacekeeper_test,
196        'restart' : restart_test,
197        'tabopenclose' : tab_open_close_test,
198        'yt+vimeo+webgl' : yt_vimeo_webgl_test
199    }
200
201
202    def run_once(self, test_duration_secs=600, fullscreen=True, subtest='gmaps'):
203        """Finds a browser with telemetry, and runs the test.
204
205        @param test_duration_secs: The test duration in seconds.
206        @param fullscreen: Whether to run the test in fullscreen.
207        """
208        self._start_time = time.time()
209        self._test_duration_secs = test_duration_secs
210        self._fullscreeen = fullscreen
211
212        self.ext_paths = []
213        if fullscreen:
214            self.ext_paths.append(
215                os.path.join(self.autodir, 'deps', 'graphics',
216                             'graphics_test_extension'))
217
218        self._test_failure_description = 'Failures_%s' % subtest
219        self.add_failures(subtest)
220        self.subtests[subtest](self)
221        self.remove_failures(subtest)
222
223