def connectServerAndClient(test, clientFactory, serverFactory):
    """
    Create a server and a client and connect the two with an
    L{IOPump}.

    @param test: the test case where the client and server will be
        used.
    @type test: L{twisted.trial.unittest.TestCase}

    @param clientFactory: The factory that creates the client object.
    @type clientFactory: L{twisted.spread.pb.PBClientFactory}

    @param serverFactory: The factory that creates the server object.
    @type serverFactory: L{twisted.spread.pb.PBServerFactory}

    @return: a 3-tuple of (client, server, pump)
    @rtype: (L{twisted.spread.pb.Broker}, L{twisted.spread.pb.Broker},
        L{IOPump})
    """
    addr = ('127.0.0.1',)
    clientBroker = clientFactory.buildProtocol(addr)
    serverBroker = serverFactory.buildProtocol(addr)

    clientTransport = StringIO()
    serverTransport = StringIO()

    clientBroker.makeConnection(protocol.FileWrapper(clientTransport))
    serverBroker.makeConnection(protocol.FileWrapper(serverTransport))
    pump = IOPump(clientBroker, serverBroker, clientTransport, serverTransport)

    def maybeDisconnect(broker):
        if not broker.disconnected:
            broker.connectionLost(failure.Failure(main.CONNECTION_DONE))

    def disconnectClientFactory():
        # There's no connector, just a FileWrapper mediated by the
        # IOPump.  Fortunately PBClientFactory.clientConnectionLost
        # doesn't do anything with the connector so we can get away
        # with passing None here.
        clientFactory.clientConnectionLost(
            connector=None,
            reason=failure.Failure(main.CONNECTION_DONE))

    test.addCleanup(maybeDisconnect, clientBroker)
    test.addCleanup(maybeDisconnect, serverBroker)
    test.addCleanup(disconnectClientFactory)
    # Establish the connection
    pump.pump()
    return clientBroker, serverBroker, pump

    Create a server and a client and connect the two with an
    L{IOPump}.

    @param test: the test case where the client and server will be
        used.
    @type test: L{twisted.trial.unittest.TestCase}

    @param clientFactory: The factory that creates the client object.
    @type clientFactory: L{twisted.spread.pb.PBClientFactory}

    @param serverFactory: The factory that creates the server object.
    @type serverFactory: L{twisted.spread.pb.PBServerFactory}

    @return: a 3-tuple of (client, server, pump)
    @rtype: (L{twisted.spread.pb.Broker}, L{twisted.spread.pb.Broker},
        L{IOPump})
    
stackoverflow/venv/lib/python3.6/site-packages/twisted/spread/test/test_pb.py