Home | History | Annotate | Download | only in okio
      1 /*
      2  * Copyright (C) 2014 Square, Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package okio;
     17 
     18 import java.io.IOException;
     19 import java.io.OutputStream;
     20 import org.junit.Test;
     21 
     22 import static okio.TestUtil.repeat;
     23 import static org.junit.Assert.assertEquals;
     24 import static org.junit.Assert.fail;
     25 
     26 /**
     27  * Tests solely for the behavior of RealBufferedSink's implementation. For generic
     28  * BufferedSink behavior use BufferedSinkTest.
     29  */
     30 public final class RealBufferedSinkTest {
     31   @Test public void inputStreamCloses() throws Exception {
     32     RealBufferedSink sink = new RealBufferedSink(new Buffer());
     33     OutputStream out = sink.outputStream();
     34     out.close();
     35     try {
     36       sink.writeUtf8("Hi!");
     37       fail();
     38     } catch (IllegalStateException e) {
     39       assertEquals("closed", e.getMessage());
     40     }
     41   }
     42 
     43   @Test public void bufferedSinkEmitsTailWhenItIsComplete() throws IOException {
     44     Buffer sink = new Buffer();
     45     BufferedSink bufferedSink = new RealBufferedSink(sink);
     46     bufferedSink.writeUtf8(repeat('a', Segment.SIZE - 1));
     47     assertEquals(0, sink.size());
     48     bufferedSink.writeByte(0);
     49     assertEquals(Segment.SIZE, sink.size());
     50     assertEquals(0, bufferedSink.buffer().size());
     51   }
     52 
     53   @Test public void bufferedSinkEmitMultipleSegments() throws IOException {
     54     Buffer sink = new Buffer();
     55     BufferedSink bufferedSink = new RealBufferedSink(sink);
     56     bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 4 - 1));
     57     assertEquals(Segment.SIZE * 3, sink.size());
     58     assertEquals(Segment.SIZE - 1, bufferedSink.buffer().size());
     59   }
     60 
     61   @Test public void bufferedSinkFlush() throws IOException {
     62     Buffer sink = new Buffer();
     63     BufferedSink bufferedSink = new RealBufferedSink(sink);
     64     bufferedSink.writeByte('a');
     65     assertEquals(0, sink.size());
     66     bufferedSink.flush();
     67     assertEquals(0, bufferedSink.buffer().size());
     68     assertEquals(1, sink.size());
     69   }
     70 
     71   @Test public void bytesEmittedToSinkWithFlush() throws Exception {
     72     Buffer sink = new Buffer();
     73     BufferedSink bufferedSink = new RealBufferedSink(sink);
     74     bufferedSink.writeUtf8("abc");
     75     bufferedSink.flush();
     76     assertEquals(3, sink.size());
     77   }
     78 
     79   @Test public void bytesNotEmittedToSinkWithoutFlush() throws Exception {
     80     Buffer sink = new Buffer();
     81     BufferedSink bufferedSink = new RealBufferedSink(sink);
     82     bufferedSink.writeUtf8("abc");
     83     assertEquals(0, sink.size());
     84   }
     85 
     86   @Test public void bytesEmittedToSinkWithEmit() throws Exception {
     87     Buffer sink = new Buffer();
     88     BufferedSink bufferedSink = new RealBufferedSink(sink);
     89     bufferedSink.writeUtf8("abc");
     90     bufferedSink.emit();
     91     assertEquals(3, sink.size());
     92   }
     93 
     94   @Test public void completeSegmentsEmitted() throws Exception {
     95     Buffer sink = new Buffer();
     96     BufferedSink bufferedSink = new RealBufferedSink(sink);
     97     bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 3));
     98     assertEquals(Segment.SIZE * 3, sink.size());
     99   }
    100 
    101   @Test public void incompleteSegmentsNotEmitted() throws Exception {
    102     Buffer sink = new Buffer();
    103     BufferedSink bufferedSink = new RealBufferedSink(sink);
    104     bufferedSink.writeUtf8(repeat('a', Segment.SIZE * 3 - 1));
    105     assertEquals(Segment.SIZE * 2, sink.size());
    106   }
    107 
    108   @Test public void closeWithExceptionWhenWriting() throws IOException {
    109     MockSink mockSink = new MockSink();
    110     mockSink.scheduleThrow(0, new IOException());
    111     BufferedSink bufferedSink = new RealBufferedSink(mockSink);
    112     bufferedSink.writeByte('a');
    113     try {
    114       bufferedSink.close();
    115       fail();
    116     } catch (IOException expected) {
    117     }
    118     mockSink.assertLog("write(Buffer[size=1 data=61], 1)", "close()");
    119   }
    120 
    121   @Test public void closeWithExceptionWhenClosing() throws IOException {
    122     MockSink mockSink = new MockSink();
    123     mockSink.scheduleThrow(1, new IOException());
    124     BufferedSink bufferedSink = new RealBufferedSink(mockSink);
    125     bufferedSink.writeByte('a');
    126     try {
    127       bufferedSink.close();
    128       fail();
    129     } catch (IOException expected) {
    130     }
    131     mockSink.assertLog("write(Buffer[size=1 data=61], 1)", "close()");
    132   }
    133 
    134   @Test public void closeWithExceptionWhenWritingAndClosing() throws IOException {
    135     MockSink mockSink = new MockSink();
    136     mockSink.scheduleThrow(0, new IOException("first"));
    137     mockSink.scheduleThrow(1, new IOException("second"));
    138     BufferedSink bufferedSink = new RealBufferedSink(mockSink);
    139     bufferedSink.writeByte('a');
    140     try {
    141       bufferedSink.close();
    142       fail();
    143     } catch (IOException expected) {
    144       assertEquals("first", expected.getMessage());
    145     }
    146     mockSink.assertLog("write(Buffer[size=1 data=61], 1)", "close()");
    147   }
    148 
    149   @Test public void operationsAfterClose() throws IOException {
    150     MockSink mockSink = new MockSink();
    151     BufferedSink bufferedSink = new RealBufferedSink(mockSink);
    152     bufferedSink.writeByte('a');
    153     bufferedSink.close();
    154 
    155     // Test a sample set of methods.
    156     try {
    157       bufferedSink.writeByte('a');
    158       fail();
    159     } catch (IllegalStateException expected) {
    160     }
    161 
    162     try {
    163       bufferedSink.write(new byte[10]);
    164       fail();
    165     } catch (IllegalStateException expected) {
    166     }
    167 
    168     try {
    169       bufferedSink.emitCompleteSegments();
    170       fail();
    171     } catch (IllegalStateException expected) {
    172     }
    173 
    174     try {
    175       bufferedSink.emit();
    176       fail();
    177     } catch (IllegalStateException expected) {
    178     }
    179 
    180     try {
    181       bufferedSink.flush();
    182       fail();
    183     } catch (IllegalStateException expected) {
    184     }
    185 
    186     // Test a sample set of methods on the OutputStream.
    187     OutputStream os = bufferedSink.outputStream();
    188     try {
    189       os.write('a');
    190       fail();
    191     } catch (IOException expected) {
    192     }
    193 
    194     try {
    195       os.write(new byte[10]);
    196       fail();
    197     } catch (IOException expected) {
    198     }
    199 
    200     // Permitted
    201     os.flush();
    202   }
    203 
    204   @Test public void writeAll() throws IOException {
    205     MockSink mockSink = new MockSink();
    206     BufferedSink bufferedSink = Okio.buffer(mockSink);
    207 
    208     bufferedSink.buffer().writeUtf8("abc");
    209     assertEquals(3, bufferedSink.writeAll(new Buffer().writeUtf8("def")));
    210 
    211     assertEquals(6, bufferedSink.buffer().size());
    212     assertEquals("abcdef", bufferedSink.buffer().readUtf8(6));
    213     mockSink.assertLog(); // No writes.
    214  }
    215 
    216   @Test public void writeAllExhausted() throws IOException {
    217     MockSink mockSink = new MockSink();
    218     BufferedSink bufferedSink = Okio.buffer(mockSink);
    219 
    220     assertEquals(0, bufferedSink.writeAll(new Buffer()));
    221     assertEquals(0, bufferedSink.buffer().size());
    222     mockSink.assertLog(); // No writes.
    223  }
    224 
    225   @Test public void writeAllWritesOneSegmentAtATime() throws IOException {
    226     Buffer write1 = new Buffer().writeUtf8(TestUtil.repeat('a', Segment.SIZE));
    227     Buffer write2 = new Buffer().writeUtf8(TestUtil.repeat('b', Segment.SIZE));
    228     Buffer write3 = new Buffer().writeUtf8(TestUtil.repeat('c', Segment.SIZE));
    229 
    230     Buffer source = new Buffer().writeUtf8(""
    231         + TestUtil.repeat('a', Segment.SIZE)
    232         + TestUtil.repeat('b', Segment.SIZE)
    233         + TestUtil.repeat('c', Segment.SIZE));
    234 
    235     MockSink mockSink = new MockSink();
    236     BufferedSink bufferedSink = Okio.buffer(mockSink);
    237     assertEquals(Segment.SIZE * 3, bufferedSink.writeAll(source));
    238 
    239     mockSink.assertLog(
    240         "write(" + write1 + ", " + write1.size() + ")",
    241         "write(" + write2 + ", " + write2.size() + ")",
    242         "write(" + write3 + ", " + write3.size() + ")");
    243  }
    244 }
    245