• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging, time
6
7from autotest_lib.client.common_lib import error
8from autotest_lib.server import test
9from autotest_lib.server.cros.faft.config.config import Config as FAFTConfig
10
11BOOT_WAIT_SECONDS = 100
12DARK_RESUME_SOURCE_PREF = '/sys/class/rtc/rtc0/device'
13POWER_DIR = '/var/lib/power_manager'
14SHUTDOWN_WAIT_SECONDS = 30
15SUSPEND_DURATION = 20
16SUSPEND_DURATION_PREF = '0.0'
17SUSPEND_WAIT_SECONDS = 10
18TMP_POWER_DIR = '/tmp/power_manager'
19
20
21class power_DarkResumeShutdownServer(test.test):
22    """Test power manager shut down from dark resume action."""
23    version = 1
24
25
26    def initialize(self, host):
27        # save original boot id
28        self.orig_boot_id = host.get_boot_id()
29
30        host.run('mkdir -p %s' % TMP_POWER_DIR)
31        # override suspend durations preference for dark resume
32        logging.info('setting dark_resume_suspend_durations to %s %d',
33                      SUSPEND_DURATION_PREF, SUSPEND_DURATION)
34        host.run('echo %s %d > %s/dark_resume_suspend_durations' %
35                 (SUSPEND_DURATION_PREF, SUSPEND_DURATION, TMP_POWER_DIR))
36
37        # override sources preference for dark resume
38        logging.info('setting dark_resume_sources to %s',
39                     DARK_RESUME_SOURCE_PREF)
40        host.run('echo %s > %s/dark_resume_sources' %
41                 (DARK_RESUME_SOURCE_PREF, TMP_POWER_DIR))
42
43        # override disabling of dark resume
44        logging.info('enabling dark resume')
45        host.run('echo 0 > %s/disable_dark_resume' % TMP_POWER_DIR)
46
47        # bind the tmp directory to the power preference directory
48        host.run('mount --bind %s %s' % (TMP_POWER_DIR, POWER_DIR))
49
50        # restart powerd to pick up new dark resume settings
51        logging.info('restarting powerd')
52        host.run('restart powerd')
53
54
55    def platform_supports_dark_resume(self, platform_name):
56        """Check if the test works on the given platform
57
58        @param platform_name: the name of the given platform
59        """
60        client_attr = FAFTConfig(platform_name)
61        return client_attr.dark_resume_capable
62
63
64    def run_once(self, host=None):
65        """Run the test.
66
67           Setup preferences so that a dark resume will happen shortly after
68           suspending the machine.
69
70           suspend the machine
71           wait
72           turn off AC power
73           wait for shutdown
74           reboot
75           turn on AC power
76
77        @param host: The machine to run the tests on
78        """
79        platform = host.run_output('mosys platform name')
80        logging.info('Checking platform %s for compatibility with dark resume',
81                     platform)
82        if not self.platform_supports_dark_resume(platform):
83            return
84
85        host.power_on()
86        # The IO redirection is to make the command return right away. For now,
87        # don't go through sys_power for suspending since those code paths use
88        # the RTC.
89        # TODO(dbasehore): rework sys_power to make the RTC alarm optional
90        host.run('/usr/bin/powerd_dbus_suspend --delay=1 '
91                 '> /dev/null 2>&1 < /dev/null &')
92        time.sleep(SUSPEND_WAIT_SECONDS)
93        host.power_off()
94
95        # wait for power manager to give up and shut down
96        logging.info('waiting for power off')
97        host.wait_down(timeout=SHUTDOWN_WAIT_SECONDS,
98                       old_boot_id=self.orig_boot_id)
99
100        # ensure host is now off
101        if host.is_up():
102            raise error.TestFail('DUT still up. Machine did not shut down from'
103                                 ' dark resume')
104        else:
105            logging.info('good, host is now off')
106
107        # restart host
108        host.power_on()
109        host.servo.power_normal_press()
110        if not host.wait_up(timeout=BOOT_WAIT_SECONDS):
111            raise error.TestFail('DUT did not turn back on after shutting down')
112
113
114    def cleanup(self, host):
115        # make sure that the machine is not suspended and that the power is on
116        # when exiting the test
117        host.power_on()
118        host.servo.ctrl_key()
119
120        # try to clean up the mess we've made if shutdown failed
121        if host.is_up() and host.get_boot_id() == self.orig_boot_id:
122            # clean up mounts
123            logging.info('cleaning up bind mounts')
124            host.run('umount %s' % POWER_DIR,
125                     ignore_status=True)
126
127            # restart powerd to pick up old retry settings
128            host.run('restart powerd')
129