Home | History | Annotate | Download | only in power_Standby
      1 # Copyright (c) 2011 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.
      4 
      5 import logging, math, time
      6 
      7 from autotest_lib.client.bin import test
      8 from autotest_lib.client.common_lib import error
      9 from autotest_lib.client.cros import power_status, rtc, sys_power
     10 
     11 class power_Standby(test.test):
     12     """Measure Standby(S3) power test."""
     13     version = 1
     14     _percent_min_charge = 0.1
     15     _min_sample_hours = 0.1
     16 
     17     def run_once(self, test_hours=None, sample_hours=None,
     18                  percent_initial_charge_min=0.2, max_milliwatts_standby=None):
     19 
     20         if test_hours <= sample_hours:
     21             raise error.TestFail("Test hours must be greater than sample hours")
     22 
     23         # If we're measuring <= 6min of S3 then the S0 time is not negligible.
     24         # Note, reasonable rule of thumb is S0 idle is ~10-20 times S3 power.
     25         if sample_hours < self._min_sample_hours:
     26             raise error.TestFail("Must suspend more than %.2f hours" % \
     27                                  sample_hours)
     28 
     29         # Query initial power status
     30         power_stats = power_status.get_status()
     31         power_stats.assert_battery_state(percent_initial_charge_min)
     32         charge_start = power_stats.battery[0].charge_now
     33         voltage_start = power_stats.battery[0].voltage_now
     34 
     35         max_hours = charge_start * voltage_start / \
     36             (max_milliwatts_standby / 1000)
     37         if max_hours < test_hours:
     38             raise error.TestFail('Battery not charged adequately for test')
     39 
     40         elapsed_hours = 0
     41 
     42         while elapsed_hours < test_hours:
     43             charge_before = power_stats.battery[0].charge_now
     44             before_suspend_secs = rtc.get_seconds()
     45             sys_power.do_suspend(sample_hours * 3600)
     46             after_suspend_secs = rtc.get_seconds()
     47 
     48             power_stats.refresh()
     49             if power_stats.percent_current_charge() < self._percent_min_charge:
     50                 logging.warning("Battery percent = %.2f%%.  Too low to continue")
     51                 break
     52 
     53             # check that the RTC slept the correct amount of time as there could
     54             # potentially be another wake source that would spoil the test.
     55             actual_hours = (after_suspend_secs - before_suspend_secs) / 3600.0
     56             logging.debug("actual_hours = %.4f", actual_hours)
     57             percent_diff = math.fabs((actual_hours - sample_hours) /
     58                                      ((actual_hours + sample_hours) / 2) * 100)
     59             if percent_diff > 2:
     60                 err_str = "Requested S3 time and actual varied by %.2f%%." \
     61                     % percent_diff
     62                 raise error.TestFail(err_str)
     63 
     64             # Check resulting charge consumption
     65             charge_used = charge_before - power_stats.battery[0].charge_now
     66             logging.debug("charge_used = %.6f", charge_used)
     67 
     68             elapsed_hours += actual_hours
     69             logging.debug("elapsed_hours = %.4f", elapsed_hours)
     70 
     71         charge_end = power_stats.battery[0].charge_now
     72         voltage_end = power_stats.battery[0].voltage_now
     73         standby_hours = power_stats.battery[0].charge_full_design / \
     74             (charge_start - charge_end) * elapsed_hours
     75         energy_used = charge_start * voltage_start - charge_end * voltage_end
     76         if energy_used <= 0:
     77             raise error.TestError("Energy used reading is suspect.")
     78         standby_milliwatts = energy_used / elapsed_hours * 1000
     79 
     80         results = {}
     81         results['milliwatts_standby_power'] = standby_milliwatts
     82         results['hours_standby_time'] = standby_hours
     83         self.write_perf_keyval(results)
     84 
     85         # need to sleep for some time to allow network connection to return
     86         time.sleep(10)
     87