aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/python/grpcio_tests/tests/unit/_reconnect_test.py
diff options
context:
space:
mode:
authorGravatar Mehrdad Afshari <mehrdada@users.noreply.github.com>2017-12-20 19:16:18 -0800
committerGravatar Mehrdad Afshari <mehrdada@users.noreply.github.com>2017-12-20 22:51:02 -0800
commit271b042c4dfa2d599e1e5b6920fb996798eac631 (patch)
treeb66118d233a503d2dd946893917df5bed4bbb33a /src/python/grpcio_tests/tests/unit/_reconnect_test.py
parent247a05e4b36a27c2a7028e740ca282156272bcc1 (diff)
Fix port picking logic in Python tests
Diffstat (limited to 'src/python/grpcio_tests/tests/unit/_reconnect_test.py')
-rw-r--r--src/python/grpcio_tests/tests/unit/_reconnect_test.py53
1 files changed, 41 insertions, 12 deletions
diff --git a/src/python/grpcio_tests/tests/unit/_reconnect_test.py b/src/python/grpcio_tests/tests/unit/_reconnect_test.py
index 1e0894f638..10aee9fb4f 100644
--- a/src/python/grpcio_tests/tests/unit/_reconnect_test.py
+++ b/src/python/grpcio_tests/tests/unit/_reconnect_test.py
@@ -31,6 +31,44 @@ def _handle_unary_unary(unused_request, unused_servicer_context):
return _RESPONSE
+def _get_reuse_socket_option():
+ try:
+ return socket.SO_REUSEPORT
+ except AttributeError:
+ # SO_REUSEPORT is unavailable on Windows, but SO_REUSEADDR
+ # allows forcibly re-binding to a port
+ return socket.SO_REUSEADDR
+
+
+def _pick_and_bind_port(sock_opt):
+ # Reserve a port, when we restart the server we want
+ # to hold onto the port
+ port = 0
+ for address_family in (socket.AF_INET6, socket.AF_INET):
+ try:
+ s = socket.socket(address_family, socket.SOCK_STREAM)
+ except socket.error:
+ continue # this address family is unavailable
+ s.setsockopt(socket.SOL_SOCKET, sock_opt, 1)
+ try:
+ s.bind(('localhost', port))
+ # for socket.SOCK_STREAM sockets, it is necessary to call
+ # listen to get the desired behavior.
+ s.listen(1)
+ port = s.getsockname()[1]
+ except socket.error:
+ # port was not available on the current address family
+ # try again
+ port = 0
+ break
+ finally:
+ s.close()
+ if s:
+ return port if port != 0 else _pick_and_bind_port(sock_opt)
+ else:
+ return None # no address family was available
+
+
class ReconnectTest(unittest.TestCase):
def test_reconnect(self):
@@ -39,18 +77,9 @@ class ReconnectTest(unittest.TestCase):
'UnaryUnary':
grpc.unary_unary_rpc_method_handler(_handle_unary_unary)
})
- # Reserve a port, when we restart the server we want
- # to hold onto the port
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- opt = socket.SO_REUSEPORT
- except AttributeError:
- # SO_REUSEPORT is unavailable on Windows, but SO_REUSEADDR
- # allows forcibly re-binding to a port
- opt = socket.SO_REUSEADDR
- s.setsockopt(socket.SOL_SOCKET, opt, 1)
- s.bind(('localhost', 0))
- port = s.getsockname()[1]
+ sock_opt = _get_reuse_socket_option()
+ port = _pick_and_bind_port(sock_opt)
+ self.assertIsNotNone(port)
server = grpc.server(server_pool, (handler,))
server.add_insecure_port('[::]:{}'.format(port))