1# Copyright 2017 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 6import os 7import tempfile 8 9from autotest_lib.client.bin import utils 10from autotest_lib.client.common_lib import error 11from autotest_lib.client.common_lib import file_utils 12from autotest_lib.client.common_lib.cros import arc, arc_util 13from autotest_lib.client.common_lib.cros import chrome 14from autotest_lib.client.cros import cryptohome 15from autotest_lib.client.cros.input_playback import keyboard 16 17 18_CHROME_EXEC_TIME = 'chrome-exec' 19_LOGOUT_STARTED_TIME = 'logout-started' 20_LOGOUT_TIMEOUT = 60 # logout should finsih in 60 seconds. 21 22 23class platform_LogoutPerf(arc.ArcTest): 24 """Measured the time for signing off from a logged on user session. 25 26 The test mainly measures the time for signing off a session and raises 27 an exception if it could not be finished in time. First, it uses telemetry 28 to login a GAIA account and waits for container boots up if the 29 device supports ARC++, then validates the account. Next, it injects the 30 ctrl+shift+q twice to logout the session, then waits for new login screen 31 , i.e. the event of 'login-visible-prompt' to calculate the time elapsed 32 for logging out. 33 """ 34 version = 1 35 36 37 def _get_latest_uptime(self, ts_name): 38 pathname = '/tmp/uptime-' + ts_name 39 if not os.path.exists(pathname): 40 logging.info('timestamp %s is missing', ts_name) 41 return 0 42 with open(pathname) as statfile: 43 values = map(lambda l: float(l.split()[0]), 44 statfile.readlines()) 45 logging.info('timestamp of %s -> %s ', ts_name, values[-1]) 46 return values[-1] 47 48 49 def _validate(self): 50 # Validate if the environment is expected. 51 if not cryptohome.is_vault_mounted( 52 user=chrome.NormalizeEmail(self.username)): 53 raise error.TestFail('Expected to find a mounted vault for %s' 54 % self.username) 55 tab = self.cr.browser.tabs.New() 56 tab.Navigate('http://accounts.google.com') 57 tab.WaitForDocumentReadyStateToBeComplete() 58 res = tab.EvaluateJavaScript(''' 59 var res = '', 60 divs = document.getElementsByTagName('div'); 61 for (var i = 0; i < divs.length; i++) { 62 res = divs[i].textContent; 63 if (res.search('%s') > 1) { 64 break; 65 } 66 } 67 res; 68 ''' % self.username) 69 if not res: 70 raise error.TestFail('No references to %s on accounts page.' 71 % self.username) 72 tab.Close() 73 74 75 def initialize(self): 76 self.keyboard = keyboard.Keyboard() 77 self.username, password = arc_util.get_test_account_info() 78 # Login a user session. 79 if utils.is_arc_available(): 80 super(platform_LogoutPerf, self).initialize( 81 gaia_login=True, 82 disable_arc_opt_in=False) 83 self.cr = self._chrome 84 else: 85 with tempfile.NamedTemporaryFile() as cap: 86 file_utils.download_file(arc_util._ARCP_URL, cap.name) 87 password = cap.read().rstrip() 88 self.cr = chrome.Chrome(gaia_login=True, 89 username=self.username, 90 password=password) 91 92 93 def arc_setup(self): 94 # Do nothing here 95 logging.info('No ARC++ specific setup required') 96 97 98 def arc_teardown(self): 99 # Do nothing here 100 logging.info('No ARC++ specific teardown required') 101 102 103 def cleanup(self): 104 self.keyboard.close() 105 if utils.is_arc_available(): 106 super(platform_LogoutPerf, self).cleanup() 107 108 109 def run_once(self): 110 """Main entry point of test.""" 111 # Validate the current GAIA login session 112 self._validate() 113 114 # Get old logout start timestamp 115 logout_started = self._get_latest_uptime(_LOGOUT_STARTED_TIME) 116 117 # Logout hotkey: pressing ctrl+shift+q twice. Double ctrl+shift+q might 118 # be interrupted by window transition, sending extra keys to reduce test 119 # flakiness. 120 for _ in range(4): 121 self.keyboard.press_key('ctrl+shift+q') 122 123 # Poll for logout start timestamp update 124 utils.poll_for_condition( 125 lambda: self._get_latest_uptime(_LOGOUT_STARTED_TIME) != 126 logout_started, 127 exception=error.TestFail('Timeout: Could not sign off in time'), 128 timeout=_LOGOUT_TIMEOUT, 129 sleep_interval=2, 130 desc='Polling for user to be logged out.') 131 132 logout_started = self._get_latest_uptime(_LOGOUT_STARTED_TIME) 133 logging.info('logout started @%s', logout_started) 134 chrome_exec = self._get_latest_uptime(_CHROME_EXEC_TIME) 135 logging.info('chrome restarts @%s', chrome_exec) 136 elapsed_time = float(chrome_exec) - float(logout_started) 137 logging.info('The elapsed time for signout is %s', elapsed_time) 138 self.output_perf_value(description='Seconds elapsed for Signout', 139 value=elapsed_time, 140 higher_is_better=False, 141 units='seconds') 142