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