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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import logging, os, utils, signal, time 5 import logging, os, utils, signal, subprocess, time
6 from autotest_lib.client.bin import chromeos_constants, site_cryptohome 6 from autotest_lib.client.bin import chromeos_constants, site_cryptohome
7 from autotest_lib.client.bin import site_utils, test 7 from autotest_lib.client.bin import site_utils, test
8 from autotest_lib.client.common_lib import error, site_ui 8 from autotest_lib.client.common_lib import error, site_ui
9 9
10 10
11 class TimeoutError(error.TestError): 11 class TimeoutError(error.TestError):
12 """Error returned if we time out while waiting on a condition.""" 12 """Error raised when we time out while waiting on a condition."""
13 pass 13 pass
14 14
15 15
16 def setup_autox(test): 16 class UnexpectedCondition(error.TestError):
17 test.job.setup_dep(['autox']) 17 """Error raised when an expected precondition is not met."""
18 # create a empty srcdir to prevent the error that checks .version file 18 pass
19 if not os.path.exists(test.srcdir): 19
20 os.mkdir(test.srcdir) 20
21 def __get_session_manager_pid():
22 """Determine the pid of the session manager.
23
24 Returns:
25 An integer indicating the current session manager pid, or None if
26 it is not running.
27 """
28
29 p = subprocess.Popen(["pgrep", "^%s$" % chromeos_constants.SESSION_MANAGER],
30 stdout=subprocess.PIPE)
31 ary = p.communicate()[0].split()
32 return int(ary[0]) if ary else None
33
34
35 def __session_manager_restarted(oldpid):
36 """Detect if the session manager has restarted.
37
38 Args:
39 oldpid: Integer indicating the last known pid of the session_manager.
40
41 Returns:
42 True if the session manager is running under a pid other than
43 'oldpid', X is running, and there is a window displayed.
44 """
45 import autox
46
47 newpid = __get_session_manager_pid()
48 if newpid and newpid != oldpid:
49 try:
50 ax = site_ui.get_autox()
51 except autox.Xlib.error.DisplayConnectionError:
52 return False
53
54 # When the session manager starts up there is a moment where we can
55 # make a connection with autox, but there is no window displayed. If
56 # we start sending keystrokes at this point they get lost. If we wait
57 # for this window to show up, things go much smoother.
58 wid = ax.get_top_window_id_at_point(0, 0)
59 if not wid:
60 return False
61
62 # The login manager displays its widgetry in a second window centered
63 # on the screen. Waiting for this window to show up is also helpful.
64 # TODO: perhaps the login manager should emit some more trustworthy
65 # signal when it's ready to accept credentials.
66 x, y = ax.get_screen_size()
67 wid2 = ax.get_top_window_id_at_point(x / 2, y / 2)
68 if wid == wid2:
69 return False
70
71 return True
72
73 return False
21 74
22 75
23 def logged_in(): 76 def logged_in():
24 # this file is created when the session_manager emits start-user-session 77 # this file is created when the session_manager emits start-user-session
25 # and removed when the session_manager emits stop-user-session 78 # and removed when the session_manager emits stop-user-session
26 return os.path.exists(chromeos_constants.LOGGED_IN_MAGIC_FILE) 79 return os.path.exists(chromeos_constants.LOGGED_IN_MAGIC_FILE)
27 80
28 81
29 # TODO: Update this to use the Python-based autox instead. 82 def attempt_login(username, password, timeout=20):
30 def attempt_login(test, script_file, timeout=10):
31 """Attempt to log in. 83 """Attempt to log in.
32 84
33 Args: 85 Args:
34 script: str filename of autox JSON script 86 script: str filename of autox JSON script
35 timeout: float number of seconds to wait 87 timeout: float number of seconds to wait
36 88
37 Raises: 89 Raises:
38 error.TestFail: autox program exited with failure
39 TimeoutError: login didn't complete before timeout 90 TimeoutError: login didn't complete before timeout
91 UnexpectedCondition: login manager is not running, or user is already
92 logged in.
40 """ 93 """
41 dep = 'autox' 94 logging.info("Attempting to login using autox.py and (%s, %s)" %
42 dep_dir = os.path.join(test.autodir, 'deps', dep) 95 (username, password))
43 test.job.install_pkg(dep, 'dep', dep_dir)
44 96
45 autox_binary = '%s/%s' % (dep_dir, 'autox') 97 if not __get_session_manager_pid():
46 autox_script = os.path.join(test.job.configdir, script_file) 98 raise UnexpectedCondition("Session manager is not running")
47 99
48 # TODO: Use something more robust that checks whether the login window is 100 if logged_in():
49 # mapped. 101 raise UnexpectedCondition("Already logged in")
50 wait_for_browser() 102
51 try: 103 ax = site_ui.get_autox()
52 utils.system(site_ui.xcommand('%s %s' % (autox_binary, autox_script))) 104 # navigate to login screen
53 except error.CmdError, e: 105 ax.send_hotkey("Ctrl+Alt+L")
54 logging.debug(e) 106 # focus username
55 raise error.TestFail('AutoX program failed to login for test user') 107 ax.send_hotkey("Alt+U")
108 ax.send_text(username)
109 # TODO(rginda): remove Tab after http://codereview.chromium.org/1390003
110 ax.send_hotkey("Tab")
111 # focus password
112 ax.send_hotkey("Alt+P")
113 ax.send_text(password)
114 ax.send_hotkey("Return")
56 115
57 site_utils.poll_for_condition( 116 site_utils.poll_for_condition(
58 lambda: logged_in(), 117 logged_in, TimeoutError('Timed out waiting for login'),
59 TimeoutError('Timed out while waiting to be logged in'),
60 timeout=timeout) 118 timeout=timeout)
61 119
62 120
63 def attempt_logout(timeout=10): 121 def attempt_logout(timeout=20):
64 """Attempt to log out by killing Chrome. 122 """Attempt to log out by killing Chrome.
65 123
66 Args: 124 Args:
67 timeout: float number of seconds to wait 125 timeout: float number of seconds to wait
68 126
69 Raises: 127 Raises:
70 TimeoutError: logout didn't complete before timeout 128 TimeoutError: logout didn't complete before timeout
129 UnexpectedCondition: user is not logged in
71 """ 130 """
72 # Gracefully exiting chrome causes the user's session to end. 131 if not logged_in():
73 wait_for_initial_chrome_window() 132 raise UnexpectedCondition('Already logged out')
74 utils.system('pkill -TERM -o ^%s$' % chromeos_constants.BROWSER) 133
134 oldpid = __get_session_manager_pid()
135
136 # Gracefully exiting the session manager causes the user's session to end.
137 utils.system('pkill -TERM -o ^%s$' % chromeos_constants.SESSION_MANAGER)
138
75 site_utils.poll_for_condition( 139 site_utils.poll_for_condition(
76 lambda: not logged_in(), 140 lambda: __session_manager_restarted(oldpid),
77 TimeoutError('Timed out while waiting for logout'), 141 TimeoutError('Timed out waiting for logout'),
78 timeout=timeout) 142 timeout)
79 143
80 144
81 def wait_for_browser(timeout=10): 145 def wait_for_browser(timeout=10):
82 """Wait until a Chrome process is running. 146 """Wait until a Chrome process is running.
83 147
84 Args: 148 Args:
85 timeout: float number of seconds to wait 149 timeout: float number of seconds to wait
86 150
87 Raises: 151 Raises:
88 TimeoutError: Chrome didn't start before timeout 152 TimeoutError: Chrome didn't start before timeout
(...skipping 22 matching lines...) Expand all
111 def wait_for_screensaver(timeout=10): 175 def wait_for_screensaver(timeout=10):
112 """Wait until xscreensaver is responding. 176 """Wait until xscreensaver is responding.
113 177
114 Args: 178 Args:
115 timeout: float number of seconds to wait 179 timeout: float number of seconds to wait
116 180
117 Raises: 181 Raises:
118 TimeoutError: xscreensaver didn't respond before timeout 182 TimeoutError: xscreensaver didn't respond before timeout
119 """ 183 """
120 site_utils.poll_for_condition( 184 site_utils.poll_for_condition(
121 lambda: os.system( 185 lambda: site_ui.xsystem('xscreensaver-command -version',
122 site_ui.xcommand('xscreensaver-command -version')) == 0, 186 ignore_status=True) == 0,
123 TimeoutError('Timed out waiting for xscreensaver to respond'), 187 TimeoutError('Timed out waiting for xscreensaver to respond'),
124 timeout=timeout) 188 timeout=timeout)
125 189
126 190
127 def wait_for_window_manager(timeout=20): 191 def wait_for_window_manager(timeout=20):
128 """Wait until the window manager is running. 192 """Wait until the window manager is running.
129 193
130 Args: 194 Args:
131 timeout: float number of seconds to wait 195 timeout: float number of seconds to wait
132 196
(...skipping 26 matching lines...) Expand all
159 nuke_process_by_name('session_manager') 223 nuke_process_by_name('session_manager')
160 wait_for_browser() 224 wait_for_browser()
161 225
162 226
163 def nuke_process_by_name(name, with_prejudice=False): 227 def nuke_process_by_name(name, with_prejudice=False):
164 pid = int(utils.system_output('pgrep -o ^%s$' % name)) 228 pid = int(utils.system_output('pgrep -o ^%s$' % name))
165 if with_prejudice: 229 if with_prejudice:
166 utils.nuke_pid(pid, [signal.SIGKILL]) 230 utils.nuke_pid(pid, [signal.SIGKILL])
167 else: 231 else:
168 utils.nuke_pid(pid) 232 utils.nuke_pid(pid)
OLDNEW
« 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