# 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)