'L{Agent} will make a TCP connection, send an HTTP request, and return a
L{Deferred} that fires when the response has been received.
@param hostName: The hostname to interpolate into the URL to be
requested.
@type hostName: L{bytes}
@param expectedAddress: The expected address string.
@type expectedAddress: L{bytes}
@param addressType: The class to construct an address out of.
@type addressType: L{type}
@param serverWrapper: A callable that takes a protocol factory and
returns a protocol factory; used to wrap the server / responder
side in a TLS server.
@type serverWrapper:
serverWrapper(L{twisted.internet.interfaces.IProtocolFactory}) ->
L{twisted.internet.interfaces.IProtocolFactory}
@param createAgent: A callable that takes a reactor and produces an
L{IAgent}; used to construct an agent with an appropriate trust
root for TLS.
@type createAgent: createAgent(reactor) -> L{IAgent}
@param scheme: The scheme to test, C{http} or C{https}
@type scheme: L{bytes}'

def integrationTest(self, hostName, expectedAddress, addressType, serverWrapper=(lambda server: server), createAgent=client.Agent, scheme='http'):

    reactor = self.createReactor()
    agent = createAgent(reactor)
    deferred = agent.request('GET', (((scheme + '://') + hostName) + '/'))
    (host, port, factory, timeout, bind) = reactor.tcpClients[0]
    self.assertEqual(host, expectedAddress)
    peerAddress = addressType('TCP', host, port)
    clientProtocol = factory.buildProtocol(peerAddress)
    clientTransport = FakeTransport(clientProtocol, False, peerAddress=peerAddress)
    clientProtocol.makeConnection(clientTransport)
    @Factory.forProtocol
    def accumulator():
        ap = AccumulatingProtocol()
        accumulator.currentProtocol = ap
        return ap
    accumulator.currentProtocol = None
    accumulator.protocolConnectionMade = None
    wrapper = serverWrapper(accumulator).buildProtocol(None)
    serverTransport = FakeTransport(wrapper, True)
    wrapper.makeConnection(serverTransport)
    pump = IOPump(clientProtocol, wrapper, clientTransport, serverTransport, False)
    pump.flush()
    lines = accumulator.currentProtocol.data.split('\r\n')
    self.assertTrue(lines[0].startswith('GET    /    HTTP'))
    headers = dict([line.split(':    ', 1) for line in lines[1:] if line])
    self.assertEqual(headers['Host'], hostName)
    self.assertNoResult(deferred)
    accumulator.currentProtocol.transport.write('HTTP/1.1    200    OK\r\nX-An-Header:    an-value\r\n\r\nContent-length:    12\r\n\r\nhello    world!')
    pump.flush()
    response = self.successResultOf(deferred)
    self.assertEquals(response.headers.getRawHeaders('x-an-header')[0], 'an-value')
