# Copyright (c) 2013 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
from autotest_lib.client.common_lib import error
from autotest_lib.server import test
from autotest_lib.server.cros.faft.config.config import Config as FAFTConfig
BOOT_WAIT_SECONDS = 100
DARK_RESUME_SOURCE_PREF = '/sys/class/rtc/rtc0/device'
POWER_DIR = '/var/lib/power_manager'
SHUTDOWN_WAIT_SECONDS = 30
SUSPEND_DURATION = 20
SUSPEND_DURATION_PREF = '0.0'
SUSPEND_WAIT_SECONDS = 10
TMP_POWER_DIR = '/tmp/power_manager'
class power_DarkResumeShutdownServer(test.test):
"""Test power manager shut down from dark resume action."""
version = 1
def initialize(self, host, power_method=None):
self._power_method = power_method
# save original boot id
self.orig_boot_id = host.get_boot_id()
host.run('mkdir -p %s' % TMP_POWER_DIR)
# override suspend durations preference for dark resume
logging.info('setting dark_resume_suspend_durations to %s %d',
SUSPEND_DURATION_PREF, SUSPEND_DURATION)
host.run('echo %s %d > %s/dark_resume_suspend_durations' %
(SUSPEND_DURATION_PREF, SUSPEND_DURATION, TMP_POWER_DIR))
# override sources preference for dark resume
logging.info('setting dark_resume_sources to %s',
DARK_RESUME_SOURCE_PREF)
host.run('echo %s > %s/dark_resume_sources' %
(DARK_RESUME_SOURCE_PREF, TMP_POWER_DIR))
# override disabling of dark resume
logging.info('enabling dark resume')
host.run('echo 0 > %s/disable_dark_resume' % TMP_POWER_DIR)
# bind the tmp directory to the power preference directory
host.run('mount --bind %s %s' % (TMP_POWER_DIR, POWER_DIR))
# restart powerd to pick up new dark resume settings
logging.info('restarting powerd')
host.run('restart powerd')
def platform_supports_dark_resume(self, platform_name):
"""Check if the test works on the given platform
@param platform_name: the name of the given platform
"""
client_attr = FAFTConfig(platform_name)
return client_attr.dark_resume_capable
def run_once(self, host=None):
"""Run the test.
Setup preferences so that a dark resume will happen shortly after
suspending the machine.
suspend the machine
wait
turn off AC power
wait for shutdown
reboot
turn on AC power
@param host: The machine to run the tests on
"""
platform = host.run_output('mosys platform name')
logging.info('Checking platform %s for compatibility with dark resume',
platform)
if not self.platform_supports_dark_resume(platform):
return
host.power_on(power_method=self._power_method)
# The IO redirection is to make the command return right away. For now,
# don't go through sys_power for suspending since those code paths use
# the RTC.
# TODO(dbasehore): rework sys_power to make the RTC alarm optional
host.run('/usr/bin/powerd_dbus_suspend --delay=1 '
'> /dev/null 2>&1 < /dev/null &')
time.sleep(SUSPEND_WAIT_SECONDS)
host.power_off(power_method=self._power_method)
# wait for power manager to give up and shut down
logging.info('waiting for power off')
host.wait_down(timeout=SHUTDOWN_WAIT_SECONDS,
old_boot_id=self.orig_boot_id)
# ensure host is now off
if host.is_up():
raise error.TestFail('DUT still up. Machine did not shut down from'
' dark resume')
else:
logging.info('good, host is now off')
# restart host
host.power_on(power_method=self._power_method)
host.servo.power_normal_press()
if not host.wait_up(timeout=BOOT_WAIT_SECONDS):
raise error.TestFail('DUT did not turn back on after shutting down')
def cleanup(self, host):
# make sure that the machine is not suspended and that the power is on
# when exiting the test
host.power_on(power_method=self._power_method)
host.servo.ctrl_key()
# try to clean up the mess we've made if shutdown failed
if host.is_up() and host.get_boot_id() == self.orig_boot_id:
# clean up mounts
logging.info('cleaning up bind mounts')
host.run('umount %s' % POWER_DIR,
ignore_status=True)
# restart powerd to pick up old retry settings
host.run('restart powerd')