View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http.impl.nio.codecs;
29  
30  import java.io.File;
31  import java.io.IOException;
32  import java.io.RandomAccessFile;
33  import java.nio.ByteBuffer;
34  import java.nio.channels.FileChannel;
35  
36  import org.apache.http.Consts;
37  import org.apache.http.WritableByteChannelMock;
38  import org.apache.http.impl.io.HttpTransportMetricsImpl;
39  import org.apache.http.impl.nio.reactor.SessionOutputBufferImpl;
40  import org.apache.http.nio.reactor.SessionOutputBuffer;
41  import org.junit.After;
42  import org.junit.Assert;
43  import org.junit.Test;
44  import org.mockito.Matchers;
45  import org.mockito.Mockito;
46  
47  /**
48   * Simple tests for {@link LengthDelimitedEncoder}.
49   */
50  public class TestLengthDelimitedEncoder {
51  
52      private File tmpfile;
53  
54      protected File createTempFile() throws IOException {
55          this.tmpfile = File.createTempFile("testFile", ".txt");
56          return this.tmpfile;
57      }
58  
59      @After
60      public void deleteTempFile() {
61          if (this.tmpfile != null && this.tmpfile.exists()) {
62              this.tmpfile.delete();
63          }
64      }
65  
66      @Test
67      public void testBasicCoding() throws Exception {
68          final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
69          final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
70          final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
71  
72          final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
73                  channel, outbuf, metrics, 16);
74          encoder.write(CodecTestUtils.wrap("stuff;"));
75          encoder.write(CodecTestUtils.wrap("more stuff"));
76  
77          final String s = channel.dump(Consts.ASCII);
78  
79          Assert.assertTrue(encoder.isCompleted());
80          Assert.assertEquals("stuff;more stuff", s);
81          Assert.assertEquals("[content length: 16; pos: 16; completed: true]", encoder.toString());
82      }
83  
84      @Test
85      public void testCodingBeyondContentLimit() throws Exception {
86          final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
87          final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
88          final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
89  
90          final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
91                  channel, outbuf, metrics, 16);
92          encoder.write(CodecTestUtils.wrap("stuff;"));
93          encoder.write(CodecTestUtils.wrap("more stuff; and a lot more stuff"));
94  
95          final String s = channel.dump(Consts.ASCII);
96  
97          Assert.assertTrue(encoder.isCompleted());
98          Assert.assertEquals("stuff;more stuff", s);
99      }
100 
101     @Test
102     public void testCodingEmptyBuffer() throws Exception {
103         final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
104         final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
105         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
106 
107         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
108                 channel, outbuf, metrics, 16);
109         encoder.write(CodecTestUtils.wrap("stuff;"));
110 
111         final ByteBuffer empty = ByteBuffer.allocate(100);
112         empty.flip();
113         encoder.write(empty);
114         encoder.write(null);
115 
116         encoder.write(CodecTestUtils.wrap("more stuff"));
117 
118         final String s = channel.dump(Consts.ASCII);
119 
120         Assert.assertTrue(encoder.isCompleted());
121         Assert.assertEquals("stuff;more stuff", s);
122     }
123 
124     @Test
125     public void testCodingCompleted() throws Exception {
126         final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
127         final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
128         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
129 
130         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
131                 channel, outbuf, metrics, 5);
132         encoder.write(CodecTestUtils.wrap("stuff"));
133 
134         try {
135             encoder.write(CodecTestUtils.wrap("more stuff"));
136             Assert.fail("IllegalStateException should have been thrown");
137         } catch (final IllegalStateException ex) {
138             // ignore
139         }
140     }
141 
142     @Test
143     public void testInvalidConstructor() {
144         final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
145         final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
146         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
147 
148         try {
149             new LengthDelimitedEncoder(null, null, null, 10);
150             Assert.fail("IllegalArgumentException should have been thrown");
151         } catch (final IllegalArgumentException ex) {
152             // ignore
153         }
154         try {
155             new LengthDelimitedEncoder(channel, null, null, 10);
156             Assert.fail("IllegalArgumentException should have been thrown");
157         } catch (final IllegalArgumentException ex) {
158             // ignore
159         }
160         try {
161             new LengthDelimitedEncoder(channel, outbuf, null, 10);
162             Assert.fail("IllegalArgumentException should have been thrown");
163         } catch (final IllegalArgumentException ex) {
164             // ignore
165         }
166         try {
167             new LengthDelimitedEncoder(channel, outbuf, metrics, -10);
168             Assert.fail("IllegalArgumentException should have been thrown");
169         } catch (final IllegalArgumentException ex) {
170             // ignore
171         }
172     }
173 
174     @Test
175     public void testCodingBeyondContentLimitFromFile() throws Exception {
176         final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
177         final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
178         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
179 
180         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
181                 channel, outbuf, metrics, 16);
182 
183         createTempFile();
184         RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
185         try {
186             testfile.write("stuff;".getBytes(Consts.ASCII));
187             testfile.write("more stuff; and a lot more stuff".getBytes(Consts.ASCII));
188         } finally {
189             testfile.close();
190         }
191 
192         testfile = new RandomAccessFile(this.tmpfile, "rw");
193         try {
194             final FileChannel fchannel = testfile.getChannel();
195             encoder.transfer(fchannel, 0, 20);
196         } finally {
197             testfile.close();
198         }
199 
200         final String s = channel.dump(Consts.ASCII);
201 
202         Assert.assertTrue(encoder.isCompleted());
203         Assert.assertEquals("stuff;more stuff", s);
204     }
205 
206     @Test
207     public void testCodingEmptyFile() throws Exception {
208         final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
209         final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
210         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
211 
212         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
213                 channel, outbuf, metrics, 16);
214         encoder.write(CodecTestUtils.wrap("stuff;"));
215 
216         //Create an empty file
217         createTempFile();
218         RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
219         testfile.close();
220 
221         testfile = new RandomAccessFile(this.tmpfile, "rw");
222         try {
223             final FileChannel fchannel = testfile.getChannel();
224             encoder.transfer(fchannel, 0, 20);
225             encoder.write(CodecTestUtils.wrap("more stuff"));
226         } finally {
227             testfile.close();
228         }
229 
230         final String s = channel.dump(Consts.ASCII);
231 
232         Assert.assertTrue(encoder.isCompleted());
233         Assert.assertEquals("stuff;more stuff", s);
234     }
235 
236     @Test
237     public void testCodingCompletedFromFile() throws Exception {
238         final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
239         final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
240         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
241 
242         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
243                 channel, outbuf, metrics, 5);
244         encoder.write(CodecTestUtils.wrap("stuff"));
245 
246         createTempFile();
247         RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
248         try {
249             testfile.write("more stuff".getBytes(Consts.ASCII));
250         } finally {
251             testfile.close();
252         }
253 
254         testfile = new RandomAccessFile(this.tmpfile, "rw");
255         try {
256             final FileChannel fchannel = testfile.getChannel();
257             encoder.transfer(fchannel, 0, 10);
258             Assert.fail("IllegalStateException should have been thrown");
259         } catch (final IllegalStateException ex) {
260             // ignore
261         } finally {
262             testfile.close();
263         }
264     }
265 
266     @Test
267     public void testCodingFromFileSmaller() throws Exception {
268         final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
269         final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
270         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
271 
272         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
273                 channel, outbuf, metrics, 16);
274 
275         createTempFile();
276         RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
277         try {
278             testfile.write("stuff;".getBytes(Consts.ASCII));
279             testfile.write("more stuff".getBytes(Consts.ASCII));
280         } finally {
281             testfile.close();
282         }
283 
284         testfile = new RandomAccessFile(this.tmpfile, "rw");
285         try {
286             final FileChannel fchannel = testfile.getChannel();
287             encoder.transfer(fchannel, 0, 20);
288         } finally {
289             testfile.close();
290         }
291         final String s = channel.dump(Consts.ASCII);
292 
293         Assert.assertTrue(encoder.isCompleted());
294         Assert.assertEquals("stuff;more stuff", s);
295     }
296 
297     @Test
298     public void testCodingFromFileFlushBuffer() throws Exception {
299         final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64);
300         final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
301         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
302 
303         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
304                 channel, outbuf, metrics, 16);
305 
306         outbuf.writeLine("header");
307 
308         createTempFile();
309         RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
310         try {
311             testfile.write("stuff;".getBytes(Consts.ASCII));
312             testfile.write("more stuff".getBytes(Consts.ASCII));
313         } finally {
314             testfile.close();
315         }
316 
317         testfile = new RandomAccessFile(this.tmpfile, "rw");
318         try {
319             final FileChannel fchannel = testfile.getChannel();
320             encoder.transfer(fchannel, 0, 20);
321         } finally {
322             testfile.close();
323         }
324         final String s = channel.dump(Consts.ASCII);
325 
326         Assert.assertTrue(encoder.isCompleted());
327         Assert.assertEquals("header\r\nstuff;more stuff", s);
328     }
329 
330     @Test
331     public void testCodingFromFileChannelSaturated() throws Exception {
332         final WritableByteChannelMockhtml#WritableByteChannelMock">WritableByteChannelMock channel = new WritableByteChannelMock(64, 4);
333         final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128);
334         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
335 
336         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(
337                 channel, outbuf, metrics, 16);
338 
339         outbuf.writeLine("header");
340 
341         createTempFile();
342         RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw");
343         try {
344             testfile.write("stuff".getBytes(Consts.ASCII));
345         } finally {
346             testfile.close();
347         }
348 
349         testfile = new RandomAccessFile(this.tmpfile, "rw");
350         try {
351             final FileChannel fchannel = testfile.getChannel();
352             encoder.transfer(fchannel, 0, 20);
353             encoder.transfer(fchannel, 0, 20);
354         } finally {
355             testfile.close();
356         }
357         final String s = channel.dump(Consts.ASCII);
358 
359         Assert.assertFalse(encoder.isCompleted());
360         Assert.assertEquals("head", s);
361     }
362 
363     @Test
364     public void testCodingNoFragmentBuffering() throws Exception {
365         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
366         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
367         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
368 
369         outbuf.writeLine("header");
370         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
371             100, 0);
372         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
373 
374         Mockito.verify(channel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
375         Mockito.verify(outbuf, Mockito.never()).write(Matchers.<ByteBuffer>any());
376         Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
377 
378         Assert.assertEquals(13, metrics.getBytesTransferred());
379 
380         outbuf.flush(channel);
381         final String s = channel.dump(Consts.ASCII);
382 
383         Assert.assertEquals("header\r\nstuff", s);
384     }
385 
386     @Test
387     public void testCodingFragmentBuffering() throws Exception {
388         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
389         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
390         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
391 
392         outbuf.writeLine("header");
393         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
394             100, 32);
395         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
396 
397         Mockito.verify(channel, Mockito.never()).write(Matchers.<ByteBuffer>any());
398         Mockito.verify(outbuf, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
399         Mockito.verify(outbuf, Mockito.never()).flush(channel);
400 
401         Assert.assertEquals(0, metrics.getBytesTransferred());
402 
403         outbuf.flush(channel);
404         final String s = channel.dump(Consts.ASCII);
405 
406         Assert.assertEquals("header\r\nstuff", s);
407     }
408 
409     @Test
410     public void testCodingFragmentBufferingMultipleFragments() throws Exception {
411         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
412         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
413         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
414 
415         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
416             100, 32);
417         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
418         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
419         Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
420 
421         Mockito.verify(channel, Mockito.never()).write(Matchers.<ByteBuffer>any());
422         Mockito.verify(outbuf, Mockito.times(3)).write(Matchers.<ByteBuffer>any());
423         Mockito.verify(outbuf, Mockito.never()).flush(channel);
424 
425         Assert.assertEquals(0, metrics.getBytesTransferred());
426 
427         outbuf.flush(channel);
428         final String s = channel.dump(Consts.ASCII);
429 
430         Assert.assertEquals("stuff-more stuff", s);
431     }
432 
433     @Test
434     public void testCodingFragmentBufferingMultipleFragmentsBeyondContentLimit() throws Exception {
435         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
436         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
437         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
438 
439         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
440             16, 32);
441         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
442         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
443         Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff; and a lot more stuff")));
444 
445         Mockito.verify(channel, Mockito.never()).write(Matchers.<ByteBuffer>any());
446         Mockito.verify(outbuf, Mockito.times(3)).write(Matchers.<ByteBuffer>any());
447         Mockito.verify(outbuf, Mockito.never()).flush(channel);
448 
449         Assert.assertEquals(0, metrics.getBytesTransferred());
450 
451         outbuf.flush(channel);
452         final String s = channel.dump(Consts.ASCII);
453 
454         Assert.assertEquals("stuff-more stuff", s);
455     }
456 
457     @Test
458     public void testCodingFragmentBufferingLargeFragment() throws Exception {
459         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
460         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
461         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
462 
463         outbuf.writeLine("header");
464         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
465             100, 2);
466         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
467 
468         Mockito.verify(channel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
469         Mockito.verify(outbuf, Mockito.never()).write(Matchers.<ByteBuffer>any());
470         Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
471 
472         Assert.assertEquals(13, metrics.getBytesTransferred());
473 
474         outbuf.flush(channel);
475         final String s = channel.dump(Consts.ASCII);
476         Assert.assertEquals("header\r\nstuff", s);
477     }
478 
479     @Test
480     public void testCodingFragmentBufferingTinyFragments() throws Exception {
481         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
482         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
483         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
484 
485         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
486             100, 1);
487         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
488         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
489         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
490         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
491         Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
492 
493         Mockito.verify(channel, Mockito.times(5)).write(Matchers.<ByteBuffer>any());
494         Mockito.verify(outbuf, Mockito.times(3)).write(Matchers.<ByteBuffer>any());
495         Mockito.verify(outbuf, Mockito.times(3)).flush(channel);
496 
497         Assert.assertEquals(18, metrics.getBytesTransferred());
498 
499         outbuf.flush(channel);
500         final String s = channel.dump(Consts.ASCII);
501 
502         Assert.assertEquals("stuff---more stuff", s);
503     }
504 
505     @Test
506     public void testCodingFragmentBufferingTinyFragments2() throws Exception {
507         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
508         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
509         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
510 
511         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
512             100, 2);
513         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
514         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
515         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
516         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
517         Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
518 
519         Mockito.verify(channel, Mockito.times(4)).write(Matchers.<ByteBuffer>any());
520         Mockito.verify(outbuf, Mockito.times(3)).write(Matchers.<ByteBuffer>any());
521         Mockito.verify(outbuf, Mockito.times(2)).flush(channel);
522 
523         Assert.assertEquals(18, metrics.getBytesTransferred());
524 
525         outbuf.flush(channel);
526         final String s = channel.dump(Consts.ASCII);
527 
528         Assert.assertEquals("stuff---more stuff", s);
529     }
530 
531     @Test
532     public void testCodingFragmentBufferingTinyFragments3() throws Exception {
533         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
534         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
535         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
536 
537         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
538             100, 3);
539         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
540         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
541         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
542         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
543         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
544         Assert.assertEquals(2, encoder.write(CodecTestUtils.wrap("--")));
545         Assert.assertEquals(10, encoder.write(CodecTestUtils.wrap("more stuff")));
546 
547         Mockito.verify(channel, Mockito.times(4)).write(Matchers.<ByteBuffer>any());
548         Mockito.verify(outbuf, Mockito.times(5)).write(Matchers.<ByteBuffer>any());
549         Mockito.verify(outbuf, Mockito.times(2)).flush(channel);
550 
551         Assert.assertEquals(21, metrics.getBytesTransferred());
552 
553         outbuf.flush(channel);
554         final String s = channel.dump(Consts.ASCII);
555 
556         Assert.assertEquals("stuff------more stuff", s);
557     }
558 
559     @Test
560     public void testCodingFragmentBufferingBufferFlush() throws Exception {
561         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
562         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
563         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
564 
565         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
566             100, 8);
567         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
568         Assert.assertEquals(6, encoder.write(CodecTestUtils.wrap("-stuff")));
569 
570         Mockito.verify(channel, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
571         Mockito.verify(outbuf, Mockito.times(3)).write(Matchers.<ByteBuffer>any());
572         Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
573 
574         Assert.assertEquals(8, metrics.getBytesTransferred());
575         Assert.assertEquals(3, outbuf.length());
576 
577         outbuf.flush(channel);
578         final String s = channel.dump(Consts.ASCII);
579 
580         Assert.assertEquals("stuff-stuff", s);
581     }
582 
583     @Test
584     public void testCodingFragmentBufferingBufferFlush2() throws Exception {
585         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64));
586         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
587         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
588 
589         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
590             100, 8);
591         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
592         Assert.assertEquals(16, encoder.write(CodecTestUtils.wrap("-much more stuff")));
593 
594         Mockito.verify(channel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
595         Mockito.verify(outbuf, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
596         Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
597 
598         Assert.assertEquals(21, metrics.getBytesTransferred());
599         Assert.assertEquals(0, outbuf.length());
600 
601         outbuf.flush(channel);
602         final String s = channel.dump(Consts.ASCII);
603 
604         Assert.assertEquals("stuff-much more stuff", s);
605     }
606 
607     @Test
608     public void testCodingFragmentBufferingChannelSaturated() throws Exception {
609         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64, 8));
610         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
611         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
612 
613         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
614             100, 3);
615         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
616         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
617         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
618         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
619         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
620         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
621         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
622         Assert.assertEquals(0, encoder.write(CodecTestUtils.wrap("-")));
623         Assert.assertEquals(0, encoder.write(CodecTestUtils.wrap("more stuff")));
624 
625         Mockito.verify(channel, Mockito.times(5)).write(Matchers.<ByteBuffer>any());
626         Mockito.verify(outbuf, Mockito.times(6)).write(Matchers.<ByteBuffer>any());
627         Mockito.verify(outbuf, Mockito.times(4)).flush(channel);
628 
629         Assert.assertEquals(8, metrics.getBytesTransferred());
630 
631         outbuf.flush(channel);
632         final String s = channel.dump(Consts.ASCII);
633 
634         Assert.assertEquals("stuff---", s);
635         Assert.assertEquals(3, outbuf.length());
636     }
637 
638     @Test
639     public void testCodingFragmentBufferingChannelSaturated2() throws Exception {
640         final WritableByteChannelMockeByteChannelMock">WritableByteChannelMock channel = Mockito.spy(new WritableByteChannelMock(64, 8));
641         final SessionOutputBuffer outbuf = Mockito.spy(new SessionOutputBufferImpl(1024, 128));
642         final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl();
643 
644         final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(channel, outbuf, metrics,
645             100, 8);
646         Assert.assertEquals(5, encoder.write(CodecTestUtils.wrap("stuff")));
647         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
648         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("-")));
649         Assert.assertEquals(1, encoder.write(CodecTestUtils.wrap("much more stuff")));
650 
651         Mockito.verify(channel, Mockito.times(3)).write(Matchers.<ByteBuffer>any());
652         Mockito.verify(outbuf, Mockito.times(3)).write(Matchers.<ByteBuffer>any());
653         Mockito.verify(outbuf, Mockito.times(1)).flush(channel);
654 
655         Assert.assertEquals(8, metrics.getBytesTransferred());
656 
657         outbuf.flush(channel);
658         final String s = channel.dump(Consts.ASCII);
659 
660         Assert.assertEquals("stuff--m", s);
661         Assert.assertEquals(0, outbuf.length());
662     }
663 
664 }