1*9c5db199SXin Li# Copyright 2014 The Chromium OS Authors. All rights reserved. 2*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 3*9c5db199SXin Li# found in the LICENSE file. 4*9c5db199SXin Li 5*9c5db199SXin Liimport logging 6*9c5db199SXin Li 7*9c5db199SXin Lifrom autotest_lib.client.cros import constants 8*9c5db199SXin Lifrom autotest_lib.server import autotest 9*9c5db199SXin Li 10*9c5db199SXin LiPOWER_DIR = '/var/lib/power_manager' 11*9c5db199SXin LiTMP_POWER_DIR = '/tmp/power_manager' 12*9c5db199SXin LiPOWER_DEFAULTS = '/usr/share/power_manager/board_specific' 13*9c5db199SXin Li 14*9c5db199SXin LiRESUME_CTRL_RETRIES = 3 15*9c5db199SXin LiRESUME_GRACE_PERIOD = 10 16*9c5db199SXin LiXMLRPC_BRINGUP_TIMEOUT_SECONDS = 60 17*9c5db199SXin LiDARK_SUSPEND_MAX_DELAY_TIMEOUT_MILLISECONDS = 60000 18*9c5db199SXin Li 19*9c5db199SXin Li 20*9c5db199SXin Liclass DarkResumeUtils(object): 21*9c5db199SXin Li """Class containing common functionality for tests which exercise dark 22*9c5db199SXin Li resume pathways. We set up powerd to allow dark resume and also configure 23*9c5db199SXin Li the suspended devices so that the backchannel can stay up. We can also 24*9c5db199SXin Li check for the number of dark resumes that have happened in a particular 25*9c5db199SXin Li suspend request. 26*9c5db199SXin Li """ 27*9c5db199SXin Li 28*9c5db199SXin Li 29*9c5db199SXin Li def __init__(self, host, duration=0): 30*9c5db199SXin Li """Set up powerd preferences so we will properly go into dark resume, 31*9c5db199SXin Li and still be able to communicate with the DUT. 32*9c5db199SXin Li 33*9c5db199SXin Li @param host: the DUT to set up dark resume for 34*9c5db199SXin Li 35*9c5db199SXin Li """ 36*9c5db199SXin Li self._host = host 37*9c5db199SXin Li logging.info('Setting up dark resume preferences') 38*9c5db199SXin Li 39*9c5db199SXin Li # Make temporary directory, which will be used to hold 40*9c5db199SXin Li # temporary preferences. We want to avoid writing into 41*9c5db199SXin Li # /var/lib so we don't have to save any state. 42*9c5db199SXin Li logging.debug('Creating temporary powerd prefs at %s', TMP_POWER_DIR) 43*9c5db199SXin Li host.run('mkdir -p %s' % TMP_POWER_DIR) 44*9c5db199SXin Li 45*9c5db199SXin Li logging.debug('Enabling dark resume') 46*9c5db199SXin Li host.run('echo 0 > %s/disable_dark_resume' % TMP_POWER_DIR) 47*9c5db199SXin Li logging.debug('setting max dark suspend delay timeout to %d msecs', 48*9c5db199SXin Li DARK_SUSPEND_MAX_DELAY_TIMEOUT_MILLISECONDS) 49*9c5db199SXin Li host.run('echo %d > %s/max_dark_suspend_delay_timeout_ms' % 50*9c5db199SXin Li (DARK_SUSPEND_MAX_DELAY_TIMEOUT_MILLISECONDS, TMP_POWER_DIR)) 51*9c5db199SXin Li 52*9c5db199SXin Li # bind the tmp directory to the power preference directory 53*9c5db199SXin Li host.run('mount --bind %s %s' % (TMP_POWER_DIR, POWER_DIR)) 54*9c5db199SXin Li 55*9c5db199SXin Li logging.debug('Restarting powerd with new settings') 56*9c5db199SXin Li host.run('stop powerd; start powerd') 57*9c5db199SXin Li 58*9c5db199SXin Li logging.debug('Starting XMLRPC session to watch for dark resumes') 59*9c5db199SXin Li self._client_proxy = self._get_xmlrpc_proxy() 60*9c5db199SXin Li 61*9c5db199SXin Li 62*9c5db199SXin Li def teardown(self): 63*9c5db199SXin Li """Clean up changes made by DarkResumeUtils.""" 64*9c5db199SXin Li 65*9c5db199SXin Li logging.info('Tearing down dark resume preferences') 66*9c5db199SXin Li 67*9c5db199SXin Li logging.debug('Cleaning up temporary powerd bind mounts') 68*9c5db199SXin Li self._host.run('umount %s' % POWER_DIR) 69*9c5db199SXin Li 70*9c5db199SXin Li logging.debug('Restarting powerd to revert to old settings') 71*9c5db199SXin Li self._host.run('stop powerd; start powerd') 72*9c5db199SXin Li 73*9c5db199SXin Li 74*9c5db199SXin Li def suspend(self, suspend_secs): 75*9c5db199SXin Li """ Suspends the device for |suspend_secs| without blocking for resume. 76*9c5db199SXin Li 77*9c5db199SXin Li @param suspend_secs : Sleep for seconds. Sets a RTC alarm to wake the 78*9c5db199SXin Li system. 79*9c5db199SXin Li """ 80*9c5db199SXin Li logging.info('Suspending DUT (in background)...') 81*9c5db199SXin Li self._client_proxy.suspend_bg(suspend_secs) 82*9c5db199SXin Li 83*9c5db199SXin Li 84*9c5db199SXin Li def stop_resuspend_on_dark_resume(self, stop_resuspend=True): 85*9c5db199SXin Li """ 86*9c5db199SXin Li If |stop_resuspend| is True, stops re-suspend on seeing a dark resume. 87*9c5db199SXin Li """ 88*9c5db199SXin Li self._client_proxy.set_stop_resuspend(stop_resuspend) 89*9c5db199SXin Li 90*9c5db199SXin Li 91*9c5db199SXin Li def count_dark_resumes(self): 92*9c5db199SXin Li """Return the number of dark resumes since the beginning of the test. 93*9c5db199SXin Li 94*9c5db199SXin Li This method will raise an error if the DUT is not reachable. 95*9c5db199SXin Li 96*9c5db199SXin Li @return the number of dark resumes counted by this DarkResumeUtils 97*9c5db199SXin Li 98*9c5db199SXin Li """ 99*9c5db199SXin Li return self._client_proxy.get_dark_resume_count() 100*9c5db199SXin Li 101*9c5db199SXin Li 102*9c5db199SXin Li 103*9c5db199SXin Li def host_has_lid(self): 104*9c5db199SXin Li """Returns True if the DUT has a lid.""" 105*9c5db199SXin Li return self._client_proxy.has_lid() 106*9c5db199SXin Li 107*9c5db199SXin Li 108*9c5db199SXin Li def _get_xmlrpc_proxy(self): 109*9c5db199SXin Li """Get a dark resume XMLRPC proxy for the host this DarkResumeUtils is 110*9c5db199SXin Li attached to. 111*9c5db199SXin Li 112*9c5db199SXin Li The returned object has no particular type. Instead, when you call 113*9c5db199SXin Li a method on the object, it marshalls the objects passed as arguments 114*9c5db199SXin Li and uses them to make RPCs on the remote server. Thus, you should 115*9c5db199SXin Li read dark_resume_xmlrpc_server.py to find out what methods are supported. 116*9c5db199SXin Li 117*9c5db199SXin Li @return proxy object for remote XMLRPC server. 118*9c5db199SXin Li 119*9c5db199SXin Li """ 120*9c5db199SXin Li # Make sure the client library is on the device so that the proxy 121*9c5db199SXin Li # code is there when we try to call it. 122*9c5db199SXin Li client_at = autotest.Autotest(self._host) 123*9c5db199SXin Li client_at.install() 124*9c5db199SXin Li # Start up the XMLRPC proxy on the client 125*9c5db199SXin Li proxy = self._host.rpc_server_tracker.xmlrpc_connect( 126*9c5db199SXin Li constants.DARK_RESUME_XMLRPC_SERVER_COMMAND, 127*9c5db199SXin Li constants.DARK_RESUME_XMLRPC_SERVER_PORT, 128*9c5db199SXin Li command_name= 129*9c5db199SXin Li constants.DARK_RESUME_XMLRPC_SERVER_CLEANUP_PATTERN, 130*9c5db199SXin Li ready_test_name= 131*9c5db199SXin Li constants.DARK_RESUME_XMLRPC_SERVER_READY_METHOD, 132*9c5db199SXin Li timeout_seconds=XMLRPC_BRINGUP_TIMEOUT_SECONDS) 133*9c5db199SXin Li return proxy 134