def test_reconnect(self): server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY) handler = grpc.method_handlers_generic_handler('test', { 'UnaryUnary': grpc.unary_unary_rpc_method_handler(_handle_unary_unary) }) options = (('grpc.so_reuseport', 1),) with bound_socket() as (host, port): addr = '{}:{}'.format(host, port) server = grpc.server(server_pool, (handler,), options=options) server.add_insecure_port(addr) server.start() channel = grpc.insecure_channel(addr) multi_callable = channel.unary_unary(_UNARY_UNARY) self.assertEqual(_RESPONSE, multi_callable(_REQUEST)) server.stop(None) # By default, the channel connectivity is checked every 5s # GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS can be set to change # this. time.sleep(5.1) server = grpc.server(server_pool, (handler,), options=options) server.add_insecure_port(addr) server.start() self.assertEqual(_RESPONSE, multi_callable(_REQUEST)) server.stop(None) channel.close()
def test_call_wait_for_ready_enabled(self): # To test the wait mechanism, Python thread is required to make # client set up first without handling them case by case. # Also, Python thread don't pass the unhandled exceptions to # main thread. So, it need another method to store the # exceptions and raise them again in main thread. unhandled_exceptions = queue.Queue() with bound_socket(listen=False) as (host, port): addr = '{}:{}'.format(host, port) wg = test_common.WaitGroup(len(_ALL_CALL_CASES)) def wait_for_transient_failure(channel_connectivity): if channel_connectivity == grpc.ChannelConnectivity.TRANSIENT_FAILURE: wg.done() def test_call(perform_call): with grpc.insecure_channel(addr) as channel: try: channel.subscribe(wait_for_transient_failure) perform_call(channel, wait_for_ready=True) except BaseException as e: # pylint: disable=broad-except # If the call failed, the thread would be destroyed. The # channel object can be collected before calling the # callback, which will result in a deadlock. wg.done() unhandled_exceptions.put(e, True) test_threads = [] for perform_call in _ALL_CALL_CASES: test_thread = threading.Thread(target=test_call, args=(perform_call, )) test_thread.exception = None test_thread.start() test_threads.append(test_thread) # Start the server after the connections are waiting wg.wait() server = test_common.test_server(reuse_port=True) server.add_generic_rpc_handlers( (_GenericHandler(weakref.proxy(self)), )) server.add_insecure_port(addr) server.start() for test_thread in test_threads: test_thread.join() # Stop the server to make test end properly server.stop(0) if not unhandled_exceptions.empty(): raise unhandled_exceptions.get(True)
async def test_if_reuse_port_enabled(server: aio.Server): port = server.add_insecure_port('localhost:0') await server.start() try: with common.bound_socket( bind_address='localhost', port=port, listen=False, ) as (unused_host, bound_port): assert bound_port == port except OSError as e: assert 'Address already in use' in str(e) return False else: return True
async def test_if_reuse_port_enabled(server: aio.Server): port = server.add_insecure_port('localhost:0') await server.start() try: with common.bound_socket( bind_address='localhost', port=port, listen=False, ) as (unused_host, bound_port): assert bound_port == port except OSError as e: if e.errno in _ADDRESS_TOKEN_ERRNO: return False else: logging.exception(e) raise else: return True
def create_dummy_channel(): """Creating dummy channels is a workaround for retries""" with bound_socket() as (host, port): return grpc.insecure_channel('{}:{}'.format(host, port))