1# Lint as: python2, python3 2# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5"""This is a client side WebGL many planets deep test.""" 6 7import numpy 8import os 9import time 10 11from autotest_lib.client.bin import test 12from autotest_lib.client.common_lib import error 13from autotest_lib.client.bin import utils 14from autotest_lib.client.common_lib.cros import chrome 15from autotest_lib.client.cros.graphics import graphics_utils 16from autotest_lib.client.cros.power import power_rapl 17 18 19class graphics_WebGLManyPlanetsDeep(graphics_utils.GraphicsTest): 20 """WebGL many planets deep graphics test.""" 21 version = 1 22 frame_data = {} 23 perf_keyval = {} 24 test_duration_secs = 30 25 26 def setup(self): 27 self.job.setup_dep(['webgl_mpd']) 28 self.job.setup_dep(['graphics']) 29 30 def initialize(self): 31 super(graphics_WebGLManyPlanetsDeep, self).initialize() 32 33 def cleanup(self): 34 super(graphics_WebGLManyPlanetsDeep, self).cleanup() 35 36 def run_many_planets_deep_test(self, browser, test_url): 37 """Runs the many planets deep test from the given url. 38 39 @param browser: The Browser object to run the test with. 40 @param test_url: The URL to the many planets deep test site. 41 """ 42 if not utils.wait_for_idle_cpu(60.0, 0.1): 43 if not utils.wait_for_idle_cpu(20.0, 0.2): 44 raise error.TestFail('Failed: Could not get idle CPU.') 45 46 tab = browser.tabs.New() 47 tab.Navigate(test_url) 48 tab.Activate() 49 tab.WaitForDocumentReadyStateToBeComplete() 50 51 # Wait 3 seconds for the page to stabilize. 52 time.sleep(3) 53 54 # Reset our own FPS counter and start recording FPS and rendering time. 55 end_time = time.time() + self.test_duration_secs 56 tab.ExecuteJavaScript('g_crosFpsCounter.reset();') 57 while time.time() < end_time: 58 frame_data = tab.EvaluateJavaScript( 59 'g_crosFpsCounter.getFrameData();') 60 for datum in frame_data: 61 if not datum or datum['seq'] in self.frame_data: 62 continue 63 self.frame_data[datum['seq']] = { 64 'start_time': datum['startTime'], 65 'frame_elapsed_time': datum['frameElapsedTime'], 66 'js_elapsed_time': datum['jsElapsedTime'] 67 } 68 time.sleep(1) 69 70 # Intel only: Record the power consumption for the next few seconds. 71 self.rapl_rate = power_rapl.get_rapl_measurement( 72 'rapl_many_planets_deep') 73 tab.Close() 74 75 def calculate_perf_values(self): 76 """Calculates all the perf values from the collected data.""" 77 arr = numpy.array([[v['frame_elapsed_time'], v['js_elapsed_time']] 78 for v in list(self.frame_data.values())]) 79 std = arr.std(axis=0) 80 mean = arr.mean(axis=0) 81 avg_fps = 1000.0 / mean[0] 82 self.perf_keyval.update({ 83 'average_fps': avg_fps, 84 'per_frame_dt_ms_std': std[0], 85 'per_frame_dt_ms_mean': mean[0], 86 'js_render_time_ms_std': std[1], 87 'js_render_time_ms_mean': mean[1] 88 }) 89 90 # Remove entries that we don't care about. 91 rapl_rate = {key: self.rapl_rate[key] 92 for key in list(self.rapl_rate.keys()) if key.endswith('pwr')} 93 # Report to chromeperf/ dashboard. 94 for key, values in list(rapl_rate.items()): 95 self.output_perf_value( 96 description=key, 97 value=values, 98 units='W', 99 higher_is_better=False, 100 graph='rapl_power_consumption' 101 ) 102 self.output_perf_value( 103 description='average_fps', 104 value=avg_fps, 105 units='fps', 106 higher_is_better=True) 107 108 with open('frame_data', 'w') as f: 109 line_format = '%10s %20s %20s %20s\n' 110 f.write(line_format % ('seq', 'start_time', 'frame_render_time_ms', 111 'js_render_time_ms')) 112 for k in sorted(self.frame_data.keys()): 113 d = self.frame_data[k] 114 f.write(line_format % (k, d['start_time'], 115 d['frame_elapsed_time'], 116 d['js_elapsed_time'])) 117 118 @graphics_utils.GraphicsTest.failure_report_decorator('graphics_WebGLManyPlanetsDeep') 119 def run_once(self, test_duration_secs=30, fullscreen=True): 120 """Finds a brower with telemetry, and run the test. 121 122 @param test_duration_secs: The test duration in seconds to run the test 123 for. 124 @param fullscreen: Whether to run the test in fullscreen. 125 """ 126 self.test_duration_secs = test_duration_secs 127 128 ext_paths = [] 129 if fullscreen: 130 ext_paths.append( 131 os.path.join(self.autodir, 'deps', 'graphics', 132 'graphics_test_extension')) 133 134 with chrome.Chrome(logged_in=False, 135 extension_paths=ext_paths, 136 init_network_controller=True) as cr: 137 websrc_dir = os.path.join(self.autodir, 'deps', 'webgl_mpd', 'src') 138 if not cr.browser.platform.SetHTTPServerDirectories(websrc_dir): 139 raise error.TestFail('Failed: Unable to start HTTP server') 140 test_url = cr.browser.platform.http_server.UrlOf( 141 os.path.join(websrc_dir, 'ManyPlanetsDeep.html')) 142 self.run_many_planets_deep_test(cr.browser, test_url) 143 144 self.calculate_perf_values() 145 self.write_perf_keyval(self.perf_keyval) 146