Home | History | Annotate | Download | only in firmware_StandbyPowerConsumption
      1 # Copyright 2016 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, time, os
      6 
      7 from autotest_lib.client.common_lib import error
      8 from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
      9 
     10 
     11 PP_PATH = '/dev/ttyUSB0'
     12 PP_LOG = '/tmp/powerplay.log'
     13 CMD = '(stty 115200 cs8 -ixon; cat) < ' + PP_PATH + ' > ' + PP_LOG
     14 WAIT_DELAY = 10
     15 LONG_TIMEOUT = 60
     16 
     17 
     18 class firmware_StandbyPowerConsumption(FirmwareTest):
     19     """Test captures power consumption data of a ChromeOS device while the
     20     device is in hibernate mode. It uses a stand alone utility called
     21     'powerplay' which is instrumented on the device using the battery terminals
     22     to provide power and track consumption. More information about powerplay can
     23     be found at go/powerplay.
     24     """
     25     version = 1
     26 
     27 
     28     def initialize(self, host, cmdline_args):
     29         (super(firmware_StandbyPowerConsumption, self)
     30                 .initialize(host, cmdline_args))
     31         self.switcher.setup_mode('normal')
     32 
     33 
     34     def get_monetary_current(self, pp_file):
     35         """Extract momentary current value from each line of powerplay data.
     36 
     37         @param pp_file: Log file containing complete powerplay data set.
     38         @return list containing momentary current values.
     39         """
     40         momentary_curr_list = list()
     41         for line in open(os.path.join(self.resultsdir, pp_file)):
     42             pp_data = (line.replace('\00', '').
     43                        replace(' ', ',').replace('\r', ''))
     44             if (not pp_data.startswith('#') and (len(pp_data) > 30)):
     45                 if pp_data[0].isdigit():
     46                     momentary_curr_list.append(
     47                             float(pp_data[pp_data.index(',')+1:]
     48                             [:pp_data[pp_data.index(',')+1:].index(',')]))
     49         return momentary_curr_list
     50 
     51 
     52     def set_powerplay_visible_to_servo_host(self, on=False):
     53         """Setting USB hub to make powerplay visible to servo host.
     54 
     55         @param on: To make powerplay visible to servo host or not.
     56         """
     57         if on:
     58             self.host.servo.switch_usbkey('host')
     59             self.host.servo.set('usb_mux_sel3', 'servo_sees_usbkey')
     60             self.host.servo.set('dut_hub1_rst1', 'off')
     61         else:
     62             self.host.servo.switch_usbkey('dut')
     63             self.host.servo.set('usb_mux_sel3', 'dut_sees_usbkey')
     64             self.host.servo.set('dut_hub1_rst1', 'on')
     65         time.sleep(WAIT_DELAY)
     66 
     67 
     68     def run_once(self, host, hibernate_length):
     69         """Main function to run autotset.
     70 
     71         @param host: Host object representing the DUT.
     72         @param hibernate_length: Length of time dut should be in hibernate mode.
     73         """
     74         self.host = host
     75 
     76         if not self.check_ec_capability(['x86','lid']):
     77             raise error.TestNAError("Nothing need to be tested on this device")
     78 
     79         self.set_powerplay_visible_to_servo_host(False)
     80         self.ec.send_command("hibernate")
     81         logging.info("Hibernating for %s seconds...", hibernate_length)
     82         self.host.test_wait_for_sleep(LONG_TIMEOUT)
     83         self.set_powerplay_visible_to_servo_host(True)
     84 
     85         self.s_host = self.host._servo_host
     86         is_pp_connected = self.s_host.run('ls ' + PP_PATH, ignore_status=True)
     87         if is_pp_connected.exit_status:
     88             self.set_powerplay_visible_to_servo_host(False)
     89             self.servo.power_short_press()
     90             if not self.host.ping_wait_up(LONG_TIMEOUT):
     91                 raise error.TestNAError('Device did not resume from hibernate.')
     92             raise error.TestFail("Could not find powerplay.")
     93 
     94         pid = self.s_host.run_background(CMD)
     95         time.sleep(hibernate_length)
     96         self.set_powerplay_visible_to_servo_host(False)
     97         self.s_host.run_background('kill -9 ' + pid)
     98         self.servo.power_short_press()
     99 
    100         pp_file = os.path.join(self.resultsdir, 'powerplay.log')
    101         self.s_host.get_file(PP_LOG, pp_file)
    102 
    103         momentary_current = self.get_monetary_current(pp_file)
    104         avg_current_usage = sum(momentary_current)/len(momentary_current)
    105         peak_current_usage = max(momentary_current)
    106         self.output_perf_value(description='average_current_usage',
    107                 value=avg_current_usage, units='amps', higher_is_better=False)
    108         self.output_perf_value(description='peak_current_usage',
    109                 value=peak_current_usage, units='amps', higher_is_better=False)
    110 
    111         perf_keyval = {}
    112         perf_keyval['average_current_usage'] = avg_current_usage
    113         perf_keyval['peak_current_usage'] = peak_current_usage
    114         self.write_perf_keyval(perf_keyval)
    115 
    116         del_pp_log = self.s_host.run('rm ' + PP_LOG, ignore_status=True)
    117         if del_pp_log.exit_status:
    118             raise error.TestNAError("Unable to delete powerplay.log on servo "
    119                                     "host.")
    120 
    121         if not self.host.ping_wait_up(LONG_TIMEOUT):
    122             raise error.TestNAError('Device did not resume from hibernate.')
    123