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:06 UTC

[06/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/classic/methods/TestRequestBuilder.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/classic/methods/TestRequestBuilder.java b/httpclient5/src/test/java/org/apache/hc/client5/http/classic/methods/TestRequestBuilder.java
new file mode 100644
index 0000000..69c7112
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/classic/methods/TestRequestBuilder.java
@@ -0,0 +1,290 @@
+/*
+ * ====================================================================
+ * 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.classic.methods;
+
+import java.net.URI;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+import org.apache.hc.client5.http.config.Configurable;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.NameValuePair;
+import org.apache.hc.core5.http.io.entity.BasicHttpEntity;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.message.BasicHeader;
+import org.apache.hc.core5.http.message.BasicNameValuePair;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestRequestBuilder {
+
+    @Test
+    public void testBasicGet() throws Exception {
+        final ClassicHttpRequest request = RequestBuilder.get().build();
+        Assert.assertNotNull(request);
+        Assert.assertEquals("GET", request.getMethod());
+        Assert.assertEquals(URI.create("/"), request.getUri());
+    }
+
+    @Test
+    public void testArbitraryMethod() throws Exception {
+        final ClassicHttpRequest request = RequestBuilder.create("Whatever").build();
+        Assert.assertNotNull(request);
+        Assert.assertEquals("Whatever", request.getMethod());
+        Assert.assertEquals(URI.create("/"), request.getUri());
+    }
+
+    @Test
+    public void testBasicWithEntity() throws Exception {
+        final HttpEntity entity = new BasicHttpEntity();
+        final ClassicHttpRequest request = RequestBuilder.post().setEntity(entity).build();
+        Assert.assertNotNull(request);
+        Assert.assertEquals("POST", request.getMethod());
+        Assert.assertEquals(URI.create("/"), request.getUri());
+        Assert.assertSame(entity, request.getEntity());
+    }
+
+    @Test
+    public void testGetWithEntity() throws Exception {
+        final HttpEntity entity = new BasicHttpEntity();
+        final ClassicHttpRequest request = RequestBuilder.get().setEntity(entity).build();
+        Assert.assertNotNull(request);
+        Assert.assertEquals("GET", request.getMethod());
+        Assert.assertEquals(URI.create("/"), request.getUri());
+        Assert.assertSame(entity, request.getEntity());
+    }
+
+    @Test
+    public void testAddParameters1() throws Exception {
+        final ClassicHttpRequest request = RequestBuilder.get()
+                .addParameter("p1", "this")
+                .addParameter("p2", "that")
+                .build();
+        Assert.assertEquals(new URI("/?p1=this&p2=that"), request.getUri());
+    }
+
+    @Test
+    public void testAddParameters2() throws Exception {
+        final ClassicHttpRequest request = RequestBuilder.get()
+                .addParameter("p1", "this")
+                .addParameters(new BasicNameValuePair("p2", "that"))
+                .build();
+        Assert.assertEquals(new URI("/?p1=this&p2=that"), request.getUri());
+    }
+
+    @Test
+    public void testAddParameters3() throws Exception {
+        final ClassicHttpRequest request = RequestBuilder.post()
+                .addParameter("p1", "this")
+                .addParameter("p2", "that")
+                .build();
+        final HttpEntity entity = request.getEntity();
+        Assert.assertNotNull(entity);
+        Assert.assertEquals(new URI("/"), request.getUri());
+        Assert.assertEquals("p1=this&p2=that", EntityUtils.toString(entity));
+    }
+
+    @Test
+    public void testAddParameters4() throws Exception {
+        final ClassicHttpRequest request = RequestBuilder.post()
+                .setUri("http://targethost/?blah")
+                .addParameter("p1", "this")
+                .addParameter("p2", "that")
+                .setEntity(new StringEntity("blah"))
+                .build();
+        Assert.assertEquals(new URI("http://targethost/?blah&p1=this&p2=that"), request.getUri());
+    }
+
+    @Test
+    public void testCopy() throws Exception {
+        final HttpEntity entity = new StringEntity("stuff");
+        final RequestConfig config = RequestConfig.custom().build();
+        final ClassicHttpRequest request = RequestBuilder.put()
+            .setUri(URI.create("/stuff"))
+            .setVersion(HttpVersion.HTTP_1_0)
+            .addHeader("header1", "stuff")
+            .setHeader("header2", "more stuff")
+            .setEntity(entity)
+            .setConfig(config)
+            .build();
+        Assert.assertNotNull(request);
+        Assert.assertEquals("PUT", request.getMethod());
+        Assert.assertEquals(URI.create("/stuff"), request.getUri());
+        Assert.assertEquals(HttpVersion.HTTP_1_0, request.getVersion());
+
+        final ClassicHttpRequest copy = RequestBuilder.copy(request).setUri("/other-stuff").build();
+        Assert.assertEquals("PUT", copy.getMethod());
+        Assert.assertEquals(URI.create("/other-stuff"), copy.getUri());
+        Assert.assertSame(entity, copy.getEntity());
+        Assert.assertTrue(copy instanceof Configurable);
+        Assert.assertSame(config, ((Configurable) copy).getConfig());
+    }
+
+    @Test
+    public void testCopyWithQueryParams() throws Exception {
+        final HttpGet get = new HttpGet("/stuff?p1=this&p2=that");
+        final RequestBuilder builder = RequestBuilder.copy(get);
+        final List<NameValuePair> parameters = builder.getParameters();
+        Assert.assertNotNull(parameters);
+        Assert.assertEquals(0, parameters.size());
+        Assert.assertEquals(new URI("/stuff?p1=this&p2=that"), builder.getUri());
+    }
+
+    @Test
+    public void testCopyWithFormParams() throws Exception {
+        final HttpPost post = new HttpPost("/stuff?p1=wtf");
+        post.setEntity(new StringEntity("p1=this&p2=that", ContentType.APPLICATION_FORM_URLENCODED));
+        final RequestBuilder builder = RequestBuilder.copy(post);
+        final List<NameValuePair> parameters = builder.getParameters();
+        Assert.assertNotNull(parameters);
+        Assert.assertEquals(2, parameters.size());
+        assertNameValuePair(new BasicNameValuePair("p1", "this"), parameters.get(0));
+        assertNameValuePair(new BasicNameValuePair("p2", "that"), parameters.get(1));
+        Assert.assertEquals(new URI("/stuff?p1=wtf"), builder.getUri());
+        Assert.assertNull(builder.getEntity());
+    }
+
+    private static void assertNameValuePair (
+            final NameValuePair expected,
+            final NameValuePair result) {
+        Assert.assertNotNull(result);
+        Assert.assertEquals(expected.getName(), result.getName());
+        Assert.assertEquals(expected.getValue(), result.getValue());
+    }
+
+    @Test
+    public void testCopyWithStringEntity() throws Exception {
+        final HttpPost post = new HttpPost("/stuff?p1=wtf");
+        final HttpEntity entity = new StringEntity("p1=this&p2=that", ContentType.TEXT_PLAIN);
+        post.setEntity(entity);
+        final RequestBuilder builder = RequestBuilder.copy(post);
+        final List<NameValuePair> parameters = builder.getParameters();
+        Assert.assertNotNull(parameters);
+        Assert.assertEquals(0, parameters.size());
+        Assert.assertEquals(new URI("/stuff?p1=wtf"), builder.getUri());
+        Assert.assertSame(entity, builder.getEntity());
+    }
+
+    @Test
+    public void testCopyAndSetUri() throws Exception {
+        final URI uri1 = URI.create("http://host1.com/path?param=something");
+        final URI uri2 = URI.create("http://host2.com/path?param=somethingdifferent");
+        final HttpGet request1 = new HttpGet(uri1);
+        final ClassicHttpRequest request2 = RequestBuilder.copy(request1).setUri(uri2).build();
+        Assert.assertEquals(request2.getUri(), uri2);
+    }
+
+    @Test
+    public void testGettersAndMutators() throws Exception {
+        final HttpEntity entity = new StringEntity("stuff");
+        final RequestConfig config = RequestConfig.custom().build();
+        final Header h1 = new BasicHeader("header1", "stuff");
+        final Header h2 = new BasicHeader("header1", "more-stuff");
+        final RequestBuilder builder = RequestBuilder.put()
+            .setUri("/stuff")
+            .setVersion(HttpVersion.HTTP_1_0)
+            .addHeader(h1)
+            .addHeader(h2)
+            .setEntity(entity)
+            .setConfig(config);
+        Assert.assertEquals("PUT", builder.getMethod());
+        Assert.assertEquals(URI.create("/stuff"), builder.getUri());
+        Assert.assertEquals(HttpVersion.HTTP_1_0, builder.getVersion());
+        Assert.assertSame(h1, builder.getFirstHeader("header1"));
+        Assert.assertSame(h2, builder.getLastHeader("header1"));
+        Assert.assertEquals(2, builder.getHeaders("header1").length);
+        Assert.assertSame(entity, builder.getEntity());
+        Assert.assertSame(config, builder.getConfig());
+
+        builder.setUri((String) null)
+            .setVersion(null)
+            .removeHeader(h1)
+            .removeHeaders("header1")
+            .removeHeader(h2)
+            .setEntity(null)
+            .setConfig(null);
+        Assert.assertEquals(null, builder.getUri());
+        Assert.assertEquals(null, builder.getVersion());
+        Assert.assertSame(null, builder.getFirstHeader("header1"));
+        Assert.assertSame(null, builder.getLastHeader("header1"));
+        Assert.assertEquals(0, builder.getHeaders("header1").length);
+        Assert.assertSame(null, builder.getEntity());
+        Assert.assertSame(null, builder.getConfig());
+
+        builder.setHeader(h2)
+            .setHeader("header1", "a-lot-more-stuff");
+        Assert.assertSame("a-lot-more-stuff", builder.getLastHeader("header1").getValue());
+        Assert.assertEquals(1, builder.getHeaders("header1").length);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testCopyNull() throws Exception {
+        RequestBuilder.copy(null);
+    }
+
+    @Test
+    public void testBuildGETwithUTF8() throws Exception {
+        assertBuild(StandardCharsets.UTF_8);
+    }
+
+    @Test
+    public void testBuildGETwithISO88591() throws Exception {
+        assertBuild(StandardCharsets.ISO_8859_1);
+    }
+
+    private void assertBuild(final Charset charset) throws Exception {
+        final RequestBuilder requestBuilder = RequestBuilder.create("GET").setCharset(charset);
+        requestBuilder.setUri("https://somehost.com/stuff");
+        requestBuilder.addParameters(createParameters());
+
+        final String encodedData1 = URLEncoder.encode("\"1\u00aa position\"", charset.displayName());
+        final String encodedData2 = URLEncoder.encode("Jos\u00e9 Abra\u00e3o", charset.displayName());
+
+        final String uriExpected = String.format("https://somehost.com/stuff?parameter1=value1&parameter2=%s&parameter3=%s", encodedData1, encodedData2);
+
+        final ClassicHttpRequest request = requestBuilder.build();
+        Assert.assertEquals(uriExpected, request.getUri().toString());
+    }
+
+    private NameValuePair[] createParameters() {
+        final NameValuePair parameters[] = new NameValuePair[3];
+        parameters[0] = new BasicNameValuePair("parameter1", "value1");
+        parameters[1] = new BasicNameValuePair("parameter2", "\"1\u00aa position\"");
+        parameters[2] = new BasicNameValuePair("parameter3", "Jos\u00e9 Abra\u00e3o");
+        return parameters;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractHttpClientResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractHttpClientResponseHandler.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractHttpClientResponseHandler.java
deleted file mode 100644
index 44a48ba..0000000
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAbstractHttpClientResponseHandler.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * ====================================================================
- * 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;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.hc.client5.http.impl.sync.AbstractHttpClientResponseHandler;
-import org.apache.hc.client5.http.impl.sync.BasicHttpClientResponseHandler;
-import org.apache.hc.client5.http.protocol.HttpResponseException;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- * Unit tests for {@link BasicHttpClientResponseHandler}.
- */
-public class TestAbstractHttpClientResponseHandler {
-
-    @Test
-    public void testSuccessfulResponse() throws Exception {
-        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
-        final HttpEntity entity = new StringEntity("42");
-        Mockito.when(response.getCode()).thenReturn(200);
-        Mockito.when(response.getEntity()).thenReturn(entity);
-
-        final AbstractHttpClientResponseHandler<Integer> handler = new AbstractHttpClientResponseHandler<Integer>() {
-
-          @Override
-          public Integer handleEntity(final HttpEntity entity) throws IOException {
-            return Integer.valueOf(new String(EntityUtils.toByteArray(entity)));
-          }
-        };
-        final Integer number = handler.handleResponse(response);
-        Assert.assertEquals(42, number.intValue());
-    }
-
-    @SuppressWarnings("boxing")
-    @Test
-    public void testUnsuccessfulResponse() throws Exception {
-        final InputStream instream = Mockito.mock(InputStream.class);
-        final HttpEntity entity = Mockito.mock(HttpEntity.class);
-        Mockito.when(entity.isStreaming()).thenReturn(true);
-        Mockito.when(entity.getContent()).thenReturn(instream);
-        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
-        Mockito.when(response.getCode()).thenReturn(404);
-        Mockito.when(response.getEntity()).thenReturn(entity);
-
-        final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
-        try {
-            handler.handleResponse(response);
-            Assert.fail("HttpResponseException expected");
-        } catch (final HttpResponseException ex) {
-            Assert.assertEquals(404, ex.getStatusCode());
-        }
-        Mockito.verify(entity).getContent();
-        Mockito.verify(instream).close();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAuthenticationStrategy.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAuthenticationStrategy.java
new file mode 100644
index 0000000..91a4d4c
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestAuthenticationStrategy.java
@@ -0,0 +1,163 @@
+/*
+ * ====================================================================
+ * 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;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hc.client5.http.auth.AuthChallenge;
+import org.apache.hc.client5.http.auth.AuthScheme;
+import org.apache.hc.client5.http.auth.AuthSchemeProvider;
+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.config.AuthSchemes;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
+import org.apache.hc.client5.http.impl.auth.BasicScheme;
+import org.apache.hc.client5.http.impl.auth.BasicSchemeFactory;
+import org.apache.hc.client5.http.impl.auth.DigestScheme;
+import org.apache.hc.client5.http.impl.auth.DigestSchemeFactory;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.config.Registry;
+import org.apache.hc.core5.http.config.RegistryBuilder;
+import org.apache.hc.core5.http.message.BasicNameValuePair;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Simple tests for {@link DefaultAuthenticationStrategy}.
+ */
+@SuppressWarnings("boxing") // test code
+public class TestAuthenticationStrategy {
+
+    @Test
+    public void testSelectInvalidInput() throws Exception {
+        final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        try {
+            authStrategy.select(null, Collections.<String, AuthChallenge>emptyMap(), context);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException ex) {
+        }
+        try {
+            authStrategy.select(ChallengeType.TARGET, null, context);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException ex) {
+        }
+        try {
+            authStrategy.select(ChallengeType.TARGET, Collections.<String, AuthChallenge>emptyMap(), null);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException ex) {
+        }
+    }
+
+    @Test
+    public void testSelectNoSchemeRegistry() throws Exception {
+        final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+
+        final Map<String, AuthChallenge> challenges = new HashMap<>();
+        challenges.put("basic", new AuthChallenge(ChallengeType.TARGET, "Basic",
+                new BasicNameValuePair("realm", "test")));
+        challenges.put("digest", new AuthChallenge(ChallengeType.TARGET, "Digest",
+                new BasicNameValuePair("realm", "test"), new BasicNameValuePair("nonce", "1234")));
+
+        final List<AuthScheme> authSchemes = authStrategy.select(ChallengeType.TARGET, challenges, context);
+        Assert.assertNotNull(authSchemes);
+        Assert.assertEquals(0, authSchemes.size());
+    }
+
+    @Test
+    public void testUnsupportedScheme() throws Exception {
+        final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+
+        final Map<String, AuthChallenge> challenges = new HashMap<>();
+        challenges.put("basic", new AuthChallenge(ChallengeType.TARGET, "Basic",
+                new BasicNameValuePair("realm", "realm1")));
+        challenges.put("digest", new AuthChallenge(ChallengeType.TARGET, "Digest",
+                new BasicNameValuePair("realm", "realm2"), new BasicNameValuePair("nonce", "1234")));
+        challenges.put("whatever", new AuthChallenge(ChallengeType.TARGET, "Whatever",
+                new BasicNameValuePair("realm", "realm3")));
+
+        final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
+            .register("basic", new BasicSchemeFactory())
+            .register("digest", new DigestSchemeFactory()).build();
+        context.setAuthSchemeRegistry(authSchemeRegistry);
+
+        final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(new AuthScope("somehost", 80),
+                new UsernamePasswordCredentials("user", "pwd".toCharArray()));
+        context.setCredentialsProvider(credentialsProvider);
+
+        final List<AuthScheme> authSchemes = authStrategy.select(ChallengeType.TARGET, challenges, context);
+        Assert.assertNotNull(authSchemes);
+        Assert.assertEquals(2, authSchemes.size());
+        final AuthScheme authScheme1 = authSchemes.get(0);
+        Assert.assertTrue(authScheme1 instanceof DigestScheme);
+        final AuthScheme authScheme2 = authSchemes.get(1);
+        Assert.assertTrue(authScheme2 instanceof BasicScheme);
+    }
+
+    @Test
+    public void testCustomAuthPreference() throws Exception {
+        final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();
+        final RequestConfig config = RequestConfig.custom()
+            .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
+            .build();
+
+        final HttpClientContext context = HttpClientContext.create();
+
+        final Map<String, AuthChallenge> challenges = new HashMap<>();
+        challenges.put("basic", new AuthChallenge(ChallengeType.TARGET, "Basic",
+                new BasicNameValuePair("realm", "realm1")));
+        challenges.put("digest", new AuthChallenge(ChallengeType.TARGET, "Digest",
+                new BasicNameValuePair("realm", "realm2"), new BasicNameValuePair("nonce", "1234")));
+
+        final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
+            .register("basic", new BasicSchemeFactory())
+            .register("digest", new DigestSchemeFactory()).build();
+        context.setAuthSchemeRegistry(authSchemeRegistry);
+        context.setRequestConfig(config);
+
+        final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(new AuthScope("somehost", 80),
+                new UsernamePasswordCredentials("user", "pwd".toCharArray()));
+        context.setCredentialsProvider(credentialsProvider);
+
+        final List<AuthScheme> authSchemes = authStrategy.select(ChallengeType.TARGET, challenges, context);
+        Assert.assertNotNull(authSchemes);
+        Assert.assertEquals(1, authSchemes.size());
+        final AuthScheme authScheme1 = authSchemes.get(0);
+        Assert.assertTrue(authScheme1 instanceof BasicScheme);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestBasicResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestBasicResponseHandler.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestBasicResponseHandler.java
deleted file mode 100644
index f8d5abb..0000000
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestBasicResponseHandler.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * ====================================================================
- * 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;
-
-import java.io.InputStream;
-
-import org.apache.hc.client5.http.impl.sync.BasicHttpClientResponseHandler;
-import org.apache.hc.client5.http.protocol.HttpResponseException;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- * Unit tests for {@link BasicHttpClientResponseHandler}.
- */
-@SuppressWarnings("boxing") // test code
-public class TestBasicResponseHandler {
-
-    @Test
-    public void testSuccessfulResponse() throws Exception {
-        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
-        final HttpEntity entity = new StringEntity("stuff");
-        Mockito.when(response.getCode()).thenReturn(200);
-        Mockito.when(response.getEntity()).thenReturn(entity);
-
-        final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
-        final String s = handler.handleResponse(response);
-        Assert.assertEquals("stuff", s);
-    }
-
-    @Test
-    public void testUnsuccessfulResponse() throws Exception {
-        final InputStream instream = Mockito.mock(InputStream.class);
-        final HttpEntity entity = Mockito.mock(HttpEntity.class);
-        Mockito.when(entity.isStreaming()).thenReturn(true);
-        Mockito.when(entity.getContent()).thenReturn(instream);
-        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
-        Mockito.when(response.getCode()).thenReturn(404);
-        Mockito.when(response.getEntity()).thenReturn(entity);
-
-        final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
-        try {
-            handler.handleResponse(response);
-            Assert.fail("HttpResponseException expected");
-        } catch (final HttpResponseException ex) {
-            Assert.assertEquals(404, ex.getStatusCode());
-        }
-        Mockito.verify(entity).getContent();
-        Mockito.verify(instream).close();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultHttpRequestRetryHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultHttpRequestRetryHandler.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultHttpRequestRetryHandler.java
new file mode 100644
index 0000000..db823d0
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultHttpRequestRetryHandler.java
@@ -0,0 +1,88 @@
+/*
+ * ====================================================================
+ * 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;
+
+import java.io.IOException;
+import java.net.UnknownHostException;
+
+import org.apache.hc.client5.http.ConnectTimeoutException;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+@SuppressWarnings("boxing") // test class
+public class TestDefaultHttpRequestRetryHandler {
+
+    @Test
+    public void noRetryOnConnectTimeout() throws Exception {
+        final HttpGet request = new HttpGet("/");
+
+        final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
+        Assert.assertEquals(3, retryHandler.getRetryCount());
+
+        Assert.assertFalse(retryHandler.retryRequest(request, new ConnectTimeoutException(), 1, null));
+    }
+
+    @Test
+    public void noRetryOnUnknownHost() throws Exception {
+        final HttpGet request = new HttpGet("/");
+
+        final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
+
+        Assert.assertFalse(retryHandler.retryRequest(request, new UnknownHostException(), 1, null));
+    }
+
+    @Test
+    public void noRetryOnAbortedRequests() throws Exception{
+        final HttpGet request = new HttpGet("/");
+        request.abort();
+
+        final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
+
+        Assert.assertFalse(retryHandler.retryRequest(request, new IOException(), 3, null));
+    }
+
+    @Test
+    public void retryOnNonAbortedRequests() throws Exception{
+        final HttpGet request = new HttpGet("/");
+
+        final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
+
+        Assert.assertTrue(retryHandler.retryRequest(request, new IOException(), 3, null));
+    }
+
+    @Test
+    public void noRetryOnConnectionTimeout() throws Exception{
+        final HttpGet request = new HttpGet("/");
+
+        final DefaultHttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler();
+
+        Assert.assertFalse(retryHandler.retryRequest(request, new ConnectTimeoutException(), 3, null));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultRedirectStrategy.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultRedirectStrategy.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultRedirectStrategy.java
new file mode 100644
index 0000000..1fc2eb2
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultRedirectStrategy.java
@@ -0,0 +1,287 @@
+/*
+ * ====================================================================
+ * 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;
+
+import java.net.URI;
+import java.util.List;
+
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.ProtocolException;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestDefaultRedirectStrategy {
+
+    @Test
+    public void testIsRedirectedMovedTemporary() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        Assert.assertFalse(redirectStrategy.isRedirected(httpget, response, context));
+        response.setHeader(HttpHeaders.LOCATION, "http://localhost/blah");
+        Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context));
+    }
+
+    @Test
+    public void testIsRedirectedMovedTemporaryNoLocation() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        Assert.assertFalse(redirectStrategy.isRedirected(httpget, response, context));
+    }
+
+    @Test
+    public void testIsRedirectedMovedPermanently() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_PERMANENTLY, "Redirect");
+        Assert.assertFalse(redirectStrategy.isRedirected(httpget, response, context));
+        response.setHeader(HttpHeaders.LOCATION, "http://localhost/blah");
+        Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context));
+    }
+
+    @Test
+    public void testIsRedirectedTemporaryRedirect() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_TEMPORARY_REDIRECT, "Redirect");
+        Assert.assertFalse(redirectStrategy.isRedirected(httpget, response, context));
+        response.setHeader(HttpHeaders.LOCATION, "http://localhost/blah");
+        Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context));
+    }
+
+    @Test
+    public void testIsRedirectedSeeOther() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_SEE_OTHER, "Redirect");
+        Assert.assertFalse(redirectStrategy.isRedirected(httpget, response, context));
+        response.setHeader(HttpHeaders.LOCATION, "http://localhost/blah");
+        Assert.assertTrue(redirectStrategy.isRedirected(httpget, response, context));
+    }
+
+    @Test
+    public void testIsRedirectedUnknownStatus() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(333, "Redirect");
+        Assert.assertFalse(redirectStrategy.isRedirected(httpget, response, context));
+        final HttpPost httppost = new HttpPost("http://localhost/");
+        Assert.assertFalse(redirectStrategy.isRedirected(httppost, response, context));
+    }
+
+    @Test
+    public void testIsRedirectedInvalidInput() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_SEE_OTHER, "Redirect");
+        try {
+            redirectStrategy.isRedirected(null, response, context);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException expected) {
+        }
+        try {
+            redirectStrategy.isRedirected(httpget, null, context);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testGetLocationUri() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response.addHeader("Location", "http://localhost/stuff");
+        final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
+        Assert.assertEquals(URI.create("http://localhost/stuff"), uri);
+    }
+
+    @Test(expected=HttpException.class)
+    public void testGetLocationUriMissingHeader() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        redirectStrategy.getLocationURI(httpget, response, context);
+    }
+
+    @Test(expected=ProtocolException.class)
+    public void testGetLocationUriInvalidLocation() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response.addHeader("Location", "http://localhost/not valid");
+        redirectStrategy.getLocationURI(httpget, response, context);
+    }
+
+    @Test
+    public void testGetLocationUriRelative() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response.addHeader("Location", "/stuff");
+        final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
+        Assert.assertEquals(URI.create("http://localhost/stuff"), uri);
+    }
+
+    @Test
+    public void testGetLocationUriRelativeWithFragment() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response.addHeader("Location", "/stuff#fragment");
+        final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
+        Assert.assertEquals(URI.create("http://localhost/stuff#fragment"), uri);
+    }
+
+    @Test
+    public void testGetLocationUriAbsoluteWithFragment() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response.addHeader("Location", "http://localhost/stuff#fragment");
+        final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
+        Assert.assertEquals(URI.create("http://localhost/stuff#fragment"), uri);
+    }
+
+    @Test
+    public void testGetLocationUriNormalized() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response.addHeader("Location", "http://localhost/././stuff/../morestuff");
+        final URI uri = redirectStrategy.getLocationURI(httpget, response, context);
+        Assert.assertEquals(URI.create("http://localhost/morestuff"), uri);
+    }
+
+    @Test
+    public void testGetLocationUriAllowCircularRedirects() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final RequestConfig config = RequestConfig.custom().setCircularRedirectsAllowed(true).build();
+        context.setRequestConfig(config);
+        final URI uri1 = URI.create("http://localhost/stuff1");
+        final URI uri2 = URI.create("http://localhost/stuff2");
+        final URI uri3 = URI.create("http://localhost/stuff3");
+        final HttpGet httpget1 = new HttpGet("http://localhost/");
+        final HttpResponse response1 = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response1.addHeader("Location", uri1.toASCIIString());
+        final HttpGet httpget2 = new HttpGet(uri1.toASCIIString());
+        final HttpResponse response2 = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response2.addHeader("Location", uri2.toASCIIString());
+        final HttpGet httpget3 = new HttpGet(uri2.toASCIIString());
+        final HttpResponse response3 = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response3.addHeader("Location", uri3.toASCIIString());
+        Assert.assertEquals(uri1, redirectStrategy.getLocationURI(httpget1, response1, context));
+        Assert.assertEquals(uri2, redirectStrategy.getLocationURI(httpget2, response2, context));
+        Assert.assertEquals(uri3, redirectStrategy.getLocationURI(httpget3, response3, context));
+
+        final List<URI> uris = context.getRedirectLocations();
+        Assert.assertNotNull(uris);
+        Assert.assertTrue(uris.contains(uri1));
+        Assert.assertTrue(uris.contains(uri2));
+        Assert.assertTrue(uris.contains(uri3));
+        Assert.assertEquals(3, uris.size());
+        Assert.assertEquals(uri1, uris.get(0));
+        Assert.assertEquals(uri2, uris.get(1));
+        Assert.assertEquals(uri3, uris.get(2));
+    }
+
+    @Test(expected=ProtocolException.class)
+    public void testGetLocationUriDisallowCircularRedirects() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/stuff");
+        final RequestConfig config = RequestConfig.custom().setCircularRedirectsAllowed(false).build();
+        context.setRequestConfig(config);
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response.addHeader("Location", "http://localhost/stuff");
+        final URI uri = URI.create("http://localhost/stuff");
+        Assert.assertEquals(uri, redirectStrategy.getLocationURI(httpget, response, context));
+        redirectStrategy.getLocationURI(httpget, response, context);
+    }
+
+    @Test
+    public void testGetLocationUriInvalidInput() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        final HttpClientContext context = HttpClientContext.create();
+        final HttpGet httpget = new HttpGet("http://localhost/");
+        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
+        response.addHeader("Location", "http://localhost/stuff");
+        try {
+            redirectStrategy.getLocationURI(null, response, context);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException expected) {
+        }
+        try {
+            redirectStrategy.getLocationURI(httpget, null, context);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException expected) {
+        }
+        try {
+            redirectStrategy.getLocationURI(httpget, response, null);
+            Assert.fail("IllegalArgumentException expected");
+        } catch (final IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testCreateLocationURI() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        Assert.assertEquals("http://blahblah/",
+                redirectStrategy.createLocationURI("http://BlahBlah").toASCIIString());
+    }
+
+    @Test(expected=ProtocolException.class)
+    public void testCreateLocationURIInvalid() throws Exception {
+        final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
+        redirectStrategy.createLocationURI(":::::::");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultServiceUnavailableRetryStrategy.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultServiceUnavailableRetryStrategy.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultServiceUnavailableRetryStrategy.java
new file mode 100644
index 0000000..daa8725
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/TestDefaultServiceUnavailableRetryStrategy.java
@@ -0,0 +1,98 @@
+/*
+ * ====================================================================
+ * 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;
+
+import java.util.Date;
+
+import org.apache.hc.client5.http.utils.DateUtils;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestDefaultServiceUnavailableRetryStrategy {
+
+    private DefaultServiceUnavailableRetryStrategy impl;
+
+    @Before
+    public void setup() {
+        this.impl = new DefaultServiceUnavailableRetryStrategy(3, 1234);
+    }
+
+    @Test
+    public void testBasics() throws Exception {
+        final HttpResponse response1 = new BasicHttpResponse(503, "Oppsie");
+        Assert.assertTrue(this.impl.retryRequest(response1, 1, null));
+        Assert.assertTrue(this.impl.retryRequest(response1, 2, null));
+        Assert.assertTrue(this.impl.retryRequest(response1, 3, null));
+        Assert.assertFalse(this.impl.retryRequest(response1, 4, null));
+        final HttpResponse response2 = new BasicHttpResponse(500, "Big Time Oppsie");
+        Assert.assertFalse(this.impl.retryRequest(response2, 1, null));
+
+        Assert.assertEquals(1234, this.impl.getRetryInterval(response1, null));
+    }
+
+    @Test
+    public void testRetryAfterHeaderAsLong() throws Exception {
+        final HttpResponse response = new BasicHttpResponse(503, "Oppsie");
+        response.setHeader(HttpHeaders.RETRY_AFTER, "321");
+
+        Assert.assertEquals(321000, this.impl.getRetryInterval(response, null));
+    }
+
+    @Test
+    public void testRetryAfterHeaderAsDate() throws Exception {
+        this.impl = new DefaultServiceUnavailableRetryStrategy(3, 1);
+        final HttpResponse response = new BasicHttpResponse(503, "Oppsie");
+
+        response.setHeader(HttpHeaders.RETRY_AFTER, DateUtils.formatDate(new Date(System.currentTimeMillis() + 100000L)));
+
+        Assert.assertTrue(this.impl.getRetryInterval(response, null) > 1);
+    }
+
+    @Test
+    public void testRetryAfterHeaderAsPastDate() throws Exception {
+        final HttpResponse response = new BasicHttpResponse(503, "Oppsie");
+
+        response.setHeader(HttpHeaders.RETRY_AFTER, DateUtils.formatDate(new Date(System.currentTimeMillis() - 100000L)));
+
+        Assert.assertEquals(0, this.impl.getRetryInterval(response, null));
+    }
+
+    @Test
+    public void testInvalidRetryAfterHeader() throws Exception {
+        final DefaultServiceUnavailableRetryStrategy impl = new DefaultServiceUnavailableRetryStrategy(3, 1234);
+
+        final HttpResponse response = new BasicHttpResponse(503, "Oppsie");
+        response.setHeader(HttpHeaders.RETRY_AFTER, "Stuff");
+
+        Assert.assertEquals(1234, impl.getRetryInterval(response, null));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestBasicCredentialsProvider.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestBasicCredentialsProvider.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestBasicCredentialsProvider.java
index 96cdc0c..cf5a5c1 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestBasicCredentialsProvider.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestBasicCredentialsProvider.java
@@ -29,7 +29,6 @@ package org.apache.hc.client5.http.impl.auth;
 import org.apache.hc.client5.http.auth.AuthScope;
 import org.apache.hc.client5.http.auth.Credentials;
 import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
-import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
 import org.apache.hc.core5.http.HttpHost;
 import org.junit.Assert;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestBasicScheme.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestBasicScheme.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestBasicScheme.java
index 4df6697..28e7589 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestBasicScheme.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestBasicScheme.java
@@ -39,7 +39,6 @@ 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.impl.sync.BasicCredentialsProvider;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.ParseException;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestDigestScheme.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestDigestScheme.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestDigestScheme.java
index 8d52c71..b464d9c 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestDigestScheme.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestDigestScheme.java
@@ -45,7 +45,6 @@ import org.apache.hc.client5.http.auth.ChallengeType;
 import org.apache.hc.client5.http.auth.Credentials;
 import org.apache.hc.client5.http.auth.MalformedChallengeException;
 import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
-import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.HeaderElement;
 import org.apache.hc.core5.http.HttpHost;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestHttpAuthenticator.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestHttpAuthenticator.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestHttpAuthenticator.java
index 27ddcf8..778d5f1 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestHttpAuthenticator.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestHttpAuthenticator.java
@@ -39,7 +39,7 @@ import org.apache.hc.client5.http.auth.ChallengeType;
 import org.apache.hc.client5.http.auth.Credentials;
 import org.apache.hc.client5.http.auth.CredentialsProvider;
 import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
-import org.apache.hc.client5.http.impl.protocol.DefaultAuthenticationStrategy;
+import org.apache.hc.client5.http.impl.DefaultAuthenticationStrategy;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpHost;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestRequestAuthCache.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestRequestAuthCache.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestRequestAuthCache.java
index 0052705..29dbc37 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestRequestAuthCache.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestRequestAuthCache.java
@@ -32,7 +32,6 @@ import org.apache.hc.client5.http.auth.AuthExchange;
 import org.apache.hc.client5.http.auth.AuthScope;
 import org.apache.hc.client5.http.auth.Credentials;
 import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
-import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.client5.http.protocol.RequestAuthCache;
 import org.apache.hc.core5.http.HttpHost;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestSystemDefaultCredentialsProvider.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestSystemDefaultCredentialsProvider.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestSystemDefaultCredentialsProvider.java
index 0e6586e..f0853c5 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestSystemDefaultCredentialsProvider.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestSystemDefaultCredentialsProvider.java
@@ -34,7 +34,7 @@ import java.net.URL;
 
 import org.apache.hc.client5.http.auth.AuthScope;
 import org.apache.hc.client5.http.auth.Credentials;
-import org.apache.hc.client5.http.sync.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.junit.Assert;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockClock.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockClock.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockClock.java
new file mode 100644
index 0000000..10d4ff8
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockClock.java
@@ -0,0 +1,42 @@
+/*
+ * ====================================================================
+ * 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;
+
+public class MockClock implements Clock {
+
+    private long t = System.currentTimeMillis();
+
+    @Override
+    public long getCurrentTime() {
+        return t;
+    }
+
+    public void setCurrentTime(final long now) {
+        t = now;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockConnPoolControl.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockConnPoolControl.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockConnPoolControl.java
new file mode 100644
index 0000000..24e17ba
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockConnPoolControl.java
@@ -0,0 +1,117 @@
+/*
+ * ====================================================================
+ * 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.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.core5.pool.ConnPoolControl;
+import org.apache.hc.core5.pool.PoolStats;
+import org.apache.hc.core5.util.TimeValue;
+
+public final class MockConnPoolControl implements ConnPoolControl<HttpRoute> {
+
+    private final ConcurrentHashMap<HttpRoute, Integer> maxPerHostMap;
+
+    private volatile int totalMax;
+    private volatile int defaultMax;
+
+    public MockConnPoolControl() {
+        super();
+        this.maxPerHostMap = new ConcurrentHashMap<>();
+        this.totalMax = 20;
+        this.defaultMax = 2;
+    }
+
+    @Override
+    public void setMaxTotal(final int max) {
+        this.totalMax = max;
+    }
+
+    @Override
+    public int getMaxTotal() {
+        return this.totalMax;
+    }
+
+    @Override
+    public PoolStats getTotalStats() {
+        return new PoolStats(-1, -1, -1, this.totalMax);
+    }
+
+    @Override
+    public PoolStats getStats(final HttpRoute route) {
+        return new PoolStats(-1, -1, -1, getMaxPerRoute(route));
+    }
+
+    @Override
+    public int getDefaultMaxPerRoute() {
+        return this.defaultMax;
+    }
+
+    @Override
+    public void setDefaultMaxPerRoute(final int max) {
+        this.defaultMax = max;
+    }
+
+    @Override
+    public void setMaxPerRoute(final HttpRoute route, final int max) {
+        this.maxPerHostMap.put(route, Integer.valueOf(max));
+    }
+
+    @Override
+    public int getMaxPerRoute(final HttpRoute route) {
+        final Integer max = this.maxPerHostMap.get(route);
+        if (max != null) {
+            return max.intValue();
+        } else {
+            return this.defaultMax;
+        }
+    }
+
+    @Override
+    public void closeIdle(final TimeValue idletime) {
+    }
+
+    @Override
+    public void closeExpired() {
+    }
+
+    public void setMaxForRoutes(final Map<HttpRoute, Integer> map) {
+        if (map == null) {
+            return;
+        }
+        this.maxPerHostMap.clear();
+        this.maxPerHostMap.putAll(map);
+    }
+
+    @Override
+    public String toString() {
+        return this.maxPerHostMap.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestAIMDBackoffManager.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestAIMDBackoffManager.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestAIMDBackoffManager.java
new file mode 100644
index 0000000..cb00a97
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestAIMDBackoffManager.java
@@ -0,0 +1,180 @@
+/*
+ * ====================================================================
+ * 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.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Random;
+
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.classic.BackoffManager;
+import org.apache.hc.core5.http.HttpHost;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestAIMDBackoffManager {
+
+    private AIMDBackoffManager impl;
+    private MockConnPoolControl connPerRoute;
+    private HttpRoute route;
+    private MockClock clock;
+
+    @Before
+    public void setUp() {
+        connPerRoute = new MockConnPoolControl();
+        route = new HttpRoute(new HttpHost("localhost", 80));
+        clock = new MockClock();
+        impl = new AIMDBackoffManager(connPerRoute, clock);
+        impl.setPerHostConnectionCap(10);
+    }
+
+    @Test
+    public void isABackoffManager() {
+        assertTrue(impl instanceof BackoffManager);
+    }
+
+    @Test
+    public void halvesConnectionsOnBackoff() {
+        connPerRoute.setMaxPerRoute(route, 4);
+        impl.backOff(route);
+        assertEquals(2, connPerRoute.getMaxPerRoute(route));
+    }
+
+    @Test
+    public void doesNotBackoffBelowOneConnection() {
+        connPerRoute.setMaxPerRoute(route, 1);
+        impl.backOff(route);
+        assertEquals(1, connPerRoute.getMaxPerRoute(route));
+    }
+
+    @Test
+    public void increasesByOneOnProbe() {
+        connPerRoute.setMaxPerRoute(route, 2);
+        impl.probe(route);
+        assertEquals(3, connPerRoute.getMaxPerRoute(route));
+    }
+
+    @Test
+    public void doesNotIncreaseBeyondPerHostMaxOnProbe() {
+        connPerRoute.setDefaultMaxPerRoute(5);
+        connPerRoute.setMaxPerRoute(route, 5);
+        impl.setPerHostConnectionCap(5);
+        impl.probe(route);
+        assertEquals(5, connPerRoute.getMaxPerRoute(route));
+    }
+
+    @Test
+    public void backoffDoesNotAdjustDuringCoolDownPeriod() {
+        connPerRoute.setMaxPerRoute(route, 4);
+        final long now = System.currentTimeMillis();
+        clock.setCurrentTime(now);
+        impl.backOff(route);
+        final long max = connPerRoute.getMaxPerRoute(route);
+        clock.setCurrentTime(now + 1);
+        impl.backOff(route);
+        assertEquals(max, connPerRoute.getMaxPerRoute(route));
+    }
+
+    @Test
+    public void backoffStillAdjustsAfterCoolDownPeriod() {
+        connPerRoute.setMaxPerRoute(route, 8);
+        final long now = System.currentTimeMillis();
+        clock.setCurrentTime(now);
+        impl.backOff(route);
+        final long max = connPerRoute.getMaxPerRoute(route);
+        clock.setCurrentTime(now + 10 * 1000L);
+        impl.backOff(route);
+        assertTrue(max == 1 || max > connPerRoute.getMaxPerRoute(route));
+    }
+
+    @Test
+    public void probeDoesNotAdjustDuringCooldownPeriod() {
+        connPerRoute.setMaxPerRoute(route, 4);
+        final long now = System.currentTimeMillis();
+        clock.setCurrentTime(now);
+        impl.probe(route);
+        final long max = connPerRoute.getMaxPerRoute(route);
+        clock.setCurrentTime(now + 1);
+        impl.probe(route);
+        assertEquals(max, connPerRoute.getMaxPerRoute(route));
+    }
+
+    @Test
+    public void probeStillAdjustsAfterCoolDownPeriod() {
+        connPerRoute.setMaxPerRoute(route, 8);
+        final long now = System.currentTimeMillis();
+        clock.setCurrentTime(now);
+        impl.probe(route);
+        final long max = connPerRoute.getMaxPerRoute(route);
+        clock.setCurrentTime(now + 10 * 1000L);
+        impl.probe(route);
+        assertTrue(max < connPerRoute.getMaxPerRoute(route));
+    }
+
+    @Test
+    public void willBackoffImmediatelyEvenAfterAProbe() {
+        connPerRoute.setMaxPerRoute(route, 8);
+        final long now = System.currentTimeMillis();
+        clock.setCurrentTime(now);
+        impl.probe(route);
+        final long max = connPerRoute.getMaxPerRoute(route);
+        clock.setCurrentTime(now + 1);
+        impl.backOff(route);
+        assertTrue(connPerRoute.getMaxPerRoute(route) < max);
+    }
+
+    @Test
+    public void backOffFactorIsConfigurable() {
+        connPerRoute.setMaxPerRoute(route, 10);
+        impl.setBackoffFactor(0.9);
+        impl.backOff(route);
+        assertEquals(9, connPerRoute.getMaxPerRoute(route));
+    }
+
+    @Test
+    public void coolDownPeriodIsConfigurable() {
+        long cd = new Random().nextLong() / 2;
+        if (cd < 0) {
+            cd *= -1;
+        }
+        if (cd < 1) {
+            cd++;
+        }
+        final long now = System.currentTimeMillis();
+        impl.setCooldownMillis(cd);
+        clock.setCurrentTime(now);
+        impl.probe(route);
+        final int max0 = connPerRoute.getMaxPerRoute(route);
+        clock.setCurrentTime(now);
+        impl.probe(route);
+        assertEquals(max0, connPerRoute.getMaxPerRoute(route));
+        clock.setCurrentTime(now + cd + 1);
+        impl.probe(route);
+        assertTrue(max0 < connPerRoute.getMaxPerRoute(route));
+    }
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestAbstractHttpClientResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestAbstractHttpClientResponseHandler.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestAbstractHttpClientResponseHandler.java
new file mode 100644
index 0000000..24b2975
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestAbstractHttpClientResponseHandler.java
@@ -0,0 +1,87 @@
+/*
+ * ====================================================================
+ * 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.HttpResponseException;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Unit tests for {@link BasicHttpClientResponseHandler}.
+ */
+public class TestAbstractHttpClientResponseHandler {
+
+    @Test
+    public void testSuccessfulResponse() throws Exception {
+        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+        final HttpEntity entity = new StringEntity("42");
+        Mockito.when(response.getCode()).thenReturn(200);
+        Mockito.when(response.getEntity()).thenReturn(entity);
+
+        final AbstractHttpClientResponseHandler<Integer> handler = new AbstractHttpClientResponseHandler<Integer>() {
+
+          @Override
+          public Integer handleEntity(final HttpEntity entity) throws IOException {
+            return Integer.valueOf(new String(EntityUtils.toByteArray(entity)));
+          }
+        };
+        final Integer number = handler.handleResponse(response);
+        Assert.assertEquals(42, number.intValue());
+    }
+
+    @SuppressWarnings("boxing")
+    @Test
+    public void testUnsuccessfulResponse() throws Exception {
+        final InputStream instream = Mockito.mock(InputStream.class);
+        final HttpEntity entity = Mockito.mock(HttpEntity.class);
+        Mockito.when(entity.isStreaming()).thenReturn(true);
+        Mockito.when(entity.getContent()).thenReturn(instream);
+        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+        Mockito.when(response.getCode()).thenReturn(404);
+        Mockito.when(response.getEntity()).thenReturn(entity);
+
+        final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
+        try {
+            handler.handleResponse(response);
+            Assert.fail("HttpResponseException expected");
+        } catch (final HttpResponseException ex) {
+            Assert.assertEquals(404, ex.getStatusCode());
+        }
+        Mockito.verify(entity).getContent();
+        Mockito.verify(instream).close();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/6d17126c/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestBasicResponseHandler.java
----------------------------------------------------------------------
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestBasicResponseHandler.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestBasicResponseHandler.java
new file mode 100644
index 0000000..08ac384
--- /dev/null
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestBasicResponseHandler.java
@@ -0,0 +1,79 @@
+/*
+ * ====================================================================
+ * 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.InputStream;
+
+import org.apache.hc.client5.http.HttpResponseException;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * Unit tests for {@link BasicHttpClientResponseHandler}.
+ */
+@SuppressWarnings("boxing") // test code
+public class TestBasicResponseHandler {
+
+    @Test
+    public void testSuccessfulResponse() throws Exception {
+        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+        final HttpEntity entity = new StringEntity("stuff");
+        Mockito.when(response.getCode()).thenReturn(200);
+        Mockito.when(response.getEntity()).thenReturn(entity);
+
+        final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
+        final String s = handler.handleResponse(response);
+        Assert.assertEquals("stuff", s);
+    }
+
+    @Test
+    public void testUnsuccessfulResponse() throws Exception {
+        final InputStream instream = Mockito.mock(InputStream.class);
+        final HttpEntity entity = Mockito.mock(HttpEntity.class);
+        Mockito.when(entity.isStreaming()).thenReturn(true);
+        Mockito.when(entity.getContent()).thenReturn(instream);
+        final ClassicHttpResponse response = Mockito.mock(ClassicHttpResponse.class);
+        Mockito.when(response.getCode()).thenReturn(404);
+        Mockito.when(response.getEntity()).thenReturn(entity);
+
+        final BasicHttpClientResponseHandler handler = new BasicHttpClientResponseHandler();
+        try {
+            handler.handleResponse(response);
+            Assert.fail("HttpResponseException expected");
+        } catch (final HttpResponseException ex) {
+            Assert.assertEquals(404, ex.getStatusCode());
+        }
+        Mockito.verify(entity).getContent();
+        Mockito.verify(instream).close();
+    }
+
+}