private void contentAddAndReadTest(String digestAlgorithm, boolean useCopyForcingByteBuf, HttpMethod method)
      throws Exception {
    // non composite content
    // start reading before addition of content
    List<HttpContent> httpContents = new ArrayList<>();
    ByteBuffer content = generateContent(httpContents, useCopyForcingByteBuf);
    doContentAddAndReadTest(digestAlgorithm, content, httpContents, 0, method);

    // start reading in the middle of content add
    httpContents.clear();
    content = generateContent(httpContents, useCopyForcingByteBuf);
    doContentAddAndReadTest(digestAlgorithm, content, httpContents, httpContents.size() / 2, method);

    // start reading after all content added
    httpContents.clear();
    content = generateContent(httpContents, useCopyForcingByteBuf);
    doContentAddAndReadTest(digestAlgorithm, content, httpContents, httpContents.size(), method);

    // composite content
    httpContents.clear();
    content = generateCompositeContent(httpContents);
    doContentAddAndReadTest(digestAlgorithm, content, httpContents, 0, method);
  }
Tests {@link NettyRequest#addContent(HttpContent)} and
{@link NettyRequest#readInto(AsyncWritableChannel, Callback)} by creating a {@link NettyRequest}, adding a few
pieces of content to it and then reading from it to match the stream with the added content.
<p/>
The read happens at different points of time w.r.t content addition (before, during, after).
@param digestAlgorithm the digest algorithm to use. Can be empty or {@code null} if digest checking is not
                       required.
@param useCopyForcingByteBuf if {@code true}, uses {@link CopyForcingByteBuf} instead of the default
                             {@link ByteBuf}.
@param method Http method
@throws Exception
ambry-rest/src/test/java/com/github/ambry/rest/NettyRequestTest.java