예제 #1
0
    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)
예제 #2
0
    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()