def initialize(self, seconds_period=20., pdash_note=''): """Perform necessary initialization prior to power test run. @param seconds_period: float of probing interval in seconds. @param pdash_note: note of the current run to send to power dashboard. @var backlight: power_utils.Backlight object. @var keyvals: dictionary of result keyvals. @var status: power_status.SysStat object. @var _checkpoint_logger: power_status.CheckpointLogger to track checkpoint data. @var _plog: power_status.PowerLogger object to monitor power. @var _psr: power_utils.DisplayPanelSelfRefresh object to monitor PSR. @var _services: service_stopper.ServiceStopper object. @var _start_time: float of time in seconds since Epoch test started. @var _stats: power_status.StatoMatic object. @var _tlog: power_status.TempLogger object to monitor temperatures. @var _clog: power_status.CPUStatsLogger object to monitor CPU(s) frequencies and c-states. @var _meas_logs: list of power_status.MeasurementLoggers """ super(power_Test, self).initialize() self.backlight = power_utils.Backlight() self.backlight.set_default() self.keyvals = dict() self.status = power_status.get_status() self._checkpoint_logger = power_status.CheckpointLogger() measurements = [] if not self.status.on_ac(): measurements.append( power_status.SystemPower(self.status.battery_path)) if power_utils.has_powercap_support(): measurements += power_rapl.create_powercap() elif power_utils.has_rapl_support(): measurements += power_rapl.create_rapl() self._plog = power_status.PowerLogger( measurements, seconds_period=seconds_period, checkpoint_logger=self._checkpoint_logger) self._psr = power_utils.DisplayPanelSelfRefresh() self._services = service_stopper.ServiceStopper( service_stopper.ServiceStopper.POWER_DRAW_SERVICES) self._services.stop_services() self._stats = power_status.StatoMatic() self._tlog = power_status.TempLogger( [], seconds_period=seconds_period, checkpoint_logger=self._checkpoint_logger) self._clog = power_status.CPUStatsLogger( seconds_period=seconds_period, checkpoint_logger=self._checkpoint_logger) self._meas_logs = [self._plog, self._tlog, self._clog] self._pdash_note = pdash_note
def initialize(self): super(hardware_MultiReaderPowerConsumption, self).initialize() # Make sure we're not on AC power self.status = power_status.get_status() if self.status.on_ac(): raise error.TestNAError( 'This test needs to be run with the AC power offline')
def initialize(self, **kwargs): """Set up local variables and ensure device is on AC power.""" self._initialize_test_constants() self._power_status = power_status.get_status() if not self._power_status.on_ac(): raise error.TestNAError('Test must be run with DUT on AC power.') self._backlight = power_utils.Backlight() super(policy_PowerManagementIdleSettings, self).initialize(**kwargs)
def run_once(self, idle_time=120, sleep=10, bt_warmup_time=20): """Collect power stats when bluetooth adapter is on or off. """ with chrome.Chrome(): self._backlight = power_utils.Backlight() self._backlight.set_default() t0 = time.time() self._start_time = t0 self._psr = power_utils.DisplayPanelSelfRefresh(init_time=t0) self.status = power_status.get_status() self._stats = power_status.StatoMatic() measurements = [] if not self.status.on_ac(): measurements.append( power_status.SystemPower(self.status.battery_path)) if power_utils.has_powercap_support(): measurements += power_rapl.create_powercap() elif power_utils.has_rapl_support(): measurements += power_rapl.create_rapl() self._plog = power_status.PowerLogger(measurements, seconds_period=sleep) self._tlog = power_status.TempLogger([], seconds_period=sleep) self._plog.start() self._tlog.start() for _ in xrange(0, idle_time, sleep): time.sleep(sleep) self.status.refresh() self.status.refresh() self._plog.checkpoint('bluetooth_adapter_off', self._start_time) self._tlog.checkpoint('', self._start_time) self._psr.refresh() # Turn on bluetooth adapter. bt_device = bluetooth_device_xmlrpc_server \ .BluetoothDeviceXmlRpcDelegate() # If we cannot start bluetoothd, fail gracefully and still write # data with bluetooth adapter off to file, as we are interested in # just that data too. start_bluetoothd() already logs the error so # not logging any error here. if not bt_device.start_bluetoothd(): return if not bt_device.set_powered(True): logging.warning("Cannot turn on bluetooth adapter.") return time.sleep(bt_warmup_time) if not bt_device._is_powered_on(): logging.warning("Bluetooth adapter is off.") return t1 = time.time() time.sleep(idle_time) self._plog.checkpoint('bluetooth_adapter_on', t1) bt_device.set_powered(False) bt_device.stop_bluetoothd()
def initialize(self, **kwargs): """Set up local variables and ensure sufficient battery charge.""" self._power_status = power_status.get_status() if not self._power_status.on_ac(): # Ensure that the battery has sufficient minimum charge. self._power_status.assert_battery_state(self.PERCENT_CHARGE_MIN) logging.info('Device power type is "%s"', self._power_type) super(policy_ChromeOsLockOnIdleSuspend, self).initialize(**kwargs)
def initialize(self): super(graphics_VideoRenderingPower, self).initialize() self._backlight = power_utils.Backlight() self._backlight.set_default() self._service_stopper = service_stopper.ServiceStopper( service_stopper.ServiceStopper.POWER_DRAW_SERVICES) self._service_stopper.stop_services() self._power_status = power_status.get_status()
def _create_dut_info_dict(self, power_rails): """Create a dictionary that contain information of the DUT. Args: power_rails: list of measured power rails Returns: DUT info dictionary """ board = utils.get_board() platform = utils.get_platform() if not platform.startswith(board): board += '_' + platform if power_utils.has_hammer(): board += '_hammer' dut_info_dict = { 'board': board, 'version': { 'hw': utils.get_hardware_revision(), 'milestone': lsbrelease_utils.get_chromeos_release_milestone(), 'os': lsbrelease_utils.get_chromeos_release_version(), 'channel': lsbrelease_utils.get_chromeos_channel(), 'firmware': utils.get_firmware_version(), 'ec': utils.get_ec_version(), 'kernel': utils.get_kernel_version(), }, 'sku': { 'cpu': utils.get_cpu_name(), 'memory_size': utils.get_mem_total_gb(), 'storage_size': utils.get_disk_size_gb(utils.get_root_device()), 'display_resolution': utils.get_screen_resolution(), }, 'ina': { 'version': 0, 'ina': power_rails, }, 'note': self._note, } if power_utils.has_battery(): status = power_status.get_status() if status.battery: # Round the battery size to nearest tenth because it is # fluctuated for platform without battery nominal voltage data. dut_info_dict['sku']['battery_size'] = round( status.battery[0].energy_full_design, 1) dut_info_dict['sku']['battery_shutdown_percent'] = \ power_utils.get_low_battery_shutdown_percent() return dut_info_dict
def run_once(self, test_which='Mains'): # This test doesn't apply to systems that run on AC only. if not power_utils.has_battery(): return # Gather power supplies status = power_status.get_status() run_dict = { 'Mains': self.run_ac, 'Battery': self.run_bat } run = run_dict.get(test_which) if run: run(status) else: raise error.TestNAError('Unknown test type: %s' % test_which)
def test_power(self, local_path): """ Runs the video power consumption test. @param local_path: the path to the video file. @return a dictionary that contains the test result. """ self._backlight = power_utils.Backlight() self._backlight.set_default() self._service_stopper = service_stopper.ServiceStopper( service_stopper.ServiceStopper.POWER_DRAW_SERVICES) self._service_stopper.stop_services() current_power_status = power_status.get_status() # We expect the DUT is powered by battery now. But this is not always # true due to other bugs. Disable this test temporarily as workaround. # TODO(kcwu): remove this workaround after AC control is stable # crbug.com/723968 if current_power_status.on_ac(): logging.warning('Still powered by AC. Skip this test') return {} # Verify that the battery is sufficiently charged. current_power_status.assert_battery_state(BATTERY_INITIAL_CHARGED_MIN) measurements = [power_status.SystemPower( current_power_status.battery_path)] def get_power(cr): power_logger = power_status.PowerLogger(measurements) power_logger.start() time.sleep(STABILIZATION_DURATION) start_time = time.time() time.sleep(MEASUREMENT_DURATION) power_logger.checkpoint('result', start_time) keyval = power_logger.calc() # save_results() will save <fname_prefix>_raw.txt and # <fname_prefix>_summary.txt, where the former contains raw data. fname_prefix = 'result_%.0f' % time.time() power_logger.save_results(self.resultsdir, fname_prefix) metric_name = 'result_' + measurements[0].domain with open(os.path.join( self.resultsdir, fname_prefix + '_raw.txt')) as f: for line in f.readlines(): if line.startswith(metric_name): split_data = line.split('\t') # split_data[0] is metric_name, [1:] are raw data. return [float(data) for data in split_data[1:]] # Return a list contains the average power only for fallback. return [keyval[metric_name + '_pwr_avg']] return self.test_webrtc(local_path, get_power)
def initialize(self): if not power_utils.has_battery(): raise error.TestNAError('DUT has no battery. Test Skipped') self.status = power_status.get_status() if not self.status.on_ac(): raise error.TestNAError( 'This test needs to be run with the AC power online') self._services = service_stopper.ServiceStopper( service_stopper.ServiceStopper.POWER_DRAW_SERVICES + ['ui']) self._services.stop_services()
def _create_powerlog_dict(self, raw_measurement): """Create powerlog dictionary from raw measurement data Data format in go/power-dashboard-data Args: raw_measurement: dictionary contains raw measurement data. Returns: A dictionary of powerlog. """ powerlog_dict = { 'format_version': 2, 'timestamp': time.time(), 'test': self._testname, 'dut': { 'board': utils.get_board(), 'version': { 'hw': utils.get_hardware_revision(), 'milestone': lsbrelease_utils.get_chromeos_release_milestone(), 'os': lsbrelease_utils.get_chromeos_release_version(), 'channel': lsbrelease_utils.get_chromeos_channel(), 'firmware': utils.get_firmware_version(), 'ec': utils.get_ec_version(), 'kernel': utils.get_kernel_version(), }, 'sku': { 'cpu': utils.get_cpu_name(), 'memory_size': utils.get_mem_total_gb(), 'storage_size': utils.get_disk_size_gb(utils.get_root_device()), 'display_resolution': utils.get_screen_resolution(), }, 'ina': { 'version': 0, 'ina': raw_measurement['data'].keys() }, 'note': '' }, 'power': raw_measurement } if power_utils.has_battery(): # Round the battery size to nearest tenth because it is fluctuated # for platform without battery norminal voltage data. powerlog_dict['dut']['sku']['battery_size'] = round( power_status.get_status().battery[0].energy_full_design, 1) powerlog_dict['dut']['sku']['battery_shutdown_percent'] = \ power_utils.get_low_battery_shutdown_percent() return powerlog_dict
def test_power(self, local_path): """ Runs the video power consumption test. @param local_path: the path to the video file. @return a dictionary that contains the test result. """ self._backlight = power_utils.Backlight() self._backlight.set_default() self._service_stopper = service_stopper.ServiceStopper( service_stopper.ServiceStopper.POWER_DRAW_SERVICES) self._service_stopper.stop_services() self._power_status = power_status.get_status() # We expect the DUT is powered by battery now. But this is not always # true due to other bugs. Disable this test temporarily as workaround. # TODO(kcwu): remove this workaround after AC control is stable # crbug.com/723968 if self._power_status.on_ac(): logging.warning('Still powered by AC. Skip this test') return {} # Verify that the battery is sufficiently charged. self._power_status.assert_battery_state(BATTERY_INITIAL_CHARGED_MIN) measurements = [ power_status.SystemPower(self._power_status.battery_path) ] if power_utils.has_rapl_support(): measurements += power_rapl.create_rapl() def get_power(cr): power_logger = power_status.PowerLogger(measurements) power_logger.start() time.sleep(STABILIZATION_DURATION) start_time = time.time() time.sleep(MEASUREMENT_DURATION) power_logger.checkpoint('result', start_time) keyval = power_logger.calc() keyval = { key: keyval[key] for key in keyval if key.endswith('_pwr') } return keyval return self.test_playback(local_path, get_power)
def __enter__(self): self._backlight = power_utils.Backlight() self._backlight.set_default() self._service_stopper = service_stopper.ServiceStopper( service_stopper.ServiceStopper.POWER_DRAW_SERVICES) self._service_stopper.stop_services() status = power_status.get_status() # Verify that we are running on battery and the battery is sufficiently # charged. status.assert_battery_state(BATTERY_INITIAL_CHARGED_MIN) self._system_power = power_status.SystemPower(status.battery_path) self._power_logger = power_status.PowerLogger([self._system_power]) return self
def run_power_test(self, browser, test_url, ac_ok): """Runs the webgl power consumption test and reports the perf results. @param browser: The Browser object to run the test with. @param test_url: The URL to the aquarium test site. @param ac_ok: Boolean on whether its ok to have AC power supplied. """ self._backlight = power_utils.Backlight() self._backlight.set_default() self._service_stopper = service_stopper.ServiceStopper( service_stopper.ServiceStopper.POWER_DRAW_SERVICES) self._service_stopper.stop_services() if not ac_ok: self._power_status = power_status.get_status() # Verify that we are running on battery and the battery is # sufficiently charged. self._power_status.assert_battery_state(BATTERY_INITIAL_CHARGED_MIN) measurements = [ power_status.SystemPower(self._power_status.battery_path) ] def get_power(): power_logger = power_status.PowerLogger(measurements) power_logger.start() time.sleep(STABILIZATION_DURATION) start_time = time.time() time.sleep(MEASUREMENT_DURATION) power_logger.checkpoint('result', start_time) keyval = power_logger.calc() logging.info('Power output %s', keyval) return keyval['result_' + measurements[0].domain + '_pwr'] self.run_fish_test(browser, test_url, 1000, perf_log=False) if not ac_ok: energy_rate = get_power() # This is a power specific test so we are not capturing # avg_fps and avg_render_time in this test. self.perf_keyval[POWER_DESCRIPTION] = energy_rate self.output_perf_value( description=POWER_DESCRIPTION, value=energy_rate, units='W', higher_is_better=False)
def run_once(self, seconds=200, sleep=10): status = power_status.get_status() if status.on_ac(): logging.warning('AC power is online -- ' 'unable to monitor energy consumption') return # If powerd is running, stop it, so that it cannot interfere with the # backlight adjustments in this test. if utils.system_output('status powerd').find('start/running') != -1: powerd_running = True utils.system_output('stop powerd') else: powerd_running = False start_energy = status.battery[0].energy self._tlog = power_status.TempLogger([], seconds_period=sleep) self._tlog.start() # Let the test run for i in range(0, seconds, sleep): time.sleep(sleep) status.refresh() status.refresh() end_energy = status.battery[0].energy consumed_energy = start_energy - end_energy energy_rate = consumed_energy * 60 * 60 / seconds keyvals = self._tlog.calc() keyvals['wh_energy_full'] = status.battery[0].energy_full keyvals['wh_start_energy'] = start_energy keyvals['wh_end_energy'] = end_energy keyvals['wh_consumed_energy'] = consumed_energy keyvals['w_average_energy_rate'] = energy_rate keyvals['w_end_energy_rate'] = status.battery[0].energy_rate self.write_perf_keyval(keyvals) # Restore powerd if it was originally running. if powerd_running: utils.system_output('start powerd')
def run_power_test(self, audio_type): """ Captures power usage and reports it to the perf dashboard. @param audio_type: audio format label to attach with perf keyval. """ self._backlight = power_utils.Backlight() self._backlight.set_default() self._service_stopper = service_stopper.ServiceStopper( service_stopper.ServiceStopper.POWER_DRAW_SERVICES) self._service_stopper.stop_services() self._power_status = power_status.get_status() # Verify that we are running on battery and the battery is sufficiently # charged. self._power_status.assert_battery_state(BATTERY_INITIAL_CHARGED_MIN) measurements = [ power_status.SystemPower(self._power_status.battery_path) ] def get_power(): power_logger = power_status.PowerLogger(measurements) power_logger.start() time.sleep(STABILIZATION_DURATION) start_time = time.time() time.sleep(MEASUREMENT_DURATION) power_logger.checkpoint('result', start_time) keyval = power_logger.calc() logging.info('Power output %s', keyval) return keyval['result_' + measurements[0].domain + '_pwr'] energy_rate = get_power() perf_keyval = {} perf_keyval[POWER_DESCRIPTION + audio_type] = energy_rate self.output_perf_value(description=POWER_DESCRIPTION + audio_type, value=energy_rate, units='W', higher_is_better=False) self.write_perf_keyval(perf_keyval)
def test_power(self): """ Runs the video power consumption test. @return a dictionary that contains the test result. """ self._backlight = power_utils.Backlight() self._backlight.set_level(0) self._power_status = power_status.get_status() self._use_ec = True if not power_utils.charge_control_by_ectool(is_charge=False): logging.warning('Can\'t stop charging') return {} if not self._power_status.battery: raise error.TestFail('No valid battery') # Verify that the battery is sufficiently charged. percent_initial_charge = self._power_status.percent_current_charge() if percent_initial_charge < BATTERY_INITIAL_CHARGED_MIN: logging.warning( 'Initial charge (%f) less than min (%f)', (percent_initial_charge, BATTERY_INITIAL_CHARGED_MIN)) return {} measurements = [ power_status.SystemPower(self._power_status.battery_path) ] def get_power(): power_logger = power_status.PowerLogger(measurements) power_logger.start() start_time = time.time() time.sleep(MEASUREMENT_DURATION) power_logger.checkpoint('result', start_time) keyval = power_logger.calc() return keyval['result_' + measurements[0].domain + '_pwr_avg'] return self.test_decode(get_power)
def run_once(self): status = power_status.get_status() statomatic = power_status.StatoMatic() meas = [power_status.SystemPower(status.battery_path)] plog = power_status.PowerLogger(meas, seconds_period=1) tlog = power_status.TempLogger(None, seconds_period=1) plog.start() tlog.start() time.sleep(2) logging.info("battery_energy: %f" % status.battery[0].energy) logging.info("linepower_online: %s" % status.on_ac()) keyvals = plog.calc() keyvals.update(tlog.calc()) keyvals.update(statomatic.publish()) for k in sorted(keyvals.keys()): logging.info("%s: %s", k, keyvals[k]) plog.save_results(self.resultsdir) tlog.save_results(self.resultsdir)
def run_once(self, delay=60, seconds=10, tries=20): self._backlight = power_utils.Backlight() # disable screen blanking. Stopping screen-locker isn't # synchronous :(. Add a sleep for now, till powerd comes around # and fixes all this for us. # TODO(davidjames): Power manager should support this feature directly time.sleep(5) graphics_utils.screen_disable_blanking() status = power_status.get_status() status.assert_battery_state(5) max_brightness = self._backlight.get_max_level() if max_brightness < 4: raise error.TestFail('Must have at least 5 backlight levels') sysfs_max = self._get_highest_sysfs_max_brightness() if max_brightness != sysfs_max: raise error.TestFail(('Max brightness %d is not the highest ' + 'possible |max_brightness|, which is %d') % (max_brightness, sysfs_max)) keyvals = {} rates = [] levels = [0, 50, 100] for i in levels: self._backlight.set_percent(i) time.sleep(delay) this_rate = [] for _ in range(tries): time.sleep(seconds) status.refresh() this_rate.append(status.battery[0].energy_rate) rate = min(this_rate) keyvals['w_bl_%d_rate' % i] = rate rates.append(rate) self.write_perf_keyval(keyvals) for i in range(1, len(levels)): if rates[i] <= rates[i - 1]: raise error.TestFail('Turning up the backlight ' \ 'should increase energy consumption')
def initialize(self, percent_initial_charge_min=10): """ Setup local variables and init the fake DM server @param percent_initial_charge_min: Minimum percentage of battery required for the test to run. """ # Username and password for the fake dm server can be anything # they are not used to authenticate against GAIA. self.username = '******' self.password = '******' self._power_status = power_status.get_status() if not self._power_status.on_ac(): # Ensure that the battery has some charge. self._power_status.assert_battery_state(percent_initial_charge_min) logging.info("Device power type is %s", self._power_type) self.fake_dm_server = enterprise_fake_dmserver.FakeDMServer( self.srcdir) self.fake_dm_server.start(self.tmpdir, self.debugdir)
def __enter__(self): status = power_status.get_status() # We expect the DUT is powered by battery now. But this is not always # true due to other bugs. Disable this test temporarily as workaround. # TODO(johnylin): remove this workaround after AC control is stable # crbug.com/914211 if status.on_ac(): logging.warning('Still powered by AC. Skip this test') raise error.TestNAError('Unable to disable AC.') # Verify that we are running on battery and the battery is sufficiently # charged. status.assert_battery_state(BATTERY_INITIAL_CHARGED_MIN) self._backlight = power_utils.Backlight() self._backlight.set_default() self._service_stopper = service_stopper.ServiceStopper( service_stopper.ServiceStopper.POWER_DRAW_SERVICES) self._service_stopper.stop_services() self._system_power = power_status.SystemPower(status.battery_path) self._power_logger = power_status.PowerLogger([self._system_power]) return self
def run_once(self, test_hours=None, sample_hours=None, max_milliwatts_standby=500, ac_ok=False, force_discharge=False, suspend_state='', bypass_check=False): """Put DUT to suspend state for |sample_hours| and measure power.""" if not power_utils.has_battery(): raise error.TestNAError( 'Skipping test because DUT has no battery.') if test_hours < sample_hours: raise error.TestFail('Test hours must be greater than sample ' 'hours.') # If we're measuring < 6min of standby then the S0 time is not # negligible. Note, reasonable rule of thumb is S0 idle is ~10-20 times # standby power. if sample_hours < self._min_sample_hours and not bypass_check: raise error.TestFail('Must standby more than %.2f hours.' % \ sample_hours) power_stats = power_status.get_status() if not ac_ok and power_stats.on_ac(): raise error.TestError('On AC, please unplug power supply.') if force_discharge: if not power_stats.on_ac(): raise error.TestError('Not on AC, please plug in power supply ' 'to attempt force discharge.') if not power_utils.charge_control_by_ectool(False): raise error.TestError('Unable to force discharge.') self._force_discharge_enabled = True charge_start = power_stats.battery[0].charge_now voltage_start = power_stats.battery[0].voltage_now max_hours = ((charge_start * voltage_start) / (max_milliwatts_standby / 1000.)) if max_hours < test_hours: raise error.TestFail('Battery not charged adequately for test.') suspender = power_suspend.Suspender(self.resultsdir, suspend_state=suspend_state) elapsed_hours = 0 results = {} loop = 0 start_ts = time.time() while elapsed_hours < test_hours: charge_before = power_stats.battery[0].charge_now before_suspend_secs = rtc.get_seconds() suspender.suspend(duration=sample_hours * 3600) after_suspend_secs = rtc.get_seconds() power_stats.refresh() if power_stats.percent_current_charge() < self._percent_min_charge: logging.warning('Battery = %.2f%%. Too low to continue.') break # check that the RTC slept the correct amount of time as there could # potentially be another wake source that would spoil the test. actual_hours = (after_suspend_secs - before_suspend_secs) / 3600.0 percent_diff = math.fabs((actual_hours - sample_hours) / ((actual_hours + sample_hours) / 2) * 100) if percent_diff > 2 and not bypass_check: err = 'Requested standby time and actual varied by %.2f%%.' \ % percent_diff raise error.TestFail(err) # Check resulting charge consumption charge_used = charge_before - power_stats.battery[0].charge_now elapsed_hours += actual_hours logging.debug( 'loop%d done: loop hours %.3f, elapsed hours %.3f ' 'charge used: %.3f', loop, actual_hours, elapsed_hours, charge_used) loop += 1 end_ts = time.time() offset = (end_ts - start_ts - elapsed_hours * 3600) / 2. offset += suspender.get_suspend_delay() start_ts += offset end_ts -= offset power_telemetry_utils.start_measurement(start_ts) power_telemetry_utils.end_measurement(end_ts) self._checkpoint_logger.checkpoint(self.tagged_testname, start_ts, end_ts) charge_end = power_stats.battery[0].charge_now total_charge_used = charge_start - charge_end if total_charge_used <= 0 and not bypass_check: raise error.TestError('Charge used is suspect.') voltage_end = power_stats.battery[0].voltage_now standby_hours = power_stats.battery[0].charge_full_design / \ total_charge_used * elapsed_hours energy_used = (voltage_start + voltage_end) / 2 * \ total_charge_used results['ah_charge_start'] = charge_start results['ah_charge_now'] = charge_end results['ah_charge_used'] = total_charge_used results['force_discharge'] = self._force_discharge_enabled results['hours_standby_time'] = standby_hours results['hours_standby_time_tested'] = elapsed_hours results['v_voltage_start'] = voltage_start results['v_voltage_now'] = voltage_end results['w_energy_rate'] = energy_used / elapsed_hours results['wh_energy_used'] = energy_used self.write_perf_keyval(results) pdash = power_dashboard.SimplePowerLoggerDashboard( end_ts - start_ts, results['w_energy_rate'], self.tagged_testname, start_ts, self.resultsdir, note=self._pdash_note) pdash.upload() self._checkpoint_logger.save_checkpoint_data(self.resultsdir) self.output_perf_value(description='hours_standby_time', value=results['hours_standby_time'], units='hours', higher_is_better=True) self.output_perf_value(description='w_energy_rate', value=results['w_energy_rate'], units='watts', higher_is_better=False) # need to sleep for some time to allow network connection to return time.sleep(10)
def initialize(self, percent_initial_charge_min=None, check_network=True, loop_time=3600, loop_count=1, should_scroll='true', should_scroll_up='true', scroll_loop='false', scroll_interval_ms='10000', scroll_by_pixels='600', test_low_batt_p=3, verbose=True, force_wifi=False, wifi_ap='', wifi_sec='none', wifi_pw='', wifi_timeout=60, tasks='', volume_level=10, mic_gain=10, low_batt_margin_p=2, ac_ok=False, log_mem_bandwidth=False, gaia_login=None, force_discharge=False, pdash_note=''): """ percent_initial_charge_min: min battery charge at start of test check_network: check that Ethernet interface is not running loop_time: length of time to run the test for in each loop loop_count: number of times to loop the test for should_scroll: should the extension scroll pages should_scroll_up: should scroll in up direction scroll_loop: continue scrolling indefinitely scroll_interval_ms: how often to scoll scroll_by_pixels: number of pixels to scroll each time test_low_batt_p: percent battery at which test should stop verbose: add more logging information force_wifi: should we force to test to run on wifi wifi_ap: the name (ssid) of the wifi access point wifi_sec: the type of security for the wifi ap wifi_pw: password for the wifi ap wifi_timeout: The timeout for wifi configuration volume_level: percent audio volume level mic_gain: percent audio microphone gain level low_batt_margin_p: percent low battery margin to be added to sys_low_batt_p to guarantee test completes prior to powerd shutdown ac_ok: boolean to allow running on AC log_mem_bandwidth: boolean to log memory bandwidth during the test gaia_login: whether real GAIA login should be attempted. If 'None' (default) then boolean is determined from URL. force_discharge: boolean of whether to tell ec to discharge battery even when the charger is plugged in. pdash_note: note of the current run to send to power dashboard. """ self._backlight = None self._services = None self._browser = None self._loop_time = loop_time self._loop_count = loop_count self._mseconds = self._loop_time * 1000 self._verbose = verbose self._sys_low_batt_p = 0. self._sys_low_batt_s = 0. self._test_low_batt_p = test_low_batt_p self._should_scroll = should_scroll self._should_scroll_up = should_scroll_up self._scroll_loop = scroll_loop self._scroll_interval_ms = scroll_interval_ms self._scroll_by_pixels = scroll_by_pixels self._tmp_keyvals = {} self._power_status = None self._force_wifi = force_wifi self._testServer = None self._tasks = tasks.replace(' ','') self._backchannel = None self._shill_proxy = None self._volume_level = volume_level self._mic_gain = mic_gain self._ac_ok = ac_ok self._log_mem_bandwidth = log_mem_bandwidth self._wait_time = 60 self._stats = collections.defaultdict(list) self._force_discharge = force_discharge self._pdash_note = pdash_note if not power_utils.has_battery(): if ac_ok and (power_utils.has_powercap_support() or power_utils.has_rapl_support()): logging.info("Device has no battery but has powercap data.") else: rsp = "Skipping test for device without battery and powercap." raise error.TestNAError(rsp) self._power_status = power_status.get_status() self._tmp_keyvals['b_on_ac'] = self._power_status.on_ac() self._gaia_login = gaia_login if gaia_login is None: self._gaia_login = power_load_util.use_gaia_login() self._username = power_load_util.get_username() self._password = power_load_util.get_password() if not ac_ok: self._power_status.assert_battery_state(percent_initial_charge_min) if force_discharge: if not power_utils.charge_control_by_ectool(False): raise error.TestError('Could not run battery force discharge.') # If force wifi enabled, convert eth0 to backchannel and connect to the # specified WiFi AP. if self._force_wifi: sec_config = None # TODO(dbasehore): Fix this when we get a better way of figuring out # the wifi security configuration. if wifi_sec == 'rsn' or wifi_sec == 'wpa': sec_config = xmlrpc_security_types.WPAConfig( psk=wifi_pw, wpa_mode=xmlrpc_security_types.WPAConfig.MODE_PURE_WPA2, wpa2_ciphers= [xmlrpc_security_types.WPAConfig.CIPHER_CCMP]) wifi_config = xmlrpc_datatypes.AssociationParameters( ssid=wifi_ap, security_config=sec_config, configuration_timeout=wifi_timeout) # If backchannel is already running, don't run it again. self._backchannel = backchannel.Backchannel() if not self._backchannel.setup(): raise error.TestError('Could not setup Backchannel network.') self._shill_proxy = wifi_proxy.WifiProxy() self._shill_proxy.remove_all_wifi_entries() for i in xrange(1,4): raw_output = self._shill_proxy.connect_to_wifi_network( wifi_config.ssid, wifi_config.security, wifi_config.security_parameters, wifi_config.save_credentials, station_type=wifi_config.station_type, hidden_network=wifi_config.is_hidden, discovery_timeout_seconds= wifi_config.discovery_timeout, association_timeout_seconds= wifi_config.association_timeout, configuration_timeout_seconds= wifi_config.configuration_timeout * i) result = xmlrpc_datatypes.AssociationResult. \ from_dbus_proxy_output(raw_output) if result.success: break logging.warn('wifi connect: disc:%d assoc:%d config:%d fail:%s', result.discovery_time, result.association_time, result.configuration_time, result.failure_reason) else: raise error.TestError('Could not connect to WiFi network.') else: # Find all wired ethernet interfaces. ifaces = [ iface for iface in interface.get_interfaces() if (not iface.is_wifi_device() and iface.name.startswith('eth')) ] logging.debug(str([iface.name for iface in ifaces])) for iface in ifaces: if check_network and iface.is_lower_up: raise error.TestError('Ethernet interface is active. ' + 'Please remove Ethernet cable') # record the max backlight level self._backlight = power_utils.Backlight() self._tmp_keyvals['level_backlight_max'] = \ self._backlight.get_max_level() self._services = service_stopper.ServiceStopper( service_stopper.ServiceStopper.POWER_DRAW_SERVICES) self._services.stop_services() self._detachable_handler = power_utils.BaseActivitySimulator() # fix up file perms for the power test extension so that chrome # can access it os.system('chmod -R 755 %s' % self.bindir) # setup a HTTP Server to listen for status updates from the power # test extension self._testServer = httpd.HTTPListener(8001, docroot=self.bindir) self._testServer.run() # initialize various interesting power related stats self._statomatic = power_status.StatoMatic() self._power_status.refresh() self._sys_low_batt_p = float(utils.system_output( 'check_powerd_config --low_battery_shutdown_percent')) self._sys_low_batt_s = int(utils.system_output( 'check_powerd_config --low_battery_shutdown_time')) if self._sys_low_batt_p and self._sys_low_batt_s: raise error.TestError( "Low battery percent and seconds are non-zero.") min_low_batt_p = min(self._sys_low_batt_p + low_batt_margin_p, 100) if self._sys_low_batt_p and (min_low_batt_p > self._test_low_batt_p): logging.warning("test low battery threshold is below system " + "low battery requirement. Setting to %f", min_low_batt_p) self._test_low_batt_p = min_low_batt_p if self._power_status.battery: self._ah_charge_start = self._power_status.battery[0].charge_now self._wh_energy_start = self._power_status.battery[0].energy
def run_once(self, power_on=True): utils.poll_for_condition( lambda: power_status.get_status().on_ac() == power_on, timeout=10, exception=error.TestError('AC power not %d' % power_on))
def run_once(self, test_hours=None, sample_hours=None, percent_initial_charge_min=0.2, max_milliwatts_standby=None): if test_hours <= sample_hours: raise error.TestFail( "Test hours must be greater than sample hours") # If we're measuring <= 6min of S3 then the S0 time is not negligible. # Note, reasonable rule of thumb is S0 idle is ~10-20 times S3 power. if sample_hours < self._min_sample_hours: raise error.TestFail("Must suspend more than %.2f hours" % \ sample_hours) # Query initial power status power_stats = power_status.get_status() power_stats.assert_battery_state(percent_initial_charge_min) charge_start = power_stats.battery[0].charge_now voltage_start = power_stats.battery[0].voltage_now max_hours = charge_start * voltage_start / \ (max_milliwatts_standby / 1000) if max_hours < test_hours: raise error.TestFail('Battery not charged adequately for test') elapsed_hours = 0 while elapsed_hours < test_hours: charge_before = power_stats.battery[0].charge_now before_suspend_secs = rtc.get_seconds() sys_power.do_suspend(sample_hours * 3600) after_suspend_secs = rtc.get_seconds() power_stats.refresh() if power_stats.percent_current_charge() < self._percent_min_charge: logging.warning( "Battery percent = %.2f%%. Too low to continue") break # check that the RTC slept the correct amount of time as there could # potentially be another wake source that would spoil the test. actual_hours = (after_suspend_secs - before_suspend_secs) / 3600.0 logging.debug("actual_hours = %.4f", actual_hours) percent_diff = math.fabs((actual_hours - sample_hours) / ((actual_hours + sample_hours) / 2) * 100) if percent_diff > 2: err_str = "Requested S3 time and actual varied by %.2f%%." \ % percent_diff raise error.TestFail(err_str) # Check resulting charge consumption charge_used = charge_before - power_stats.battery[0].charge_now logging.debug("charge_used = %.6f", charge_used) elapsed_hours += actual_hours logging.debug("elapsed_hours = %.4f", elapsed_hours) charge_end = power_stats.battery[0].charge_now voltage_end = power_stats.battery[0].voltage_now standby_hours = power_stats.battery[0].charge_full_design / \ (charge_start - charge_end) * elapsed_hours energy_used = charge_start * voltage_start - charge_end * voltage_end if energy_used <= 0: raise error.TestError("Energy used reading is suspect.") standby_milliwatts = energy_used / elapsed_hours * 1000 results = {} results['milliwatts_standby_power'] = standby_milliwatts results['hours_standby_time'] = standby_hours self.write_perf_keyval(results) # need to sleep for some time to allow network connection to return time.sleep(10)