普通文本  |  130行  |  4.7 KB

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