11/*
22 * Copyright (c) 2010 Google Inc.
3- *
3+ *
44 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55 * in compliance with the License. You may obtain a copy of the License at
6- *
6+ *
77 * http://www.apache.org/licenses/LICENSE-2.0
8- *
8+ *
99 * Unless required by applicable law or agreed to in writing, software distributed under the License
1010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
1111 * or implied. See the License for the specific language governing permissions and limitations under
3737
3838/**
3939 * Tests {@link HttpRequest}.
40- *
40+ *
4141 * @author Yaniv Inbar
4242 */
4343public class HttpRequestTest extends TestCase {
@@ -272,13 +272,13 @@ public void testMissingLocationRedirect() throws IOException {
272272 Assert .assertEquals (1 , fakeTransport .lowLevelExecCalls );
273273 }
274274
275- static private class FailThenSuccessTransport extends MockHttpTransport {
275+ static private class FailThenSuccessBackoffTransport extends MockHttpTransport {
276276
277277 public int lowLevelExecCalls ;
278278 int errorStatusCode ;
279279 int callsBeforeSuccess ;
280280
281- protected FailThenSuccessTransport (int errorStatusCode , int callsBeforeSuccess ) {
281+ protected FailThenSuccessBackoffTransport (int errorStatusCode , int callsBeforeSuccess ) {
282282 this .errorStatusCode = errorStatusCode ;
283283 this .callsBeforeSuccess = callsBeforeSuccess ;
284284 }
@@ -310,9 +310,88 @@ public LowLevelHttpRequest buildGetRequest(String url) {
310310 }
311311 }
312312
313+ static private class FailThenSuccessConnectionErrorTransport extends MockHttpTransport {
314+
315+ public int lowLevelExecCalls ;
316+ int callsBeforeSuccess ;
317+
318+ protected FailThenSuccessConnectionErrorTransport (int callsBeforeSuccess ) {
319+ this .callsBeforeSuccess = callsBeforeSuccess ;
320+ }
321+
322+ public LowLevelHttpRequest retryableGetRequest = new MockLowLevelHttpRequest () {
323+
324+ @ Override
325+ public LowLevelHttpResponse execute () throws IOException {
326+ lowLevelExecCalls ++;
327+
328+ if (lowLevelExecCalls <= callsBeforeSuccess ) {
329+ throw new IOException ();
330+ }
331+ // Return success when count is more than callsBeforeSuccess
332+ MockLowLevelHttpResponse response = new MockLowLevelHttpResponse ();
333+ response .setStatusCode (200 );
334+ return response ;
335+ }
336+ };
337+
338+ @ Override
339+ public LowLevelHttpRequest buildGetRequest (String url ) {
340+ return retryableGetRequest ;
341+ }
342+ }
343+
344+ public void testExecuteErrorWithRetryEnabled () throws IOException {
345+ int callsBeforeSuccess = 3 ;
346+ FailThenSuccessConnectionErrorTransport fakeTransport =
347+ new FailThenSuccessConnectionErrorTransport (callsBeforeSuccess );
348+ HttpRequest req =
349+ fakeTransport .createRequestFactory ().buildGetRequest (new GenericUrl ("http://not/used" ));
350+ req .setRetryOnExecuteIOException (true );
351+ req .setNumberOfRetries (callsBeforeSuccess + 1 );
352+ HttpResponse resp = req .execute ();
353+
354+ Assert .assertEquals (200 , resp .getStatusCode ());
355+ Assert .assertEquals (4 , fakeTransport .lowLevelExecCalls );
356+ }
357+
358+ public void testExecuteErrorWithRetryEnabledBeyondRetryLimit () throws IOException {
359+ int callsBeforeSuccess = 11 ;
360+ FailThenSuccessConnectionErrorTransport fakeTransport =
361+ new FailThenSuccessConnectionErrorTransport (callsBeforeSuccess );
362+ HttpRequest req =
363+ fakeTransport .createRequestFactory ().buildGetRequest (new GenericUrl ("http://not/used" ));
364+ req .setRetryOnExecuteIOException (true );
365+ req .setNumberOfRetries (callsBeforeSuccess - 1 );
366+ try {
367+ req .execute ();
368+ fail ("Expected: " + IOException .class );
369+ } catch (IOException e ) {
370+ // Expected
371+ }
372+ Assert .assertEquals (callsBeforeSuccess , fakeTransport .lowLevelExecCalls );
373+ }
374+
375+ public void testExecuteErrorWithRetryDisabled () throws IOException {
376+ int callsBeforeSuccess = 3 ;
377+ FailThenSuccessConnectionErrorTransport fakeTransport =
378+ new FailThenSuccessConnectionErrorTransport (callsBeforeSuccess );
379+ HttpRequest req =
380+ fakeTransport .createRequestFactory ().buildGetRequest (new GenericUrl ("http://not/used" ));
381+ // retryOnExecuteError is disabled by default.
382+ req .setNumberOfRetries (callsBeforeSuccess + 1 );
383+ try {
384+ req .execute ();
385+ fail ("Expected: " + IOException .class );
386+ } catch (IOException e ) {
387+ // Expected
388+ }
389+ Assert .assertEquals (1 , fakeTransport .lowLevelExecCalls );
390+ }
391+
313392 public void testAbnormalResponseHandlerWithNoBackOff () throws IOException {
314- FailThenSuccessTransport fakeTransport =
315- new FailThenSuccessTransport (HttpStatusCodes .STATUS_CODE_UNAUTHORIZED , 1 );
393+ FailThenSuccessBackoffTransport fakeTransport =
394+ new FailThenSuccessBackoffTransport (HttpStatusCodes .STATUS_CODE_UNAUTHORIZED , 1 );
316395 MockHttpUnsuccessfulResponseHandler handler = new MockHttpUnsuccessfulResponseHandler (true );
317396
318397 HttpRequest req =
@@ -327,8 +406,8 @@ public void testAbnormalResponseHandlerWithNoBackOff() throws IOException {
327406 }
328407
329408 public void testAbnormalResponseHandlerWithBackOff () throws IOException {
330- FailThenSuccessTransport fakeTransport =
331- new FailThenSuccessTransport (HttpStatusCodes .STATUS_CODE_SERVER_ERROR , 1 );
409+ FailThenSuccessBackoffTransport fakeTransport =
410+ new FailThenSuccessBackoffTransport (HttpStatusCodes .STATUS_CODE_SERVER_ERROR , 1 );
332411 MockHttpUnsuccessfulResponseHandler handler = new MockHttpUnsuccessfulResponseHandler (true );
333412 MockBackOffPolicy backOffPolicy = new MockBackOffPolicy ();
334413
@@ -346,8 +425,8 @@ public void testAbnormalResponseHandlerWithBackOff() throws IOException {
346425 }
347426
348427 public void testBackOffSingleCall () throws IOException {
349- FailThenSuccessTransport fakeTransport =
350- new FailThenSuccessTransport (HttpStatusCodes .STATUS_CODE_SERVER_ERROR , 1 );
428+ FailThenSuccessBackoffTransport fakeTransport =
429+ new FailThenSuccessBackoffTransport (HttpStatusCodes .STATUS_CODE_SERVER_ERROR , 1 );
351430 MockHttpUnsuccessfulResponseHandler handler = new MockHttpUnsuccessfulResponseHandler (false );
352431 MockBackOffPolicy backOffPolicy = new MockBackOffPolicy ();
353432
@@ -366,8 +445,9 @@ public void testBackOffSingleCall() throws IOException {
366445
367446 public void testBackOffMultipleCalls () throws IOException {
368447 int callsBeforeSuccess = 5 ;
369- FailThenSuccessTransport fakeTransport =
370- new FailThenSuccessTransport (HttpStatusCodes .STATUS_CODE_SERVER_ERROR , callsBeforeSuccess );
448+ FailThenSuccessBackoffTransport fakeTransport =
449+ new FailThenSuccessBackoffTransport (HttpStatusCodes .STATUS_CODE_SERVER_ERROR ,
450+ callsBeforeSuccess );
371451 MockHttpUnsuccessfulResponseHandler handler = new MockHttpUnsuccessfulResponseHandler (false );
372452 MockBackOffPolicy backOffPolicy = new MockBackOffPolicy ();
373453
@@ -386,13 +466,15 @@ public void testBackOffMultipleCalls() throws IOException {
386466
387467 public void testBackOffCallsBeyondRetryLimit () throws IOException {
388468 int callsBeforeSuccess = 11 ;
389- FailThenSuccessTransport fakeTransport =
390- new FailThenSuccessTransport (HttpStatusCodes .STATUS_CODE_SERVER_ERROR , callsBeforeSuccess );
469+ FailThenSuccessBackoffTransport fakeTransport =
470+ new FailThenSuccessBackoffTransport (HttpStatusCodes .STATUS_CODE_SERVER_ERROR ,
471+ callsBeforeSuccess );
391472 MockHttpUnsuccessfulResponseHandler handler = new MockHttpUnsuccessfulResponseHandler (false );
392473 MockBackOffPolicy backOffPolicy = new MockBackOffPolicy ();
393474
394475 HttpRequest req =
395476 fakeTransport .createRequestFactory ().buildGetRequest (new GenericUrl ("http://not/used" ));
477+ req .setNumberOfRetries (callsBeforeSuccess - 1 );
396478 req .setUnsuccessfulResponseHandler (handler );
397479 req .setBackOffPolicy (backOffPolicy );
398480 try {
@@ -407,8 +489,8 @@ public void testBackOffCallsBeyondRetryLimit() throws IOException {
407489 }
408490
409491 public void testBackOffUnRecognizedStatusCode () throws IOException {
410- FailThenSuccessTransport fakeTransport =
411- new FailThenSuccessTransport (HttpStatusCodes .STATUS_CODE_UNAUTHORIZED , 1 );
492+ FailThenSuccessBackoffTransport fakeTransport =
493+ new FailThenSuccessBackoffTransport (HttpStatusCodes .STATUS_CODE_UNAUTHORIZED , 1 );
412494 MockHttpUnsuccessfulResponseHandler handler = new MockHttpUnsuccessfulResponseHandler (false );
413495 MockBackOffPolicy backOffPolicy = new MockBackOffPolicy ();
414496
@@ -430,8 +512,9 @@ public void testBackOffUnRecognizedStatusCode() throws IOException {
430512
431513 public void testBackOffStop () throws IOException {
432514 int callsBeforeSuccess = 5 ;
433- FailThenSuccessTransport fakeTransport =
434- new FailThenSuccessTransport (HttpStatusCodes .STATUS_CODE_SERVER_ERROR , callsBeforeSuccess );
515+ FailThenSuccessBackoffTransport fakeTransport =
516+ new FailThenSuccessBackoffTransport (HttpStatusCodes .STATUS_CODE_SERVER_ERROR ,
517+ callsBeforeSuccess );
435518 MockHttpUnsuccessfulResponseHandler handler = new MockHttpUnsuccessfulResponseHandler (false );
436519 MockBackOffPolicy backOffPolicy = new MockBackOffPolicy ();
437520 backOffPolicy .returnBackOffStop = true ;
0 commit comments