1# Lint as: python2, python3 2# Copyright 2018 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. 5import logging 6import time 7 8from autotest_lib.client.common_lib.cros import chrome 9from autotest_lib.client.cros.input_playback import keyboard 10from autotest_lib.client.cros.power import power_dashboard 11from autotest_lib.client.cros.power import power_status 12from autotest_lib.client.cros.power import power_test 13 14FISHES_COUNT = { 15 1: 'setSetting0', 16 100: 'setSetting1', 17 500: 'setSetting2', 18 1000: 'setSetting3', 19 3000: 'setSetting4', 20 5000: 'setSetting5', 21 10000: 'setSetting6', 22 15000: 'setSetting7', 23 20000: 'setSetting8', 24 25000: 'setSetting9', 25 30000: 'setSetting10', 26} 27 28 29class power_ThermalLoad(power_test.power_Test): 30 """class for power_ThermalLoad test. 31 """ 32 version = 2 33 34 FISHTANK_URL = 'http://crospower.page.link/power_ThermalLoad' 35 HOUR = 60 * 60 36 37 def select_fishes(self, tab, fish_settings): 38 """Simple wrapper to select the required fish count 39 40 @param tab: An Autotest Chrome tab instance. 41 @param fish_settings: Webgl fish count settings 42 """ 43 tab.ExecuteJavaScript('%s.click();' % fish_settings) 44 45 def run_once(self, 46 test_url=FISHTANK_URL, 47 duration=2.5 * HOUR, 48 numFish=3000): 49 """run_once method. 50 51 @param test_url: url of webgl heavy page. 52 @param duration: time in seconds to display url and measure power. 53 @param numFish: number of fish to pass to WebGL Aquarium. 54 """ 55 # --disable-sync disables test account info sync, eg. Wi-Fi credentials, 56 # so that each test run does not remember info from last test run. 57 extra_browser_args = ['--disable-sync'] 58 # b/228256145 to avoid powerd restart 59 extra_browser_args.append('--disable-features=FirmwareUpdaterApp') 60 with chrome.Chrome(extra_browser_args=extra_browser_args, 61 init_network_controller=True) as self.cr: 62 tab = self.cr.browser.tabs.New() 63 tab.Activate() 64 65 # Just measure power in full-screen. 66 fullscreen = tab.EvaluateJavaScript('document.webkitIsFullScreen') 67 if not fullscreen: 68 with keyboard.Keyboard() as keys: 69 keys.press_key('f4') 70 71 # Stop services again as Chrome might have restarted them. 72 self._services.stop_services() 73 74 self.backlight.set_percent(100) 75 76 logging.info('Navigating to url: %s', test_url) 77 tab.Navigate(test_url) 78 tab.WaitForDocumentReadyStateToBeComplete() 79 logging.info("Selecting %d Fishes", numFish) 80 self.select_fishes(tab, FISHES_COUNT[numFish]) 81 82 self._flog = FishTankFpsLogger(tab, 83 seconds_period=self._seconds_period, 84 checkpoint_logger=self._checkpoint_logger) 85 self._meas_logs.append(self._flog) 86 power_dashboard.get_dashboard_factory().registerDataType( 87 FishTankFpsLogger, power_dashboard.VideoFpsLoggerDashboard) 88 89 self.start_measurements() 90 while time.time() - self._start_time < duration: 91 time.sleep(60) 92 self.status.refresh() 93 if self.status.is_low_battery(): 94 logging.info( 95 'Low battery, stop test early after %.0f minutes', 96 (time.time() - self._start_time) / 60) 97 return 98 99 100class FishTankFpsLogger(power_status.MeasurementLogger): 101 """Class to measure Video WebGL Aquarium fps & fish per sec.""" 102 103 def __init__(self, tab, seconds_period=20.0, checkpoint_logger=None): 104 """Initialize a FishTankFpsLogger. 105 106 Args: 107 tab: Chrome tab object 108 """ 109 super(FishTankFpsLogger, self).__init__([], seconds_period, 110 checkpoint_logger) 111 self._tab = tab 112 (frameCount, frameTime) = self._tab.EvaluateJavaScript( 113 '[frameCount, Date.now()/1000]') 114 fishCount = self.get_fish_count(tab) 115 self.domains = ['avg_fps_%04d_fishes' % fishCount] 116 self._lastFrameCount = frameCount 117 self._lastFrameTime = frameTime 118 119 def get_fish_count(self, tab): 120 style_string = 'color: red;' 121 for count, setting in FISHES_COUNT.items(): 122 style = tab.EvaluateJavaScript('%s.getAttribute("style")' % 123 setting) 124 if style == style_string: 125 return count 126 127 def refresh(self): 128 (frameCount, frameTime 129 ) = self._tab.EvaluateJavaScript('[frameCount, Date.now()/1000]') 130 period = frameTime - self._lastFrameTime 131 fps = (frameCount - self._lastFrameCount) / period 132 self._lastFrameCount = frameCount 133 self._lastFrameTime = frameTime 134 return [fps] 135 136 def save_results(self, resultsdir, fname_prefix=None): 137 if not fname_prefix: 138 fname_prefix = '%s_results_%.0f' % (self.domains[0], time.time()) 139 super(FishTankFpsLogger, self).save_results(resultsdir, fname_prefix) 140 141 def calc(self, mtype='fps'): 142 return super(FishTankFpsLogger, self).calc(mtype) 143