private static <E extends Exception> void writeAndCheckCallback(Object buf, RetainingAsyncWritableChannel channel,
      long bytesWritten, Class<E> exceptionClass, RestServiceErrorCode errorCode) throws Exception {
    int remainingBeforeWrite = remainingBytes(buf);
    FutureResult<Long> callbackResult = new FutureResult<>();
    FutureResult<Long> futureResult = writeBufferToChannel(buf, channel, callbackResult);
    assertEquals("Unexpected number of bytes read from buffer", bytesWritten,
        remainingBeforeWrite - remainingBytes(buf));
    for (FutureResult<Long> f : Arrays.asList(futureResult, callbackResult)) {
      // operation should be completed within method body.
      assertTrue("Operation not completed", f.isDone());
      assertEquals("Bytes written incorrect in callback", bytesWritten, (long) f.result());
      if (exceptionClass != null) {
        TestUtils.assertException(ExecutionException.class, f::get, e -> {
          E exceptionCause = exceptionClass.cast(e.getCause());
          if (errorCode != null && exceptionCause instanceof RestServiceException) {
            assertEquals("Unexpected error code", errorCode, ((RestServiceException) exceptionCause).getErrorCode());
          }
        });
      }
    }
  }
Test the behavior of {@link RetainingAsyncWritableChannel#write(ByteBuffer, Callback)}.
@param buf the buffer to write.
@param channel the channel to write to.
@param bytesWritten the expected number of bytes written.
@param exceptionClass if non-null, check that the write operation encountered this exception.
@param errorCode if non-null, check that the cause {@link RestServiceException} has this error code.
ambry-commons/src/test/java/com/github/ambry/commons/RetainingAsyncWritableChannelTest.java