| Index: client/bin/site_login.py
|
| diff --git a/client/bin/site_login.py b/client/bin/site_login.py
|
| index b2c1c1b767ff8476e93243a992d6aa9028e2f501..15fa7862e7048139cb8748f10c9f31d55dae60ca 100644
|
| --- a/client/bin/site_login.py
|
| +++ b/client/bin/site_login.py
|
| @@ -2,22 +2,75 @@
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
|
|
| -import logging, os, utils, signal, time
|
| +import logging, os, utils, signal, subprocess, time
|
| from autotest_lib.client.bin import chromeos_constants, site_cryptohome
|
| from autotest_lib.client.bin import site_utils, test
|
| from autotest_lib.client.common_lib import error, site_ui
|
|
|
|
|
| class TimeoutError(error.TestError):
|
| - """Error returned if we time out while waiting on a condition."""
|
| - pass
|
| + """Error raised when we time out while waiting on a condition."""
|
| + pass
|
|
|
|
|
| -def setup_autox(test):
|
| - test.job.setup_dep(['autox'])
|
| - # create a empty srcdir to prevent the error that checks .version file
|
| - if not os.path.exists(test.srcdir):
|
| - os.mkdir(test.srcdir)
|
| +class UnexpectedCondition(error.TestError):
|
| + """Error raised when an expected precondition is not met."""
|
| + pass
|
| +
|
| +
|
| +def __get_session_manager_pid():
|
| + """Determine the pid of the session manager.
|
| +
|
| + Returns:
|
| + An integer indicating the current session manager pid, or None if
|
| + it is not running.
|
| + """
|
| +
|
| + p = subprocess.Popen(["pgrep", "^%s$" % chromeos_constants.SESSION_MANAGER],
|
| + stdout=subprocess.PIPE)
|
| + ary = p.communicate()[0].split()
|
| + return int(ary[0]) if ary else None
|
| +
|
| +
|
| +def __session_manager_restarted(oldpid):
|
| + """Detect if the session manager has restarted.
|
| +
|
| + Args:
|
| + oldpid: Integer indicating the last known pid of the session_manager.
|
| +
|
| + Returns:
|
| + True if the session manager is running under a pid other than
|
| + 'oldpid', X is running, and there is a window displayed.
|
| + """
|
| + import autox
|
| +
|
| + newpid = __get_session_manager_pid()
|
| + if newpid and newpid != oldpid:
|
| + try:
|
| + ax = site_ui.get_autox()
|
| + except autox.Xlib.error.DisplayConnectionError:
|
| + return False
|
| +
|
| + # When the session manager starts up there is a moment where we can
|
| + # make a connection with autox, but there is no window displayed. If
|
| + # we start sending keystrokes at this point they get lost. If we wait
|
| + # for this window to show up, things go much smoother.
|
| + wid = ax.get_top_window_id_at_point(0, 0)
|
| + if not wid:
|
| + return False
|
| +
|
| + # The login manager displays its widgetry in a second window centered
|
| + # on the screen. Waiting for this window to show up is also helpful.
|
| + # TODO: perhaps the login manager should emit some more trustworthy
|
| + # signal when it's ready to accept credentials.
|
| + x, y = ax.get_screen_size()
|
| + wid2 = ax.get_top_window_id_at_point(x / 2, y / 2)
|
| + if wid == wid2:
|
| + return False
|
| +
|
| + return True
|
| +
|
| + return False
|
|
|
|
|
| def logged_in():
|
| @@ -26,8 +79,7 @@ def logged_in():
|
| return os.path.exists(chromeos_constants.LOGGED_IN_MAGIC_FILE)
|
|
|
|
|
| -# TODO: Update this to use the Python-based autox instead.
|
| -def attempt_login(test, script_file, timeout=10):
|
| +def attempt_login(username, password, timeout=20):
|
| """Attempt to log in.
|
|
|
| Args:
|
| @@ -35,32 +87,38 @@ def attempt_login(test, script_file, timeout=10):
|
| timeout: float number of seconds to wait
|
|
|
| Raises:
|
| - error.TestFail: autox program exited with failure
|
| TimeoutError: login didn't complete before timeout
|
| + UnexpectedCondition: login manager is not running, or user is already
|
| + logged in.
|
| """
|
| - dep = 'autox'
|
| - dep_dir = os.path.join(test.autodir, 'deps', dep)
|
| - test.job.install_pkg(dep, 'dep', dep_dir)
|
| -
|
| - autox_binary = '%s/%s' % (dep_dir, 'autox')
|
| - autox_script = os.path.join(test.job.configdir, script_file)
|
| -
|
| - # TODO: Use something more robust that checks whether the login window is
|
| - # mapped.
|
| - wait_for_browser()
|
| - try:
|
| - utils.system(site_ui.xcommand('%s %s' % (autox_binary, autox_script)))
|
| - except error.CmdError, e:
|
| - logging.debug(e)
|
| - raise error.TestFail('AutoX program failed to login for test user')
|
| + logging.info("Attempting to login using autox.py and (%s, %s)" %
|
| + (username, password))
|
| +
|
| + if not __get_session_manager_pid():
|
| + raise UnexpectedCondition("Session manager is not running")
|
| +
|
| + if logged_in():
|
| + raise UnexpectedCondition("Already logged in")
|
| +
|
| + ax = site_ui.get_autox()
|
| + # navigate to login screen
|
| + ax.send_hotkey("Ctrl+Alt+L")
|
| + # focus username
|
| + ax.send_hotkey("Alt+U")
|
| + ax.send_text(username)
|
| + # TODO(rginda): remove Tab after http://codereview.chromium.org/1390003
|
| + ax.send_hotkey("Tab")
|
| + # focus password
|
| + ax.send_hotkey("Alt+P")
|
| + ax.send_text(password)
|
| + ax.send_hotkey("Return")
|
|
|
| site_utils.poll_for_condition(
|
| - lambda: logged_in(),
|
| - TimeoutError('Timed out while waiting to be logged in'),
|
| + logged_in, TimeoutError('Timed out waiting for login'),
|
| timeout=timeout)
|
|
|
|
|
| -def attempt_logout(timeout=10):
|
| +def attempt_logout(timeout=20):
|
| """Attempt to log out by killing Chrome.
|
|
|
| Args:
|
| @@ -68,14 +126,20 @@ def attempt_logout(timeout=10):
|
|
|
| Raises:
|
| TimeoutError: logout didn't complete before timeout
|
| + UnexpectedCondition: user is not logged in
|
| """
|
| - # Gracefully exiting chrome causes the user's session to end.
|
| - wait_for_initial_chrome_window()
|
| - utils.system('pkill -TERM -o ^%s$' % chromeos_constants.BROWSER)
|
| + if not logged_in():
|
| + raise UnexpectedCondition('Already logged out')
|
| +
|
| + oldpid = __get_session_manager_pid()
|
| +
|
| + # Gracefully exiting the session manager causes the user's session to end.
|
| + utils.system('pkill -TERM -o ^%s$' % chromeos_constants.SESSION_MANAGER)
|
| +
|
| site_utils.poll_for_condition(
|
| - lambda: not logged_in(),
|
| - TimeoutError('Timed out while waiting for logout'),
|
| - timeout=timeout)
|
| + lambda: __session_manager_restarted(oldpid),
|
| + TimeoutError('Timed out waiting for logout'),
|
| + timeout)
|
|
|
|
|
| def wait_for_browser(timeout=10):
|
| @@ -118,8 +182,8 @@ def wait_for_screensaver(timeout=10):
|
| TimeoutError: xscreensaver didn't respond before timeout
|
| """
|
| site_utils.poll_for_condition(
|
| - lambda: os.system(
|
| - site_ui.xcommand('xscreensaver-command -version')) == 0,
|
| + lambda: site_ui.xsystem('xscreensaver-command -version',
|
| + ignore_status=True) == 0,
|
| TimeoutError('Timed out waiting for xscreensaver to respond'),
|
| timeout=timeout)
|
|
|
|
|