# Copyright 2019 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. import logging from autotest_lib.client.bin import test from autotest_lib.client.common_lib import error from autotest_lib.client.common_lib.cros import chrome from autotest_lib.client.common_lib import utils from autotest_lib.client.cros.power import power_status from autotest_lib.client.cros.power import power_utils class power_BatteryDrain(test.test): """Not a test, but a utility for server tests to drain the battery below a certain threshold within a certain timeframe.""" version = 1 backlight = None keyboard_backlight = None url = 'https://crospower.page.link/power_BatteryDrain' def cleanup(self): '''Cleanup for a test run''' if self._force_discharge: if not power_utils.charge_control_by_ectool(True): logging.warn('Can not restore from force discharge.') if self.backlight: self.backlight.restore() if self.keyboard_backlight: default_level = self.keyboard_backlight.get_default_level() self.keyboard_backlight.set_level(default_level) def run_once(self, drain_to_percent, drain_timeout, force_discharge=False): ''' Entry point of this test. The DUT must not be connected to AC. It turns the screen and keyboard backlight up as high as possible, and then opens Chrome to a WebGL heavy webpage. I also tried using a dedicated tool for stress-testing the CPU (https://github.com/intel/psst), but that only drew 27 watts on my DUT, compared with 35 watts using the WebGL website. If you find a better way to use a lot of power, please modify this test! @param drain_to_percent: Battery percentage to drain to. @param drain_timeout: In seconds. @param force_discharge: Force discharge even with AC plugged in. ''' status = power_status.get_status() if not status.battery: raise error.TestNAError('DUT has no battery. Test Skipped') self._force_discharge = force_discharge if force_discharge: if not power_utils.charge_control_by_ectool(False): raise error.TestError('Could not run battery force discharge.') ac_error = error.TestFail('DUT is on AC power, but should not be') if not force_discharge and status.on_ac(): raise ac_error self.backlight = power_utils.Backlight() self.backlight.set_percent(100) try: self.keyboard_backlight = power_utils.KbdBacklight() self.keyboard_backlight.set_percent(100) except power_utils.KbdBacklightException as e: logging.info("Assuming no keyboard backlight due to %s", str(e)) self.keyboard_backlight = None with chrome.Chrome(init_network_controller=True) as cr: tab = cr.browser.tabs.New() tab.Navigate(self.url) logging.info( 'Waiting {} seconds for battery to drain to {} percent'.format( drain_timeout, drain_to_percent)) def is_battery_low_enough(): """Check if battery level reach target.""" status.refresh() if not force_discharge and status.on_ac(): raise ac_error return status.percent_display_charge() <= drain_to_percent err = error.TestFail( "Battery did not drain to {} percent in {} seconds".format( drain_to_percent, drain_timeout)) utils.poll_for_condition(is_battery_low_enough, exception=err, timeout=drain_timeout, sleep_interval=1)