private EmbeddedChannel doKeepAliveTest(EmbeddedChannel channel, HttpMethod httpMethod,
      RestServiceErrorCode errorCode, HttpResponseStatus expectedResponseStatus, int contentSize,
      Boolean keepAliveHint) {
    boolean keepAlive = true;
    for (int i = 0; i < 2; i++) {
      HttpHeaders httpHeaders = new DefaultHttpHeaders();
      TestingUri uri = TestingUri.OnResponseCompleteWithNonRestException;
      if (errorCode != null) {
        uri = TestingUri.OnResponseCompleteWithRestException;
        httpHeaders.set(MockNettyMessageProcessor.REST_SERVICE_ERROR_CODE_HEADER_NAME, errorCode);
      }
      if (!keepAlive) {
        httpHeaders.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
      }
      if (keepAliveHint != null) {
        // this will get set in the NettyRequest when it is created
        httpHeaders.set(RestUtils.InternalKeys.KEEP_ALIVE_ON_ERROR_HINT, keepAliveHint);
      }
      byte[] content = null;
      if (contentSize > 0) {
        content = TestUtils.getRandomBytes(contentSize);
      }
      HttpRequest request = RestTestUtils.createFullRequest(httpMethod, uri.toString(), httpHeaders, content);
      if (contentSize > 1) {
        HttpUtil.setTransferEncodingChunked(request, true);
      } else {
        HttpUtil.setContentLength(request, contentSize);
      }
      channel.writeInbound(request);
      HttpResponse response = channel.readOutbound();
      assertEquals("Unexpected response status", expectedResponseStatus, response.status());
      if (!(response instanceof FullHttpResponse)) {
        // empty the channel
        while (channel.readOutbound() != null) {
        }
      }
      boolean shouldBeAlive = true;
      if (keepAliveHint != null) {
        shouldBeAlive = keepAliveHint;
      } else if (httpMethod.equals(HttpMethod.POST)) {
        shouldBeAlive = false;
      } else if (httpMethod.equals(HttpMethod.PUT)) {
        shouldBeAlive = contentSize == 0;
      }
      shouldBeAlive = shouldBeAlive && keepAlive && !NettyResponseChannel.CLOSE_CONNECTION_ERROR_STATUSES.contains(
          expectedResponseStatus);

      assertEquals("Channel state (open/close) not as expected", shouldBeAlive, channel.isActive());
      assertEquals("Connection header should be consistent with channel state", shouldBeAlive,
          HttpUtil.isKeepAlive(response));
      if (!shouldBeAlive) {
        channel.close();
        channel = createEmbeddedChannel();
      }
      keepAlive = !keepAlive;
    }
    return channel;
  }
Does the keep-alive test by setting the {@link HttpHeaderNames#CONNECTION} to its two possible values and tests
that the response has the appropriate value for the {@link HttpHeaderNames#CONNECTION}.
@param channel the {@link EmbeddedChannel} to send the request over.
@param httpMethod the {@link HttpMethod} of the request.
@param errorCode the {@link RestServiceErrorCode} to induce at {@link MockNettyMessageProcessor}. {@code null} if
                 {@link TestingUri#OnResponseCompleteWithNonRestException} is desired.
@param expectedResponseStatus the expected {@link HttpResponseStatus} from remote.
@param contentSize the size of the content to attach with the request. No content attached if size is 0. If size >
                   1, then {@link HttpHeaderNames#TRANSFER_ENCODING} is set to {@link HttpHeaderValues#CHUNKED}.
@param keepAliveHint if {@code null}, no hint is added. If not {@code null}, hint is set to the given value
@return the {@link EmbeddedChannel} to use once this function is complete. If the channel did not close, this
function will return the {@code channel} instance that was passed, otherwise it returns a new channel.
ambry-rest/src/test/java/com/github/ambry/rest/NettyResponseChannelTest.java