You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/09/02 15:28:05 UTC
[05/17] httpcomponents-client git commit: Moved classes and renamed
packages (no functional changes)
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestCloseableHttpClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestCloseableHttpClient.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestCloseableHttpClient.java
new file mode 100644
index 0000000..f75a394
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestCloseableHttpClient.java
@@ -0,0 +1,182 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Simple tests for {@link CloseableHttpClient}.
+ */
+@SuppressWarnings({"boxing","static-access"}) // test code
+public class TestCloseableHttpClient {
+
+ static abstract class NoopCloseableHttpClient extends CloseableHttpClient {
+
+ @Override
+ protected CloseableHttpResponse doExecute(
+ final HttpHost target,
+ final ClassicHttpRequest request,
+ final HttpContext context) throws IOException {
+ return null;
+ }
+
+ }
+
+ private NoopCloseableHttpClient client;
+ private InputStream content;
+ private HttpEntity entity;
+ private ClassicHttpResponse originResponse;
+ private CloseableHttpResponse response;
+
+ @Before
+ public void setup() throws Exception {
+ content = Mockito.mock(InputStream.class);
+ entity = Mockito.mock(HttpEntity.class);
+ originResponse = Mockito.mock(ClassicHttpResponse.class);
+ response = CloseableHttpResponse.adapt(originResponse);
+ Mockito.when(entity.getContent()).thenReturn(content);
+ Mockito.when(entity.isStreaming()).thenReturn(Boolean.TRUE);
+ Mockito.when(response.getEntity()).thenReturn(entity);
+ client = Mockito.mock(NoopCloseableHttpClient.class, Mockito.CALLS_REAL_METHODS);
+ }
+
+ @Test
+ public void testExecuteRequestAbsoluteURI() throws Exception {
+ final HttpGet httpget = new HttpGet("https://somehost:444/stuff");
+ client.execute(httpget);
+
+ Mockito.verify(client).doExecute(
+ Mockito.eq(new HttpHost("somehost", 444, "https")),
+ Mockito.same(httpget),
+ (HttpContext) Mockito.isNull());
+ }
+
+ @Test
+ public void testExecuteRequestRelativeURI() throws Exception {
+ final HttpGet httpget = new HttpGet("/stuff");
+ client.execute(httpget);
+
+ Mockito.verify(client).doExecute(
+ (HttpHost) Mockito.isNull(),
+ Mockito.same(httpget),
+ (HttpContext) Mockito.isNull());
+ }
+
+ @Test
+ public void testExecuteRequest() throws Exception {
+ final HttpGet httpget = new HttpGet("https://somehost:444/stuff");
+
+ Mockito.when(client.doExecute(
+ new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response);
+
+ final CloseableHttpResponse result = client.execute(httpget);
+ Assert.assertSame(response, result);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testExecuteRequestHandleResponse() throws Exception {
+ final HttpGet httpget = new HttpGet("https://somehost:444/stuff");
+
+ Mockito.when(client.doExecute(
+ new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response);
+
+ final HttpClientResponseHandler<HttpResponse> handler = Mockito.mock(HttpClientResponseHandler.class);
+
+ client.execute(httpget, handler);
+
+ Mockito.verify(client).doExecute(
+ Mockito.eq(new HttpHost("somehost", 444, "https")),
+ Mockito.same(httpget),
+ (HttpContext) Mockito.isNull());
+ Mockito.verify(handler).handleResponse(response);
+ Mockito.verify(content).close();
+ }
+
+ @Test(expected=IOException.class)
+ @SuppressWarnings("unchecked")
+ public void testExecuteRequestHandleResponseIOException() throws Exception {
+ final HttpGet httpget = new HttpGet("https://somehost:444/stuff");
+
+ Mockito.when(client.doExecute(
+ new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response);
+
+ final HttpClientResponseHandler<HttpResponse> handler = Mockito.mock(HttpClientResponseHandler.class);
+
+ Mockito.when(handler.handleResponse(response)).thenThrow(new IOException());
+
+ try {
+ client.execute(httpget, handler);
+ } catch (final IOException ex) {
+ Mockito.verify(client).doExecute(
+ Mockito.eq(new HttpHost("somehost", 444, "https")),
+ Mockito.same(httpget),
+ (HttpContext) Mockito.isNull());
+ Mockito.verify(originResponse).close();
+ throw ex;
+ }
+ }
+
+ @Test(expected=RuntimeException.class)
+ @SuppressWarnings("unchecked")
+ public void testExecuteRequestHandleResponseHttpException() throws Exception {
+ final HttpGet httpget = new HttpGet("https://somehost:444/stuff");
+
+ Mockito.when(client.doExecute(
+ new HttpHost("somehost", 444, "https"), httpget, null)).thenReturn(response);
+
+ final HttpClientResponseHandler<HttpResponse> handler = Mockito.mock(HttpClientResponseHandler.class);
+
+ Mockito.when(handler.handleResponse(response)).thenThrow(new RuntimeException());
+
+ try {
+ client.execute(httpget, handler);
+ } catch (final RuntimeException ex) {
+ Mockito.verify(client).doExecute(
+ Mockito.eq(new HttpHost("somehost", 444, "https")),
+ Mockito.same(httpget),
+ (HttpContext) Mockito.isNull());
+ Mockito.verify(response).close();
+ throw ex;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java
new file mode 100644
index 0000000..4f5d8be
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java
@@ -0,0 +1,359 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.hc.client5.http.AuthenticationStrategy;
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.RouteInfo;
+import org.apache.hc.client5.http.auth.AuthChallenge;
+import org.apache.hc.client5.http.auth.AuthScheme;
+import org.apache.hc.client5.http.auth.AuthScope;
+import org.apache.hc.client5.http.auth.ChallengeType;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hc.client5.http.classic.ExecChain;
+import org.apache.hc.client5.http.classic.ExecRuntime;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.entity.EntityBuilder;
+import org.apache.hc.client5.http.impl.TunnelRefusedException;
+import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
+import org.apache.hc.client5.http.impl.auth.BasicScheme;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ConnectionReuseStrategy;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+@SuppressWarnings({"boxing","static-access"}) // test code
+public class TestConnectExec {
+
+ @Mock
+ private ConnectionReuseStrategy reuseStrategy;
+ @Mock
+ private HttpProcessor proxyHttpProcessor;
+ @Mock
+ private AuthenticationStrategy proxyAuthStrategy;
+ @Mock
+ private ExecRuntime execRuntime;
+ @Mock
+ private ExecChain execChain;
+
+ private ConnectExec exec;
+ private HttpHost target;
+ private HttpHost proxy;
+
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ exec = new ConnectExec(reuseStrategy, proxyHttpProcessor, proxyAuthStrategy);
+ target = new HttpHost("foo", 80);
+ proxy = new HttpHost("bar", 8888);
+ }
+
+ @Test
+ public void testExecAcquireConnection() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ response.setEntity(EntityBuilder.create()
+ .setStream(new ByteArrayInputStream(new byte[]{}))
+ .build());
+ context.setUserToken("Blah");
+
+ Mockito.when(execRuntime.isConnectionAcquired()).thenReturn(false);
+ Mockito.when(execRuntime.execute(
+ Mockito.same(request),
+ Mockito.<HttpClientContext>any())).thenReturn(response);
+ Mockito.when(reuseStrategy.keepAlive(
+ Mockito.same(request),
+ Mockito.same(response),
+ Mockito.<HttpClientContext>any())).thenReturn(false);
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ exec.execute(request, scope, execChain);
+ Mockito.verify(execRuntime).acquireConnection(route, "Blah", context);
+ Mockito.verify(execRuntime).connect(context);
+ }
+
+ @Test
+ public void testEstablishDirectRoute() throws Exception {
+ final HttpRoute route = new HttpRoute(target);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(execRuntime).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(execRuntime.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ exec.execute(request, scope, execChain);
+
+ Mockito.verify(execRuntime).connect(context);
+ Mockito.verify(execRuntime, Mockito.never()).execute(Mockito.<ClassicHttpRequest>any(), Mockito.<HttpClientContext>any());
+ }
+
+ @Test
+ public void testEstablishRouteDirectProxy() throws Exception {
+ final HttpRoute route = new HttpRoute(target, null, proxy, false);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(execRuntime).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(execRuntime.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ exec.execute(request, scope, execChain);
+
+ Mockito.verify(execRuntime).connect(context);
+ Mockito.verify(execRuntime, Mockito.never()).execute(Mockito.<ClassicHttpRequest>any(), Mockito.<HttpClientContext>any());
+ }
+
+ @Test
+ public void testEstablishRouteViaProxyTunnel() throws Exception {
+ final HttpRoute route = new HttpRoute(target, null, proxy, true);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(execRuntime).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(execRuntime.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+ Mockito.when(execRuntime.execute(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(response);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ exec.execute(request, scope, execChain);
+
+ Mockito.verify(execRuntime).connect(context);
+ final ArgumentCaptor<ClassicHttpRequest> reqCaptor = ArgumentCaptor.forClass(ClassicHttpRequest.class);
+ Mockito.verify(execRuntime).execute(
+ reqCaptor.capture(),
+ Mockito.same(context));
+ final HttpRequest connect = reqCaptor.getValue();
+ Assert.assertNotNull(connect);
+ Assert.assertEquals("CONNECT", connect.getMethod());
+ Assert.assertEquals(HttpVersion.HTTP_1_1, connect.getVersion());
+ Assert.assertEquals("foo:80", connect.getRequestUri());
+ }
+
+ @Test(expected = HttpException.class)
+ public void testEstablishRouteViaProxyTunnelUnexpectedResponse() throws Exception {
+ final HttpRoute route = new HttpRoute(target, null, proxy, true);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(101, "Lost");
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(execRuntime).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(execRuntime.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+ Mockito.when(execRuntime.execute(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(response);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ exec.execute(request, scope, execChain);
+ }
+
+ @Test(expected = HttpException.class)
+ public void testEstablishRouteViaProxyTunnelFailure() throws Exception {
+ final HttpRoute route = new HttpRoute(target, null, proxy, true);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(500, "Boom");
+ response.setEntity(new StringEntity("Ka-boom"));
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(execRuntime).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(execRuntime.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+ Mockito.when(execRuntime.execute(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(response);
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ try {
+ exec.execute(request, scope, execChain);
+ } catch (final TunnelRefusedException ex) {
+ Assert.assertEquals("Ka-boom", ex.getResponseMessage());
+ Mockito.verify(execRuntime).disconnect();
+ Mockito.verify(execRuntime).discardConnection();
+ throw ex;
+ }
+ }
+
+ @Test
+ public void testEstablishRouteViaProxyTunnelRetryOnAuthChallengePersistentConnection() throws Exception {
+ final HttpRoute route = new HttpRoute(target, null, proxy, true);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response1 = new BasicClassicHttpResponse(407, "Huh?");
+ response1.setHeader(HttpHeaders.PROXY_AUTHENTICATE, "Basic realm=test");
+ final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
+ response1.setEntity(EntityBuilder.create()
+ .setStream(instream1)
+ .build());
+ final ClassicHttpResponse response2 = new BasicClassicHttpResponse(200, "OK");
+
+ final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials("user", "pass".toCharArray()));
+ context.setCredentialsProvider(credentialsProvider);
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(execRuntime).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(execRuntime.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+ Mockito.when(reuseStrategy.keepAlive(
+ Mockito.same(request),
+ Mockito.<HttpResponse>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
+ Mockito.when(execRuntime.execute(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(response1, response2);
+
+ Mockito.when(proxyAuthStrategy.select(
+ Mockito.eq(ChallengeType.PROXY),
+ Mockito.<Map<String, AuthChallenge>>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>singletonList(new BasicScheme()));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ exec.execute(request, scope, execChain);
+
+ Mockito.verify(execRuntime).connect(context);
+ Mockito.verify(instream1).close();
+ }
+
+ @Test
+ public void testEstablishRouteViaProxyTunnelRetryOnAuthChallengeNonPersistentConnection() throws Exception {
+ final HttpRoute route = new HttpRoute(target, null, proxy, true);
+ final HttpClientContext context = new HttpClientContext();
+ final ClassicHttpRequest request = new HttpGet("http://bar/test");
+ final ClassicHttpResponse response1 = new BasicClassicHttpResponse(407, "Huh?");
+ response1.setHeader(HttpHeaders.PROXY_AUTHENTICATE, "Basic realm=test");
+ final InputStream instream1 = Mockito.spy(new ByteArrayInputStream(new byte[] {1, 2, 3}));
+ response1.setEntity(EntityBuilder.create()
+ .setStream(instream1)
+ .build());
+ final ClassicHttpResponse response2 = new BasicClassicHttpResponse(200, "OK");
+
+ final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials("user", "pass".toCharArray()));
+ context.setCredentialsProvider(credentialsProvider);
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(execRuntime).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(execRuntime.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+ Mockito.when(reuseStrategy.keepAlive(
+ Mockito.same(request),
+ Mockito.<HttpResponse>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(Boolean.FALSE);
+ Mockito.when(execRuntime.execute(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(response1, response2);
+
+ Mockito.when(proxyAuthStrategy.select(
+ Mockito.eq(ChallengeType.PROXY),
+ Mockito.<Map<String, AuthChallenge>>any(),
+ Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>singletonList(new BasicScheme()));
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ exec.execute(request, scope, execChain);
+
+ Mockito.verify(execRuntime).connect(context);
+ Mockito.verify(instream1, Mockito.never()).close();
+ Mockito.verify(execRuntime).disconnect();
+ }
+
+ @Test(expected = HttpException.class)
+ public void testEstablishRouteViaProxyTunnelMultipleHops() throws Exception {
+ 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 ClassicHttpRequest request = new HttpGet("http://bar/test");
+
+ final ConnectionState connectionState = new ConnectionState();
+ Mockito.doAnswer(connectionState.connectAnswer()).when(execRuntime).connect(Mockito.<HttpClientContext>any());
+ Mockito.when(execRuntime.isConnected()).thenAnswer(connectionState.isConnectedAnswer());
+
+ final ExecChain.Scope scope = new ExecChain.Scope(route, request, execRuntime, context);
+ exec.execute(request, scope, execChain);
+ }
+
+ static class ConnectionState {
+
+ private boolean connected;
+
+ public Answer connectAnswer() {
+
+ return new Answer() {
+
+ @Override
+ public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
+ connected = true;
+ return null;
+ }
+
+ };
+ }
+
+ public Answer<Boolean> isConnectedAnswer() {
+
+ return new Answer<Boolean>() {
+
+ @Override
+ public Boolean answer(final InvocationOnMock invocationOnMock) throws Throwable {
+ return connected;
+ }
+
+ };
+
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestContentCompressionExec.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestContentCompressionExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestContentCompressionExec.java
new file mode 100644
index 0000000..950b6fb
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestContentCompressionExec.java
@@ -0,0 +1,229 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.StandardMethods;
+import org.apache.hc.client5.http.classic.ExecChain;
+import org.apache.hc.client5.http.classic.ExecRuntime;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.entity.DecompressingEntity;
+import org.apache.hc.client5.http.entity.GzipDecompressingEntity;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
+import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TestContentCompressionExec {
+
+ @Mock
+ private ExecRuntime execRuntime;
+ @Mock
+ private ExecChain execChain;
+ @Mock
+ private ClassicHttpRequest originaRequest;
+
+ private HttpClientContext context;
+ private HttpHost host;
+ private ExecChain.Scope scope;
+ private ContentCompressionExec impl;
+
+ @Before
+ public void setup() {
+ host = new HttpHost("somehost", 80);
+ context = HttpClientContext.create();
+ scope = new ExecChain.Scope(new HttpRoute(host), originaRequest, execRuntime, context);
+ impl = new ContentCompressionExec();
+ }
+
+
+ @Test
+ public void testContentEncodingNoEntity() throws Exception {
+ final ClassicHttpRequest request = new BasicClassicHttpRequest(StandardMethods.GET.name(), host, "/");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+
+ Mockito.when(execChain.proceed(request, scope)).thenReturn(response);
+
+ impl.execute(request, scope, execChain);
+
+ final HttpEntity entity = response.getEntity();
+ Assert.assertNull(entity);
+ }
+
+ @Test
+ public void testNoContentEncoding() throws Exception {
+ final ClassicHttpRequest request = new BasicClassicHttpRequest(StandardMethods.GET.name(), host, "/");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ final StringEntity original = new StringEntity("plain stuff");
+ response.setEntity(original);
+
+ Mockito.when(execChain.proceed(request, scope)).thenReturn(response);
+
+ impl.execute(request, scope, execChain);
+
+ final HttpEntity entity = response.getEntity();
+ Assert.assertNotNull(entity);
+ Assert.assertTrue(entity instanceof StringEntity);
+ }
+
+ @Test
+ public void testGzipContentEncoding() throws Exception {
+ final ClassicHttpRequest request = new BasicClassicHttpRequest(StandardMethods.GET.name(), host, "/");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ final StringEntity original = new StringEntity("encoded stuff");
+ original.setContentEncoding("GZip");
+ response.setEntity(original);
+
+ Mockito.when(execChain.proceed(request, scope)).thenReturn(response);
+
+ impl.execute(request, scope, execChain);
+
+ final HttpEntity entity = response.getEntity();
+ Assert.assertNotNull(entity);
+ Assert.assertTrue(entity instanceof DecompressingEntity);
+ }
+
+ @Test
+ public void testGzipContentEncodingZeroLength() throws Exception {
+ final ClassicHttpRequest request = new BasicClassicHttpRequest(StandardMethods.GET.name(), host, "/");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ final StringEntity original = new StringEntity("");
+ original.setContentEncoding("GZip");
+ response.setEntity(original);
+
+ Mockito.when(execChain.proceed(request, scope)).thenReturn(response);
+
+ impl.execute(request, scope, execChain);
+
+ final HttpEntity entity = response.getEntity();
+ Assert.assertNotNull(entity);
+ Assert.assertTrue(entity instanceof StringEntity);
+ }
+
+ @Test
+ public void testXGzipContentEncoding() throws Exception {
+ final ClassicHttpRequest request = new BasicClassicHttpRequest(StandardMethods.GET.name(), host, "/");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ final StringEntity original = new StringEntity("encoded stuff");
+ original.setContentEncoding("x-gzip");
+ response.setEntity(original);
+
+ Mockito.when(execChain.proceed(request, scope)).thenReturn(response);
+
+ impl.execute(request, scope, execChain);
+
+ final HttpEntity entity = response.getEntity();
+ Assert.assertNotNull(entity);
+ Assert.assertTrue(entity instanceof DecompressingEntity);
+ }
+
+ @Test
+ public void testDeflateContentEncoding() throws Exception {
+ final ClassicHttpRequest request = new BasicClassicHttpRequest(StandardMethods.GET.name(), host, "/");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ final StringEntity original = new StringEntity("encoded stuff");
+ original.setContentEncoding("deFlaTe");
+ response.setEntity(original);
+
+ Mockito.when(execChain.proceed(request, scope)).thenReturn(response);
+
+ impl.execute(request, scope, execChain);
+
+ final HttpEntity entity = response.getEntity();
+ Assert.assertNotNull(entity);
+ Assert.assertTrue(entity instanceof DecompressingEntity);
+ }
+
+ @Test
+ public void testIdentityContentEncoding() throws Exception {
+ final ClassicHttpRequest request = new BasicClassicHttpRequest(StandardMethods.GET.name(), host, "/");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ final StringEntity original = new StringEntity("encoded stuff");
+ original.setContentEncoding("identity");
+ response.setEntity(original);
+
+ Mockito.when(execChain.proceed(request, scope)).thenReturn(response);
+
+ impl.execute(request, scope, execChain);
+
+ final HttpEntity entity = response.getEntity();
+ Assert.assertNotNull(entity);
+ Assert.assertTrue(entity instanceof StringEntity);
+ }
+
+ @Test(expected=HttpException.class)
+ public void testUnknownContentEncoding() throws Exception {
+ final ClassicHttpRequest request = new BasicClassicHttpRequest(StandardMethods.GET.name(), host, "/");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ final StringEntity original = new StringEntity("encoded stuff");
+ original.setContentEncoding("whatever");
+ response.setEntity(original);
+
+ impl = new ContentCompressionExec(false);
+
+ Mockito.when(execChain.proceed(request, scope)).thenReturn(response);
+
+ impl.execute(request, scope, execChain);
+ }
+
+ @Test
+ public void testContentEncodingRequestParameter() throws Exception {
+ final ClassicHttpRequest request = new BasicClassicHttpRequest(StandardMethods.GET.name(), host, "/");
+ final ClassicHttpResponse response = new BasicClassicHttpResponse(200, "OK");
+ final StringEntity original = new StringEntity("encoded stuff");
+ original.setContentEncoding("GZip");
+ response.setEntity(original);
+
+ final RequestConfig config = RequestConfig.custom()
+ .setContentCompressionEnabled(false)
+ .build();
+
+ context.setAttribute(HttpClientContext.REQUEST_CONFIG, config);
+
+ Mockito.when(execChain.proceed(request, scope)).thenReturn(response);
+
+ impl.execute(request, scope, execChain);
+
+ final HttpEntity entity = response.getEntity();
+ Assert.assertNotNull(entity);
+ Assert.assertFalse(entity instanceof GzipDecompressingEntity);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestCookieIdentityComparator.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestCookieIdentityComparator.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestCookieIdentityComparator.java
new file mode 100644
index 0000000..ceeff4f
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestCookieIdentityComparator.java
@@ -0,0 +1,139 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import org.apache.hc.client5.http.cookie.CookieIdentityComparator;
+import org.apache.hc.client5.http.impl.cookie.BasicClientCookie;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Simple tests for {@link CookieIdentityComparator}.
+ */
+public class TestCookieIdentityComparator {
+
+ @Test
+ public void testCookieIdentityComparasionByName() {
+ final CookieIdentityComparator comparator = new CookieIdentityComparator();
+ final BasicClientCookie c1 = new BasicClientCookie("name", "value1");
+ final BasicClientCookie c2 = new BasicClientCookie("name", "value2");
+ Assert.assertTrue(comparator.compare(c1, c2) == 0);
+
+ final BasicClientCookie c3 = new BasicClientCookie("name1", "value");
+ final BasicClientCookie c4 = new BasicClientCookie("name2", "value");
+ Assert.assertFalse(comparator.compare(c3, c4) == 0);
+ }
+
+ @Test
+ public void testCookieIdentityComparasionByNameAndDomain() {
+ final CookieIdentityComparator comparator = new CookieIdentityComparator();
+ final BasicClientCookie c1 = new BasicClientCookie("name", "value1");
+ c1.setDomain("www.domain.com");
+ final BasicClientCookie c2 = new BasicClientCookie("name", "value2");
+ c2.setDomain("www.domain.com");
+ Assert.assertTrue(comparator.compare(c1, c2) == 0);
+
+ final BasicClientCookie c3 = new BasicClientCookie("name", "value1");
+ c3.setDomain("www.domain.com");
+ final BasicClientCookie c4 = new BasicClientCookie("name", "value2");
+ c4.setDomain("domain.com");
+ Assert.assertFalse(comparator.compare(c3, c4) == 0);
+ }
+
+ @Test
+ public void testCookieIdentityComparasionByNameAndNullDomain() {
+ final CookieIdentityComparator comparator = new CookieIdentityComparator();
+ final BasicClientCookie c1 = new BasicClientCookie("name", "value1");
+ c1.setDomain(null);
+ final BasicClientCookie c2 = new BasicClientCookie("name", "value2");
+ c2.setDomain(null);
+ Assert.assertTrue(comparator.compare(c1, c2) == 0);
+
+ final BasicClientCookie c3 = new BasicClientCookie("name", "value1");
+ c3.setDomain("www.domain.com");
+ final BasicClientCookie c4 = new BasicClientCookie("name", "value2");
+ c4.setDomain(null);
+ Assert.assertFalse(comparator.compare(c3, c4) == 0);
+ }
+
+ @Test
+ public void testCookieIdentityComparasionByNameAndLocalHost() {
+ final CookieIdentityComparator comparator = new CookieIdentityComparator();
+ final BasicClientCookie c1 = new BasicClientCookie("name", "value1");
+ c1.setDomain("localhost");
+ final BasicClientCookie c2 = new BasicClientCookie("name", "value2");
+ c2.setDomain("localhost");
+ Assert.assertTrue(comparator.compare(c1, c2) == 0);
+
+ final BasicClientCookie c3 = new BasicClientCookie("name", "value1");
+ c3.setDomain("localhost.local");
+ final BasicClientCookie c4 = new BasicClientCookie("name", "value2");
+ c4.setDomain("localhost");
+ Assert.assertTrue(comparator.compare(c3, c4) == 0);
+ }
+
+ @Test
+ public void testCookieIdentityComparasionByNameDomainAndPath() {
+ final CookieIdentityComparator comparator = new CookieIdentityComparator();
+ final BasicClientCookie c1 = new BasicClientCookie("name", "value1");
+ c1.setDomain("www.domain.com");
+ c1.setPath("/whatever");
+ final BasicClientCookie c2 = new BasicClientCookie("name", "value2");
+ c2.setDomain("www.domain.com");
+ c2.setPath("/whatever");
+ Assert.assertTrue(comparator.compare(c1, c2) == 0);
+
+ final BasicClientCookie c3 = new BasicClientCookie("name", "value1");
+ c3.setDomain("www.domain.com");
+ c3.setPath("/whatever");
+ final BasicClientCookie c4 = new BasicClientCookie("name", "value2");
+ c4.setDomain("domain.com");
+ c4.setPath("/whatever-not");
+ Assert.assertFalse(comparator.compare(c3, c4) == 0);
+ }
+
+ @Test
+ public void testCookieIdentityComparasionByNameDomainAndNullPath() {
+ final CookieIdentityComparator comparator = new CookieIdentityComparator();
+ final BasicClientCookie c1 = new BasicClientCookie("name", "value1");
+ c1.setDomain("www.domain.com");
+ c1.setPath("/");
+ final BasicClientCookie c2 = new BasicClientCookie("name", "value2");
+ c2.setDomain("www.domain.com");
+ c2.setPath(null);
+ Assert.assertTrue(comparator.compare(c1, c2) == 0);
+
+ final BasicClientCookie c3 = new BasicClientCookie("name", "value1");
+ c3.setDomain("www.domain.com");
+ c3.setPath("/whatever");
+ final BasicClientCookie c4 = new BasicClientCookie("name", "value2");
+ c4.setDomain("domain.com");
+ c4.setPath(null);
+ Assert.assertFalse(comparator.compare(c3, c4) == 0);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestDefaultBackoffStrategy.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestDefaultBackoffStrategy.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestDefaultBackoffStrategy.java
new file mode 100644
index 0000000..f8614de
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestDefaultBackoffStrategy.java
@@ -0,0 +1,83 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.net.ConnectException;
+import java.net.SocketTimeoutException;
+
+import org.apache.hc.core5.http.ConnectionRequestTimeoutException;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class TestDefaultBackoffStrategy {
+
+ private DefaultBackoffStrategy impl;
+
+ @Before
+ public void setUp() {
+ impl = new DefaultBackoffStrategy();
+ }
+
+ @Test
+ public void backsOffForSocketTimeouts() {
+ assertTrue(impl.shouldBackoff(new SocketTimeoutException()));
+ }
+
+ @Test
+ public void backsOffForConnectionTimeouts() {
+ assertTrue(impl.shouldBackoff(new ConnectException()));
+ }
+
+ @Test
+ public void doesNotBackOffForConnectionManagerTimeout() {
+ assertFalse(impl.shouldBackoff(new ConnectionRequestTimeoutException()));
+ }
+
+ @Test
+ public void backsOffForServiceUnavailable() {
+ final HttpResponse resp = new BasicHttpResponse(HttpStatus.SC_SERVICE_UNAVAILABLE, "Service Unavailable");
+ assertTrue(impl.shouldBackoff(resp));
+ }
+
+ @Test
+ public void doesNotBackOffForNon503StatusCodes() {
+ for(int i = 100; i <= 599; i++) {
+ if (i == HttpStatus.SC_SERVICE_UNAVAILABLE) {
+ continue;
+ }
+ final HttpResponse resp = new BasicHttpResponse(i, "Foo");
+ assertFalse(impl.shouldBackoff(resp));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestExecRuntimeImpl.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestExecRuntimeImpl.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestExecRuntimeImpl.java
new file mode 100644
index 0000000..2e53cd1
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestExecRuntimeImpl.java
@@ -0,0 +1,308 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.hc.client5.http.CancellableAware;
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.io.ConnectionEndpoint;
+import org.apache.hc.client5.http.io.HttpClientConnectionManager;
+import org.apache.hc.client5.http.io.LeaseRequest;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.concurrent.Cancellable;
+import org.apache.hc.core5.http.ConnectionRequestTimeoutException;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
+import org.apache.hc.core5.io.ShutdownType;
+import org.apache.hc.core5.util.TimeValue;
+import org.apache.logging.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+@SuppressWarnings({"static-access"}) // test code
+public class TestExecRuntimeImpl {
+
+ @Mock
+ private Logger log;
+ @Mock
+ private HttpClientConnectionManager mgr;
+ @Mock
+ private LeaseRequest leaseRequest;
+ @Mock
+ private HttpRequestExecutor requestExecutor;
+ @Mock
+ private CancellableAware cancellableAware;
+ @Mock
+ private ConnectionEndpoint connectionEndpoint;
+
+ private HttpRoute route;
+ private ExecRuntimeImpl execRuntime;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ route = new HttpRoute(new HttpHost("host", 80));
+ execRuntime = new ExecRuntimeImpl(log, mgr, requestExecutor, cancellableAware);
+ }
+
+ @Test
+ public void testAcquireEndpoint() throws Exception {
+ final HttpClientContext context = HttpClientContext.create();
+ final RequestConfig config = RequestConfig.custom()
+ .setConnectTimeout(123, TimeUnit.MILLISECONDS)
+ .setSocketTimeout(234, TimeUnit.MILLISECONDS)
+ .setConnectionRequestTimeout(345, TimeUnit.MILLISECONDS)
+ .build();
+ context.setRequestConfig(config);
+ final HttpRoute route = new HttpRoute(new HttpHost("host", 80));
+
+ Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
+ Mockito.when(leaseRequest.get(
+ Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
+
+ execRuntime.acquireConnection(route, null, context);
+
+ Assert.assertTrue(execRuntime.isConnectionAcquired());
+ Assert.assertSame(connectionEndpoint, execRuntime.ensureValid());
+ Assert.assertFalse(execRuntime.isConnected());
+ Assert.assertFalse(execRuntime.isConnectionReusable());
+
+ Mockito.verify(leaseRequest).get(345, TimeUnit.MILLISECONDS);
+ Mockito.verify(cancellableAware, Mockito.times(1)).setCancellable(leaseRequest);
+ Mockito.verify(cancellableAware, Mockito.times(1)).setCancellable(execRuntime);
+ Mockito.verify(cancellableAware, Mockito.times(2)).setCancellable(Mockito.<Cancellable>any());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAcquireEndpointAlreadyAcquired() throws Exception {
+ final HttpClientContext context = HttpClientContext.create();
+
+ Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
+ Mockito.when(leaseRequest.get(
+ Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
+
+ execRuntime.acquireConnection(route, null, context);
+
+ Assert.assertTrue(execRuntime.isConnectionAcquired());
+ Assert.assertSame(connectionEndpoint, execRuntime.ensureValid());
+
+ execRuntime.acquireConnection(route, null, context);
+ }
+
+ @Test(expected = ConnectionRequestTimeoutException.class)
+ public void testAcquireEndpointLeaseRequestTimeout() throws Exception {
+ final HttpClientContext context = HttpClientContext.create();
+
+ Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
+ Mockito.when(leaseRequest.get(
+ Mockito.anyLong(), Mockito.<TimeUnit>any())).thenThrow(new TimeoutException());
+
+ execRuntime.acquireConnection(route, null, context);
+ }
+
+ @Test(expected = RequestFailedException.class)
+ public void testAcquireEndpointLeaseRequestFailure() throws Exception {
+ final HttpClientContext context = HttpClientContext.create();
+
+ Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
+ Mockito.when(leaseRequest.get(
+ Mockito.anyLong(), Mockito.<TimeUnit>any())).thenThrow(new ExecutionException(new IllegalStateException()));
+
+ execRuntime.acquireConnection(route, null, context);
+ }
+
+ @Test
+ public void testAbortEndpoint() throws Exception {
+ final HttpClientContext context = HttpClientContext.create();
+ Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
+ Mockito.when(leaseRequest.get(
+ Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
+
+ execRuntime.acquireConnection(new HttpRoute(new HttpHost("host", 80)), null, context);
+ Assert.assertTrue(execRuntime.isConnectionAcquired());
+ execRuntime.discardConnection();
+
+ Assert.assertFalse(execRuntime.isConnectionAcquired());
+
+ Mockito.verify(connectionEndpoint).shutdown(ShutdownType.IMMEDIATE);
+ Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS);
+
+ execRuntime.discardConnection();
+
+ Mockito.verify(connectionEndpoint, Mockito.times(1)).shutdown(ShutdownType.IMMEDIATE);
+ Mockito.verify(mgr, Mockito.times(1)).release(
+ Mockito.<ConnectionEndpoint>any(),
+ Mockito.any(),
+ Mockito.<TimeValue>any());
+ }
+
+ @Test
+ public void testCancell() throws Exception {
+ final HttpClientContext context = HttpClientContext.create();
+
+ Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
+ Mockito.when(leaseRequest.get(
+ Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
+
+ execRuntime.acquireConnection(route, null, context);
+ Assert.assertTrue(execRuntime.isConnectionAcquired());
+
+ Assert.assertTrue(execRuntime.cancel());
+
+ Assert.assertFalse(execRuntime.isConnectionAcquired());
+
+ Mockito.verify(connectionEndpoint).shutdown(ShutdownType.IMMEDIATE);
+ Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS);
+
+ Assert.assertFalse(execRuntime.cancel());
+
+ Mockito.verify(connectionEndpoint, Mockito.times(1)).shutdown(ShutdownType.IMMEDIATE);
+ Mockito.verify(mgr, Mockito.times(1)).release(
+ Mockito.<ConnectionEndpoint>any(),
+ Mockito.any(),
+ Mockito.<TimeValue>any());
+ }
+
+ @Test
+ public void testReleaseEndpointReusable() throws Exception {
+ final HttpClientContext context = HttpClientContext.create();
+
+ Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
+ Mockito.when(leaseRequest.get(
+ Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
+
+ execRuntime.acquireConnection(route, null, context);
+ Assert.assertTrue(execRuntime.isConnectionAcquired());
+
+ execRuntime.setConnectionState("some state");
+ execRuntime.setConnectionValidFor(TimeValue.ofMillis(100000));
+ execRuntime.markConnectionReusable();
+
+ execRuntime.releaseConnection();
+
+ Assert.assertFalse(execRuntime.isConnectionAcquired());
+
+ Mockito.verify(connectionEndpoint, Mockito.never()).close();
+ Mockito.verify(mgr).release(connectionEndpoint, "some state", TimeValue.ofMillis(100000));
+
+ execRuntime.releaseConnection();
+
+ Mockito.verify(mgr, Mockito.times(1)).release(
+ Mockito.<ConnectionEndpoint>any(),
+ Mockito.any(),
+ Mockito.<TimeValue>any());
+ }
+
+ @Test
+ public void testReleaseEndpointNonReusable() throws Exception {
+ final HttpClientContext context = HttpClientContext.create();
+
+ Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
+ Mockito.when(leaseRequest.get(
+ Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
+
+ execRuntime.acquireConnection(route, null, context);
+ Assert.assertTrue(execRuntime.isConnectionAcquired());
+
+ execRuntime.setConnectionState("some state");
+ execRuntime.setConnectionValidFor(TimeValue.ofMillis(100000));
+ execRuntime.markConnectionNonReusable();
+
+ execRuntime.releaseConnection();
+
+ Assert.assertFalse(execRuntime.isConnectionAcquired());
+
+ Mockito.verify(connectionEndpoint, Mockito.times(1)).close();
+ Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS);
+
+ execRuntime.releaseConnection();
+
+ Mockito.verify(mgr, Mockito.times(1)).release(
+ Mockito.<ConnectionEndpoint>any(),
+ Mockito.any(),
+ Mockito.<TimeValue>any());
+ }
+
+ @Test
+ public void testConnectEndpoint() throws Exception {
+ final HttpClientContext context = HttpClientContext.create();
+ final RequestConfig config = RequestConfig.custom()
+ .setConnectTimeout(123, TimeUnit.MILLISECONDS)
+ .setSocketTimeout(234, TimeUnit.MILLISECONDS)
+ .setConnectionRequestTimeout(345, TimeUnit.MILLISECONDS)
+ .build();
+ context.setRequestConfig(config);
+
+ Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
+ Mockito.when(leaseRequest.get(
+ Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
+
+ execRuntime.acquireConnection(route, null, context);
+ Assert.assertTrue(execRuntime.isConnectionAcquired());
+
+ Mockito.when(connectionEndpoint.isConnected()).thenReturn(false);
+ Assert.assertFalse(execRuntime.isConnected());
+
+ execRuntime.connect(context);
+
+ Mockito.verify(mgr).connect(connectionEndpoint, TimeValue.ofMillis(123), context);
+ Mockito.verify(connectionEndpoint).setSocketTimeout(234);
+ }
+
+ @Test
+ public void testDisonnectEndpoint() throws Exception {
+ final HttpClientContext context = HttpClientContext.create();
+
+ Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
+ Mockito.when(leaseRequest.get(
+ Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
+
+ execRuntime.acquireConnection(route, null, context);
+ Assert.assertTrue(execRuntime.isConnectionAcquired());
+
+ Mockito.when(connectionEndpoint.isConnected()).thenReturn(true);
+ Assert.assertTrue(execRuntime.isConnected());
+
+ execRuntime.connect(context);
+
+ Mockito.verify(mgr, Mockito.never()).connect(
+ Mockito.same(connectionEndpoint), Mockito.<TimeValue>any(), Mockito.<HttpClientContext>any());
+
+ execRuntime.disconnect();
+
+ Mockito.verify(connectionEndpoint).close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestFutureRequestExecutionService.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestFutureRequestExecutionService.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestFutureRequestExecutionService.java
new file mode 100644
index 0000000..461cb34
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestFutureRequestExecutionService.java
@@ -0,0 +1,201 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.io.HttpClientConnectionManager;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
+import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
+import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("boxing") // test code
+public class TestFutureRequestExecutionService {
+
+ private HttpServer localServer;
+ private String uri;
+ private FutureRequestExecutionService httpAsyncClientWithFuture;
+
+ private final AtomicBoolean blocked = new AtomicBoolean(false);
+
+ @Before
+ public void before() throws Exception {
+ this.localServer = ServerBootstrap.bootstrap()
+ .register("/wait", new HttpRequestHandler() {
+
+ @Override
+ public void handle(
+ final ClassicHttpRequest request,
+ final ClassicHttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+ try {
+ while(blocked.get()) {
+ Thread.sleep(10);
+ }
+ } catch (final InterruptedException e) {
+ throw new IllegalStateException(e);
+ }
+ response.setCode(200);
+ }
+ }).create();
+
+ this.localServer.start();
+ uri = "http://localhost:" + this.localServer.getLocalPort() + "/wait";
+ final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create()
+ .setMaxConnPerRoute(5)
+ .build();
+ final CloseableHttpClient httpClient = HttpClientBuilder.create()
+ .setConnectionManager(cm)
+ .build();
+ final ExecutorService executorService = Executors.newFixedThreadPool(5);
+ httpAsyncClientWithFuture = new FutureRequestExecutionService(httpClient, executorService);
+ }
+
+ @After
+ public void after() throws Exception {
+ blocked.set(false); // any remaining requests should unblock
+ this.localServer.stop();
+ httpAsyncClientWithFuture.close();
+ }
+
+ @Test
+ public void shouldExecuteSingleCall() throws InterruptedException, ExecutionException {
+ final HttpRequestFutureTask<Boolean> task = httpAsyncClientWithFuture.execute(
+ new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler());
+ Assert.assertTrue("request should have returned OK", task.get().booleanValue());
+ }
+
+ @Test(expected=CancellationException.class)
+ public void shouldCancel() throws InterruptedException, ExecutionException {
+ final HttpRequestFutureTask<Boolean> task = httpAsyncClientWithFuture.execute(
+ new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler());
+ task.cancel(true);
+ task.get();
+ }
+
+ @Test(expected=TimeoutException.class)
+ public void shouldTimeout() throws InterruptedException, ExecutionException, TimeoutException {
+ blocked.set(true);
+ final HttpRequestFutureTask<Boolean> task = httpAsyncClientWithFuture.execute(
+ new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler());
+ task.get(10, TimeUnit.MILLISECONDS);
+ }
+
+ @Test
+ public void shouldExecuteMultipleCalls() throws Exception {
+ final int reqNo = 100;
+ final Queue<Future<Boolean>> tasks = new LinkedList<>();
+ for(int i = 0; i < reqNo; i++) {
+ final Future<Boolean> task = httpAsyncClientWithFuture.execute(
+ new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler());
+ tasks.add(task);
+ }
+ for (final Future<Boolean> task : tasks) {
+ final Boolean b = task.get();
+ Assert.assertNotNull(b);
+ Assert.assertTrue("request should have returned OK", b.booleanValue());
+ }
+ }
+
+ @Test
+ public void shouldExecuteMultipleCallsAndCallback() throws Exception {
+ final int reqNo = 100;
+ final Queue<Future<Boolean>> tasks = new LinkedList<>();
+ final CountDownLatch latch = new CountDownLatch(reqNo);
+ for(int i = 0; i < reqNo; i++) {
+ final Future<Boolean> task = httpAsyncClientWithFuture.execute(
+ new HttpGet(uri), HttpClientContext.create(),
+ new OkidokiHandler(), new CountingCallback(latch));
+ tasks.add(task);
+ }
+ Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
+ for (final Future<Boolean> task : tasks) {
+ final Boolean b = task.get();
+ Assert.assertNotNull(b);
+ Assert.assertTrue("request should have returned OK", b.booleanValue());
+ }
+ }
+
+ private final class CountingCallback implements FutureCallback<Boolean> {
+
+ private final CountDownLatch latch;
+
+ CountingCallback(final CountDownLatch latch) {
+ super();
+ this.latch = latch;
+ }
+
+ @Override
+ public void failed(final Exception ex) {
+ latch.countDown();
+ }
+
+ @Override
+ public void completed(final Boolean result) {
+ latch.countDown();
+ }
+
+ @Override
+ public void cancelled() {
+ latch.countDown();
+ }
+ }
+
+
+ private final class OkidokiHandler implements HttpClientResponseHandler<Boolean> {
+ @Override
+ public Boolean handleResponse(
+ final ClassicHttpResponse response) throws IOException {
+ return response.getCode() == 200;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalHttpClient.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalHttpClient.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalHttpClient.java
new file mode 100644
index 0000000..3612ef4
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalHttpClient.java
@@ -0,0 +1,219 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.impl.classic;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.hc.client5.http.ClientProtocolException;
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.auth.AuthSchemeProvider;
+import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.classic.ExecChain;
+import org.apache.hc.client5.http.classic.ExecChainHandler;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.cookie.CookieSpecProvider;
+import org.apache.hc.client5.http.cookie.CookieStore;
+import org.apache.hc.client5.http.io.HttpClientConnectionManager;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.routing.HttpRoutePlanner;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.config.Lookup;
+import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Simple tests for {@link InternalHttpClient}.
+ */
+@SuppressWarnings({"static-access"}) // test code
+public class TestInternalHttpClient {
+
+ @Mock
+ private HttpClientConnectionManager connManager;
+ @Mock
+ private HttpRequestExecutor requestExecutor;
+ @Mock
+ private ExecChainHandler execChain;
+ @Mock
+ private HttpRoutePlanner routePlanner;
+ @Mock
+ private Lookup<CookieSpecProvider> cookieSpecRegistry;
+ @Mock
+ private Lookup<AuthSchemeProvider> authSchemeRegistry;
+ @Mock
+ private CookieStore cookieStore;
+ @Mock
+ private CredentialsProvider credentialsProvider;
+ @Mock
+ private RequestConfig defaultConfig;
+ @Mock
+ private Closeable closeable1;
+ @Mock
+ private Closeable closeable2;
+
+ private InternalHttpClient client;
+
+ @SuppressWarnings("unchecked")
+ @Before
+ public void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ client = new InternalHttpClient(connManager, requestExecutor, new ExecChainElement(execChain, null), routePlanner,
+ cookieSpecRegistry, authSchemeRegistry, cookieStore, credentialsProvider,
+ defaultConfig, Arrays.asList(closeable1, closeable2));
+
+ }
+
+ @Test
+ public void testExecute() throws Exception {
+ final HttpGet httpget = new HttpGet("http://somehost/stuff");
+ final HttpRoute route = new HttpRoute(new HttpHost("somehost", 80));
+
+ Mockito.when(routePlanner.determineRoute(
+ Mockito.eq(new HttpHost("somehost")),
+ Mockito.<HttpClientContext>any())).thenReturn(route);
+
+ client.execute(httpget);
+
+ Mockito.verify(execChain).execute(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any(),
+ Mockito.<ExecChain>any());
+ }
+
+ @Test(expected=ClientProtocolException.class)
+ public void testExecuteHttpException() throws Exception {
+ final HttpGet httpget = new HttpGet("http://somehost/stuff");
+ final HttpRoute route = new HttpRoute(new HttpHost("somehost", 80));
+
+ Mockito.when(routePlanner.determineRoute(
+ Mockito.eq(new HttpHost("somehost")),
+ Mockito.<HttpClientContext>any())).thenReturn(route);
+ Mockito.when(execChain.execute(
+ Mockito.<ClassicHttpRequest>any(),
+ Mockito.<ExecChain.Scope>any(),
+ Mockito.<ExecChain>any())).thenThrow(new HttpException());
+
+ client.execute(httpget);
+ }
+
+ @Test
+ public void testExecuteDefaultContext() throws Exception {
+ final HttpGet httpget = new HttpGet("http://somehost/stuff");
+ final HttpRoute route = new HttpRoute(new HttpHost("somehost", 80));
+
+ Mockito.when(routePlanner.determineRoute(
+ Mockito.eq(new HttpHost("somehost")),
+ Mockito.<HttpClientContext>any())).thenReturn(route);
+
+ final HttpClientContext context = HttpClientContext.create();
+ client.execute(httpget, context);
+
+ Assert.assertSame(cookieSpecRegistry, context.getCookieSpecRegistry());
+ Assert.assertSame(authSchemeRegistry, context.getAuthSchemeRegistry());
+ Assert.assertSame(cookieStore, context.getCookieStore());
+ Assert.assertSame(credentialsProvider, context.getCredentialsProvider());
+ Assert.assertSame(defaultConfig, context.getRequestConfig());
+ }
+
+ @Test
+ public void testExecuteRequestConfig() throws Exception {
+ final HttpGet httpget = new HttpGet("http://somehost/stuff");
+ final HttpRoute route = new HttpRoute(new HttpHost("somehost", 80));
+
+ Mockito.when(routePlanner.determineRoute(
+ Mockito.eq(new HttpHost("somehost")),
+ Mockito.<HttpClientContext>any())).thenReturn(route);
+
+ final RequestConfig config = RequestConfig.custom().build();
+ httpget.setConfig(config);
+ final HttpClientContext context = HttpClientContext.create();
+ client.execute(httpget, context);
+
+ Assert.assertSame(config, context.getRequestConfig());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testExecuteLocalContext() throws Exception {
+ final HttpGet httpget = new HttpGet("http://somehost/stuff");
+ final HttpRoute route = new HttpRoute(new HttpHost("somehost", 80));
+
+ Mockito.when(routePlanner.determineRoute(
+ Mockito.eq(new HttpHost("somehost")),
+ Mockito.<HttpClientContext>any())).thenReturn(route);
+
+ final HttpClientContext context = HttpClientContext.create();
+
+ final Lookup<CookieSpecProvider> localCookieSpecRegistry = Mockito.mock(Lookup.class);
+ final Lookup<AuthSchemeProvider> localAuthSchemeRegistry = Mockito.mock(Lookup.class);
+ final CookieStore localCookieStore = Mockito.mock(CookieStore.class);
+ final CredentialsProvider localCredentialsProvider = Mockito.mock(CredentialsProvider.class);
+ final RequestConfig localConfig = RequestConfig.custom().build();
+
+ context.setCookieSpecRegistry(localCookieSpecRegistry);
+ context.setAuthSchemeRegistry(localAuthSchemeRegistry);
+ context.setCookieStore(localCookieStore);
+ context.setCredentialsProvider(localCredentialsProvider);
+ context.setRequestConfig(localConfig);
+
+ client.execute(httpget, context);
+
+ Assert.assertSame(localCookieSpecRegistry, context.getCookieSpecRegistry());
+ Assert.assertSame(localAuthSchemeRegistry, context.getAuthSchemeRegistry());
+ Assert.assertSame(localCookieStore, context.getCookieStore());
+ Assert.assertSame(localCredentialsProvider, context.getCredentialsProvider());
+ Assert.assertSame(localConfig, context.getRequestConfig());
+ }
+
+ @Test
+ public void testClientClose() throws Exception {
+ client.close();
+
+ Mockito.verify(closeable1).close();
+ Mockito.verify(closeable2).close();
+ }
+
+ @Test
+ public void testClientCloseIOException() throws Exception {
+ Mockito.doThrow(new IOException()).when(closeable1).close();
+
+ client.close();
+
+ Mockito.verify(closeable1).close();
+ Mockito.verify(closeable2).close();
+ }
+
+}