@Test
public void testCursor() throws IOException {

    File bd = mkdir("cursor");
    Random rnd = new Random(123);
    PersistentMessageBuffer b = new PersistentMessageBuffer(bd);
    b.setFirstId(1000);
    b.setSegmentLength(8192 + MessageFile.FILE_HEADER_SIZE);
    MessageCursor c = b.cursor(0);
    assertFalse(c.next());
    Msg m0 = appendFixedSizeMsg(b, 100, 4096, rnd);
    assertNextMsg(m0, c);
    assertFalse(c.next());
    c.close();
    // cursor starting on an empty buffer is a special case so repeat the test with a 'normal' cursor
    c = b.cursor(0);
    assertNextMsg(m0, c);
    assertFalse(c.next());
    // this fills up the first file
    Msg m1 = appendFixedSizeMsg(b, 200, 4096, rnd);
    assertNextMsg(m1, c);
    assertFalse(c.next());
    // fill the 2nd file and start the 3rd
    Msg m2 = appendFixedSizeMsg(b, 300, 4096, rnd);
    Msg m3 = appendFixedSizeMsg(b, 400, 4096, rnd);
    Msg m4 = appendFixedSizeMsg(b, 500, 4096, rnd);
    // these messages are fetched from 2nd file (not current file)
    assertNextMsg(m2, c);
    assertNextMsg(m3, c);
    // this one comes from current
    assertNextMsg(m4, c);
    assertFalse(c.next());
    c.close();
    // now run 2 cursors together
    c = b.cursor(0);
    MessageCursor c2 = b.cursor(0);
    assertNextMsg(m0, c);
    assertNextMsg(m0, c2);
    c.close();
    c2.close();
    // check seeking by id works
    seekByIdCheck(b, m0);
    seekByIdCheck(b, m1);
    seekByIdCheck(b, m2);
    seekByIdCheck(b, m3);
    seekByIdCheck(b, m4);
    // check seeking by timestamp works
    seekByTimestampCheck(b, m0);
    seekByTimestampCheck(b, m1);
    seekByTimestampCheck(b, m2);
    seekByTimestampCheck(b, m3);
    seekByTimestampCheck(b, m4);
    b.close();
    // check seeking by timestamp works on newly opened buffer
    b = new PersistentMessageBuffer(bd);
    seekByTimestampCheck(b, m0);
    b.close();
}