• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5import logging, time, os
6
7from autotest_lib.client.common_lib import error
8from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
9
10
11PP_PATH = '/dev/ttyUSB0'
12PP_LOG = '/tmp/powerplay.log'
13CMD = '(stty 115200 cs8 -ixon; cat) < ' + PP_PATH + ' > ' + PP_LOG
14WAIT_DELAY = 10
15LONG_TIMEOUT = 60
16
17
18class 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