/**
   * This test makes sure that even when the decoder is confronted with various chunk sizes in the
   * middle of decoding, it can recover and decode all the time eventually.
   */
  @Test
  public void shouldHandleNonUniformNetworkBatches() {
    ByteBuf incoming = Unpooled.copiedBuffer(SET_REQUEST_WITH_CONTENT);
    while (incoming.isReadable()) {
      channel.writeInbound(incoming.readBytes(5));
    }

    BinaryMemcacheRequest request = (BinaryMemcacheRequest) channel.readInbound();

    assertThat(request, notNullValue());
    assertThat(request.getHeader(), notNullValue());
    assertThat(request.getKey(), notNullValue());
    assertThat(request.getExtras(), nullValue());

    request.release();

    MemcacheContent content1 = (MemcacheContent) channel.readInbound();
    MemcacheContent content2 = (MemcacheContent) channel.readInbound();

    assertThat(content1, instanceOf(MemcacheContent.class));
    assertThat(content2, instanceOf(LastMemcacheContent.class));

    assertThat(content1.content().readableBytes(), is(3));
    assertThat(content2.content().readableBytes(), is(5));

    content1.release();
    content2.release();
  }
  @Test
  public void shouldDecodeSeparatedValues() {
    String msgBody = "Not found";
    channel = new EmbeddedChannel(new BinaryMemcacheResponseDecoder());

    channel.writeInbound(Unpooled.buffer().writeBytes(GET_RESPONSE_CHUNK_1));
    channel.writeInbound(Unpooled.buffer().writeBytes(GET_RESPONSE_CHUNK_2));

    // First message
    BinaryMemcacheResponse response = (BinaryMemcacheResponse) channel.readInbound();
    assertThat(response.getHeader().getStatus(), is(BinaryMemcacheResponseStatus.KEY_ENOENT));
    assertThat(response.getHeader().getTotalBodyLength(), is(msgBody.length()));
    response.release();

    // First message first content chunk
    MemcacheContent content = (MemcacheContent) channel.readInbound();
    assertThat(content, instanceOf(LastMemcacheContent.class));
    assertThat(content.content().toString(CharsetUtil.UTF_8), is(msgBody));
    content.release();

    // Second message
    response = (BinaryMemcacheResponse) channel.readInbound();
    assertThat(response.getHeader().getStatus(), is(BinaryMemcacheResponseStatus.KEY_ENOENT));
    assertThat(response.getHeader().getTotalBodyLength(), is(msgBody.length()));
    response.release();

    // Second message first content chunk
    content = (MemcacheContent) channel.readInbound();
    assertThat(content, instanceOf(MemcacheContent.class));
    assertThat(content.content().toString(CharsetUtil.UTF_8), is(msgBody.substring(0, 7)));
    content.release();

    // Second message second content chunk
    content = (MemcacheContent) channel.readInbound();
    assertThat(content, instanceOf(LastMemcacheContent.class));
    assertThat(content.content().toString(CharsetUtil.UTF_8), is(msgBody.substring(7, 9)));
    content.release();

    // Third message
    response = (BinaryMemcacheResponse) channel.readInbound();
    assertThat(response.getHeader().getStatus(), is(BinaryMemcacheResponseStatus.KEY_ENOENT));
    assertThat(response.getHeader().getTotalBodyLength(), is(msgBody.length()));
    response.release();

    // Third message first content chunk
    content = (MemcacheContent) channel.readInbound();
    assertThat(content, instanceOf(LastMemcacheContent.class));
    assertThat(content.content().toString(CharsetUtil.UTF_8), is(msgBody));
    content.release();
  }
  /** This test makes sure that large content is emitted in chunks. */
  @Test
  public void shouldDecodeRequestWithChunkedContent() {
    int smallBatchSize = 2;
    channel = new EmbeddedChannel(new BinaryMemcacheRequestDecoder(smallBatchSize));

    ByteBuf incoming = Unpooled.buffer();
    incoming.writeBytes(SET_REQUEST_WITH_CONTENT);
    channel.writeInbound(incoming);

    BinaryMemcacheRequest request = (BinaryMemcacheRequest) channel.readInbound();

    assertThat(request, notNullValue());
    assertThat(request.getHeader(), notNullValue());
    assertThat(request.getKey(), notNullValue());
    assertThat(request.getExtras(), nullValue());

    BinaryMemcacheRequestHeader header = request.getHeader();
    assertThat(header.getKeyLength(), is((short) 3));
    assertThat(header.getExtrasLength(), is((byte) 0));
    assertThat(header.getTotalBodyLength(), is(11));

    request.release();

    int expectedContentChunks = 4;
    for (int i = 1; i <= expectedContentChunks; i++) {
      MemcacheContent content = (MemcacheContent) channel.readInbound();
      if (i < expectedContentChunks) {
        assertThat(content, instanceOf(MemcacheContent.class));
      } else {
        assertThat(content, instanceOf(LastMemcacheContent.class));
      }
      assertThat(content.content().readableBytes(), is(2));
      content.release();
    }
    assertThat(channel.readInbound(), nullValue());
  }