/** * Using the given {@code appender}'s {@link Appender#append(LogSegment, ByteBuffer)} function, * tests for various cases for append operations. * * @param appender the {@link Appender} to use * @throws IOException */ private void doAppendTest(Appender appender) throws IOException { String currSegmentName = "log_current"; LogSegment segment = getSegment(currSegmentName, STANDARD_SEGMENT_SIZE, true); try { long writeStartOffset = segment.getStartOffset(); byte[] bufOne = TestUtils.getRandomBytes(STANDARD_SEGMENT_SIZE / 2); byte[] bufTwo = TestUtils.getRandomBytes(STANDARD_SEGMENT_SIZE / 3); appender.append(segment, ByteBuffer.wrap(bufOne)); assertEquals( "End offset is not as expected", writeStartOffset + bufOne.length, segment.getEndOffset()); appender.append(segment, ByteBuffer.wrap(bufTwo)); assertEquals( "End offset is not as expected", writeStartOffset + bufOne.length + bufTwo.length, segment.getEndOffset()); // try to do a write that won't fit ByteBuffer failBuf = ByteBuffer.wrap( TestUtils.getRandomBytes((int) (STANDARD_SEGMENT_SIZE - writeStartOffset + 1))); long writeOverFlowCount = metrics.overflowWriteError.getCount(); try { appender.append(segment, failBuf); fail("Append should have failed because data won't fit in the segment"); } catch (IllegalArgumentException e) { assertEquals( "Write overflow should have been reported", writeOverFlowCount + 1, metrics.overflowWriteError.getCount()); assertEquals("Position of buffer has changed", 0, failBuf.position()); } // read and ensure data matches readAndEnsureMatch(segment, writeStartOffset, bufOne); readAndEnsureMatch(segment, writeStartOffset + bufOne.length, bufTwo); segment.close(); // ensure that append fails. ByteBuffer buffer = ByteBuffer.wrap(TestUtils.getRandomBytes(1)); try { appender.append(segment, buffer); fail("Append should have failed because segments are closed"); } catch (ClosedChannelException e) { assertEquals("Position of buffer has changed", 0, buffer.position()); } } finally { closeSegmentAndDeleteFile(segment); } }