@Test
  public void testDecodingFileWithBufferedSessionData() throws Exception {
    final ReadableByteChannel channel =
        new ReadableByteChannelMock(
            new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, Consts.ASCII);

    final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
    final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
    final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);

    final int i = inbuf.fill(channel);
    Assert.assertEquals(7, i);

    createTempFile();
    final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
    try {
      final FileChannel fchannel = testfile.getChannel();
      long pos = 0;
      while (!decoder.isCompleted()) {
        final long bytesRead = decoder.transfer(fchannel, pos, 10);
        if (bytesRead > 0) {
          pos += bytesRead;
        }
      }

      // count everything except the initial 7 bytes that went to the session buffer
      Assert.assertEquals(testfile.length() - 7, metrics.getBytesTransferred());
    } finally {
      testfile.close();
    }
    Assert.assertEquals(
        "stuff; more stuff; a lot more stuff!", CodecTestUtils.readFromFile(this.tmpfile));
  }
  @Test
  public void testInvalidInput() throws Exception {
    final String s = "stuff";
    final ReadableByteChannel channel = new ReadableByteChannelMock(new String[] {s}, Consts.ASCII);

    final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
    final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
    final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);

    try {
      decoder.read(null);
      Assert.fail("IllegalArgumentException should have been thrown");
    } catch (final IllegalArgumentException ex) {
      // expected
    }
  }
  @Test
  public void testBasicDecoding() throws Exception {
    final ReadableByteChannel channel =
        new ReadableByteChannelMock(new String[] {"stuff;", "more stuff"}, Consts.ASCII);

    final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
    final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
    final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);

    final ByteBuffer dst = ByteBuffer.allocate(1024);

    int bytesRead = decoder.read(dst);
    Assert.assertEquals(6, bytesRead);
    Assert.assertEquals("stuff;", CodecTestUtils.convert(dst));
    Assert.assertFalse(decoder.isCompleted());
    Assert.assertEquals(6, metrics.getBytesTransferred());

    dst.clear();
    bytesRead = decoder.read(dst);
    Assert.assertEquals(10, bytesRead);
    Assert.assertEquals("more stuff", CodecTestUtils.convert(dst));
    Assert.assertFalse(decoder.isCompleted());
    Assert.assertEquals(16, metrics.getBytesTransferred());

    dst.clear();
    bytesRead = decoder.read(dst);
    Assert.assertEquals(-1, bytesRead);
    Assert.assertTrue(decoder.isCompleted());
    Assert.assertEquals(16, metrics.getBytesTransferred());

    dst.clear();
    bytesRead = decoder.read(dst);
    Assert.assertEquals(-1, bytesRead);
    Assert.assertTrue(decoder.isCompleted());
    Assert.assertEquals(16, metrics.getBytesTransferred());

    Assert.assertEquals("[identity; completed: true]", decoder.toString());
  }
  @Test
  public void testWriteBeyondFileSize() throws Exception {
    final ReadableByteChannel channel =
        new ReadableByteChannelMock(new String[] {"a"}, Consts.ASCII);

    final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII);
    final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
    final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics);

    createTempFile();
    final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
    try {
      Assert.assertEquals(0, testfile.length());
      final FileChannel fchannel = testfile.getChannel();
      try {
        decoder.transfer(fchannel, 5, 10);
        Assert.fail("expected IOException");
      } catch (final IOException iox) {
      }
    } finally {
      testfile.close();
    }
  }