diff options
Diffstat (limited to 'okio/src/jvmTest/java/okio/DeflaterSinkTest.java')
-rw-r--r-- | okio/src/jvmTest/java/okio/DeflaterSinkTest.java | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/okio/src/jvmTest/java/okio/DeflaterSinkTest.java b/okio/src/jvmTest/java/okio/DeflaterSinkTest.java new file mode 100644 index 00000000..f0a31f00 --- /dev/null +++ b/okio/src/jvmTest/java/okio/DeflaterSinkTest.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2014 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package okio; + +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.Deflater; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; +import org.junit.Test; + +import static kotlin.text.StringsKt.repeat; +import static okio.TestUtil.SEGMENT_SIZE; +import static okio.TestUtil.randomBytes; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public final class DeflaterSinkTest { + @Test public void deflateWithClose() throws Exception { + Buffer data = new Buffer(); + String original = "They're moving in herds. They do move in herds."; + data.writeUtf8(original); + Buffer sink = new Buffer(); + DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); + deflaterSink.write(data, data.size()); + deflaterSink.close(); + Buffer inflated = inflate(sink); + assertEquals(original, inflated.readUtf8()); + } + + @Test public void deflateWithSyncFlush() throws Exception { + String original = "Yes, yes, yes. That's why we're taking extreme precautions."; + Buffer data = new Buffer(); + data.writeUtf8(original); + Buffer sink = new Buffer(); + DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); + deflaterSink.write(data, data.size()); + deflaterSink.flush(); + Buffer inflated = inflate(sink); + assertEquals(original, inflated.readUtf8()); + } + + @Test public void deflateWellCompressed() throws IOException { + String original = repeat("a", 1024 * 1024); + Buffer data = new Buffer(); + data.writeUtf8(original); + Buffer sink = new Buffer(); + DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); + deflaterSink.write(data, data.size()); + deflaterSink.close(); + Buffer inflated = inflate(sink); + assertEquals(original, inflated.readUtf8()); + } + + @Test public void deflatePoorlyCompressed() throws IOException { + ByteString original = randomBytes(1024 * 1024); + Buffer data = new Buffer(); + data.write(original); + Buffer sink = new Buffer(); + DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); + deflaterSink.write(data, data.size()); + deflaterSink.close(); + Buffer inflated = inflate(sink); + assertEquals(original, inflated.readByteString()); + } + + @Test public void multipleSegmentsWithoutCompression() throws IOException { + Buffer buffer = new Buffer(); + Deflater deflater = new Deflater(); + deflater.setLevel(Deflater.NO_COMPRESSION); + DeflaterSink deflaterSink = new DeflaterSink(buffer, deflater); + int byteCount = SEGMENT_SIZE * 4; + deflaterSink.write(new Buffer().writeUtf8(repeat("a", byteCount)), byteCount); + deflaterSink.close(); + assertEquals(repeat("a", byteCount), inflate(buffer).readUtf8(byteCount)); + } + + @Test public void deflateIntoNonemptySink() throws Exception { + String original = "They're moving in herds. They do move in herds."; + + // Exercise all possible offsets for the outgoing segment. + for (int i = 0; i < SEGMENT_SIZE; i++) { + Buffer data = new Buffer().writeUtf8(original); + Buffer sink = new Buffer().writeUtf8(repeat("a", i)); + + DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); + deflaterSink.write(data, data.size()); + deflaterSink.close(); + + sink.skip(i); + Buffer inflated = inflate(sink); + assertEquals(original, inflated.readUtf8()); + } + } + + /** + * This test deflates a single segment of without compression because that's + * the easiest way to force close() to emit a large amount of data to the + * underlying sink. + */ + @Test public void closeWithExceptionWhenWritingAndClosing() throws IOException { + MockSink mockSink = new MockSink(); + mockSink.scheduleThrow(0, new IOException("first")); + mockSink.scheduleThrow(1, new IOException("second")); + Deflater deflater = new Deflater(); + deflater.setLevel(Deflater.NO_COMPRESSION); + DeflaterSink deflaterSink = new DeflaterSink(mockSink, deflater); + deflaterSink.write(new Buffer().writeUtf8(repeat("a", SEGMENT_SIZE)), SEGMENT_SIZE); + try { + deflaterSink.close(); + fail(); + } catch (IOException expected) { + assertEquals("first", expected.getMessage()); + } + mockSink.assertLogContains("close()"); + } + + /** + * Uses streaming decompression to inflate {@code deflated}. The input must + * either be finished or have a trailing sync flush. + */ + private Buffer inflate(Buffer deflated) throws IOException { + InputStream deflatedIn = deflated.inputStream(); + Inflater inflater = new Inflater(); + InputStream inflatedIn = new InflaterInputStream(deflatedIn, inflater); + Buffer result = new Buffer(); + byte[] buffer = new byte[8192]; + while (!inflater.needsInput() || deflated.size() > 0 || deflatedIn.available() > 0) { + int count = inflatedIn.read(buffer, 0, buffer.length); + if (count != -1) { + result.write(buffer, 0, count); + } + } + return result; + } +} |