From c5a3b102bc77723988cfa3234fb489d9bc2c5968 Mon Sep 17 00:00:00 2001 From: Josh Rosen Date: Thu, 14 May 2015 00:17:30 -0700 Subject: [PATCH] Add failing regression test for #107 --- .../xerial/snappy/SnappyOutputStreamTest.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/test/java/org/xerial/snappy/SnappyOutputStreamTest.java b/src/test/java/org/xerial/snappy/SnappyOutputStreamTest.java index 10850a8..b6f4009 100755 --- a/src/test/java/org/xerial/snappy/SnappyOutputStreamTest.java +++ b/src/test/java/org/xerial/snappy/SnappyOutputStreamTest.java @@ -31,6 +31,8 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import org.junit.Test; +import org.xerial.snappy.buffer.BufferAllocatorFactory; +import org.xerial.snappy.buffer.CachedBufferAllocator; import org.xerial.util.FileResource; import org.xerial.util.log.Logger; @@ -157,6 +159,38 @@ public class SnappyOutputStreamTest } } + @Test + public void closeShouldBeIdempotent() throws Exception { + // Regression test for issue #107, a bug where close() was non-idempotent and would release + // its buffers to the allocator multiple times, which could cause scenarios where two open + // SnappyOutputStreams could share the same buffers, leading to stream corruption issues. + final BufferAllocatorFactory bufferAllocatorFactory = CachedBufferAllocator.factory; + final int BLOCK_SIZE = 4096; + // Create a stream, use it, then close it once: + ByteArrayOutputStream ba1 = new ByteArrayOutputStream(); + SnappyOutputStream os1 = new SnappyOutputStream(ba1, BLOCK_SIZE, bufferAllocatorFactory); + os1.write(42); + os1.close(); + // Create a new output stream, which should end up re-using the first stream's freed buffers + ByteArrayOutputStream ba2 = new ByteArrayOutputStream(); + SnappyOutputStream os2 = new SnappyOutputStream(ba2, BLOCK_SIZE, bufferAllocatorFactory); + // Close the first stream a second time, which is supposed to be safe due to idempotency: + os1.close(); + // Allocate a third output stream, which is supposed to get its own fresh set of buffers: + ByteArrayOutputStream ba3 = new ByteArrayOutputStream(); + SnappyOutputStream os3 = new SnappyOutputStream(ba3, BLOCK_SIZE, bufferAllocatorFactory); + // Since the second and third streams should have distinct sets of buffers, writes to these + // streams should not interfere with one another: + os2.write(2); + os3.write(3); + os2.close(); + os3.close(); + SnappyInputStream in2 = new SnappyInputStream(new ByteArrayInputStream(ba2.toByteArray())); + assertEquals(2, in2.read()); + SnappyInputStream in3 = new SnappyInputStream(new ByteArrayInputStream(ba3.toByteArray())); + assertEquals(3, in3.read()); + } + @Test public void longArrayCompress() throws Exception { long[] l = new long[10];