@Test
  public void whenBlock_whenNoSpace() {
    for (int k = 0; k < ringbuffer.capacity(); k++) {
      topic.publish("old");
    }

    final long tail = ringbuffer.tailSequence();
    final long head = ringbuffer.headSequence();

    // add the item
    final Future f =
        spawn(
            new Runnable() {
              @Override
              public void run() {
                topic.publish("new");
              }
            });

    assertTrueAllTheTime(
        new AssertTask() {
          @Override
          public void run() throws Exception {
            assertFalse(f.isDone());
            assertEquals(tail, ringbuffer.tailSequence());
            assertEquals(head, ringbuffer.headSequence());
          }
        },
        5);

    // assert that message is published eventually
    assertCompletesEventually(f);
  }
  public static void main(String[] args) throws Exception {
    HazelcastInstance hz = Hazelcast.newHazelcastInstance();

    Ringbuffer<Long> rb = hz.getRingbuffer("rb");
    // we start from the oldest item.
    // if you want to start from the next item, call rb.tailSequence()+1
    long sequence = rb.headSequence();
    System.out.println("Start reading from: " + sequence);
    while (true) {
      long item = rb.readOne(sequence);
      sequence++;
      System.out.println("Read: " + item);
    }
  }
  @Test
  public void whenDiscardOldest_whenNoSpace() {
    for (int k = 0; k < ringbuffer.capacity(); k++) {
      topic.publish("old");
    }

    long tail = ringbuffer.tailSequence();
    long head = ringbuffer.headSequence();

    topic.publish("new");

    // check that an item has been added
    assertEquals(tail + 1, ringbuffer.tailSequence());
    assertEquals(head + 1, ringbuffer.headSequence());
  }
  @Test
  public void whenDiscardNewest_whenNoSpace() {
    for (int k = 0; k < ringbuffer.capacity(); k++) {
      topic.publish("old");
    }

    long tail = ringbuffer.tailSequence();
    long head = ringbuffer.headSequence();

    topic.publish("new");

    // check that nothing has changed
    assertEquals(tail, ringbuffer.tailSequence());
    assertEquals(head, ringbuffer.headSequence());
  }
  @Test
  public void test_whenSpace() throws Exception {
    topic.publish("foo");

    ReliableTopicMessage msg = ringbuffer.readOne(0);
    assertEquals("foo", serializationService.toObject(msg.getPayload()));
  }
  @Test
  public void whenError_andNoSpace() {
    for (int k = 0; k < ringbuffer.capacity(); k++) {
      topic.publish("old");
    }

    long tail = ringbuffer.tailSequence();
    long head = ringbuffer.headSequence();

    try {
      topic.publish("new");
      fail();
    } catch (TopicOverloadException expected) {
      EmptyStatement.ignore(expected);
    }

    assertEquals(tail, ringbuffer.tailSequence());
    assertEquals(head, ringbuffer.headSequence());
  }
  @Test
  public void whenBlock_whenNoSpace() {
    for (int k = 0; k < ringbuffer.capacity(); k++) {
      topic.publish("old");
    }

    final long tail = ringbuffer.tailSequence();
    final long head = ringbuffer.headSequence();

    // add the item
    final Future f =
        spawn(
            new Runnable() {
              @Override
              public void run() {
                topic.publish("new");
              }
            });

    // make sure it doesn't complete within 3 seconds. We have a 2 second error margin to prevent
    // spurious test failures
    assertTrueAllTheTime(
        new AssertTask() {
          @Override
          public void run() throws Exception {
            assertFalse(f.isDone());
            assertEquals(tail, ringbuffer.tailSequence());
            assertEquals(head, ringbuffer.headSequence());
          }
        },
        3);

    assertCompletesEventually(f);

    assertEquals(tail + 1, ringbuffer.tailSequence());
    // since the ringbuffer got cleaned, the head is at the tail
    assertEquals(tail + 1, ringbuffer.headSequence());
  }