| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """This is a client side WebGL many planets deep test.""" |
| |
| import numpy |
| import os |
| import time |
| |
| from autotest_lib.client.bin import test |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.bin import utils |
| from autotest_lib.client.common_lib.cros import chrome |
| from autotest_lib.client.cros.graphics import graphics_utils |
| from autotest_lib.client.cros.power import power_rapl |
| |
| |
| class graphics_WebGLManyPlanetsDeep(graphics_utils.GraphicsTest): |
| """WebGL many planets deep graphics test.""" |
| version = 1 |
| frame_data = {} |
| perf_keyval = {} |
| test_duration_secs = 30 |
| |
| def setup(self): |
| self.job.setup_dep(['webgl_mpd']) |
| self.job.setup_dep(['graphics']) |
| |
| def initialize(self): |
| super(graphics_WebGLManyPlanetsDeep, self).initialize() |
| |
| def cleanup(self): |
| super(graphics_WebGLManyPlanetsDeep, self).cleanup() |
| |
| def run_many_planets_deep_test(self, browser, test_url): |
| """Runs the many planets deep test from the given url. |
| |
| @param browser: The Browser object to run the test with. |
| @param test_url: The URL to the many planets deep test site. |
| """ |
| if not utils.wait_for_idle_cpu(60.0, 0.1): |
| if not utils.wait_for_idle_cpu(20.0, 0.2): |
| raise error.TestFail('Failed: Could not get idle CPU.') |
| |
| tab = browser.tabs.New() |
| tab.Navigate(test_url) |
| tab.Activate() |
| tab.WaitForDocumentReadyStateToBeComplete() |
| |
| # Wait 3 seconds for the page to stabilize. |
| time.sleep(3) |
| |
| # Reset our own FPS counter and start recording FPS and rendering time. |
| end_time = time.time() + self.test_duration_secs |
| tab.ExecuteJavaScript('g_crosFpsCounter.reset();') |
| while time.time() < end_time: |
| frame_data = tab.EvaluateJavaScript( |
| 'g_crosFpsCounter.getFrameData();') |
| for datum in frame_data: |
| if not datum or datum['seq'] in self.frame_data: |
| continue |
| self.frame_data[datum['seq']] = { |
| 'start_time': datum['startTime'], |
| 'frame_elapsed_time': datum['frameElapsedTime'], |
| 'js_elapsed_time': datum['jsElapsedTime'] |
| } |
| time.sleep(1) |
| |
| # Intel only: Record the power consumption for the next few seconds. |
| self.rapl_rate = power_rapl.get_rapl_measurement( |
| 'rapl_many_planets_deep') |
| tab.Close() |
| |
| def calculate_perf_values(self): |
| """Calculates all the perf values from the collected data.""" |
| arr = numpy.array([[v['frame_elapsed_time'], v['js_elapsed_time']] |
| for v in self.frame_data.itervalues()]) |
| std = arr.std(axis=0) |
| mean = arr.mean(axis=0) |
| avg_fps = 1000.0 / mean[0] |
| self.perf_keyval.update({ |
| 'average_fps': avg_fps, |
| 'per_frame_dt_ms_std': std[0], |
| 'per_frame_dt_ms_mean': mean[0], |
| 'js_render_time_ms_std': std[1], |
| 'js_render_time_ms_mean': mean[1] |
| }) |
| |
| # Remove entries that we don't care about. |
| rapl_rate = {key: self.rapl_rate[key] |
| for key in self.rapl_rate.keys() if key.endswith('pwr')} |
| # Report to chromeperf/ dashboard. |
| for key, values in rapl_rate.iteritems(): |
| self.output_perf_value( |
| description=key, |
| value=values, |
| units='W', |
| higher_is_better=False, |
| graph='rapl_power_consumption' |
| ) |
| self.output_perf_value( |
| description='average_fps', |
| value=avg_fps, |
| units='fps', |
| higher_is_better=True) |
| |
| with open('frame_data', 'w') as f: |
| line_format = '%10s %20s %20s %20s\n' |
| f.write(line_format % ('seq', 'start_time', 'frame_render_time_ms', |
| 'js_render_time_ms')) |
| for k in sorted(self.frame_data.keys()): |
| d = self.frame_data[k] |
| f.write(line_format % (k, d['start_time'], |
| d['frame_elapsed_time'], |
| d['js_elapsed_time'])) |
| |
| @graphics_utils.GraphicsTest.failure_report_decorator('graphics_WebGLManyPlanetsDeep') |
| def run_once(self, test_duration_secs=30, fullscreen=True): |
| """Finds a brower with telemetry, and run the test. |
| |
| @param test_duration_secs: The test duration in seconds to run the test |
| for. |
| @param fullscreen: Whether to run the test in fullscreen. |
| """ |
| self.test_duration_secs = test_duration_secs |
| |
| ext_paths = [] |
| if fullscreen: |
| ext_paths.append( |
| os.path.join(self.autodir, 'deps', 'graphics', |
| 'graphics_test_extension')) |
| |
| with chrome.Chrome(logged_in=False, |
| extension_paths=ext_paths, |
| init_network_controller=True) as cr: |
| websrc_dir = os.path.join(self.autodir, 'deps', 'webgl_mpd', 'src') |
| if not cr.browser.platform.SetHTTPServerDirectories(websrc_dir): |
| raise error.TestFail('Failed: Unable to start HTTP server') |
| test_url = cr.browser.platform.http_server.UrlOf( |
| os.path.join(websrc_dir, 'ManyPlanetsDeep.html')) |
| self.run_many_planets_deep_test(cr.browser, test_url) |
| |
| self.calculate_perf_values() |
| self.write_perf_keyval(self.perf_keyval) |