aboutsummaryrefslogtreecommitdiff
path: root/okio/src/jvmTest/java/okio/DeflaterSinkTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'okio/src/jvmTest/java/okio/DeflaterSinkTest.java')
-rw-r--r--okio/src/jvmTest/java/okio/DeflaterSinkTest.java149
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;
+ }
+}