blob: 19da1b5744149a3d991112f843ff9f0c122cad0d [file] [log] [blame]
# 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.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome
class graphics_WebGLManyPlanetsDeep(test.test):
"""WebGL many planets deep graphics test."""
version = 1
def setup(self):
self.job.setup_dep(['webgl_mpd'])
self.job.setup_dep(['graphics'])
def initialize(self):
self.frame_data = {}
self.perf_keyval = {}
def poll_for_condition(self, tab, condition, error_msg):
"""Waits until javascript condition is true.
@param tab: The tab the javascript/condition runs on.
@param condition: The javascript condition to evaluate.
@param error_msg: Test failure error string on timeout.
"""
utils.poll_for_condition(
lambda: tab.EvaluateJavaScript(condition),
exception=error.TestError(error_msg),
timeout=self.test_duration_secs,
sleep_interval=1)
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.
"""
tab = browser.tabs.New()
tab.Navigate(test_url)
tab.Activate()
self.poll_for_condition(tab, 'typeof start !== \'undefined\'',
'Timed out loading the test.')
# Wait 3 seconds for the page to stabilize.
# TODO(ihf): Add a function that waits for low system load.
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)
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]
})
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']))
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(extension_paths=ext_paths) as cr:
websrc_dir = os.path.join(self.autodir, 'deps', 'webgl_mpd', 'src')
if not cr.browser.SetHTTPServerDirectories(websrc_dir):
raise error.TestError('Unable to start HTTP server')
test_url = cr.browser.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)