普通文本  |  123行  |  4.93 KB

# 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.')