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