@Test
  public void testCloseDuringPendingRequest() throws Exception {
    CyclicBarrier beforeRequest = new CyclicBarrier(2);
    CyclicBarrier afterRequest = new CyclicBarrier(2);
    StaticRequestProcessor processor = new StaticRequestProcessor(beforeRequest, afterRequest);
    processor.setResponse(
        new TestingResponse(
            HttpStatus.NO_CONTENT, ImmutableListMultimap.<String, String>of(), new byte[0]));

    CyclicBarrier requestComplete = new CyclicBarrier(2);
    TestingClientCallback callback = new TestingClientCallback(requestComplete);

    URI location = URI.create("http://localhost:8080");
    HttpPageBufferClient client =
        new HttpPageBufferClient(
            new TestingHttpClient(processor, executor),
            new DataSize(10, Unit.MEGABYTE),
            new Duration(1, TimeUnit.MINUTES),
            location,
            callback,
            blockEncodingManager,
            executor,
            Stopwatch.createUnstarted());

    assertStatus(client, location, "queued", 0, 0, 0, 0, "not scheduled");

    // send request
    client.scheduleRequest();
    beforeRequest.await(10, TimeUnit.SECONDS);
    assertStatus(client, location, "running", 0, 1, 0, 0, "PROCESSING_REQUEST");
    assertEquals(client.isRunning(), true);
    // request is pending, now close it
    client.close();

    try {
      requestComplete.await(10, TimeUnit.SECONDS);
    } catch (BrokenBarrierException ignored) {
    }
    try {
      afterRequest.await(10, TimeUnit.SECONDS);
    } catch (BrokenBarrierException ignored) {
      afterRequest.reset();
    }
    // client.close() triggers a DELETE request, so wait for it to finish
    beforeRequest.await(10, TimeUnit.SECONDS);
    afterRequest.await(10, TimeUnit.SECONDS);
    requestComplete.await(10, TimeUnit.SECONDS);
    assertStatus(client, location, "closed", 0, 1, 2, 1, "not scheduled");
  }
  @Test
  public void testInvalidResponses() throws Exception {
    CyclicBarrier beforeRequest = new CyclicBarrier(1);
    CyclicBarrier afterRequest = new CyclicBarrier(1);
    StaticRequestProcessor processor = new StaticRequestProcessor(beforeRequest, afterRequest);

    CyclicBarrier requestComplete = new CyclicBarrier(2);
    TestingClientCallback callback = new TestingClientCallback(requestComplete);

    URI location = URI.create("http://localhost:8080");
    HttpPageBufferClient client =
        new HttpPageBufferClient(
            new TestingHttpClient(processor, executor),
            new DataSize(10, Unit.MEGABYTE),
            new Duration(1, TimeUnit.MINUTES),
            location,
            callback,
            blockEncodingManager,
            executor,
            Stopwatch.createUnstarted());

    assertStatus(client, location, "queued", 0, 0, 0, 0, "not scheduled");

    // send not found response and verify response was ignored
    processor.setResponse(
        new TestingResponse(
            HttpStatus.NOT_FOUND,
            ImmutableListMultimap.of(CONTENT_TYPE, PRESTO_PAGES),
            new byte[0]));
    client.scheduleRequest();
    requestComplete.await(10, TimeUnit.SECONDS);
    assertEquals(callback.getPages().size(), 0);
    assertEquals(callback.getCompletedRequests(), 1);
    assertEquals(callback.getFinishedBuffers(), 0);
    assertEquals(callback.getFailedBuffers(), 1);
    assertInstanceOf(callback.getFailure(), PageTransportErrorException.class);
    assertContains(
        callback.getFailure().getMessage(),
        "Expected response code to be 200, but was 404 Not Found");
    assertStatus(client, location, "queued", 0, 1, 1, 1, "not scheduled");

    // send invalid content type response and verify response was ignored
    callback.resetStats();
    processor.setResponse(
        new TestingResponse(
            HttpStatus.OK, ImmutableListMultimap.of(CONTENT_TYPE, "INVALID_TYPE"), new byte[0]));
    client.scheduleRequest();
    requestComplete.await(10, TimeUnit.SECONDS);
    assertEquals(callback.getPages().size(), 0);
    assertEquals(callback.getCompletedRequests(), 1);
    assertEquals(callback.getFinishedBuffers(), 0);
    assertEquals(callback.getFailedBuffers(), 1);
    assertInstanceOf(callback.getFailure(), PageTransportErrorException.class);
    assertContains(
        callback.getFailure().getMessage(),
        "Expected application/x-presto-pages response from server but got INVALID_TYPE");
    assertStatus(client, location, "queued", 0, 2, 2, 2, "not scheduled");

    // send unexpected content type response and verify response was ignored
    callback.resetStats();
    processor.setResponse(
        new TestingResponse(
            HttpStatus.OK, ImmutableListMultimap.of(CONTENT_TYPE, "text/plain"), new byte[0]));
    client.scheduleRequest();
    requestComplete.await(10, TimeUnit.SECONDS);
    assertEquals(callback.getPages().size(), 0);
    assertEquals(callback.getCompletedRequests(), 1);
    assertEquals(callback.getFinishedBuffers(), 0);
    assertEquals(callback.getFailedBuffers(), 1);
    assertInstanceOf(callback.getFailure(), PageTransportErrorException.class);
    assertContains(
        callback.getFailure().getMessage(),
        "Expected application/x-presto-pages response from server but got text/plain");
    assertStatus(client, location, "queued", 0, 3, 3, 3, "not scheduled");

    // close client and verify
    client.close();
    requestComplete.await(10, TimeUnit.SECONDS);
    assertStatus(client, location, "closed", 0, 3, 4, 3, "not scheduled");
  }