Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Unified Diff: client/bin/site_login.py

Issue 1534001: switch to autox.py and robustify login/logout code (Closed)
Patch Set: merge with head Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « client/bin/chromeos_constants.py ('k') | client/bin/site_ui_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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)
« no previous file with comments | « client/bin/chromeos_constants.py ('k') | client/bin/site_ui_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698