package lsr.paxos.storage;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import lsr.common.Configuration;
import lsr.common.PID;
import lsr.common.ProcessDescriptor;
import lsr.paxos.Snapshot;
import lsr.paxos.storage.ConsensusInstance.LogEntryState;
import org.junit.Before;
import org.junit.Test;
public class InMemoryStorageTest {
private Storage storage;
@Before
public void setUp() {
List<PID> processes = new ArrayList<PID>();
processes.add(mock(PID.class));
processes.add(mock(PID.class));
processes.add(mock(PID.class));
Configuration configuration = new Configuration(processes);
ProcessDescriptor.initialize(configuration, 0);
storage = new InMemoryStorage();
}
@Test
public void shouldReturnAcceptors() {
BitSet acceptors = new BitSet();
acceptors.set(0, 3);
assertEquals(acceptors, storage.getAcceptors());
}
@Test
public void shouldCopyAcceptorsBeforeReturn() {
storage.getAcceptors().clear();
BitSet acceptors = new BitSet();
acceptors.set(0, 3);
assertEquals(acceptors, storage.getAcceptors());
}
@Test
public void initialValueOfFirstUncommittedShouldEqualZero() {
assertEquals(0, storage.getFirstUncommitted());
}
@Test
public void shouldCreateEmptyLog() {
assertEquals(0, storage.getLog().getInstanceMap().size());
}
@Test
public void shouldUpdateFirstUncommited() {
SortedMap<Integer, ConsensusInstance> map = new TreeMap<Integer, ConsensusInstance>();
map.put(0, new ConsensusInstance(0, LogEntryState.DECIDED, 1, null));
map.put(1, new ConsensusInstance(1, LogEntryState.DECIDED, 2, null));
map.put(2, new ConsensusInstance(2, LogEntryState.KNOWN, 3, null));
map.put(3, new ConsensusInstance(3, LogEntryState.DECIDED, 4, null));
Log log = mock(Log.class);
storage = new InMemoryStorage(log);
when(log.getInstanceMap()).thenReturn(map);
when(log.getNextId()).thenReturn(5);
storage.updateFirstUncommitted();
assertEquals(2, storage.getFirstUncommitted());
}
@Test
public void shouldUpdateFirstUncommitedWithSnapshot() {
Snapshot snapshot = new Snapshot();
snapshot.setNextInstanceId(5);
storage.setLastSnapshot(snapshot);
storage.updateFirstUncommitted();
assertEquals(5, storage.getFirstUncommitted());
}
@Test
public void initialViewNumberShouldEqualZero() {
assertEquals(0, storage.getView());
}
@Test
public void shouldSetHigherView() {
storage.setView(5);
assertEquals(5, storage.getView());
storage.setView(9);
assertEquals(9, storage.getView());
}
@Test
public void shouldNotSetLowerView() {
storage.setView(5);
assertEquals(5, storage.getView());
try {
storage.setView(3);
} catch (IllegalArgumentException e) {
return;
}
fail();
}
@Test
public void shouldNotSetEqualView() {
storage.setView(5);
assertEquals(5, storage.getView());
try {
storage.setView(5);
} catch (IllegalArgumentException e) {
return;
}
fail();
}
@Test
public void shouldHaveEmptyEpochAfterInitialization() {
assertEquals(0, storage.getEpoch().length);
}
@Test
public void shouldAllowToSetEpoch() {
long[] epoch = new long[] {3, 1, 2};
storage.setEpoch(epoch);
assertArrayEquals(epoch, storage.getEpoch());
}
@Test
public void shouldUpdateEpoch() {
storage.setEpoch(new long[] {3, 1, 2});
storage.updateEpoch(new long[] {2, 2, 3});
assertArrayEquals(new long[] {3, 2, 3}, storage.getEpoch());
}
@Test
public void shouldUpdateSingleEpoch() {
storage.setEpoch(new long[] {1, 2, 3});
storage.updateEpoch(10, 1);
assertArrayEquals(new long[] {1, 10, 3}, storage.getEpoch());
}
@Test
public void shouldThrowExceptionForInvalidEpochVector() {
storage.setEpoch(new long[] {1, 2, 3});
try {
storage.updateEpoch(new long[] {1, 2, 3, 4});
} catch (IllegalArgumentException e) {
return;
}
fail();
}
@Test
public void shouldThrowExceptionForInvalidEpoch() {
storage.setEpoch(new long[] {1, 2, 3});
try {
storage.updateEpoch(5, 3);
} catch (IllegalArgumentException e) {
return;
}
fail();
}
@Test
public void shouldNotHaveSnapshotAfterInitialization() {
assertNull(storage.getLastSnapshot());
}
@Test
public void shouldSetNewSnapshot() {
Snapshot snapshot = mock(Snapshot.class);
storage.setLastSnapshot(snapshot);
assertEquals(snapshot, storage.getLastSnapshot());
}
}