Index: oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriterTest.java =================================================================== --- oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriterTest.java (revision 1839550) +++ oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriterTest.java (working copy) @@ -24,7 +24,9 @@ import static org.junit.Assert.assertNotEquals; import java.io.File; +import java.util.Collections; import java.util.List; +import java.util.Random; import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState; import org.apache.jackrabbit.oak.segment.file.FileStore; @@ -96,4 +98,38 @@ assertNotEquals(before, after); } + @Test + public void tooBigRecord() throws Exception { + try (FileStore store = openFileStore()) { + + // Please don't change anything from the following statement yet. + // Read the next comment to understand why. + + SegmentBufferWriter writer = new SegmentBufferWriter( + store.getSegmentIdProvider(), + store.getReader(), + "t", + store.getRevisions().getHead().getSegment().getGcGeneration() + ); + + // The size of the record is chosen with the precise intention to + // fool `writer` into having enough space to write the record. In + // particular, at the end of `prepare()`, `writer` will have + // `this.length = 262144`, which is `MAX_SEGMENT_SIZE`, and + // `this.position = 0`. This result is particularly sensitive to the + // initial content of the segment, which in turn is influenced by + // the segment info. Try to change the writer ID in the constructor + // of `SegmentBufferWriter` to a longer string, and you will have + // `prepare()` throw ISEs because the writer ID is embedded in the + // segment info. + + int size = 262101; + writer.prepare(RecordType.BLOCK, size, Collections.emptyList(), store); + byte[] data = new byte[size]; + new Random().nextBytes(data); + writer.writeBytes(data, 0, size); + writer.flush(store); + } + } + }