@Test
  public void testEstablishRouteViaProxyTunnelRetryOnAuthChallengeNonPersistentConnection()
      throws Exception {
    final AuthState authState = new AuthState();
    final HttpRoute route = new HttpRoute(target, null, proxy, true);
    final HttpClientContext context = new HttpClientContext();
    final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test"));
    final HttpResponse response1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 401, "Huh?");
    final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
    response1.setEntity(EntityBuilder.create().setStream(instream1).build());
    final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");

    Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE);
    Mockito.when(
            proxyAuthStrategy.isAuthenticationRequested(
                Mockito.eq(proxy), Mockito.same(response1), Mockito.<HttpClientContext>any()))
        .thenReturn(Boolean.TRUE);
    Mockito.when(
            reuseStrategy.keepAlive(Mockito.<HttpResponse>any(), Mockito.<HttpClientContext>any()))
        .thenReturn(Boolean.FALSE);
    Mockito.when(
            requestExecutor.execute(
                Mockito.<HttpRequest>any(),
                Mockito.<HttpClientConnection>any(),
                Mockito.<HttpClientContext>any()))
        .thenReturn(response1, response2);

    mainClientExec.establishRoute(authState, managedConn, route, request, context);

    Mockito.verify(connManager).connect(managedConn, route, 0, context);
    Mockito.verify(connManager).routeComplete(managedConn, route, context);
    Mockito.verify(instream1, Mockito.never()).close();
    Mockito.verify(managedConn).close();
  }
  @Test(expected = HttpException.class)
  public void testEstablishRouteViaProxyTunnelFailure() throws Exception {
    final AuthState authState = new AuthState();
    final HttpRoute route = new HttpRoute(target, null, proxy, true);
    final HttpClientContext context = new HttpClientContext();
    final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test"));
    final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 500, "Boom");
    response.setEntity(new StringEntity("Ka-boom"));

    Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE);
    Mockito.when(
            requestExecutor.execute(
                Mockito.<HttpRequest>any(),
                Mockito.<HttpClientConnection>any(),
                Mockito.<HttpClientContext>any()))
        .thenReturn(response);

    try {
      mainClientExec.establishRoute(authState, managedConn, route, request, context);
    } catch (final TunnelRefusedException ex) {
      final HttpResponse r = ex.getResponse();
      Assert.assertEquals("Ka-boom", EntityUtils.toString(r.getEntity()));

      Mockito.verify(managedConn).close();

      throw ex;
    }
  }
  @Test
  public void testEstablishRouteDirectProxy() throws Exception {
    final AuthState authState = new AuthState();
    final HttpRoute route = new HttpRoute(target, null, proxy, false);
    final HttpClientContext context = new HttpClientContext();
    final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test"));

    Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE);

    mainClientExec.establishRoute(authState, managedConn, route, request, context);

    Mockito.verify(connManager).connect(managedConn, route, 0, context);
    Mockito.verify(connManager).routeComplete(managedConn, route, context);
  }
  @Test(expected = HttpException.class)
  public void testEstablishRouteViaProxyTunnelUnexpectedResponse() throws Exception {
    final AuthState authState = new AuthState();
    final HttpRoute route = new HttpRoute(target, null, proxy, true);
    final HttpClientContext context = new HttpClientContext();
    final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test"));
    final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 101, "Lost");

    Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE);
    Mockito.when(
            requestExecutor.execute(
                Mockito.<HttpRequest>any(),
                Mockito.<HttpClientConnection>any(),
                Mockito.<HttpClientContext>any()))
        .thenReturn(response);

    mainClientExec.establishRoute(authState, managedConn, route, request, context);
  }
  @Test(expected = HttpException.class)
  public void testEstablishRouteViaProxyTunnelMultipleHops() throws Exception {
    final AuthState authState = new AuthState();
    final HttpHost proxy1 = new HttpHost("this", 8888);
    final HttpHost proxy2 = new HttpHost("that", 8888);
    final HttpRoute route =
        new HttpRoute(
            target,
            null,
            new HttpHost[] {proxy1, proxy2},
            true,
            RouteInfo.TunnelType.TUNNELLED,
            RouteInfo.LayerType.LAYERED);
    final HttpClientContext context = new HttpClientContext();
    final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test"));

    Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE);

    mainClientExec.establishRoute(authState, managedConn, route, request, context);
  }
  @Test
  public void testEstablishRouteViaProxyTunnel() throws Exception {
    final AuthState authState = new AuthState();
    final HttpRoute route = new HttpRoute(target, null, proxy, true);
    final HttpClientContext context = new HttpClientContext();
    final RequestConfig config = RequestConfig.custom().setConnectTimeout(321).build();
    context.setRequestConfig(config);
    final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("http://bar/test"));
    final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");

    Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE);
    Mockito.when(
            requestExecutor.execute(
                Mockito.<HttpRequest>any(),
                Mockito.<HttpClientConnection>any(),
                Mockito.<HttpClientContext>any()))
        .thenReturn(response);

    mainClientExec.establishRoute(authState, managedConn, route, request, context);

    Mockito.verify(connManager).connect(managedConn, route, 321, context);
    Mockito.verify(connManager).routeComplete(managedConn, route, context);
    final ArgumentCaptor<HttpRequest> reqCaptor = ArgumentCaptor.forClass(HttpRequest.class);
    Mockito.verify(requestExecutor)
        .execute(reqCaptor.capture(), Mockito.same(managedConn), Mockito.same(context));
    final HttpRequest connect = reqCaptor.getValue();
    Assert.assertNotNull(connect);
    Assert.assertEquals("CONNECT", connect.getRequestLine().getMethod());
    Assert.assertEquals(HttpVersion.HTTP_1_1, connect.getRequestLine().getProtocolVersion());
    Assert.assertEquals("foo:80", connect.getRequestLine().getUri());
  }