hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1448420 [4/4] - in /httpcomponents/httpcore/trunk: ./ httpcore-ab/src/main/java/org/apache/http/benchmark/ httpcore-nio/src/main/java/org/apache/http/impl/nio/ httpcore-nio/src/main/java/org/apache/http/impl/nio/codecs/ httpcore-nio/src/ma...
Date Wed, 20 Feb 2013 21:16:21 GMT
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java?rev=1448420&r1=1448419&r2=1448420&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java
(original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java
Wed Feb 20 21:16:19 2013
@@ -27,68 +27,71 @@
 
 package org.apache.http.impl.nio.codecs;
 
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.OutputStreamWriter;
+import java.io.IOException;
+import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
 import java.nio.channels.FileChannel;
-import java.nio.channels.WritableByteChannel;
 
 import org.apache.http.Consts;
+import org.apache.http.WritableByteChannelMock;
 import org.apache.http.impl.io.HttpTransportMetricsImpl;
 import org.apache.http.impl.nio.reactor.SessionOutputBufferImpl;
 import org.apache.http.nio.reactor.SessionOutputBuffer;
-import org.apache.http.util.EncodingUtils;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 /**
  * Simple tests for {@link LengthDelimitedEncoder}.
  */
 public class TestLengthDelimitedEncoder {
 
-    private static ByteBuffer wrap(final String s) {
-        return ByteBuffer.wrap(EncodingUtils.getAsciiBytes(s));
+    private File tmpfile;
+
+    protected File createTempFile() throws IOException {
+        this.tmpfile = File.createTempFile("testFile", ".txt");
+        return this.tmpfile;
     }
 
-    private static WritableByteChannel newChannel(final ByteArrayOutputStream baos) {
-        return Channels.newChannel(baos);
+    @After
+    public void deleteTempFile() {
+        if (this.tmpfile != null && this.tmpfile.exists()) {
+            this.tmpfile.delete();
+        }
     }
 
     @Test
     public void testBasicCoding() throws Exception {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final WritableByteChannel channel = newChannel(baos);
-        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, Consts.ASCII);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
-        encoder.write(wrap("stuff;"));
-        encoder.write(wrap("more stuff"));
+        encoder.write(CodecTestUtils.wrap("stuff;"));
+        encoder.write(CodecTestUtils.wrap("more stuff"));
 
-        final String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
+        Assert.assertEquals("[content length: 16; pos: 16; completed: true]", encoder.toString());
     }
 
     @Test
     public void testCodingBeyondContentLimit() throws Exception {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final WritableByteChannel channel = newChannel(baos);
-        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, Consts.ASCII);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
-        encoder.write(wrap("stuff;"));
-        encoder.write(wrap("more stuff; and a lot more stuff"));
+        encoder.write(CodecTestUtils.wrap("stuff;"));
+        encoder.write(CodecTestUtils.wrap("more stuff; and a lot more stuff"));
 
-        final String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
@@ -96,23 +99,22 @@ public class TestLengthDelimitedEncoder 
 
     @Test
     public void testCodingEmptyBuffer() throws Exception {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final WritableByteChannel channel = newChannel(baos);
-        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, Consts.ASCII);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
-        encoder.write(wrap("stuff;"));
+        encoder.write(CodecTestUtils.wrap("stuff;"));
 
         final ByteBuffer empty = ByteBuffer.allocate(100);
         empty.flip();
         encoder.write(empty);
         encoder.write(null);
 
-        encoder.write(wrap("more stuff"));
+        encoder.write(CodecTestUtils.wrap("more stuff"));
 
-        final String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
@@ -120,194 +122,542 @@ public class TestLengthDelimitedEncoder 
 
     @Test
     public void testCodingCompleted() throws Exception {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final WritableByteChannel channel = newChannel(baos);
-        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, Consts.ASCII);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 5);
-        encoder.write(wrap("stuff"));
+        encoder.write(CodecTestUtils.wrap("stuff"));
 
         try {
-            encoder.write(wrap("more stuff"));
+            encoder.write(CodecTestUtils.wrap("more stuff"));
             Assert.fail("IllegalStateException should have been thrown");
         } catch (final IllegalStateException ex) {
             // ignore
         }
     }
 
-    /* ----------------- FileChannel Part testing --------------------------- */
+    @Test
+    public void testInvalidConstructor() {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        try {
+            new LengthDelimitedEncoder(null, null, null, 10);
+            Assert.fail("IllegalArgumentException should have been thrown");
+        } catch (final IllegalArgumentException ex) {
+            // ignore
+        }
+        try {
+            new LengthDelimitedEncoder(channel, null, null, 10);
+            Assert.fail("IllegalArgumentException should have been thrown");
+        } catch (final IllegalArgumentException ex) {
+            // ignore
+        }
+        try {
+            new LengthDelimitedEncoder(channel, outbuf, null, 10);
+            Assert.fail("IllegalArgumentException should have been thrown");
+        } catch (final IllegalArgumentException ex) {
+            // ignore
+        }
+        try {
+            new LengthDelimitedEncoder(channel, outbuf, metrics, -10);
+            Assert.fail("IllegalArgumentException should have been thrown");
+        } catch (final IllegalArgumentException ex) {
+            // ignore
+        }
+    }
+
     @Test
     public void testCodingBeyondContentLimitFromFile() throws Exception {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final WritableByteChannel channel = newChannel(baos);
-        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, Consts.ASCII);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
 
-        final File tmpFile = File.createTempFile("testFile", ".txt");
-        final FileOutputStream fout = new FileOutputStream(tmpFile);
-        final OutputStreamWriter wrtout = new OutputStreamWriter(fout);
-
-        wrtout.write("stuff;");
-        wrtout.write("more stuff; and a lot more stuff");
-
-        wrtout.flush();
-        wrtout.close();
-
-        final FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write("stuff;".getBytes("US-ASCII"));
+            testfile.write("more stuff; and a lot more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
+        }
 
-        encoder.transfer(fchannel, 0, 20);
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
+        }
 
-        final String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
-
-        fchannel.close();
-
-        deleteWithCheck(tmpFile);
-    }
-
-    private void deleteWithCheck(final File handle){
-        if (!handle.delete() && handle.exists()){
-            System.err.println("Failed to delete: "+handle.getPath());
-        }
     }
 
     @Test
     public void testCodingEmptyFile() throws Exception {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final WritableByteChannel channel = newChannel(baos);
-        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, Consts.ASCII);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
-        encoder.write(wrap("stuff;"));
+        encoder.write(CodecTestUtils.wrap("stuff;"));
 
         //Create an empty file
-        final File tmpFile = File.createTempFile("testFile", ".txt");
-        final FileOutputStream fout = new FileOutputStream(tmpFile);
-        final OutputStreamWriter wrtout = new OutputStreamWriter(fout);
-
-        wrtout.flush();
-        wrtout.close();
-
-        final FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        testfile.close();
 
-        encoder.transfer(fchannel, 0, 20);
-
-        encoder.write(wrap("more stuff"));
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+            encoder.write(CodecTestUtils.wrap("more stuff"));
+        } finally {
+            testfile.close();
+        }
 
-        final String s = baos.toString("US-ASCII");
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
-
-        fchannel.close();
-        deleteWithCheck(tmpFile);
     }
 
     @Test
     public void testCodingCompletedFromFile() throws Exception {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final WritableByteChannel channel = newChannel(baos);
-        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, Consts.ASCII);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 5);
-        encoder.write(wrap("stuff"));
-
-        final File tmpFile = File.createTempFile("testFile", ".txt");
-        final FileOutputStream fout = new FileOutputStream(tmpFile);
-        final OutputStreamWriter wrtout = new OutputStreamWriter(fout);
-
-        wrtout.write("more stuff");
+        encoder.write(CodecTestUtils.wrap("stuff"));
 
-        wrtout.flush();
-        wrtout.close();
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write("more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
+        }
 
-        final FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
+            final FileChannel fchannel = testfile.getChannel();
             encoder.transfer(fchannel, 0, 10);
             Assert.fail("IllegalStateException should have been thrown");
         } catch (final IllegalStateException ex) {
             // ignore
         } finally {
-            fchannel.close();
-            deleteWithCheck(tmpFile);
+            testfile.close();
         }
     }
 
     @Test
     public void testCodingFromFileSmaller() throws Exception {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final WritableByteChannel channel = newChannel(baos);
-        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, Consts.ASCII);
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
                 channel, outbuf, metrics, 16);
 
-        final File tmpFile = File.createTempFile("testFile", ".txt");
-        final FileOutputStream fout = new FileOutputStream(tmpFile);
-        final OutputStreamWriter wrtout = new OutputStreamWriter(fout);
-
-        wrtout.write("stuff;");
-        wrtout.write("more stuff;");
-
-        wrtout.flush();
-        wrtout.close();
-
-        final FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
-
-        encoder.transfer(fchannel, 0, 20);
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            testfile.write("stuff;".getBytes("US-ASCII"));
+            testfile.write("more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
+        }
 
-        final String s = baos.toString("US-ASCII");
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
+        try {
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
+        }
+        final String s = channel.dump(Consts.ASCII);
 
         Assert.assertTrue(encoder.isCompleted());
         Assert.assertEquals("stuff;more stuff", s);
-
-        fchannel.close();
-        deleteWithCheck(tmpFile);
     }
 
     @Test
-    public void testInvalidConstructor() {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final WritableByteChannel channel = newChannel(baos);
-        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128, Consts.ASCII);
+    public void testCodingFromFileFlushBuffer() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
 
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+                channel, outbuf, metrics, 16);
+
+        outbuf.writeLine("header");
+
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            new LengthDelimitedEncoder(null, null, null, 10);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (final IllegalArgumentException ex) {
-            // ignore
+            testfile.write("stuff;".getBytes("US-ASCII"));
+            testfile.write("more stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
         }
+
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            new LengthDelimitedEncoder(channel, null, null, 10);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (final IllegalArgumentException ex) {
-            // ignore
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
         }
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertTrue(encoder.isCompleted());
+        Assert.assertEquals("header\r\nstuff;more stuff", s);
+    }
+
+    @Test
+    public void testCodingFromFileChannelSaturated() throws Exception {
+        final WritableByteChannelMock channel = new WritableByteChannelMock(64, 4);
+        final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
+                channel, outbuf, metrics, 16);
+
+        outbuf.writeLine("header");
+
+        createTempFile();
+        RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            new LengthDelimitedEncoder(channel, outbuf, null, 10);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (final IllegalArgumentException ex) {
-            // ignore
+            testfile.write("stuff".getBytes("US-ASCII"));
+        } finally {
+            testfile.close();
         }
+
+        testfile = new RandomAccessFile(this.tmpfile, "rw");
         try {
-            new LengthDelimitedEncoder(channel, outbuf, metrics, -10);
-            Assert.fail("IllegalArgumentException should have been thrown");
-        } catch (final IllegalArgumentException ex) {
-            // ignore
+            final FileChannel fchannel = testfile.getChannel();
+            encoder.transfer(fchannel, 0, 20);
+            encoder.transfer(fchannel, 0, 20);
+        } finally {
+            testfile.close();
         }
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertFalse(encoder.isCompleted());
+        Assert.assertEquals("head", s);
+    }
+
+    @Test
+    public void testCodingNoFragmentBuffering() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        outbuf.writeLine("header");
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 0);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+
+        Mockito.verify(channel, Mockito.times(2)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(13, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("header\r\nstuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBuffering() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        outbuf.writeLine("header");
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 32);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+
+        Mockito.verify(channel, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).flush(channel);
+
+        Assert.assertEquals(0, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("header\r\nstuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingMultipleFragments() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 32);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).flush(channel);
+
+        Assert.assertEquals(0, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingMultipleFragmentsBeyondContentLimit() throws Exception
{
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            16, 32);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff; and a lot
more stuff")));
+
+        Mockito.verify(channel, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).flush(channel);
+
+        Assert.assertEquals(0, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingLargeFragment() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        outbuf.writeLine("header");
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 2);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+
+        Mockito.verify(channel, Mockito.times(2)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.never()).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(13, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+        Assert.assertEquals("header\r\nstuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingTinyFragments() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 1);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(5)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).flush(channel);
+
+        Assert.assertEquals(18, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff---more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingTinyFragments2() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 2);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(4)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(2)).flush(channel);
+
+        Assert.assertEquals(18, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff---more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingTinyFragments3() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 3);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(2, encoder.write(CodecTestUtils.wrap("--")));
+        Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(4)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(5)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(2)).flush(channel);
+
+        Assert.assertEquals(21, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff------more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingBufferFlush() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 8);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(6, encoder.write(CodecTestUtils.wrap("-stuff")));
+
+        Mockito.verify(channel, Mockito.times(1)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(8, metrics.getBytesTransferred());
+        Assert.assertEquals(3, outbuf.length());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingBufferFlush2() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 8);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(16, encoder.write(CodecTestUtils.wrap("-much more stuff")));
+
+        Mockito.verify(channel, Mockito.times(2)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(21, metrics.getBytesTransferred());
+        Assert.assertEquals(0, outbuf.length());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff-much more stuff", s);
+    }
+
+    @Test
+    public void testCodingFragmentBufferingChannelSaturated() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64,
8));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 3);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(0, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(0, encoder.write(CodecTestUtils.wrap("more stuff")));
+
+        Mockito.verify(channel, Mockito.times(5)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(6)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(4)).flush(channel);
+
+        Assert.assertEquals(8, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff---", s);
+        Assert.assertEquals(3, outbuf.length());
+    }
+
+    @Test
+    public void testCodingFragmentBufferingChannelSaturated2() throws Exception {
+        final WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64,
8));
+        final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024,
128));
+        final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
+
+        final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf,
metrics,
+            100, 8);
+        Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
+        Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("much more stuff")));
+
+        Mockito.verify(channel, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(3)).write(Mockito.<ByteBuffer>any());
+        Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
+
+        Assert.assertEquals(8, metrics.getBytesTransferred());
+
+        outbuf.flush(channel);
+        final String s = channel.dump(Consts.ASCII);
+
+        Assert.assertEquals("stuff--m", s);
+        Assert.assertEquals(0, outbuf.length());
     }
 
 }

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/util/TestBuffers.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/util/TestBuffers.java?rev=1448420&r1=1448419&r2=1448420&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/util/TestBuffers.java
(original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/util/TestBuffers.java
Wed Feb 20 21:16:19 2013
@@ -54,7 +54,7 @@ public class TestBuffers {
     @Test
     public void testInputBufferOperations() throws IOException {
         final ReadableByteChannel channel = new ReadableByteChannelMock(
-                new String[] {"stuff;", "more stuff"}, "US-ASCII");
+                new String[] {"stuff;", "more stuff"}, Consts.ASCII);
 
         final ContentDecoder decoder = new ContentDecoderMock(channel);
 

Modified: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/config/ConnectionConfig.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/config/ConnectionConfig.java?rev=1448420&r1=1448419&r2=1448420&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/config/ConnectionConfig.java
(original)
+++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/config/ConnectionConfig.java
Wed Feb 20 21:16:19 2013
@@ -44,23 +44,37 @@ public class ConnectionConfig implements
 
     public static final ConnectionConfig DEFAULT = new Builder().build();
 
+    private final int bufferSize;
+    private final int fragmentSizeHint;
     private final Charset charset;
     private final CodingErrorAction malformedInputAction;
     private final CodingErrorAction unmappableInputAction;
     private final MessageConstraints messageConstraints;
 
     ConnectionConfig(
+            final int bufferSize,
+            final int fragmentSizeHint,
             final Charset charset,
             final CodingErrorAction malformedInputAction,
             final CodingErrorAction unmappableInputAction,
             final MessageConstraints messageConstraints) {
         super();
+        this.bufferSize = bufferSize;
+        this.fragmentSizeHint = fragmentSizeHint;
         this.charset = charset;
         this.malformedInputAction = malformedInputAction;
         this.unmappableInputAction = unmappableInputAction;
         this.messageConstraints = messageConstraints;
     }
 
+    public int getBufferSize() {
+        return bufferSize;
+    }
+
+    public int getFragmentSizeHint() {
+        return fragmentSizeHint;
+    }
+
     public Charset getCharset() {
         return charset;
     }
@@ -85,7 +99,9 @@ public class ConnectionConfig implements
     @Override
     public String toString() {
         final StringBuilder builder = new StringBuilder();
-        builder.append("[charset=").append(this.charset)
+        builder.append("[bufferSize=").append(this.bufferSize)
+                .append(", fragmentSizeHint=").append(this.fragmentSizeHint)
+                .append(", charset=").append(this.charset)
                 .append(", malformedInputAction=").append(this.malformedInputAction)
                 .append(", unmappableInputAction=").append(this.unmappableInputAction)
                 .append(", messageConstraints=").append(this.messageConstraints)
@@ -108,16 +124,25 @@ public class ConnectionConfig implements
 
     public static class Builder {
 
+        private int bufferSize;
+        private int fragmentSizeHint;
         private Charset charset;
         private CodingErrorAction malformedInputAction;
         private CodingErrorAction unmappableInputAction;
         private MessageConstraints messageConstraints;
 
         Builder() {
+            this.fragmentSizeHint = -1;
         }
 
-        public Charset getCharset() {
-            return charset;
+        public Builder setBufferSize(final int bufferSize) {
+            this.bufferSize = bufferSize;
+            return this;
+        }
+
+        public Builder setFragmentSizeHint(final int fragmentSizeHint) {
+            this.fragmentSizeHint = fragmentSizeHint;
+            return this;
         }
 
         public Builder setCharset(final Charset charset) {
@@ -151,7 +176,11 @@ public class ConnectionConfig implements
             if (cs == null && (malformedInputAction != null || unmappableInputAction
!= null)) {
                 cs = Consts.ASCII;
             }
+            final int bufSize = this.bufferSize > 0 ? this.bufferSize : 8 * 1024;
+            final int fragmentHintSize  = this.fragmentSizeHint >= 0 ? this.fragmentSizeHint
: bufSize;
             return new ConnectionConfig(
+                    bufSize,
+                    fragmentHintSize,
                     charset,
                     malformedInputAction,
                     unmappableInputAction,



Mime
View raw message