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