# Copyright 2016 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, time, os from autotest_lib.client.common_lib import error from autotest_lib.server.cros.faft.firmware_test import FirmwareTest PP_PATH = '/dev/ttyUSB0' PP_LOG = '/tmp/powerplay.log' CMD = '(stty 115200 cs8 -ixon; cat) < ' + PP_PATH + ' > ' + PP_LOG WAIT_DELAY = 10 LONG_TIMEOUT = 60 class firmware_StandbyPowerConsumption(FirmwareTest): """Test captures power consumption data of a ChromeOS device while the device is in hibernate mode. It uses a stand alone utility called 'powerplay' which is instrumented on the device using the battery terminals to provide power and track consumption. More information about powerplay can be found at go/powerplay. """ version = 1 def initialize(self, host, cmdline_args): (super(firmware_StandbyPowerConsumption, self) .initialize(host, cmdline_args)) self.switcher.setup_mode('normal') def get_monetary_current(self, pp_file): """Extract momentary current value from each line of powerplay data. @param pp_file: Log file containing complete powerplay data set. @return list containing momentary current values. """ momentary_curr_list = list() for line in open(os.path.join(self.resultsdir, pp_file)): pp_data = (line.replace('\00', ''). replace(' ', ',').replace('\r', '')) if (not pp_data.startswith('#') and (len(pp_data) > 30)): if pp_data[0].isdigit(): momentary_curr_list.append( float(pp_data[pp_data.index(',')+1:] [:pp_data[pp_data.index(',')+1:].index(',')])) return momentary_curr_list def set_powerplay_visible_to_servo_host(self, on=False): """Setting USB hub to make powerplay visible to servo host. @param on: To make powerplay visible to servo host or not. """ if on: self.host.servo.switch_usbkey('host') self.host.servo.set('usb_mux_sel3', 'servo_sees_usbkey') self.host.servo.set('dut_hub1_rst1', 'off') else: self.host.servo.switch_usbkey('dut') self.host.servo.set('usb_mux_sel3', 'dut_sees_usbkey') self.host.servo.set('dut_hub1_rst1', 'on') time.sleep(WAIT_DELAY) def run_once(self, host, hibernate_length): """Main function to run autotset. @param host: Host object representing the DUT. @param hibernate_length: Length of time dut should be in hibernate mode. """ self.host = host if not self.check_ec_capability(['x86','lid']): raise error.TestNAError("Nothing need to be tested on this device") self.set_powerplay_visible_to_servo_host(False) self.ec.send_command("hibernate") logging.info("Hibernating for %s seconds...", hibernate_length) self.host.test_wait_for_sleep(LONG_TIMEOUT) self.set_powerplay_visible_to_servo_host(True) self.s_host = self.host._servo_host is_pp_connected = self.s_host.run('ls ' + PP_PATH, ignore_status=True) if is_pp_connected.exit_status: self.set_powerplay_visible_to_servo_host(False) self.servo.power_short_press() if not self.host.ping_wait_up(LONG_TIMEOUT): raise error.TestNAError('Device did not resume from hibernate.') raise error.TestFail("Could not find powerplay.") pid = self.s_host.run_background(CMD) time.sleep(hibernate_length) self.set_powerplay_visible_to_servo_host(False) self.s_host.run_background('kill -9 ' + pid) self.servo.power_short_press() pp_file = os.path.join(self.resultsdir, 'powerplay.log') self.s_host.get_file(PP_LOG, pp_file) momentary_current = self.get_monetary_current(pp_file) avg_current_usage = sum(momentary_current)/len(momentary_current) peak_current_usage = max(momentary_current) self.output_perf_value(description='average_current_usage', value=avg_current_usage, units='amps', higher_is_better=False) self.output_perf_value(description='peak_current_usage', value=peak_current_usage, units='amps', higher_is_better=False) perf_keyval = {} perf_keyval['average_current_usage'] = avg_current_usage perf_keyval['peak_current_usage'] = peak_current_usage self.write_perf_keyval(perf_keyval) del_pp_log = self.s_host.run('rm ' + PP_LOG, ignore_status=True) if del_pp_log.exit_status: raise error.TestNAError("Unable to delete powerplay.log on servo " "host.") if not self.host.ping_wait_up(LONG_TIMEOUT): raise error.TestNAError('Device did not resume from hibernate.')