package lsr.paxos; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.BitSet; import lsr.common.Dispatcher; import lsr.common.ProcessDescriptorHelper; import lsr.paxos.messages.Accept; import lsr.paxos.messages.Message; import lsr.paxos.messages.Prepare; import lsr.paxos.messages.PrepareOK; import lsr.paxos.messages.Propose; import lsr.paxos.network.Network; import lsr.paxos.storage.ConsensusInstance; import lsr.paxos.storage.InMemoryStorage; import lsr.paxos.storage.Log; import lsr.paxos.storage.Storage; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; public class AcceptorTest { private Dispatcher dispatcher; private Paxos paxos; private Storage storage; private Network network; private Acceptor acceptor; @Before public void setUp() { ProcessDescriptorHelper.initialize(3, 0); dispatcher = mock(Dispatcher.class); when(dispatcher.amIInDispatcher()).thenReturn(true); paxos = mock(Paxos.class); when(paxos.getDispatcher()).thenReturn(dispatcher); storage = new InMemoryStorage(); network = mock(Network.class); acceptor = new Acceptor(paxos, storage, network); } @Test public void shouldHandlePrepareMessage() { storage.setView(5); Prepare prepare = new Prepare(6, 1); acceptor.onPrepare(prepare, 1); ArgumentCaptor<Message> messageArgument = ArgumentCaptor.forClass(Message.class); verify(network).sendMessage(messageArgument.capture(), eq(1)); PrepareOK prepareOk = (PrepareOK) messageArgument.getValue(); assertArrayEquals(new long[] {}, prepareOk.getEpoch()); assertEquals(6, prepareOk.getView()); assertArrayEquals(new ConsensusInstance[] {}, prepareOk.getPrepared()); } @Test public void shouldAddEpochVectorToPrepareOk() { storage.setView(5); storage.setEpoch(new long[] {2, 3, 1}); Prepare prepare = new Prepare(6, 1); acceptor.onPrepare(prepare, 1); ArgumentCaptor<Message> messageArgument = ArgumentCaptor.forClass(Message.class); verify(network).sendMessage(messageArgument.capture(), eq(1)); PrepareOK prepareOk = (PrepareOK) messageArgument.getValue(); assertArrayEquals(new long[] {2, 3, 1}, prepareOk.getEpoch()); assertEquals(6, prepareOk.getView()); assertArrayEquals(new ConsensusInstance[] {}, prepareOk.getPrepared()); } @Test public void shouldSendPreparedInstances() { Log log = storage.getLog(); log.getInstance(4); assertEquals(5, log.getNextId()); Prepare prepare = new Prepare(6, 2); acceptor.onPrepare(prepare, 1); ArgumentCaptor<Message> messageArgument = ArgumentCaptor.forClass(Message.class); verify(network).sendMessage(messageArgument.capture(), eq(1)); PrepareOK prepareOk = (PrepareOK) messageArgument.getValue(); assertArrayEquals( new ConsensusInstance[] {log.getInstance(2), log.getInstance(3), log.getInstance(4)}, prepareOk.getPrepared()); } @Test public void shouldHandleProposeMessage() { storage.setView(1); Propose propose = new Propose(1, 0, new byte[] {1, 2, 3}); acceptor.onPropose(propose, 1); ArgumentCaptor<Message> messageArgument = ArgumentCaptor.forClass(Message.class); verify(network).sendMessage(messageArgument.capture(), any(BitSet.class)); Accept accept = (Accept) messageArgument.getValue(); assertEquals(propose.getView(), accept.getView()); assertEquals(propose.getInstanceId(), accept.getInstanceId()); } }