blob: d4c98e4130ead01793b73792a2b2ff5786ddffb8 [file] [log] [blame]
Josh Gaob1df00e2018-08-07 14:31:17 -07001#!/usr/bin/env python3
Dan Alberta4169f92015-07-24 17:08:33 -07002#
3# Copyright (C) 2015 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17"""Tests for the adb program itself.
18
19This differs from things in test_device.py in that there is no API for these
20things. Most of these tests involve specific error messages or the help text.
21"""
Dan Alberta4169f92015-07-24 17:08:33 -070022
Spencer Lowcc4a4b12015-10-14 17:32:44 -070023import contextlib
Spencer Low9a999242015-09-16 20:45:53 -070024import os
Dan Alberta4169f92015-07-24 17:08:33 -070025import random
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -070026import select
Spencer Lowcc4a4b12015-10-14 17:32:44 -070027import socket
28import struct
Dan Alberta4169f92015-07-24 17:08:33 -070029import subprocess
Spencer Low9a999242015-09-16 20:45:53 -070030import threading
Dan Alberta4169f92015-07-24 17:08:33 -070031import unittest
32
Dan Alberta4169f92015-07-24 17:08:33 -070033
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -070034@contextlib.contextmanager
Luis Hector Chavez947b2132018-05-02 09:10:29 -070035def fake_adbd(protocol=socket.AF_INET, port=0):
36 """Creates a fake ADB daemon that just replies with a CNXN packet."""
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -070037
38 serversock = socket.socket(protocol, socket.SOCK_STREAM)
Luis Hector Chavez947b2132018-05-02 09:10:29 -070039 serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -070040 if protocol == socket.AF_INET:
Josh Gao4db70c52018-08-08 13:08:08 -070041 serversock.bind(("127.0.0.1", port))
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -070042 else:
Josh Gao4db70c52018-08-08 13:08:08 -070043 serversock.bind(("::1", port))
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -070044 serversock.listen(1)
45
46 # A pipe that is used to signal the thread that it should terminate.
Josh Gao6afbf792018-08-07 16:07:25 -070047 readsock, writesock = socket.socketpair()
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -070048
Josh Gaob1df00e2018-08-07 14:31:17 -070049 def _adb_packet(command: bytes, arg0: int, arg1: int, data: bytes) -> bytes:
Josh Gao4db70c52018-08-08 13:08:08 -070050 bin_command = struct.unpack("I", command)[0]
51 buf = struct.pack("IIIIII", bin_command, arg0, arg1, len(data), 0,
Luis Hector Chavezda74b902018-04-17 14:25:04 -070052 bin_command ^ 0xffffffff)
53 buf += data
54 return buf
55
Josh Gaob1df00e2018-08-07 14:31:17 -070056 def _handle(sock):
57 with contextlib.closing(sock) as serversock:
Josh Gao6afbf792018-08-07 16:07:25 -070058 rlist = [readsock, serversock]
Josh Gaob1df00e2018-08-07 14:31:17 -070059 cnxn_sent = {}
60 while True:
61 read_ready, _, _ = select.select(rlist, [], [])
62 for ready in read_ready:
Josh Gao6afbf792018-08-07 16:07:25 -070063 if ready == readsock:
Josh Gaob1df00e2018-08-07 14:31:17 -070064 # Closure pipe
Josh Gaob1df00e2018-08-07 14:31:17 -070065 for f in rlist:
Josh Gao6afbf792018-08-07 16:07:25 -070066 f.close()
Josh Gaob1df00e2018-08-07 14:31:17 -070067 return
68 elif ready == serversock:
69 # Server socket
70 conn, _ = ready.accept()
71 rlist.append(conn)
72 else:
73 # Client socket
74 data = ready.recv(1024)
Josh Gao4db70c52018-08-08 13:08:08 -070075 if not data or data.startswith(b"OPEN"):
Josh Gaob1df00e2018-08-07 14:31:17 -070076 if ready in cnxn_sent:
77 del cnxn_sent[ready]
78 ready.shutdown(socket.SHUT_RDWR)
79 ready.close()
80 rlist.remove(ready)
81 continue
Luis Hector Chavez947b2132018-05-02 09:10:29 -070082 if ready in cnxn_sent:
Josh Gaob1df00e2018-08-07 14:31:17 -070083 continue
84 cnxn_sent[ready] = True
Josh Gao4db70c52018-08-08 13:08:08 -070085 ready.sendall(_adb_packet(b"CNXN", 0x01000001, 1024 * 1024,
86 b"device::ro.product.name=fakeadb"))
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -070087
88 port = serversock.getsockname()[1]
Josh Gaob1df00e2018-08-07 14:31:17 -070089 server_thread = threading.Thread(target=_handle, args=(serversock,))
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -070090 server_thread.start()
91
92 try:
93 yield port
94 finally:
Josh Gao6afbf792018-08-07 16:07:25 -070095 writesock.close()
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -070096 server_thread.join()
97
98
Luis Hector Chavez0aeda102018-04-20 10:31:29 -070099@contextlib.contextmanager
100def adb_connect(unittest, serial):
101 """Context manager for an ADB connection.
102
103 This automatically disconnects when done with the connection.
104 """
105
Josh Gao4db70c52018-08-08 13:08:08 -0700106 output = subprocess.check_output(["adb", "connect", serial])
Josh Gaob1df00e2018-08-07 14:31:17 -0700107 unittest.assertEqual(output.strip(),
Josh Gao4db70c52018-08-08 13:08:08 -0700108 "connected to {}".format(serial).encode("utf8"))
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700109
110 try:
111 yield
112 finally:
113 # Perform best-effort disconnection. Discard the output.
Josh Gao4db70c52018-08-08 13:08:08 -0700114 subprocess.Popen(["adb", "disconnect", serial],
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700115 stdout=subprocess.PIPE,
116 stderr=subprocess.PIPE).communicate()
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700117
118
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700119@contextlib.contextmanager
120def adb_server():
121 """Context manager for an ADB server.
122
Josh Gao4db70c52018-08-08 13:08:08 -0700123 This creates an ADB server and returns the port it"s listening on.
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700124 """
125
126 port = 5038
127 # Kill any existing server on this non-default port.
Josh Gao4db70c52018-08-08 13:08:08 -0700128 subprocess.check_output(["adb", "-P", str(port), "kill-server"],
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700129 stderr=subprocess.STDOUT)
130 read_pipe, write_pipe = os.pipe()
Josh Gaob1df00e2018-08-07 14:31:17 -0700131 os.set_inheritable(write_pipe, True)
Josh Gao4db70c52018-08-08 13:08:08 -0700132 proc = subprocess.Popen(["adb", "-L", "tcp:localhost:{}".format(port),
133 "fork-server", "server",
134 "--reply-fd", str(write_pipe)], close_fds=False)
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700135 try:
136 os.close(write_pipe)
137 greeting = os.read(read_pipe, 1024)
Josh Gao4db70c52018-08-08 13:08:08 -0700138 assert greeting == b"OK\n", repr(greeting)
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700139 yield port
140 finally:
141 proc.terminate()
142 proc.wait()
143
144
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700145class CommandlineTest(unittest.TestCase):
146 """Tests for the ADB commandline."""
Dan Alberta4169f92015-07-24 17:08:33 -0700147
148 def test_help(self):
149 """Make sure we get _something_ out of help."""
150 out = subprocess.check_output(
Josh Gao4db70c52018-08-08 13:08:08 -0700151 ["adb", "help"], stderr=subprocess.STDOUT)
Dan Alberta4169f92015-07-24 17:08:33 -0700152 self.assertGreater(len(out), 0)
153
154 def test_version(self):
155 """Get a version number out of the output of adb."""
Josh Gao4db70c52018-08-08 13:08:08 -0700156 lines = subprocess.check_output(["adb", "version"]).splitlines()
Dan Alberta4169f92015-07-24 17:08:33 -0700157 version_line = lines[0]
Josh Gaob1df00e2018-08-07 14:31:17 -0700158 self.assertRegex(
Josh Gao4db70c52018-08-08 13:08:08 -0700159 version_line, rb"^Android Debug Bridge version \d+\.\d+\.\d+$")
Dan Alberta4169f92015-07-24 17:08:33 -0700160 if len(lines) == 2:
161 # Newer versions of ADB have a second line of output for the
162 # version that includes a specific revision (git SHA).
163 revision_line = lines[1]
Josh Gaob1df00e2018-08-07 14:31:17 -0700164 self.assertRegex(
Josh Gao4db70c52018-08-08 13:08:08 -0700165 revision_line, rb"^Revision [0-9a-f]{12}-android$")
Dan Alberta4169f92015-07-24 17:08:33 -0700166
167 def test_tcpip_error_messages(self):
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700168 """Make sure 'adb tcpip' parsing is sane."""
Josh Gao4db70c52018-08-08 13:08:08 -0700169 proc = subprocess.Popen(["adb", "tcpip"],
Josh Gaob1df00e2018-08-07 14:31:17 -0700170 stdout=subprocess.PIPE,
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700171 stderr=subprocess.STDOUT)
172 out, _ = proc.communicate()
173 self.assertEqual(1, proc.returncode)
Josh Gao4db70c52018-08-08 13:08:08 -0700174 self.assertIn(b"requires an argument", out)
Dan Alberta4169f92015-07-24 17:08:33 -0700175
Josh Gao4db70c52018-08-08 13:08:08 -0700176 proc = subprocess.Popen(["adb", "tcpip", "foo"],
Josh Gaob1df00e2018-08-07 14:31:17 -0700177 stdout=subprocess.PIPE,
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700178 stderr=subprocess.STDOUT)
179 out, _ = proc.communicate()
180 self.assertEqual(1, proc.returncode)
Josh Gao4db70c52018-08-08 13:08:08 -0700181 self.assertIn(b"invalid port", out)
Dan Alberta4169f92015-07-24 17:08:33 -0700182
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700183
184class ServerTest(unittest.TestCase):
185 """Tests for the ADB server."""
186
187 @staticmethod
188 def _read_pipe_and_set_event(pipe, event):
189 """Reads a pipe until it is closed, then sets the event."""
190 pipe.read()
Spencer Low9a999242015-09-16 20:45:53 -0700191 event.set()
192
Spencer Low9a999242015-09-16 20:45:53 -0700193 def test_handle_inheritance(self):
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700194 """Test that launch_server() does not inherit handles.
195
196 launch_server() should not let the adb server inherit
197 stdin/stdout/stderr handles, which can cause callers of adb.exe to hang.
198 This test also runs fine on unix even though the impetus is an issue
199 unique to Windows.
200 """
Spencer Low9a999242015-09-16 20:45:53 -0700201 # This test takes 5 seconds to run on Windows: if there is no adb server
202 # running on the the port used below, adb kill-server tries to make a
203 # TCP connection to a closed port and that takes 1 second on Windows;
204 # adb start-server does the same TCP connection which takes another
205 # second, and it waits 3 seconds after starting the server.
206
207 # Start adb client with redirected stdin/stdout/stderr to check if it
208 # passes those redirections to the adb server that it starts. To do
209 # this, run an instance of the adb server on a non-default port so we
210 # don't conflict with a pre-existing adb server that may already be
211 # setup with adb TCP/emulator connections. If there is a pre-existing
212 # adb server, this also tests whether multiple instances of the adb
213 # server conflict on adb.log.
214
215 port = 5038
216 # Kill any existing server on this non-default port.
Josh Gao4db70c52018-08-08 13:08:08 -0700217 subprocess.check_output(["adb", "-P", str(port), "kill-server"],
Spencer Low9a999242015-09-16 20:45:53 -0700218 stderr=subprocess.STDOUT)
219
220 try:
221 # Run the adb client and have it start the adb server.
Josh Gao4db70c52018-08-08 13:08:08 -0700222 proc = subprocess.Popen(["adb", "-P", str(port), "start-server"],
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700223 stdin=subprocess.PIPE,
224 stdout=subprocess.PIPE,
225 stderr=subprocess.PIPE)
Spencer Low9a999242015-09-16 20:45:53 -0700226
227 # Start threads that set events when stdout/stderr are closed.
228 stdout_event = threading.Event()
229 stdout_thread = threading.Thread(
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700230 target=ServerTest._read_pipe_and_set_event,
231 args=(proc.stdout, stdout_event))
Spencer Low9a999242015-09-16 20:45:53 -0700232 stdout_thread.start()
233
234 stderr_event = threading.Event()
235 stderr_thread = threading.Thread(
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700236 target=ServerTest._read_pipe_and_set_event,
237 args=(proc.stderr, stderr_event))
Spencer Low9a999242015-09-16 20:45:53 -0700238 stderr_thread.start()
239
240 # Wait for the adb client to finish. Once that has occurred, if
241 # stdin/stderr/stdout are still open, it must be open in the adb
242 # server.
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700243 proc.wait()
Spencer Low9a999242015-09-16 20:45:53 -0700244
245 # Try to write to stdin which we expect is closed. If it isn't
246 # closed, we should get an IOError. If we don't get an IOError,
247 # stdin must still be open in the adb server. The adb client is
248 # probably letting the adb server inherit stdin which would be
249 # wrong.
250 with self.assertRaises(IOError):
Josh Gao4db70c52018-08-08 13:08:08 -0700251 proc.stdin.write(b"x")
Josh Gaob1df00e2018-08-07 14:31:17 -0700252 proc.stdin.flush()
Spencer Low9a999242015-09-16 20:45:53 -0700253
254 # Wait a few seconds for stdout/stderr to be closed (in the success
255 # case, this won't wait at all). If there is a timeout, that means
256 # stdout/stderr were not closed and and they must be open in the adb
257 # server, suggesting that the adb client is letting the adb server
258 # inherit stdout/stderr which would be wrong.
259 self.assertTrue(stdout_event.wait(5), "adb stdout not closed")
260 self.assertTrue(stderr_event.wait(5), "adb stderr not closed")
Josh Gaob1df00e2018-08-07 14:31:17 -0700261 stdout_thread.join()
262 stderr_thread.join()
Spencer Low9a999242015-09-16 20:45:53 -0700263 finally:
264 # If we started a server, kill it.
Josh Gao4db70c52018-08-08 13:08:08 -0700265 subprocess.check_output(["adb", "-P", str(port), "kill-server"],
Spencer Low9a999242015-09-16 20:45:53 -0700266 stderr=subprocess.STDOUT)
Dan Alberta4169f92015-07-24 17:08:33 -0700267
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700268
269class EmulatorTest(unittest.TestCase):
270 """Tests for the emulator connection."""
271
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700272 def _reset_socket_on_close(self, sock):
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700273 """Use SO_LINGER to cause TCP RST segment to be sent on socket close."""
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700274 # The linger structure is two shorts on Windows, but two ints on Unix.
Josh Gao4db70c52018-08-08 13:08:08 -0700275 linger_format = "hh" if os.name == "nt" else "ii"
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700276 l_onoff = 1
277 l_linger = 0
278
279 sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
280 struct.pack(linger_format, l_onoff, l_linger))
281 # Verify that we set the linger structure properly by retrieving it.
282 linger = sock.getsockopt(socket.SOL_SOCKET, socket.SO_LINGER, 16)
283 self.assertEqual((l_onoff, l_linger),
284 struct.unpack_from(linger_format, linger))
285
286 def test_emu_kill(self):
287 """Ensure that adb emu kill works.
288
289 Bug: https://code.google.com/p/android/issues/detail?id=21021
290 """
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700291 with contextlib.closing(
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700292 socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as listener:
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700293 # Use SO_REUSEADDR so subsequent runs of the test can grab the port
294 # even if it is in TIME_WAIT.
295 listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Josh Gao4db70c52018-08-08 13:08:08 -0700296 listener.bind(("127.0.0.1", 0))
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700297 listener.listen(4)
Josh Gao13781e82018-04-03 12:55:18 -0700298 port = listener.getsockname()[1]
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700299
300 # Now that listening has started, start adb emu kill, telling it to
301 # connect to our mock emulator.
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700302 proc = subprocess.Popen(
Josh Gao4db70c52018-08-08 13:08:08 -0700303 ["adb", "-s", "emulator-" + str(port), "emu", "kill"],
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700304 stderr=subprocess.STDOUT)
305
306 accepted_connection, addr = listener.accept()
307 with contextlib.closing(accepted_connection) as conn:
308 # If WSAECONNABORTED (10053) is raised by any socket calls,
309 # then adb probably isn't reading the data that we sent it.
Josh Gao4db70c52018-08-08 13:08:08 -0700310 conn.sendall(("Android Console: type 'help' for a list "
311 "of commands\r\n").encode("utf8"))
312 conn.sendall(b"OK\r\n")
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700313
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700314 with contextlib.closing(conn.makefile()) as connf:
315 line = connf.readline()
Josh Gao4db70c52018-08-08 13:08:08 -0700316 if line.startswith("auth"):
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700317 # Ignore the first auth line.
318 line = connf.readline()
Josh Gao4db70c52018-08-08 13:08:08 -0700319 self.assertEqual("kill\n", line)
320 self.assertEqual("quit\n", connf.readline())
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700321
Josh Gao4db70c52018-08-08 13:08:08 -0700322 conn.sendall(b"OK: killing emulator, bye bye\r\n")
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700323
324 # Use SO_LINGER to send TCP RST segment to test whether adb
325 # ignores WSAECONNRESET on Windows. This happens with the
326 # real emulator because it just calls exit() without closing
327 # the socket or calling shutdown(SD_SEND). At process
328 # termination, Windows sends a TCP RST segment for every
329 # open socket that shutdown(SD_SEND) wasn't used on.
330 self._reset_socket_on_close(conn)
331
332 # Wait for adb to finish, so we can check return code.
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700333 proc.communicate()
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700334
335 # If this fails, adb probably isn't ignoring WSAECONNRESET when
336 # reading the response from the adb emu kill command (on Windows).
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700337 self.assertEqual(0, proc.returncode)
338
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700339 def test_emulator_connect(self):
340 """Ensure that the emulator can connect.
341
342 Bug: http://b/78991667
343 """
344 with adb_server() as server_port:
345 with fake_adbd() as port:
Josh Gao4db70c52018-08-08 13:08:08 -0700346 serial = "emulator-{}".format(port - 1)
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700347 # Ensure that the emulator is not there.
348 try:
Josh Gao4db70c52018-08-08 13:08:08 -0700349 subprocess.check_output(["adb", "-P", str(server_port),
350 "-s", serial, "get-state"],
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700351 stderr=subprocess.STDOUT)
Josh Gao4db70c52018-08-08 13:08:08 -0700352 self.fail("Device should not be available")
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700353 except subprocess.CalledProcessError as err:
354 self.assertEqual(
355 err.output.strip(),
Josh Gao4db70c52018-08-08 13:08:08 -0700356 "error: device '{}' not found".format(serial).encode("utf8"))
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700357
358 # Let the ADB server know that the emulator has started.
359 with contextlib.closing(
Josh Gaob1df00e2018-08-07 14:31:17 -0700360 socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
Josh Gao4db70c52018-08-08 13:08:08 -0700361 sock.connect(("localhost", server_port))
362 command = "host:emulator:{}".format(port).encode("utf8")
363 sock.sendall(b"%04x%s" % (len(command), command))
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700364
365 # Ensure the emulator is there.
Josh Gao4db70c52018-08-08 13:08:08 -0700366 subprocess.check_call(["adb", "-P", str(server_port),
367 "-s", serial, "wait-for-device"])
368 output = subprocess.check_output(["adb", "-P", str(server_port),
369 "-s", serial, "get-state"])
370 self.assertEqual(output.strip(), b"device")
Luis Hector Chaveza452f0e2018-05-02 10:47:01 -0700371
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700372
373class ConnectionTest(unittest.TestCase):
374 """Tests for adb connect."""
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700375
Josh Gao50bde8d2016-09-01 14:54:18 -0700376 def test_connect_ipv4_ipv6(self):
377 """Ensure that `adb connect localhost:1234` will try both IPv4 and IPv6.
378
379 Bug: http://b/30313466
380 """
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -0700381 for protocol in (socket.AF_INET, socket.AF_INET6):
382 try:
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700383 with fake_adbd(protocol=protocol) as port:
Josh Gao4db70c52018-08-08 13:08:08 -0700384 serial = "localhost:{}".format(port)
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700385 with adb_connect(self, serial):
386 pass
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -0700387 except socket.error:
388 print("IPv6 not available, skipping")
389 continue
Josh Gao50bde8d2016-09-01 14:54:18 -0700390
Luis Hector Chavezbf8a7222018-04-17 19:25:33 -0700391 def test_already_connected(self):
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700392 """Ensure that an already-connected device stays connected."""
393
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700394 with fake_adbd() as port:
Josh Gao4db70c52018-08-08 13:08:08 -0700395 serial = "localhost:{}".format(port)
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700396 with adb_connect(self, serial):
397 # b/31250450: this always returns 0 but probably shouldn't.
Josh Gao4db70c52018-08-08 13:08:08 -0700398 output = subprocess.check_output(["adb", "connect", serial])
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700399 self.assertEqual(
Josh Gaob1df00e2018-08-07 14:31:17 -0700400 output.strip(),
Josh Gao4db70c52018-08-08 13:08:08 -0700401 "already connected to {}".format(serial).encode("utf8"))
Josh Gao50bde8d2016-09-01 14:54:18 -0700402
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700403 def test_reconnect(self):
404 """Ensure that a disconnected device reconnects."""
Josh Gao50bde8d2016-09-01 14:54:18 -0700405
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700406 with fake_adbd() as port:
Josh Gao4db70c52018-08-08 13:08:08 -0700407 serial = "localhost:{}".format(port)
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700408 with adb_connect(self, serial):
Josh Gao4db70c52018-08-08 13:08:08 -0700409 output = subprocess.check_output(["adb", "-s", serial,
410 "get-state"])
411 self.assertEqual(output.strip(), b"device")
Josh Gao13781e82018-04-03 12:55:18 -0700412
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700413 # This will fail.
Josh Gao4db70c52018-08-08 13:08:08 -0700414 proc = subprocess.Popen(["adb", "-s", serial, "shell", "true"],
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700415 stdout=subprocess.PIPE,
416 stderr=subprocess.STDOUT)
417 output, _ = proc.communicate()
Josh Gao4db70c52018-08-08 13:08:08 -0700418 self.assertEqual(output.strip(), b"error: closed")
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700419
Josh Gao4db70c52018-08-08 13:08:08 -0700420 subprocess.check_call(["adb", "-s", serial, "wait-for-device"])
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700421
Josh Gao4db70c52018-08-08 13:08:08 -0700422 output = subprocess.check_output(["adb", "-s", serial,
423 "get-state"])
424 self.assertEqual(output.strip(), b"device")
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700425
426 # Once we explicitly kick a device, it won't attempt to
427 # reconnect.
Josh Gao4db70c52018-08-08 13:08:08 -0700428 output = subprocess.check_output(["adb", "disconnect", serial])
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700429 self.assertEqual(
Josh Gaob1df00e2018-08-07 14:31:17 -0700430 output.strip(),
Josh Gao4db70c52018-08-08 13:08:08 -0700431 "disconnected {}".format(serial).encode("utf8"))
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700432 try:
Josh Gao4db70c52018-08-08 13:08:08 -0700433 subprocess.check_output(["adb", "-s", serial, "get-state"],
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700434 stderr=subprocess.STDOUT)
Josh Gao4db70c52018-08-08 13:08:08 -0700435 self.fail("Device should not be available")
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700436 except subprocess.CalledProcessError as err:
Luis Hector Chavez0aeda102018-04-20 10:31:29 -0700437 self.assertEqual(
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700438 err.output.strip(),
Josh Gao4db70c52018-08-08 13:08:08 -0700439 "error: device '{}' not found".format(serial).encode("utf8"))
Spencer Lowcc4a4b12015-10-14 17:32:44 -0700440
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700441
Dan Alberta4169f92015-07-24 17:08:33 -0700442def main():
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700443 """Main entrypoint."""
Dan Alberta4169f92015-07-24 17:08:33 -0700444 random.seed(0)
Luis Hector Chavez947b2132018-05-02 09:10:29 -0700445 unittest.main(verbosity=3)
Dan Alberta4169f92015-07-24 17:08:33 -0700446
447
Josh Gao4db70c52018-08-08 13:08:08 -0700448if __name__ == "__main__":
Dan Alberta4169f92015-07-24 17:08:33 -0700449 main()