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() # We just need an unused TCP port host, port, sock = get_socket(sock_options=(socket.SO_REUSEADDR, )) sock.close() 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.daemon = True 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)
def test_concurrent_propagation(self): _THREAD_COUNT = 32 _RPC_COUNT = 32 set_up_expected_context() with _server() as port: target = "localhost:{}".format(port) local_credentials = grpc.local_channel_credentials() test_call_credentials = TestCallCredentials() call_credentials = grpc.metadata_call_credentials( test_call_credentials, "test call credentials") composite_credentials = grpc.composite_channel_credentials( local_credentials, call_credentials) wait_group = test_common.WaitGroup(_THREAD_COUNT) def _run_on_thread(exception_queue): try: with grpc.secure_channel(target, composite_credentials) as channel: stub = channel.unary_unary(_UNARY_UNARY) wait_group.done() wait_group.wait() for i in range(_RPC_COUNT): response = stub(_REQUEST, wait_for_ready=True) self.assertEqual(_REQUEST, response) except Exception as e: # pylint: disable=broad-except exception_queue.put(e) threads = [] for _ in range(_THREAD_COUNT): q = queue.Queue() thread = threading.Thread(target=_run_on_thread, args=(q, )) thread.setDaemon(True) thread.start() threads.append((thread, q)) for thread, q in threads: thread.join() if not q.empty(): raise q.get()