Home | History | Annotate | Download | only in power_DarkResumeShutdownServer
      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 
      5 import logging, time
      6 
      7 from autotest_lib.client.common_lib import error
      8 from autotest_lib.server import test
      9 from autotest_lib.server.cros.faft.config.config import Config as FAFTConfig
     10 
     11 BOOT_WAIT_SECONDS = 100
     12 DARK_RESUME_SOURCE_PREF = '/sys/class/rtc/rtc0/device'
     13 POWER_DIR = '/var/lib/power_manager'
     14 SHUTDOWN_WAIT_SECONDS = 30
     15 SUSPEND_DURATION = 20
     16 SUSPEND_DURATION_PREF = '0.0'
     17 SUSPEND_WAIT_SECONDS = 10
     18 TMP_POWER_DIR = '/tmp/power_manager'
     19 
     20 
     21 class 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