/* * Copyright 2014 WANdisco * * WANdisco licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package c5db.log; import c5db.interfaces.replication.QuorumConfiguration; import c5db.replication.ReplicatorTestUtil; import c5db.replication.generated.LogEntry; import com.google.common.collect.Lists; import org.junit.Test; import static c5db.interfaces.replication.QuorumConfiguration.EMPTY; import static c5db.log.OLogEntryOracle.QuorumConfigurationWithSeqNum; import static c5db.replication.ReplicatorTestUtil.entries; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; public class NavigableMapOLogEntryOracleTest { private final NavigableMapOLogEntryOracle oracle = new NavigableMapOLogEntryOracle(); private final QuorumConfiguration firstConfig = QuorumConfiguration.of(Lists.newArrayList(1L)); private final QuorumConfiguration secondConfig = firstConfig.getTransitionalConfiguration(Lists.newArrayList(2L)); @Test public void returnsTheElectionTermAtAGivenSeqNum() throws Exception { havingLogged( entries() .term(17).seqNums(5, 6, 7) .term(18).seqNums(8, 9, 10)); assertThat(oracle.getTermAtSeqNum(4), is(equalTo(0L))); assertThat(oracle.getTermAtSeqNum(5), is(equalTo(17L))); assertThat(oracle.getTermAtSeqNum(10), is(equalTo(18L))); } @Test public void handlesTruncationsAndUpdatesTermInformationAccordingly() throws Exception { havingLogged( entries() .term(7).seqNums(1, 2)); havingTruncatedToSeqNum(2); havingLogged( entries() .term(8).seqNums(2)); assertThat(oracle.getTermAtSeqNum(1), is(equalTo(7L))); assertThat(oracle.getTermAtSeqNum(2), is(equalTo(8L))); } @Test public void returnsTheLastQuorumConfigurationAndItsSeqNum() throws Exception { havingLogged( entries() .term(999) .seqNums(5) .configurationAndSeqNum(firstConfig, 6) .seqNums(7, 8, 9)); assertThat(oracle.getLastQuorumConfig(), is(equalTo(configurationAndSeqNum(firstConfig, 6)))); havingLogged( entries() .term(999) .configurationAndSeqNum(secondConfig, 10)); assertThat(oracle.getLastQuorumConfig(), is(equalTo(configurationAndSeqNum(secondConfig, 10)))); } @Test public void handlesTruncationsAndUpdatesQuorumConfigurationInformationAccordingly() throws Exception { havingLogged( entries() .term(7).configurationAndSeqNum(firstConfig, 1)); havingTruncatedToSeqNum(1); assertThat(oracle.getLastQuorumConfig(), is(equalTo(configurationAndSeqNum(EMPTY, 0)))); havingLogged( entries() .term(8).configurationAndSeqNum(secondConfig, 2)); assertThat(oracle.getLastQuorumConfig(), is(equalTo(configurationAndSeqNum(secondConfig, 2)))); } @Test public void reportsAGreatestSeqNumOfZeroWhenNothingHasBeenLogged() throws Exception { assertThat(oracle.getGreatestSeqNum(), is(equalTo(0L))); } @Test public void reportsTheGreatestSeqNumLogged() throws Exception { havingLogged( entries() .term(8).seqNums(1, 2, 3)); assertThat(oracle.getGreatestSeqNum(), is(equalTo(3L))); } @Test public void takesTruncationIntoAccountWhenReportingTheGreatestSeqNumLogged() throws Exception { havingLogged( entries() .term(8).seqNums(1, 2, 3)); havingTruncatedToSeqNum(2); assertThat(oracle.getGreatestSeqNum(), is(equalTo(1L))); havingTruncatedToSeqNum(1); assertThat(oracle.getGreatestSeqNum(), is(equalTo(0L))); } private void havingLogged(ReplicatorTestUtil.LogSequenceBuilder sequenceBuilder) { for (LogEntry entry : sequenceBuilder.build()) { OLogEntry oLogEntry = OLogEntry.fromProtostuff(entry); oracle.notifyLogging(oLogEntry); } } private void havingTruncatedToSeqNum(long seqNum) { oracle.notifyTruncation(seqNum); } private QuorumConfigurationWithSeqNum configurationAndSeqNum(QuorumConfiguration quorumConfiguration, long seqNum) { return new QuorumConfigurationWithSeqNum(quorumConfiguration, seqNum); } }