Beispiel #1
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldPerformTruncation() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldPerformTruncation()
        {
            // when
            // we have a log appended up to appendIndex, and committed somewhere before that
            long appendIndex            = 5;
            long localTermForAllEntries = 1L;

            Outcome         outcome = mock(typeof(Outcome));
            ReadableRaftLog logMock = mock(typeof(ReadableRaftLog));

            when(logMock.ReadEntryTerm(anyLong())).thenReturn(localTermForAllEntries);                   // for simplicity, all entries are at term 1
            when(logMock.AppendIndex()).thenReturn(appendIndex);

            ReadableRaftState state = mock(typeof(ReadableRaftState));

            when(state.EntryLog()).thenReturn(logMock);
            when(state.CommitIndex()).thenReturn(appendIndex - 3);

            // when
            // the leader asks to append after the commit index an entry that mismatches on term
            Appending.HandleAppendEntriesRequest(state, outcome, new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request(_aMember, localTermForAllEntries, appendIndex - 2, localTermForAllEntries, new RaftLogEntry[] { new RaftLogEntry(localTermForAllEntries + 1, ReplicatedInteger.valueOf(2)) }, appendIndex + 3), NullLog.Instance);

            // then
            // we must produce a TruncateLogCommand at the earliest mismatching index
            verify(outcome, times(1)).addLogCommand(argThat(new LogCommandMatcher(appendIndex - 1)));
        }
Beispiel #2
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldNotAllowTruncationAtCommit() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldNotAllowTruncationAtCommit()
        {
            // given
            long commitIndex            = 5;
            long localTermForAllEntries = 1L;

            Outcome         outcome = mock(typeof(Outcome));
            ReadableRaftLog logMock = mock(typeof(ReadableRaftLog));

            when(logMock.ReadEntryTerm(anyLong())).thenReturn(localTermForAllEntries);                   // for simplicity, all entries are at term 1
            when(logMock.AppendIndex()).thenReturn(commitIndex);

            ReadableRaftState state = mock(typeof(ReadableRaftState));

            when(state.EntryLog()).thenReturn(logMock);
            when(state.CommitIndex()).thenReturn(commitIndex);

            // when - then
            try
            {
                Appending.HandleAppendEntriesRequest(state, outcome, new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request(_aMember, localTermForAllEntries, commitIndex - 1, localTermForAllEntries, new RaftLogEntry[] { new RaftLogEntry(localTermForAllEntries + 1, ReplicatedInteger.valueOf(2)) }, commitIndex + 3), NullLog.Instance);
                fail("Appending should not allow truncation at or before the commit index");
            }
            catch (System.InvalidOperationException)
            {
                // ok
            }
        }
Beispiel #3
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_Vote_Response res) throws java.io.IOException
            public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_Vote_Response res)
            {
                if (res.Term() > Ctx.term())
                {
                    Outcome.NextTerm = res.Term();
                    Outcome.NextRole = FOLLOWER;
                    Log.info("Moving to FOLLOWER state after receiving vote response from %s at term %d (I am at %d)", res.From(), res.Term(), Ctx.term());
                    return(Outcome);
                }
                else if (res.Term() < Ctx.term() || !res.VoteGranted())
                {
                    return(Outcome);
                }

                if (!res.From().Equals(Ctx.myself()))
                {
                    Outcome.addVoteForMe(res.From());
                }

                if (isQuorum(Ctx.votingMembers(), Outcome.VotesForMe))
                {
                    Outcome.Leader = Ctx.myself();
                    Appending.AppendNewEntry(Ctx, Outcome, new NewLeaderBarrier());
                    Leader.SendHeartbeats(Ctx, Outcome);

                    Outcome.LastLogIndexBeforeWeBecameLeader = Ctx.entryLog().appendIndex();
                    Outcome.electedLeader();
                    Outcome.renewElectionTimeout();
                    Outcome.NextRole = LEADER;
                    Log.info("Moving to LEADER state at term %d (I am %s), voted for by %s", Ctx.term(), Ctx.myself(), Outcome.VotesForMe);
                }
                return(Outcome);
            }
Beispiel #4
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldNotAttemptToTruncateAtIndexBeforeTheLogPrevIndex() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldNotAttemptToTruncateAtIndexBeforeTheLogPrevIndex()
        {
            // given
            // a log with prevIndex and prevTerm set
            ReadableRaftLog logMock   = mock(typeof(ReadableRaftLog));
            long            prevIndex = 5;
            long            prevTerm  = 5;

            when(logMock.PrevIndex()).thenReturn(prevIndex);
            when(logMock.ReadEntryTerm(prevIndex)).thenReturn(prevTerm);
            // and which also properly returns -1 as the term for an unknown entry, in this case prevIndex - 2
            when(logMock.ReadEntryTerm(prevIndex - 2)).thenReturn(-1L);

            // also, a state with a given commitIndex, obviously ahead of prevIndex
            long commitIndex        = 10;
            ReadableRaftState state = mock(typeof(ReadableRaftState));

            when(state.EntryLog()).thenReturn(logMock);
            when(state.CommitIndex()).thenReturn(commitIndex);
            // which is also the append index
            when(logMock.AppendIndex()).thenReturn(commitIndex);

            // when
            // an appendEntriesRequest arrives for appending entries before the prevIndex (for whatever reason)
            Outcome outcome = mock(typeof(Outcome));

            Appending.HandleAppendEntriesRequest(state, outcome, new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request(_aMember, prevTerm, prevIndex - 2, prevTerm, new RaftLogEntry[] { new RaftLogEntry(prevTerm, ReplicatedInteger.valueOf(2)) }, commitIndex + 3), NullLog.Instance);

            // then
            // there should be no truncate commands. Actually, the whole thing should be a no op
            verify(outcome, never()).addLogCommand(any());
        }
Beispiel #5
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_NewEntry_BatchRequest req) throws java.io.IOException
            public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_NewEntry_BatchRequest req)
            {
                ICollection <ReplicatedContent> contents = req.Contents();

                Appending.AppendNewEntries(Ctx, Outcome, contents);
                return(Outcome);
            }
Beispiel #6
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_NewEntry_Request req) throws java.io.IOException
            public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_NewEntry_Request req)
            {
                ReplicatedContent content = req.Content();

                Appending.AppendNewEntry(Ctx, Outcome, content);
                return(Outcome);
            }
Beispiel #7
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request req) throws java.io.IOException
            public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request req)
            {
                if (req.LeaderTerm() < Ctx.term())
                {
                    Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(Ctx.myself(), Ctx.term(), false, req.PrevLogIndex(), Ctx.entryLog().appendIndex());

                    Outcome.addOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(req.From(), appendResponse));
                    return(Outcome);
                }

                Outcome.NextRole = FOLLOWER;
                Log.info("Moving to FOLLOWER state after receiving append entries request from %s at term %d (I am at %d)n", req.From(), req.LeaderTerm(), Ctx.term());
                Appending.HandleAppendEntriesRequest(Ctx, Outcome, req, Log);
                return(Outcome);
            }
Beispiel #8
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request req) throws java.io.IOException
            public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request req)
            {
                if (req.LeaderTerm() < Ctx.term())
                {
                    Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response appendResponse = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response(Ctx.myself(), Ctx.term(), false, -1, Ctx.entryLog().appendIndex());

                    Outcome.addOutgoingMessage(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(req.From(), appendResponse));
                    return(Outcome);
                }
                else if (req.LeaderTerm() == Ctx.term())
                {
                    throw new System.InvalidOperationException("Two leaders in the same term.");
                }
                else
                {
                    // There is a new leader in a later term, we should revert to follower. (§5.1)
                    StepDownToFollower(Outcome, Ctx);
                    Log.info("Moving to FOLLOWER state after receiving append request at term %d (my term is " + "%d) from %s", req.LeaderTerm(), Ctx.term(), req.From());
                    Appending.HandleAppendEntriesRequest(Ctx, Outcome, req, Log);
                    return(Outcome);
                }
            }
Beispiel #9
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request request) throws java.io.IOException
            public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Request request)
            {
                Appending.HandleAppendEntriesRequest(Ctx, Outcome, request, Log);
                return(Outcome);
            }