OLD | NEW |
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 Loading... |
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 Loading... |
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) |
OLD | NEW |