@Test
  public void shouldLateJoinTransmission() {
    final int length = 8;
    final int recordLength = length + HEADER_LENGTH;
    final int recordLengthAligned = align(recordLength, RECORD_ALIGNMENT);
    final long tail = (CAPACITY * 3L) + HEADER_LENGTH + recordLengthAligned;
    final long latestRecord = tail - recordLengthAligned;
    final int recordOffset = (int) latestRecord & (CAPACITY - 1);

    when(buffer.getLongVolatile(TAIL_INTENT_COUNTER_OFFSET)).thenReturn(tail);
    when(buffer.getLongVolatile(TAIL_COUNTER_INDEX)).thenReturn(tail);
    when(buffer.getLong(LATEST_COUNTER_INDEX)).thenReturn(latestRecord);

    when(buffer.getInt(lengthOffset(recordOffset))).thenReturn(recordLength);
    when(buffer.getInt(typeOffset(recordOffset))).thenReturn(MSG_TYPE_ID);

    assertTrue(broadcastReceiver.receiveNext());
    assertThat(broadcastReceiver.typeId(), is(MSG_TYPE_ID));
    assertThat(broadcastReceiver.buffer(), is(buffer));
    assertThat(broadcastReceiver.offset(), is(msgOffset(recordOffset)));
    assertThat(broadcastReceiver.length(), is(length));

    assertTrue(broadcastReceiver.validate());
    assertThat(broadcastReceiver.lappedCount(), is(greaterThan(0L)));
  }
  @Test
  public void shouldReceiveFirstMessageFromBuffer() {
    final int length = 8;
    final int recordLength = length + HEADER_LENGTH;
    final int recordLengthAligned = align(recordLength, RECORD_ALIGNMENT);
    final long tail = recordLengthAligned;
    final long latestRecord = tail - recordLengthAligned;
    final int recordOffset = (int) latestRecord;

    when(buffer.getLongVolatile(TAIL_INTENT_COUNTER_OFFSET)).thenReturn(tail);
    when(buffer.getLongVolatile(TAIL_COUNTER_INDEX)).thenReturn(tail);
    when(buffer.getInt(lengthOffset(recordOffset))).thenReturn(recordLength);
    when(buffer.getInt(typeOffset(recordOffset))).thenReturn(MSG_TYPE_ID);

    assertTrue(broadcastReceiver.receiveNext());
    assertThat(broadcastReceiver.typeId(), is(MSG_TYPE_ID));
    assertThat(broadcastReceiver.buffer(), is(buffer));
    assertThat(broadcastReceiver.offset(), is(msgOffset(recordOffset)));
    assertThat(broadcastReceiver.length(), is(length));

    assertTrue(broadcastReceiver.validate());

    final InOrder inOrder = inOrder(buffer);
    inOrder.verify(buffer).getLongVolatile(TAIL_COUNTER_INDEX);
    inOrder.verify(buffer).getLongVolatile(TAIL_INTENT_COUNTER_OFFSET);
  }
  @Test
  public void shouldDealWithRecordBecomingInvalidDueToOverwrite() {
    final int length = 8;
    final int recordLength = length + HEADER_LENGTH;
    final int recordLengthAligned = align(recordLength, RECORD_ALIGNMENT);
    final long tail = recordLengthAligned;
    final long latestRecord = tail - recordLengthAligned;
    final int recordOffset = (int) latestRecord;

    when(buffer.getLongVolatile(TAIL_INTENT_COUNTER_OFFSET))
        .thenReturn(tail)
        .thenReturn(tail + (CAPACITY - (recordLengthAligned)));
    when(buffer.getLongVolatile(TAIL_COUNTER_INDEX)).thenReturn(tail);

    when(buffer.getInt(lengthOffset(recordOffset))).thenReturn(recordLength);
    when(buffer.getInt(typeOffset(recordOffset))).thenReturn(MSG_TYPE_ID);

    assertTrue(broadcastReceiver.receiveNext());
    assertThat(broadcastReceiver.typeId(), is(MSG_TYPE_ID));
    assertThat(broadcastReceiver.buffer(), is(buffer));
    assertThat(broadcastReceiver.offset(), is(msgOffset(recordOffset)));
    assertThat(broadcastReceiver.length(), is(length));

    assertFalse(
        broadcastReceiver.validate()); // Need to receiveNext() to catch up with transmission again.

    final InOrder inOrder = inOrder(buffer);
    inOrder.verify(buffer).getLongVolatile(TAIL_COUNTER_INDEX);
  }
  @Test
  public void shouldCopeWithPaddingRecordAndWrapOfBufferForNextRecord() {
    final int length = 120;
    final int recordLength = length + HEADER_LENGTH;
    final int recordLengthAligned = align(recordLength, RECORD_ALIGNMENT);
    final long catchupTail = (CAPACITY * 2L) - HEADER_LENGTH;
    final long postPaddingTail = catchupTail + HEADER_LENGTH + recordLengthAligned;
    final long latestRecord = catchupTail - recordLengthAligned;
    final int catchupOffset = (int) latestRecord & (CAPACITY - 1);

    when(buffer.getLongVolatile(TAIL_INTENT_COUNTER_OFFSET))
        .thenReturn(catchupTail)
        .thenReturn(postPaddingTail);
    when(buffer.getLongVolatile(TAIL_COUNTER_INDEX))
        .thenReturn(catchupTail)
        .thenReturn(postPaddingTail);
    when(buffer.getLong(LATEST_COUNTER_INDEX)).thenReturn(latestRecord);
    when(buffer.getInt(lengthOffset(catchupOffset))).thenReturn(recordLength);
    when(buffer.getInt(typeOffset(catchupOffset))).thenReturn(MSG_TYPE_ID);

    final int paddingOffset = (int) catchupTail & (CAPACITY - 1);
    final int recordOffset = (int) (postPaddingTail - recordLengthAligned) & (CAPACITY - 1);
    when(buffer.getInt(typeOffset(paddingOffset))).thenReturn(PADDING_MSG_TYPE_ID);

    when(buffer.getInt(lengthOffset(recordOffset))).thenReturn(recordLength);
    when(buffer.getInt(typeOffset(recordOffset))).thenReturn(MSG_TYPE_ID);

    assertTrue(broadcastReceiver.receiveNext()); // To catch up to record before padding.

    assertTrue(broadcastReceiver.receiveNext()); // no skip over the padding and read next record.
    assertThat(broadcastReceiver.typeId(), is(MSG_TYPE_ID));
    assertThat(broadcastReceiver.buffer(), is(buffer));
    assertThat(broadcastReceiver.offset(), is(msgOffset(recordOffset)));
    assertThat(broadcastReceiver.length(), is(length));

    assertTrue(broadcastReceiver.validate());
  }
 @Test
 public void shouldNotReceiveFromEmptyBuffer() {
   assertFalse(broadcastReceiver.receiveNext());
 }
 @Test
 public void shouldNotBeLappedBeforeReception() {
   assertThat(broadcastReceiver.lappedCount(), is(0L));
 }
 @Test
 public void shouldCalculateCapacityForBuffer() {
   assertThat(broadcastReceiver.capacity(), is(CAPACITY));
 }