/*
 * Copyright 2017 Palantir Technologies, Inc. All rights reserved.
 *
 * Licensed under the BSD-3 License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/BSD-3-Clause
 *
 * 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 com.palantir.paxos;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.List;
import java.util.concurrent.Executors;

import org.junit.Test;

import com.google.common.collect.ImmutableList;

// TODO(nziebart): these tests are mostly sanity checks, until we have better tests for {@link PaxosQuorumChecker}.
public class PaxosLatestRoundVerifierTest {

    private static final long EARLIER_ROUND = 4L;
    private static final long ROUND = 5L;
    private static final long LATER_ROUND = 6L;

    private final PaxosAcceptor acceptor1 = mock(PaxosAcceptor.class);
    private final PaxosAcceptor acceptor2 = mock(PaxosAcceptor.class);
    private final PaxosAcceptor acceptor3 = mock(PaxosAcceptor.class);

    private final List<PaxosAcceptor> acceptors = ImmutableList.of(
            acceptor1,
            acceptor2,
            acceptor3);

    private final PaxosLatestRoundVerifierImpl verifier = new PaxosLatestRoundVerifierImpl(acceptors, 2,
            Executors.newCachedThreadPool());

    @Test
    public void hasQuorumIfAllNodesAgree() {
        when(acceptor1.getLatestSequencePreparedOrAccepted()).thenReturn(ROUND);
        when(acceptor2.getLatestSequencePreparedOrAccepted()).thenReturn(ROUND);
        when(acceptor3.getLatestSequencePreparedOrAccepted()).thenReturn(ROUND);

        assertThat(verifier.isLatestRound(ROUND)).isEqualTo(PaxosQuorumStatus.QUORUM_AGREED);
    }

    @Test
    public void hasQuorumIfQuorumAgrees() {
        when(acceptor1.getLatestSequencePreparedOrAccepted()).thenReturn(ROUND);
        when(acceptor2.getLatestSequencePreparedOrAccepted()).thenReturn(ROUND);
        when(acceptor3.getLatestSequencePreparedOrAccepted()).thenReturn(LATER_ROUND);

        assertThat(verifier.isLatestRound(ROUND)).isEqualTo(PaxosQuorumStatus.QUORUM_AGREED);
    }

    @Test
    public void hasAgreementIfLatestSequenceIsOlder() {
        when(acceptor1.getLatestSequencePreparedOrAccepted()).thenReturn(EARLIER_ROUND);
        when(acceptor2.getLatestSequencePreparedOrAccepted()).thenReturn(EARLIER_ROUND);
        when(acceptor3.getLatestSequencePreparedOrAccepted()).thenReturn(LATER_ROUND);

        assertThat(verifier.isLatestRound(ROUND)).isEqualTo(PaxosQuorumStatus.QUORUM_AGREED);
    }

    @Test
    public void doesNotHaveQuorumIfQuorumFails() {
        when(acceptor1.getLatestSequencePreparedOrAccepted()).thenThrow(new RuntimeException("foo"));
        when(acceptor2.getLatestSequencePreparedOrAccepted()).thenThrow(new RuntimeException("foo"));
        when(acceptor3.getLatestSequencePreparedOrAccepted()).thenReturn(ROUND);

        assertThat(verifier.isLatestRound(ROUND)).isEqualTo(PaxosQuorumStatus.NO_QUORUM);
    }

    @Test
    public void hasDisagreementIfQuorumDoesNotAgree() {
        when(acceptor1.getLatestSequencePreparedOrAccepted()).thenReturn(ROUND);
        when(acceptor2.getLatestSequencePreparedOrAccepted()).thenReturn(LATER_ROUND);
        when(acceptor3.getLatestSequencePreparedOrAccepted()).thenReturn(LATER_ROUND);

        assertThat(verifier.isLatestRound(ROUND)).isEqualTo(PaxosQuorumStatus.SOME_DISAGREED);
    }

}

@@ -838,16 +838,52 @@
 ecutors;
+%0Aimport java.util.function.Supplier;
 %0A%0Aimport
@@ -1600,24 +1600,99 @@
 cceptor3);%0A%0A
+    private final Supplier%3CBoolean%3E onlyLogOnQuorumFailure = () -%3E false;%0A%0A
     private 
@@ -1827,16 +1827,40 @@
 adPool()
+, onlyLogOnQuorumFailure
 );%0A%0A    

fix test