### Question:
AWSServerErrorRetryHandler extends BackoffLimitedRetryHandler { @Override public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) { switch (response.getStatusCode()) { case 500: case 503: if (response.getPayload() != null) { closeClientButKeepContentStream(response); AWSError error = utils.parseAWSErrorFromContent(command.getCurrentRequest(), response); if (error != null) { return shouldRetryRequestOnError(command, response, error); } } break; case 504: return super.shouldRetryRequest(command, response); } return false; } @Inject  AWSServerErrorRetryHandler(AWSUtils utils,
         @ServerError Set<String> retryableServerCodes); @Override boolean shouldRetryRequest(HttpCommand command, HttpResponse response); void imposeBackoffExponentialDelay(long period, int pow, int failureCount, int max, String commandDescription);  }### Answer:
@Test public void testUnknown500DoesNotRetry() { AWSUtils utils = createMock(AWSUtils.class); HttpCommand command = createMock(HttpCommand.class); replay(utils, command); AWSServerErrorRetryHandler retry = new AWSServerErrorRetryHandler(utils, ImmutableSet.<String> of()); assertFalse(retry.shouldRetryRequest(command, HttpResponse.builder().statusCode(INTERNAL_SERVER_ERROR.getStatusCode()).build())); verify(utils, command); }
@Test(dataProvider = "codes") public void testDoesBackoffAndRetryForHttpStatusCodeAndErrorCode(int httpStatusCode, String errorCode) { AWSUtils utils = createMock(AWSUtils.class); HttpCommand command = createMock(HttpCommand.class); HttpRequest putBucket = HttpRequest.builder().method(PUT) .endpoint("https: HttpResponse response = HttpResponse.builder().statusCode(httpStatusCode) .payload(Payloads.newStringPayload(String.format("<Error><Code>%s</Code></Error>", errorCode))).build(); expect(command.getCurrentRequest()).andReturn(putBucket); final AtomicInteger counter = new AtomicInteger(); expect(command.incrementFailureCount()).andAnswer(new IAnswer<Integer>() { @Override public Integer answer() throws Throwable { return counter.incrementAndGet(); } }).anyTimes(); expect(command.isReplayable()).andReturn(true).anyTimes(); expect(command.getFailureCount()).andAnswer(new IAnswer<Integer>() { @Override public Integer answer() throws Throwable { return counter.get(); } }).anyTimes(); AWSError error = new AWSError(); error.setCode(errorCode); expect(utils.parseAWSErrorFromContent(putBucket, response)).andReturn(error); replay(utils, command); AWSServerErrorRetryHandler retry = new AWSServerErrorRetryHandler(utils, ImmutableSet.of("RequestLimitExceeded", "InternalError")); assert retry.shouldRetryRequest(command, response); verify(utils, command); }
@Test public void test504DoesRetry() { AWSUtils utils = createMock(AWSUtils.class); HttpCommand command = createMock(HttpCommand.class); expect(command.getFailureCount()).andReturn(1).anyTimes(); expect(command.incrementFailureCount()).andReturn(1); expect(command.isReplayable()).andReturn(true); replay(utils, command); AWSServerErrorRetryHandler retry = new AWSServerErrorRetryHandler(utils, ImmutableSet.<String> of()); assertTrue(retry.shouldRetryRequest(command, HttpResponse.builder().statusCode(504).build())); verify(utils, command); }