1# Copyright 2018 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4import time 5 6from autotest_lib.client.bin import test 7from autotest_lib.client.cros import service_stopper 8from autotest_lib.client.cros.power import power_dashboard 9from autotest_lib.client.cros.power import power_rapl 10from autotest_lib.client.cros.power import power_status 11from autotest_lib.client.cros.power import power_telemetry_utils 12from autotest_lib.client.cros.power import power_utils 13 14 15class power_Test(test.test): 16 """Optional base class power related tests.""" 17 version = 1 18 19 def initialize(self, seconds_period=20., pdash_note=''): 20 """Perform necessary initialization prior to power test run. 21 22 @param seconds_period: float of probing interval in seconds. 23 @param pdash_note: note of the current run to send to power dashboard. 24 25 @var backlight: power_utils.Backlight object. 26 @var keyvals: dictionary of result keyvals. 27 @var status: power_status.SysStat object. 28 29 @var _checkpoint_logger: power_status.CheckpointLogger to track 30 checkpoint data. 31 @var _plog: power_status.PowerLogger object to monitor power. 32 @var _psr: power_utils.DisplayPanelSelfRefresh object to monitor PSR. 33 @var _services: service_stopper.ServiceStopper object. 34 @var _start_time: float of time in seconds since Epoch test started. 35 @var _stats: power_status.StatoMatic object. 36 @var _tlog: power_status.TempLogger object to monitor temperatures. 37 @var _clog: power_status.CPUStatsLogger object to monitor CPU(s) 38 frequencies and c-states. 39 @var _meas_logs: list of power_status.MeasurementLoggers 40 """ 41 super(power_Test, self).initialize() 42 self.backlight = power_utils.Backlight() 43 self.backlight.set_default() 44 self.keyvals = dict() 45 self.status = power_status.get_status() 46 47 self._checkpoint_logger = power_status.CheckpointLogger() 48 49 measurements = [] 50 if not self.status.on_ac(): 51 measurements.append( 52 power_status.SystemPower(self.status.battery_path)) 53 if power_utils.has_powercap_support(): 54 measurements += power_rapl.create_powercap() 55 elif power_utils.has_rapl_support(): 56 measurements += power_rapl.create_rapl() 57 self._plog = power_status.PowerLogger(measurements, 58 seconds_period=seconds_period, 59 checkpoint_logger=self._checkpoint_logger) 60 self._psr = power_utils.DisplayPanelSelfRefresh() 61 self._services = service_stopper.ServiceStopper( 62 service_stopper.ServiceStopper.POWER_DRAW_SERVICES) 63 self._services.stop_services() 64 self._stats = power_status.StatoMatic() 65 66 self._tlog = power_status.TempLogger([], 67 seconds_period=seconds_period, 68 checkpoint_logger=self._checkpoint_logger) 69 self._clog = power_status.CPUStatsLogger(seconds_period=seconds_period, 70 checkpoint_logger=self._checkpoint_logger) 71 72 self._meas_logs = [self._plog, self._tlog, self._clog] 73 74 self._pdash_note = pdash_note 75 76 def warmup(self, warmup_time=30): 77 """Warm up. 78 79 Wait between initialization and run_once for new settings to stabilize. 80 81 @param warmup_time: integer of seconds to warmup. 82 """ 83 time.sleep(warmup_time) 84 85 def start_measurements(self): 86 """Start measurements.""" 87 for log in self._meas_logs: 88 log.start() 89 self._start_time = time.time() 90 power_telemetry_utils.start_measurement() 91 92 def loop_sleep(self, loop, sleep_secs): 93 """Jitter free sleep. 94 95 @param loop: integer of loop (1st is zero). 96 @param sleep_secs: integer of desired sleep seconds. 97 """ 98 next_time = self._start_time + (loop + 1) * sleep_secs 99 time.sleep(next_time - time.time()) 100 101 def checkpoint_measurements(self, name, start_time=None): 102 """Checkpoint measurements. 103 104 @param name: string name of measurement being checkpointed. 105 @param start_time: float of time in seconds since Epoch that 106 measurements being checkpointed began. 107 """ 108 if not start_time: 109 start_time = self._start_time 110 self.status.refresh() 111 self._checkpoint_logger.checkpoint(name, start_time) 112 self._psr.refresh() 113 114 def publish_keyvals(self): 115 """Publish power result keyvals.""" 116 keyvals = self._stats.publish() 117 keyvals['level_backlight_max'] = self.backlight.get_max_level() 118 keyvals['level_backlight_current'] = self.backlight.get_level() 119 120 # record battery stats if not on AC 121 if self.status.on_ac(): 122 keyvals['b_on_ac'] = 1 123 else: 124 keyvals['b_on_ac'] = 0 125 126 if self.status.battery: 127 keyvals['ah_charge_full'] = self.status.battery[0].charge_full 128 keyvals['ah_charge_full_design'] = \ 129 self.status.battery[0].charge_full_design 130 keyvals['ah_charge_now'] = self.status.battery[0].charge_now 131 keyvals['a_current_now'] = self.status.battery[0].current_now 132 keyvals['wh_energy'] = self.status.battery[0].energy 133 keyvals['w_energy_rate'] = self.status.battery[0].energy_rate 134 keyvals['v_voltage_min_design'] = \ 135 self.status.battery[0].voltage_min_design 136 keyvals['v_voltage_now'] = self.status.battery[0].voltage_now 137 138 for log in self._meas_logs: 139 keyvals.update(log.calc()) 140 keyvals.update(self._psr.get_keyvals()) 141 142 self.keyvals.update(keyvals) 143 144 core_keyvals = power_utils.get_core_keyvals(self.keyvals) 145 self.write_perf_keyval(core_keyvals) 146 147 def _publish_dashboard(self): 148 """Report results to chromeperf & power dashboard.""" 149 150 self.publish_keyvals() 151 152 # publish power values 153 for key, values in self.keyvals.iteritems(): 154 if key.endswith('pwr'): 155 self.output_perf_value(description=key, value=values, units='W', 156 higher_is_better=False, graph='power') 157 158 # publish temperature values 159 for key, values in self.keyvals.iteritems(): 160 if key.endswith('temp'): 161 self.output_perf_value(description=key, value=values, units='C', 162 higher_is_better=False, graph='temperature') 163 164 # publish to power dashboard 165 pdash = power_dashboard.PowerLoggerDashboard( 166 self._plog, self.tagged_testname, self.resultsdir, 167 note=self._pdash_note) 168 pdash.upload() 169 cdash = power_dashboard.CPUStatsLoggerDashboard( 170 self._clog, self.tagged_testname, self.resultsdir, 171 note=self._pdash_note) 172 cdash.upload() 173 tdash = power_dashboard.TempLoggerDashboard( 174 self._tlog, self.tagged_testname, self.resultsdir, 175 note=self._pdash_note) 176 tdash.upload() 177 178 def _save_results(self): 179 """Save results of each logger in resultsdir.""" 180 for log in self._meas_logs: 181 log.save_results(self.resultsdir) 182 self._checkpoint_logger.save_checkpoint_data(self.resultsdir) 183 184 def postprocess_iteration(self): 185 """Write keyval and send data to dashboard.""" 186 power_telemetry_utils.end_measurement() 187 super(power_Test, self).postprocess_iteration() 188 self._publish_dashboard() 189 self._save_results() 190 191 def cleanup(self): 192 """Reverse setting change in initialization.""" 193 if self.backlight: 194 self.backlight.restore() 195 self._services.restore_services() 196 super(power_Test, self).cleanup() 197