diff options
author | Luis Hector Chavez | 2018-04-17 21:25:33 -0500 |
---|---|---|
committer | Luis Hector Chavez | 2018-04-17 23:49:43 -0500 |
commit | 8b67c520998c6fca95c62fdd864e42647cb8da49 (patch) | |
tree | f83749f4f558a3733ddd3fc9bd7ac513301a3f32 | |
parent | 5d3958525543d4be02c4530dba9aab964623755d (diff) | |
download | platform-system-core-8b67c520998c6fca95c62fdd864e42647cb8da49.tar.gz platform-system-core-8b67c520998c6fca95c62fdd864e42647cb8da49.tar.xz platform-system-core-8b67c520998c6fca95c62fdd864e42647cb8da49.zip |
Improve test_adb.py
This change uses a context manager to create the fake ADB servers (and
cleanly tear them down.
Bug: 74411879
Test: python system/core/adb/test_adb.py
Change-Id: I722d2c4135259b1b0ef00a1510aa8402e87ecf72
-rw-r--r-- | adb/test_adb.py | 97 |
1 files changed, 66 insertions, 31 deletions
diff --git a/adb/test_adb.py b/adb/test_adb.py index 3bb433ddd..363002f8d 100644 --- a/adb/test_adb.py +++ b/adb/test_adb.py | |||
@@ -21,9 +21,11 @@ things. Most of these tests involve specific error messages or the help text. | |||
21 | """ | 21 | """ |
22 | from __future__ import print_function | 22 | from __future__ import print_function |
23 | 23 | ||
24 | import binascii | ||
24 | import contextlib | 25 | import contextlib |
25 | import os | 26 | import os |
26 | import random | 27 | import random |
28 | import select | ||
27 | import socket | 29 | import socket |
28 | import struct | 30 | import struct |
29 | import subprocess | 31 | import subprocess |
@@ -33,6 +35,52 @@ import unittest | |||
33 | import adb | 35 | import adb |
34 | 36 | ||
35 | 37 | ||
38 | @contextlib.contextmanager | ||
39 | def fake_adb_server(protocol=socket.AF_INET, port=0): | ||
40 | """Creates a fake ADB server that just replies with a CNXN packet.""" | ||
41 | |||
42 | serversock = socket.socket(protocol, socket.SOCK_STREAM) | ||
43 | if protocol == socket.AF_INET: | ||
44 | serversock.bind(('127.0.0.1', port)) | ||
45 | else: | ||
46 | serversock.bind(('::1', port)) | ||
47 | serversock.listen(1) | ||
48 | |||
49 | # A pipe that is used to signal the thread that it should terminate. | ||
50 | readpipe, writepipe = os.pipe() | ||
51 | |||
52 | def _handle(): | ||
53 | rlist = [readpipe, serversock] | ||
54 | while True: | ||
55 | ready, _, _ = select.select(rlist, [], []) | ||
56 | for r in ready: | ||
57 | if r == readpipe: | ||
58 | # Closure pipe | ||
59 | os.close(r) | ||
60 | serversock.shutdown(socket.SHUT_RDWR) | ||
61 | serversock.close() | ||
62 | return | ||
63 | elif r == serversock: | ||
64 | # Server socket | ||
65 | conn, _ = r.accept() | ||
66 | rlist.append(conn) | ||
67 | else: | ||
68 | # Client socket | ||
69 | data = r.recv(1024) | ||
70 | if not data: | ||
71 | rlist.remove(r) | ||
72 | |||
73 | port = serversock.getsockname()[1] | ||
74 | server_thread = threading.Thread(target=_handle) | ||
75 | server_thread.start() | ||
76 | |||
77 | try: | ||
78 | yield port | ||
79 | finally: | ||
80 | os.close(writepipe) | ||
81 | server_thread.join() | ||
82 | |||
83 | |||
36 | class NonApiTest(unittest.TestCase): | 84 | class NonApiTest(unittest.TestCase): |
37 | """Tests for ADB that aren't a part of the AndroidDevice API.""" | 85 | """Tests for ADB that aren't a part of the AndroidDevice API.""" |
38 | 86 | ||
@@ -211,45 +259,32 @@ class NonApiTest(unittest.TestCase): | |||
211 | 259 | ||
212 | Bug: http://b/30313466 | 260 | Bug: http://b/30313466 |
213 | """ | 261 | """ |
214 | ipv4 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | 262 | for protocol in (socket.AF_INET, socket.AF_INET6): |
215 | ipv4.bind(('127.0.0.1', 0)) | 263 | try: |
216 | ipv4.listen(1) | 264 | with fake_adb_server(protocol=protocol) as port: |
265 | output = subprocess.check_output( | ||
266 | ['adb', 'connect', 'localhost:{}'.format(port)]) | ||
267 | |||
268 | self.assertEqual( | ||
269 | output.strip(), 'connected to localhost:{}'.format(port)) | ||
270 | except socket.error: | ||
271 | print("IPv6 not available, skipping") | ||
272 | continue | ||
217 | 273 | ||
218 | ipv6 = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) | 274 | def test_already_connected(self): |
219 | try: | 275 | with fake_adb_server() as port: |
220 | ipv6.bind(('::1', ipv4.getsockname()[1] + 1)) | ||
221 | ipv6.listen(1) | ||
222 | except socket.error: | ||
223 | print("IPv6 not available, skipping") | ||
224 | return | ||
225 | |||
226 | for s in (ipv4, ipv6): | ||
227 | port = s.getsockname()[1] | ||
228 | output = subprocess.check_output( | 276 | output = subprocess.check_output( |
229 | ['adb', 'connect', 'localhost:{}'.format(port)]) | 277 | ['adb', 'connect', 'localhost:{}'.format(port)]) |
230 | 278 | ||
231 | self.assertEqual( | 279 | self.assertEqual( |
232 | output.strip(), 'connected to localhost:{}'.format(port)) | 280 | output.strip(), 'connected to localhost:{}'.format(port)) |
233 | s.close() | ||
234 | 281 | ||
235 | def test_already_connected(self): | 282 | # b/31250450: this always returns 0 but probably shouldn't. |
236 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | 283 | output = subprocess.check_output( |
237 | s.bind(('127.0.0.1', 0)) | 284 | ['adb', 'connect', 'localhost:{}'.format(port)]) |
238 | s.listen(2) | ||
239 | |||
240 | port = s.getsockname()[1] | ||
241 | output = subprocess.check_output( | ||
242 | ['adb', 'connect', 'localhost:{}'.format(port)]) | ||
243 | |||
244 | self.assertEqual( | ||
245 | output.strip(), 'connected to localhost:{}'.format(port)) | ||
246 | |||
247 | # b/31250450: this always returns 0 but probably shouldn't. | ||
248 | output = subprocess.check_output( | ||
249 | ['adb', 'connect', 'localhost:{}'.format(port)]) | ||
250 | 285 | ||
251 | self.assertEqual( | 286 | self.assertEqual( |
252 | output.strip(), 'already connected to localhost:{}'.format(port)) | 287 | output.strip(), 'already connected to localhost:{}'.format(port)) |
253 | 288 | ||
254 | def main(): | 289 | def main(): |
255 | random.seed(0) | 290 | random.seed(0) |