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