public LossDetectorTest() { lossHandler = mock(LossHandler.class); lossDetector = new LossDetector(DELAY_GENERATOR, lossHandler); dataHeader.wrap(rcvBuffer); }
/** * Dump the contents of a segment file to a {@link PrintStream}. * * @param out for the dumped contents. * @param messageDumpLimit for the number of bytes per message fragment to dump. * @param buffer the wraps the segment file. */ public static void dumpSegment(final PrintStream out, final int messageDumpLimit, final UnsafeBuffer buffer) { final DataHeaderFlyweight dataHeaderFlyweight = new DataHeaderFlyweight(); final int length = buffer.capacity(); int offset = 0; while (offset < length) { dataHeaderFlyweight.wrap(buffer, offset, length - offset); out.println(offset + ": " + dataHeaderFlyweight.toString()); final int frameLength = dataHeaderFlyweight.frameLength(); if (frameLength < DataHeaderFlyweight.HEADER_LENGTH) { break; } final int limit = min(frameLength - HEADER_LENGTH, messageDumpLimit); out.println(LogInspector.formatBytes(buffer, offset + HEADER_LENGTH, limit)); offset += BitUtil.align(frameLength, FrameDescriptor.FRAME_ALIGNMENT); } } }
@Before public void setUp() { dataHeader.wrap(rcvBuffer); for (int i = 0; i < PARTITION_COUNT; i++) { termBuffers[i] = new UnsafeBuffer(allocateDirect(TERM_BUFFER_LENGTH)); } final UnsafeBuffer logMetaDataBuffer = new UnsafeBuffer(allocateDirect(LOG_META_DATA_LENGTH)); when(logBuffers.duplicateTermBuffers()).thenReturn(termBuffers); when(logBuffers.termLength()).thenReturn(TERM_BUFFER_LENGTH); when(logBuffers.metaDataBuffer()).thenReturn(logMetaDataBuffer); }
@Test public void shouldNotSendSetupFrameAfterReceivingStatusMessage() { final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(0); publication.onStatusMessage(msg, rcvAddress); // publication.senderPositionLimit(flowControl.onStatusMessage(msg, rcvAddress, )); sender.doWork(); assertThat(receivedFrames.size(), is(1)); receivedFrames.remove(); currentTimestamp += Configuration.PUBLICATION_SETUP_TIMEOUT_NS + 10; sender.doWork(); assertThat(receivedFrames.size(), is(1)); dataHeader.wrap(receivedFrames.remove()); assertThat(dataHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); // heartbeat assertThat(dataHeader.frameLength(), is(0)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(1))); }
@Test public void shouldNotSendUntilStatusMessageReceived() { final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(PAYLOAD.length)); buffer.putBytes(0, PAYLOAD); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); sender.doWork(); assertThat(receivedFrames.size(), is(1)); setupHeader.wrap(receivedFrames.remove()); assertThat(setupHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_SETUP)); final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH); publication.onStatusMessage(msg, rcvAddress); sender.doWork(); assertThat(receivedFrames.size(), is(1)); dataHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(dataHeader.frameLength(), is(FRAME_LENGTH)); assertThat(dataHeader.termId(), is(INITIAL_TERM_ID)); assertThat(dataHeader.streamId(), is(STREAM_ID)); assertThat(dataHeader.sessionId(), is(SESSION_ID)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(1))); assertThat(dataHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); assertThat(dataHeader.flags(), is(DataHeaderFlyweight.BEGIN_AND_END_FLAGS)); assertThat(dataHeader.version(), is((short)HeaderFlyweight.CURRENT_VERSION)); }
@Test public void shouldNotBeAbleToSendAfterUsingUpYourWindow() { final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(PAYLOAD.length)); buffer.putBytes(0, PAYLOAD); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH); publication.onStatusMessage(msg, rcvAddress); sender.doWork(); assertThat(receivedFrames.size(), is(2)); receivedFrames.remove(); // skip setup dataHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(dataHeader.frameLength(), is(FRAME_LENGTH)); assertThat(dataHeader.termId(), is(INITIAL_TERM_ID)); assertThat(dataHeader.streamId(), is(STREAM_ID)); assertThat(dataHeader.sessionId(), is(SESSION_ID)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(1))); assertThat(dataHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); assertThat(dataHeader.flags(), is(DataHeaderFlyweight.BEGIN_AND_END_FLAGS)); assertThat(dataHeader.version(), is((short)HeaderFlyweight.CURRENT_VERSION)); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); sender.doWork(); assertThat(receivedFrames.size(), is(0)); }
@Test public void shouldBeAbleToSendOnChannel() { final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH); publication.onStatusMessage(msg, rcvAddress); final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(PAYLOAD.length)); buffer.putBytes(0, PAYLOAD); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); sender.doWork(); assertThat(receivedFrames.size(), is(2)); setupHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(setupHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_SETUP)); dataHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(dataHeader.frameLength(), is(FRAME_LENGTH)); assertThat(dataHeader.termId(), is(INITIAL_TERM_ID)); assertThat(dataHeader.streamId(), is(STREAM_ID)); assertThat(dataHeader.sessionId(), is(SESSION_ID)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(1))); assertThat(dataHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); assertThat(dataHeader.flags(), is(DataHeaderFlyweight.BEGIN_AND_END_FLAGS)); assertThat(dataHeader.version(), is((short)HeaderFlyweight.CURRENT_VERSION)); }
@Test public void shouldSendLastDataFrameAsHeartbeatWhenIdle() { final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class); when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID); when(msg.consumptionTermOffset()).thenReturn(0); when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH); publication.onStatusMessage(msg, rcvAddress); final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(PAYLOAD.length)); buffer.putBytes(0, PAYLOAD); termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null, INITIAL_TERM_ID); sender.doWork(); assertThat(receivedFrames.size(), is(2)); // should send ticks receivedFrames.remove(); // skip setup & data frame receivedFrames.remove(); currentTimestamp += Configuration.PUBLICATION_HEARTBEAT_TIMEOUT_NS - 1; sender.doWork(); assertThat(receivedFrames.size(), is(0)); // should not send yet currentTimestamp += 10; sender.doWork(); assertThat(receivedFrames.size(), greaterThanOrEqualTo(1)); // should send ticks dataHeader.wrap(receivedFrames.remove()); assertThat(dataHeader.frameLength(), is(0)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(2))); }
assertThat(receivedFrames.size(), greaterThanOrEqualTo(1)); // should send ticks dataHeader.wrap(receivedFrames.remove()); assertThat(dataHeader.frameLength(), is(0)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(2))); assertThat(receivedFrames.size(), greaterThanOrEqualTo(1)); // should send ticks dataHeader.wrap(receivedFrames.remove()); assertThat(dataHeader.frameLength(), is(0)); assertThat(dataHeader.termOffset(), is(offsetOfMessage(2)));
assertThat(setupHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_SETUP)); dataHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(dataHeader.frameLength(), is(FRAME_LENGTH)); assertThat(dataHeader.termId(), is(INITIAL_TERM_ID)); assertThat(dataHeader.version(), is((short)HeaderFlyweight.CURRENT_VERSION)); dataHeader.wrap(new UnsafeBuffer(receivedFrames.remove())); assertThat(dataHeader.frameLength(), is(FRAME_LENGTH)); assertThat(dataHeader.termId(), is(INITIAL_TERM_ID));
sendChannelEndpoint.registerForRead(controlTransportPoller); encodeDataHeader.wrap(buffer); encodeDataHeader .version(HeaderFlyweight.CURRENT_VERSION)
case HeaderFlyweight.HDR_TYPE_DATA: final DataHeaderFlyweight dataFrame = DATA_HEADER; dataFrame.wrap(buffer, frameOffset, buffer.capacity() - frameOffset); dissect(dataFrame, builder); break;
@Before public void before() throws Exception { when(mockPosition.getWeak()).then((invocation) -> positionLong); when(mockPosition.get()).then((invocation) -> positionLong); doAnswer( (invocation) -> { positionLong = invocation.getArgument(0); return null; }) .when(mockPosition).setOrdered(anyLong()); termFile = File.createTempFile("test.rec", "sourceIdentity"); mockLogBufferChannel = FileChannel.open(termFile.toPath(), CREATE, READ, WRITE); mockLogBufferMapped = new UnsafeBuffer( mockLogBufferChannel.map(FileChannel.MapMode.READ_WRITE, 0, TERM_BUFFER_LENGTH)); final DataHeaderFlyweight headerFlyweight = new DataHeaderFlyweight(); headerFlyweight.wrap(mockLogBufferMapped, TERM_OFFSET, DataHeaderFlyweight.HEADER_LENGTH); headerFlyweight .termOffset(TERM_OFFSET) .sessionId(SESSION_ID) .streamId(STREAM_ID) .headerType(DataHeaderFlyweight.HDR_TYPE_DATA) .frameLength(RECORDED_BLOCK_LENGTH); context = new Archive.Context() .segmentFileLength(SEGMENT_LENGTH) .archiveDir(archiveDir) .catalog(mockCatalog) .epochClock(epochClock); }
@Test public void shouldReadAndWriteDataHeaderCorrectly() { encodeDataHeader.wrap(aBuff); encodeDataHeader.version((short)1); encodeDataHeader.flags(DataHeaderFlyweight.BEGIN_AND_END_FLAGS); encodeDataHeader.headerType(HeaderFlyweight.HDR_TYPE_DATA); encodeDataHeader.frameLength(DataHeaderFlyweight.HEADER_LENGTH); encodeDataHeader.sessionId(0xdeadbeef); encodeDataHeader.streamId(0x44332211); encodeDataHeader.termId(0x99887766); decodeDataHeader.wrap(aBuff); assertThat(decodeDataHeader.version(), is((short)1)); assertThat(decodeDataHeader.flags(), is(DataHeaderFlyweight.BEGIN_AND_END_FLAGS)); assertThat(decodeDataHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_DATA)); assertThat(decodeDataHeader.frameLength(), is(DataHeaderFlyweight.HEADER_LENGTH)); assertThat(decodeDataHeader.sessionId(), is(0xdeadbeef)); assertThat(decodeDataHeader.streamId(), is(0x44332211)); assertThat(decodeDataHeader.termId(), is(0x99887766)); assertThat(decodeDataHeader.dataOffset(), is(DataHeaderFlyweight.HEADER_LENGTH)); }
@Test public void shouldFillGapAfterExistingFrame() { final int gapOffset = 128; final int gapLength = 64; dataFlyweight .sessionId(SESSION_ID) .termId(TERM_ID) .streamId(STREAM_ID) .flags(UNFRAGMENTED) .frameLength(gapOffset); dataFlyweight.setMemory(0, gapOffset - DataHeaderFlyweight.HEADER_LENGTH, (byte)'x'); assertTrue(TermGapFiller.tryFillGap(metaDataBuffer, termBuffer, TERM_ID, gapOffset, gapLength)); dataFlyweight.wrap(termBuffer, gapOffset, termBuffer.capacity() - gapOffset); assertThat(dataFlyweight.frameLength(), is(gapLength)); assertThat(dataFlyweight.termOffset(), is(gapOffset)); assertThat(dataFlyweight.sessionId(), is(SESSION_ID)); assertThat(dataFlyweight.termId(), is(TERM_ID)); assertThat(dataFlyweight.headerType(), is(PADDING_FRAME_TYPE)); assertThat((byte)(dataFlyweight.flags()), is(UNFRAGMENTED)); }
@Test public void shouldFillGapAtEndOfTerm() { final int gapOffset = termBuffer.capacity() - 64; final int gapLength = 64; dataFlyweight .sessionId(SESSION_ID) .termId(TERM_ID) .streamId(STREAM_ID) .flags(UNFRAGMENTED) .frameLength(termBuffer.capacity() - gapOffset); dataFlyweight.setMemory(0, gapOffset - DataHeaderFlyweight.HEADER_LENGTH, (byte)'x'); assertTrue(TermGapFiller.tryFillGap(metaDataBuffer, termBuffer, TERM_ID, gapOffset, gapLength)); dataFlyweight.wrap(termBuffer, gapOffset, termBuffer.capacity() - gapOffset); assertThat(dataFlyweight.frameLength(), is(gapLength)); assertThat(dataFlyweight.termOffset(), is(gapOffset)); assertThat(dataFlyweight.sessionId(), is(SESSION_ID)); assertThat(dataFlyweight.termId(), is(TERM_ID)); assertThat(dataFlyweight.headerType(), is(PADDING_FRAME_TYPE)); assertThat((byte)(dataFlyweight.flags()), is(UNFRAGMENTED)); } }
.wrap(termBuffer, secondExistingFrameOffset, termBuffer.capacity() - secondExistingFrameOffset); dataFlyweight .sessionId(SESSION_ID) dataFlyweight.wrap(termBuffer, gapOffset, termBuffer.capacity() - gapOffset); assertThat(dataFlyweight.frameLength(), is(gapLength)); assertThat(dataFlyweight.termOffset(), is(gapOffset));
private void fillDataFrame(final DataHeaderFlyweight header, final int termOffset, final byte[] payload) { header.wrap(dataBuffer); header .termOffset(termOffset) .termId(ACTIVE_TERM_ID) .streamId(STREAM_ID) .sessionId(SESSION_ID) .frameLength(DataHeaderFlyweight.HEADER_LENGTH + payload.length) .headerType(HeaderFlyweight.HDR_TYPE_DATA) .flags(DataHeaderFlyweight.BEGIN_AND_END_FLAGS) .version(HeaderFlyweight.CURRENT_VERSION); if (0 < payload.length) { dataBuffer.putBytes(header.dataOffset(), payload); } }
private void addReceivedDataFrame(final int msgNum) { dataHeader.wrap(rcvBuffer); dataHeader.termId(TERM_ID) .streamId(STREAM_ID) .sessionId(SESSION_ID) .termOffset(offsetOfFrame(msgNum)) .frameLength(MESSAGE_LENGTH) .headerType(HeaderFlyweight.HDR_TYPE_DATA) .flags(DataHeaderFlyweight.BEGIN_AND_END_FLAGS) .version(HeaderFlyweight.CURRENT_VERSION); rcvBuffer.putBytes(dataHeader.dataOffset(), DATA); TermRebuilder.insert(termBuffer, offsetOfFrame(msgNum), rcvBuffer, MESSAGE_LENGTH); } }
private void recordFragment( final RecordingWriter recordingWriter, final UnsafeBuffer buffer, final DataHeaderFlyweight headerFlyweight, final Header header, final int message, final byte flags, final int type) { final int offset = INITIAL_TERM_OFFSET + message * FRAME_LENGTH; headerFlyweight.wrap(buffer, offset, HEADER_LENGTH); headerFlyweight .streamId(STREAM_ID) .sessionId(SESSION_ID) .termOffset(offset) .termId(INITIAL_TERM_ID) .reservedValue(message) .headerType(type) .flags(flags) .frameLength(FRAME_LENGTH); buffer.setMemory( offset + HEADER_LENGTH, FRAME_LENGTH - HEADER_LENGTH, (byte)message); header.offset(offset); recordingWriter.onBlock(buffer, offset, FRAME_LENGTH, SESSION_ID, INITIAL_TERM_ID); recordingPosition += FRAME_LENGTH; }