package org.f1x.store;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class Test_InMemoryMessageStore {
private static final int STORE_SIZE = 1 << 6;
private InMemoryMessageStore store;
@Before
public void init() {
store = new InMemoryMessageStore (STORE_SIZE);
}
@Test
public void simple() {
put(1, "MSG1");
put(2, "MSG2");
put(3, "MSG3");
//System.out.println(store.dump());
assertNotFound(4);
assertGet(3, "MSG3");
assertGet(3, "MSG3");
assertGet(1, "MSG1");
assertGet(2, "MSG2");
assertNotFound(0);
}
@Test
public void testEmpty() {
assertNotFound(123);
put(123, "MSG");
assertNotFound(122);
assertGet(123, "MSG");
assertNotFound(124);
store.clean();
assertNotFound(123);
}
@Test
public void reset() {
put(1, "MSG1");
put(2, "MSG2");
put(3, "MSG3");
store.clean();
assertNotFound(1);
assertNotFound(2);
assertNotFound(3);
put(1, "MSG1");
put(2, "MSG2");
put(3, "MSG3");
assertGet(3, "MSG3");
assertGet(1, "MSG1");
assertGet(2, "MSG2");
}
@Test
public void wrappedStore() {
final String FORMAT = "MSG%07d";
final int msgSize = String.format(FORMAT, 0).length();
final int n = 3*STORE_SIZE / (2*msgSize);
for (int i=1; i < n; i++) {
String msg = String.format(FORMAT, i);
put(i, msg);
}
System.out.println(store.dump());
assertNotFound(n);
assertGet(n-1, String.format(FORMAT, n-1));
assertGet(n-2, String.format(FORMAT, n-2));
assertGet(n-3, String.format(FORMAT, n-3));
assertNotFound(n-4);
}
@Test
public void testIterator1 () {
put(1, "MSG1");
put(2, "MESSAGE2");
put(3, "MSG3");
assertIterator (1, 3, "MSG1,MESSAGE2,MSG3");
assertIterator (1, 1, "MSG1");
assertIterator (2, 2, "MESSAGE2");
assertIterator (3, 3, "MSG3");
assertIterator (1, 2, "MSG1,MESSAGE2");
assertIterator (2, 3, "MESSAGE2,MSG3");
}
@Test
public void testIterator2 () {
put(10, "1");
put(20, "2");
put(30, "#3");
put(40, "4");
put(50, "5");
System.out.println(store.dump());
assertIterator (10, 50, "1,2,#3,4,5");
assertIterator (1, 100, "1,2,#3,4,5");
assertIterator (20, 40, "2,#3,4");
assertIterator (30, 30, "#3");
assertIterator (40, 40, "4");
assertIterator (39, 41, "4");
}
/** Same as before but due to small buffer size we keep only last four messages (M2, M3, M4, M5) */
@Test
public void testIteratorWithOverflow2 () {
put(10, "M1");
put(20, "M2");
put(30, "MSG3");
put(40, "M4");
put(50, "M5");
System.out.println(store.dump()); // MSG1 is overridden by MSG5
assertIterator (10, 50, "M2,MSG3,M4,M5");
assertIterator (1, 100, "M2,MSG3,M4,M5");
assertIterator (20, 40, "M2,MSG3,M4");
assertIterator (30, 30, "MSG3");
assertIterator (40, 40, "M4");
assertIterator (39, 41, "M4");
}
/** Same as before but due to small buffer size we keep only last three messages (M3, M4, M5) */
@Test
public void testIteratorWithOverflow3 () {
put(10, "MSG1");
put(20, "MSG2");
put(30, "MESSAGE3");
put(40, "MSG4");
put(50, "MSG5");
System.out.println(store.dump()); // MSG1 is overridden by MSG5
assertIterator (10, 50, "MESSAGE3,MSG4,MSG5");
assertIterator (1, 100, "MESSAGE3,MSG4,MSG5");
assertIterator (20, 40, "MESSAGE3,MSG4");
assertIterator (30, 30, "MESSAGE3");
assertIterator (40, 40, "MSG4");
assertIterator (39, 41, "MSG4");
}
@Test
public void testEmptyIterators () {
assertIterator (1, 1, "");
assertIterator (1, 2, "");
put(10, "MSG1");
put(20, "MSG2");
put(30, "MESSAGE4");
put(40, "MSG4");
put(50, "MSG5");
assertIterator (1, 2, "");
assertIterator (31, 32, "");
assertIterator (51, 55, "");
}
@Test(expected = IllegalStateException.class)
public void zeroAsSequenceNum() {
put(0, "DUMMY");
}
@Test(expected = IllegalStateException.class)
public void negativeSequenceNum() {
put(-1, "DUMMY");
}
@Test(expected = IllegalStateException.class)
public void outOfOrderSequenceNum() {
put(2, "DUMMY");
put(1, "DUMMY");
}
@Test(expected = IllegalStateException.class)
public void outOfOrderSequenceNum1() {
put(1, "DUMMY");
put(1, "DUMMY");
}
private void put (int seqNum, String content) {
put(seqNum, content.getBytes());
}
private void put (int seqNum, byte [] content) {
store.put (seqNum, content, 0, content.length);
}
private void assertGet(int seqNum, String expectedContent) {
byte [] buffer = new byte[256];
if (store.get(seqNum, buffer) <= 0)
Assert.fail("Can't find message with sequence number " + seqNum);
String actualContent = new String (buffer, 0, sizeof(buffer));
Assert.assertEquals(expectedContent, actualContent);
}
private void assertNotFound(int seqNum) {
byte [] buffer = new byte[256];
if (store.get(seqNum, buffer) > 0)
Assert.fail("Was not supposed to find message with sequence number " + seqNum + " found: " + new String (buffer, 0, sizeof(buffer)));
}
private void assertIterator(int fromSeqNum, int toSeqNum, String expectedContent) {
MessageStore.MessageStoreIterator iter = store.iterator(fromSeqNum, toSeqNum);
byte [] buffer = new byte [256];
StringBuilder sb = new StringBuilder();
while (true) {
if (iter.next(buffer) <= 0)
break;
if (sb.length() > 0)
sb.append(",");
String item = new String (buffer, 0, sizeof(buffer));
sb.append(item);
}
Assert.assertEquals("Range [" + fromSeqNum + ", " + toSeqNum +"]", expectedContent, sb.toString());
}
private static int sizeof(byte[] szBytes) {
int result = 0;
while(szBytes[result] != 0)
result++;
return result;
}
}