blob: 849e332721804dcf84ec88777bfea0a3f5e2d959 [file] [log] [blame]
# Copyright (c) 2014 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, re, time
from autotest_lib.server import autotest, test
from autotest_lib.client.common_lib import error
_CHARGING = 'CHARGING'
_DISCHARGING = 'DISCHARGING'
_WAIT_SECS_AFTER_SWITCH = 5
_LONG_TIMEOUT = 120
_CLIENT_LOGIN = 'desktopui_SimpleLogin'
_WAKE_PRESS_IN_SEC = 0.2
_SUSPEND_TIME = 10
class platform_PowerStatusStress(test.test):
"""Uses RPM and servo to test the power_supply_info output. """
version = 1
def action_login(self):
"""Login i.e. runs running client test
@exception TestFail failed to login within timeout.
"""
self.autotest_client.run_test(_CLIENT_LOGIN,
exit_without_logout=True)
def wait_to_suspend(self, suspend_timeout = _LONG_TIMEOUT):
"""Wait for DUT to suspend.
@param suspend_timeout: Time in seconds to wait to disconnect
@exception TestFail if fail to suspend/disconnect in time
"""
if not self.host.ping_wait_down(timeout=suspend_timeout):
raise error.TestFail("Unable to suspend in %s sec" %
suspend_timeout)
def wait_to_come_up(self, resume_timeout = _LONG_TIMEOUT):
"""Wait for DUT to resume.
@param resume_timeout: Time in seconds to wait to come up
@exception TestFail if fail to come_up in time
"""
if not self.host.wait_up(timeout=resume_timeout):
raise error.TestFail("Unable to resume in %s sec" %
resume_timeout)
def do_suspend_resume(self):
""" Suspends the DUT through powerd_dbus_suspend
"""
#Suspend
logging.debug('Suspending...')
if self.has_lid:
self.host.servo.lid_close()
self.wait_to_suspend()
time.sleep(_SUSPEND_TIME)
else:
self.host.suspend(suspend_time=_SUSPEND_TIME)
#Resume
logging.debug('Resuming...')
if self.has_lid:
self.host.servo.lid_open()
else:
self.host.servo.power_key(_WAKE_PRESS_IN_SEC)
self.wait_to_come_up()
def cleanup(self):
""" Finish as powered on and lid open"""
self.host.power_on()
self.host.servo.lid_open()
def switch_power_and_verify(self, powered_on, expected):
""" Main action on switching the power state, and verifying status
@param powered_on: a boolean ON if True, OFF else
@param expected: touple of cmd and values to verify
@exception TestFail if line_power or battery state do not match
"""
bat_state = _CHARGING if powered_on else _DISCHARGING,
logging.info('Switching status to %s ', bat_state)
if powered_on:
self.host.power_on()
else:
self.host.power_off()
time.sleep(_WAIT_SECS_AFTER_SWITCH)
# Suspend/resume
self.do_suspend_resume()
# Get power_supply_info output
psi_output = self.host.run('power_supply_info').stdout.strip()
psi_output = psi_output.replace('\n', '')
exp_psi_online, exp_psi_enum_type, exp_psi_bat_state = expected
is_psi_online = re.match(r'.+online:\s+%s.+' % exp_psi_online,
psi_output) is not None
is_psi_enum_type = re.match(r'.+enum type:\s+%s.+' % exp_psi_enum_type,
psi_output) is not None
is_psi_bat_state = re.match(r'.+state:\s+%s.+' % exp_psi_bat_state,
psi_output) is not None
if not all([is_psi_online, is_psi_enum_type, is_psi_bat_state]):
raise error.TestFail('Bad %s state!' % bat_state)
def run_once(self, host, loop_count):
self.host = host
dut_type = host.get_board_type()
if dut_type != 'CHROMEBOOK':
raise error.TestNAError(
'This test is not supported on %s' % dut_type)
self.autotest_client = autotest.Autotest(self.host)
# Start as powered on
if self.host.has_power():
self.host.power_on()
else:
raise error.TestError('No RPM is setup to device')
# Check if DUT has lid.
self.has_lid = True
if self.host.servo.get('lid_open') == 'not_applicable':
self.has_lid = False
else:
# Check if lid_open control is good.
self.host.servo.lid_open()
if self.host.servo.get('lid_open') != 'yes':
self.has_lid = False
# Login to device
self.action_login()
pdu_connected = True
for i in xrange(loop_count):
logging.info('--- Iteration %d', (i + 1))
# Discharging state
expected = ('no', 'Disconnected', 'Discharging')
self.switch_power_and_verify(False, expected)
# Charging state - it could be any of the three below
expected = ('yes', 'AC', '(Charging|Fully charged)')
self.switch_power_and_verify(True, expected)