Home | History | Annotate | Download | only in graphics_WebGLPerformance
      1 # Copyright (c) 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 """This is a client side WebGL performance test.
      5 
      6 http://hg.mozilla.org/users/bjacob_mozilla.com/webgl-perf-tests/raw-file/3729e8afac99/index.html
      7 
      8 From the sources:
      9 Keep in mind that these tests are not realistic workloads. These are not
     10 benchmarks aiming to compare browser or GPU performance. These are only useful
     11 to catch performance regressions in a given browser and system.
     12 """
     13 
     14 import logging
     15 import os
     16 import math
     17 
     18 from autotest_lib.client.bin import utils
     19 from autotest_lib.client.common_lib import error
     20 from autotest_lib.client.common_lib.cros import chrome
     21 from autotest_lib.client.cros.graphics import graphics_utils
     22 
     23 
     24 class graphics_WebGLPerformance(graphics_utils.GraphicsTest):
     25     """WebGL performance graphics test."""
     26     version = 1
     27     _test_duration_secs = 0
     28     perf_keyval = {}
     29     _waived_tests = ['convert-Canvas-to-rgb-float.html',
     30                      'convert-Canvas-to-rgb-float-premultiplied.html']
     31 
     32     def setup(self):
     33         self.job.setup_dep(['webgl_perf'])
     34         self.job.setup_dep(['graphics'])
     35 
     36     def initialize(self):
     37         super(graphics_WebGLPerformance, self).initialize()
     38 
     39     def cleanup(self):
     40         super(graphics_WebGLPerformance, self).cleanup()
     41 
     42     def run_performance_test(self, browser, test_url):
     43         """Runs the performance test from the given url.
     44 
     45         @param browser: The Browser object to run the test with.
     46         @param test_url: The URL to the performance test site.
     47         """
     48         if not utils.wait_for_idle_cpu(60.0, 0.1):
     49             if not utils.wait_for_idle_cpu(20.0, 0.2):
     50                 raise error.TestFail('Failed: Could not get idle CPU.')
     51 
     52         # Kick off test.
     53         tab = browser.tabs.New()
     54         tab.Navigate(test_url)
     55         tab.Activate()
     56         tab.WaitForDocumentReadyStateToBeComplete()
     57 
     58         # Wait for test completion.
     59         tab.WaitForJavaScriptCondition('test_completed == true',
     60                                        timeout=self._test_duration_secs)
     61 
     62         # Get all the result data
     63         results = tab.EvaluateJavaScript('testsRun')
     64         logging.info('results: %s', results)
     65         # Get the geometric mean of individual runtimes.
     66         sumOfLogResults = 0
     67         sumOfPassed = 0
     68         sumOfFailed = 0
     69         sumOfWaived = 0
     70         for result in results:
     71             if result.get('url') in self._waived_tests or result.get('skip'):
     72                 sumOfWaived += 1
     73             elif 'error' in result:
     74                 self.add_failures(result.get('url'))
     75                 sumOfFailed += 1
     76             else:
     77                 sumOfLogResults += math.log(result['testResult'])
     78                 sumOfPassed += 1
     79         time_ms_geom_mean = round(100 * math.exp(
     80             sumOfLogResults / len(results))) / 100
     81 
     82         logging.info('WebGLPerformance: time_ms_geom_mean = %f',
     83                      time_ms_geom_mean)
     84 
     85         # Output numbers for plotting by harness.
     86         keyvals = {}
     87         keyvals['time_ms_geom_mean'] = time_ms_geom_mean
     88         self.write_perf_keyval(keyvals)
     89         self.output_perf_value(
     90             description='time_geom_mean',
     91             value=time_ms_geom_mean,
     92             units='ms',
     93             higher_is_better=False,
     94             graph='time_geom_mean')
     95         # Add extra value to the graph distinguishing different boards.
     96         variant = utils.get_board_with_frequency_and_memory()
     97         desc = 'time_geom_mean-%s' % variant
     98         self.output_perf_value(
     99             description=desc,
    100             value=time_ms_geom_mean,
    101             units='ms',
    102             higher_is_better=False,
    103             graph='time_geom_mean')
    104 
    105         # Get a copy of the test report.
    106         test_report = tab.EvaluateJavaScript('test_report')
    107         results_path = os.path.join(
    108             self.bindir,
    109             '../../results/default/graphics_WebGLPerformance/test_report.html')
    110         f = open(results_path, 'w+')
    111         f.write(test_report)
    112         f.close()
    113 
    114         tab.Close()
    115         return sumOfPassed, sumOfWaived, sumOfFailed
    116 
    117     def run_once(self, test_duration_secs=2700, fullscreen=True):
    118         """Finds a brower with telemetry, and run the test.
    119 
    120         @param test_duration_secs: The test duration in seconds.
    121         @param fullscreen: Whether to run the test in fullscreen.
    122         """
    123         # To avoid 0ms on fast machines like samus the workload was increased.
    124         # Unfortunately that makes running on slow machines impractical without
    125         # deviating from upstream too much.
    126         if utils.get_gpu_family() == 'pinetrail':
    127             # TODO(ihf): return a TestPass(message) once available.
    128             logging.warning('Test is too slow to run regularly.')
    129             return
    130 
    131         self._test_duration_secs = test_duration_secs
    132         ext_paths = []
    133         if fullscreen:
    134             ext_paths.append(
    135                 os.path.join(self.autodir, 'deps', 'graphics',
    136                              'graphics_test_extension'))
    137 
    138         with chrome.Chrome(logged_in=False,
    139                            extension_paths=ext_paths,
    140                            init_network_controller=True) as cr:
    141             websrc_dir = os.path.join(self.autodir, 'deps', 'webgl_perf', 'src')
    142             if not cr.browser.platform.SetHTTPServerDirectories(websrc_dir):
    143                 raise error.TestFail('Failed: Unable to start HTTP server')
    144             test_url = cr.browser.platform.http_server.UrlOf(
    145                 os.path.join(websrc_dir, 'index.html'))
    146 
    147             passed, waived, failed = self.run_performance_test(cr.browser,
    148                                                                test_url)
    149             logging.debug('Number of tests: %d, passed: %d, '
    150                           'waived: %d, failed: %d',
    151                           passed + waived + failed, passed, waived, failed)
    152             if failed > 0:
    153                 raise error.TestFail('Failed: %d tests failed.' % failed)
    154