| # Copyright 2020 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 time |
| |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.cros.power import power_status |
| from autotest_lib.client.cros.power import power_test |
| |
| SEC_PERIOD = 1.0 |
| SEC_WARMUP = 1.0 |
| SEC_SLEEP = 5.0 |
| |
| # For batteries with 11 to 50 charge cycles, require last full charge > 98% |
| # of battery design capacity. For batteries with 51 to 300 charge cycles, |
| # require last full charge > 75% of battery design capacity. For batteries |
| # outside these ranges, throw TestNAError. |
| BATTERY_REQUIREMENT = ((10, -1.0), (50, 98.0), (300, 75.0)) |
| |
| |
| class power_BatteryDesignCapacity(power_test.power_Test): |
| """Test to qualify whether last full charge meets battery design capacity. |
| """ |
| version = 1 |
| |
| def initialize(self, pdash_note=''): |
| """Measure power with a short interval.""" |
| super(power_BatteryDesignCapacity, |
| self).initialize(seconds_period=SEC_PERIOD, |
| pdash_note=pdash_note) |
| |
| def warmup(self): |
| """Warm up for a short time.""" |
| super(power_BatteryDesignCapacity, self).warmup(warmup_time=SEC_WARMUP) |
| |
| def run_once(self, requirement=BATTERY_REQUIREMENT): |
| """ |
| Collect battery charge data and check if last full charge meets battery |
| design capacity. |
| |
| @param requirement: last full charge / battery design capacity percentage |
| expected for cycle count, listed from low cycle count |
| to high cycle count. |
| """ |
| self.start_measurements() |
| |
| b = power_status.get_status().battery |
| keyvals = dict() |
| err = None |
| cycle_count = b.cycle_count |
| keyvals['cycle_count'] = cycle_count |
| keyvals['ah_charge_full'] = b.charge_full |
| keyvals['ah_charge_full_design'] = b.charge_full_design |
| percent_full_vs_design = 100.0 * b.charge_full / b.charge_full_design |
| keyvals['percent_full_vs_design'] = percent_full_vs_design |
| keyvals['battery_design_capacity_qualify'] = False |
| keyvals['manufacturer'] = b.manufacturer |
| keyvals['model_name'] = b.model_name |
| keyvals['serial_number'] = b.serial_number |
| keyvals['battery_id'] = (b.manufacturer + '_' + b.model_name + '_' + |
| b.serial_number) |
| |
| if len(requirement) < 2: |
| raise error.TestFail( |
| 'Battery design capacity requirement has wrong format.') |
| |
| if cycle_count <= requirement[0][0]: |
| err = error.TestNAError |
| estr = ('Device battery has %d charge cycles currently. More than ' |
| '%d cycles are needed to judge whether last full charge ' |
| 'meets battery design capacity.' % |
| (cycle_count, requirement[0][0])) |
| elif cycle_count > requirement[-1][0]: |
| err = error.TestNAError |
| estr = ('Device battery has %d charge cycles currently. This is ' |
| 'more than %d cycles which means that the battery might ' |
| 'have degraded. Please re-run this test with a newer ' |
| 'battery.' % (cycle_count, requirement[-1][0])) |
| else: |
| for max_cycle, percent_required in requirement: |
| if cycle_count > max_cycle: |
| continue |
| if percent_full_vs_design >= percent_required: |
| keyvals['battery_design_capacity_qualify'] = True |
| else: |
| err = error.TestFail |
| estr = ('Device battery last full charge is %f%% of design ' |
| 'capacity, lower than %f%%. This battery fails ' |
| 'design capacity qualification.' % |
| (percent_full_vs_design, percent_required)) |
| break |
| self.write_perf_keyval(keyvals) |
| if err: |
| raise err(estr) |
| # Sleep for a bit to collect logger data. |
| time.sleep(SEC_SLEEP) |