From 71a4860a714847a4c9563c1595a16fa286d80659 Mon Sep 17 00:00:00 2001 From: shaan1337 Date: Tue, 19 May 2020 16:44:43 +0400 Subject: [PATCH] Add new election tests covering most of the scenarios in GetBestLeaderCandidate() Add TestElectedLeaderId property to ElectionsService for test visibility --- .../ElectionsService/ElectionsServiceTests.cs | 570 +++++++++++++----- .../Services/ElectionsService.cs | 2 + 2 files changed, 433 insertions(+), 139 deletions(-) diff --git a/src/EventStore.Core.Tests/Services/ElectionsService/ElectionsServiceTests.cs b/src/EventStore.Core.Tests/Services/ElectionsService/ElectionsServiceTests.cs index e10bd0348bd..1b03badf499 100644 --- a/src/EventStore.Core.Tests/Services/ElectionsService/ElectionsServiceTests.cs +++ b/src/EventStore.Core.Tests/Services/ElectionsService/ElectionsServiceTests.cs @@ -31,12 +31,13 @@ public abstract class ElectionsFixture { new IPEndPoint(IPAddress.Loopback, id), new IPEndPoint(IPAddress.Loopback, id), false); - protected static readonly Func MemberInfoFromVNode = - (nodeInfo, timestamp, state, isAlive, epochId) => MemberInfo.ForVNode( + protected static readonly Func MemberInfoFromVNode = + (nodeInfo, timestamp, state, isAlive, epochNumber, epochId, priority) => MemberInfo.ForVNode( nodeInfo.InstanceId, timestamp, state, isAlive, nodeInfo.InternalTcp, nodeInfo.InternalSecureTcp, nodeInfo.ExternalTcp, nodeInfo.ExternalSecureTcp, - nodeInfo.HttpEndPoint, 0, 0, 0, 0, 0, epochId, 0, + nodeInfo.HttpEndPoint, + 0, 0, 0, 0, epochNumber, epochId, priority, nodeInfo.IsReadOnlyReplica); protected ElectionsFixture(VNodeInfo node, VNodeInfo nodeTwo, VNodeInfo nodeThree) { @@ -49,7 +50,7 @@ public abstract class ElectionsFixture { _nodeTwo = nodeTwo; _nodeThree = nodeThree; _sut = new Core.Services.ElectionsService(_publisher, - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), 3, + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), 3, new InMemoryCheckpoint(0), new InMemoryCheckpoint(0), new FakeEpochManager(), () => 0L, 0, _timeProvider); @@ -61,9 +62,9 @@ public class when_starting_elections : ElectionsFixture { public when_starting_elections() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -108,9 +109,9 @@ public class when_starting_elections_after_elections_have_started : ElectionsFix public when_starting_elections_after_elections_have_started() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -127,9 +128,9 @@ public class when_node_is_shutting_down_and_starting_elections : ElectionsFixtur public when_node_is_shutting_down_and_starting_elections() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -145,9 +146,9 @@ public class when_node_is_shutting_down_and_elections_timed_out : ElectionsFixtu public when_node_is_shutting_down_and_elections_timed_out() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -165,9 +166,9 @@ public class when_elections_timeout_for_a_different_view_than_last_attempted_vie public when_elections_timeout_for_a_different_view_than_last_attempted_view() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -184,9 +185,9 @@ public class when_elections_timeout : ElectionsFixture { public when_elections_timeout() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -217,9 +218,9 @@ public class when_node_is_shutting_down_and_view_change_proof_is_triggered : Ele public when_node_is_shutting_down_and_view_change_proof_is_triggered() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -235,9 +236,9 @@ public class when_view_change_proof_is_triggered_and_the_first_election_has_not_ public when_view_change_proof_is_triggered_and_the_first_election_has_not_completed() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -260,9 +261,9 @@ public class when_view_change_proof_is_triggered_and_the_first_election_has_comp public when_view_change_proof_is_triggered_and_the_first_election_has_completed() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -300,9 +301,9 @@ public class when_receiving_view_change_and_shutting_down : ElectionsFixture { public when_receiving_view_change_and_shutting_down() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -320,9 +321,9 @@ public class when_receiving_view_change_and_idle : ElectionsFixture { public when_receiving_view_change_and_idle() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -339,9 +340,9 @@ public class when_receiving_view_change_for_an_earlier_view_than_installed : Ele public when_receiving_view_change_for_an_earlier_view_than_installed() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -359,9 +360,9 @@ public class when_receiving_a_view_change_for_a_later_view_than_last_attempted_v public when_receiving_a_view_change_for_a_later_view_than_last_attempted_view() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -392,9 +393,9 @@ public class when_receiving_view_change_from_majority_and_acceptor_of_the_curren public when_receiving_view_change_from_majority_and_acceptor_of_the_current_view() : base(NodeFactory(1), NodeFactory(2), NodeFactory(3)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -412,9 +413,9 @@ public class when_receiving_view_change_from_majority : ElectionsFixture { public when_receiving_view_change_from_majority() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -440,9 +441,9 @@ public class when_receiving_a_prepare_when_node_is_shutting_down : ElectionsFixt public when_receiving_a_prepare_when_node_is_shutting_down() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -458,9 +459,9 @@ public class when_receiving_a_prepare_for_the_same_node : ElectionsFixture { public when_receiving_a_prepare_for_the_same_node() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -477,9 +478,9 @@ public class when_receiving_a_prepare_not_for_the_last_attempted_view : Election public when_receiving_a_prepare_not_for_the_last_attempted_view() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -496,9 +497,9 @@ public class when_receiving_a_prepare_from_an_unknown_node : ElectionsFixture { public when_receiving_a_prepare_from_an_unknown_node() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -516,9 +517,9 @@ public class when_receiving_a_prepare : ElectionsFixture { public when_receiving_a_prepare() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _clusterInfo = new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)); _sut.Handle(new GossipMessage.GossipUpdated(_clusterInfo)); } @@ -543,9 +544,9 @@ public class when_receiving_prepare_ok_and_node_is_shutting_down : ElectionsFixt public when_receiving_prepare_ok_and_node_is_shutting_down() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -566,9 +567,9 @@ public class when_receiving_prepare_ok_and_elections_have_not_started : Election public when_receiving_prepare_ok_and_elections_have_not_started() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -584,9 +585,9 @@ public class when_receiving_prepare_ok_for_not_the_current_attempted_view : Elec public when_receiving_prepare_ok_for_not_the_current_attempted_view() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -604,9 +605,9 @@ public class when_receiving_a_duplicate_prepare_ok : ElectionsFixture { public when_receiving_a_duplicate_prepare_ok() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -626,9 +627,9 @@ public class when_receiving_majority_prepare_ok : ElectionsFixture { public when_receiving_majority_prepare_ok() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -664,9 +665,9 @@ public class when_node_is_shutting_down_and_receive_a_proposal : ElectionsFixtur public when_node_is_shutting_down_and_receive_a_proposal() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -684,9 +685,9 @@ public class when_receiving_a_proposal_from_the_same_node : ElectionsFixture { public when_receiving_a_proposal_from_the_same_node() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -704,9 +705,9 @@ public class when_receiving_a_proposal_as_the_acceptor_of_the_current_view : Ele public when_receiving_a_proposal_as_the_acceptor_of_the_current_view() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -728,9 +729,9 @@ public class when_receiving_a_proposal_not_for_the_current_installed_view : Elec public when_receiving_a_proposal_not_for_the_current_installed_view() : base(NodeFactory(1), NodeFactory(2), NodeFactory(3)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -751,9 +752,9 @@ public class when_receiving_a_proposal_from_an_unknown_node : ElectionsFixture { public when_receiving_a_proposal_from_an_unknown_node() : base(NodeFactory(1), NodeFactory(2), NodeFactory(3)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -774,9 +775,9 @@ public class when_receiving_a_proposal_for_an_unknown_node : ElectionsFixture { public when_receiving_a_proposal_for_an_unknown_node() : base(NodeFactory(1), NodeFactory(2), NodeFactory(3)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -797,9 +798,9 @@ public class when_receiving_a_proposal_as_acceptor : ElectionsFixture { public when_receiving_a_proposal_as_acceptor() : base(NodeFactory(1), NodeFactory(2), NodeFactory(3)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -839,9 +840,9 @@ public class when_node_is_shutting_down_and_receiving_accept : ElectionsFixture public when_node_is_shutting_down_and_receiving_accept() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -858,9 +859,9 @@ public class when_receiving_accept_for_not_the_current_installed_view : Election public when_receiving_accept_for_not_the_current_installed_view() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -882,9 +883,9 @@ public class when_receiving_accept_without_a_leader_having_been_proposed : Elect public when_receiving_accept_without_a_leader_having_been_proposed() : base(NodeFactory(1), NodeFactory(2), NodeFactory(3)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -905,9 +906,9 @@ public class when_receiving_accept_and_leader_proposal_does_not_match_accept_lea public when_receiving_accept_and_leader_proposal_does_not_match_accept_leader() : base(NodeFactory(1), NodeFactory(2), NodeFactory(3)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -931,9 +932,9 @@ public class when_receiving_majority_accept : ElectionsFixture { public when_receiving_majority_accept() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -967,9 +968,9 @@ public class when_elections_timeout_and_not_electing_leader : ElectionsFixture { public when_elections_timeout_and_not_electing_leader() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -994,9 +995,9 @@ public class when_updating_node_priority : ElectionsFixture { public when_updating_node_priority() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -1015,9 +1016,9 @@ public class when_resigning_node_and_node_is_not_the_current_leader : ElectionsF public when_resigning_node_and_node_is_not_the_current_leader() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -1042,9 +1043,9 @@ public class when_resigning_node_and_is_the_current_leader : ElectionsFixture { public when_resigning_node_and_is_the_current_leader() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -1075,9 +1076,9 @@ public class when_receiving_leader_is_resigning : ElectionsFixture { public when_receiving_leader_is_resigning() : base(NodeFactory(1), NodeFactory(2), NodeFactory(3)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -1099,9 +1100,9 @@ public class when_resigning_node_and_majority_resigning_ok_received : ElectionsF public when_resigning_node_and_majority_resigning_ok_received() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -1132,9 +1133,9 @@ public class when_electing_a_leader_and_leader_node_resigned : ElectionsFixture public when_electing_a_leader_and_leader_node_resigned() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -1182,12 +1183,12 @@ public class when_electing_a_leader_and_leader_node_resigned : ElectionsFixture public class when_a_leader_is_found_during_leader_discovery : ElectionsFixture { public when_a_leader_is_found_during_leader_discovery() : base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { - var info = MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId); + var info = MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0); _sut.Handle(new LeaderDiscoveryMessage.LeaderFound(info)); _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( - MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId), + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), info, - MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, _epochId)))); + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); } [Test] @@ -1224,4 +1225,295 @@ public class when_the_elections_service_is_initialized_as_read_only_replica { }); } } + public class when_electing_a_leader_and_prepare_ok_is_received_from_previous_leader_in_epoch_record : ElectionsFixture { + public when_electing_a_leader_and_prepare_ok_is_received_from_previous_leader_in_epoch_record() : + base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { + + _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0)))); + + _sut.Handle(new ElectionMessage.StartElections()); + _sut.Handle(new ElectionMessage.ViewChange(_nodeThree.InstanceId, _nodeThree.HttpEndPoint, 0)); + + _sut.Handle(new ElectionMessage.PrepareOk(0, _nodeThree.InstanceId, _nodeThree.HttpEndPoint, 10, 0, + _epochId, _nodeThree.InstanceId, 0, 0, 0, 0, new ClusterInfo())); + + _publisher.Messages.Clear(); + _sut.Handle(new ElectionMessage.Accept(_nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, + _nodeThree.InstanceId, _nodeThree.HttpEndPoint, 0)); + } + + [Test] + public void previous_leader_should_be_elected() { + var expected = new Message[] { + new ElectionMessage.ElectionsDone(0, + MemberInfo.ForVNode( + _nodeThree.InstanceId, _timeProvider.UtcNow, VNodeState.Unknown, true, + _nodeThree.InternalTcp, + _nodeThree.InternalSecureTcp, _nodeThree.ExternalTcp, _nodeThree.ExternalSecureTcp, + _nodeThree.HttpEndPoint, + 0, 0, 0, 0, 0, _epochId, 0, + _nodeThree.IsReadOnlyReplica)), + }; + + AssertEx.AssertUsingDeepCompare(_publisher.Messages.ToArray(), expected); + } + } + + public class when_electing_a_leader_and_prepare_ok_is_not_received_from_previous_leader_in_epoch_record : ElectionsFixture { + public when_electing_a_leader_and_prepare_ok_is_not_received_from_previous_leader_in_epoch_record() : + base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { + + //we mark the 3rd node as dead in _node's gossip so that it does not affect the results of the elections + _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, false, 0, _epochId, 0)))); + + _sut.Handle(new ElectionMessage.StartElections()); + _sut.Handle(new ElectionMessage.ViewChange(_nodeThree.InstanceId, _nodeThree.HttpEndPoint, 0)); + } + + public class + and_previous_leader_is_present_and_alive_in_cluster_info_in_received_prepare_ok : + when_electing_a_leader_and_prepare_ok_is_not_received_from_previous_leader_in_epoch_record { + + public and_previous_leader_is_present_and_alive_in_cluster_info_in_received_prepare_ok() { + _sut.Handle(new ElectionMessage.PrepareOk(0, _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 10, 0, + _epochId, _nodeThree.InstanceId, 0, 0, 0, 0, + new ClusterInfo( + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0) + ))); + + _publisher.Messages.Clear(); + _sut.Handle(new ElectionMessage.Accept(_nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, + _nodeThree.InstanceId, _nodeThree.HttpEndPoint, 0)); + } + + [Test] + public void previous_leader_should_be_elected() { + //the TestElectedLeaderId property has been added for test visibility + //we cannot see the ElectionsDone message here since the leader of the elections thinks that the elected leader is dead + Assert.AreEqual(_nodeThree.InstanceId, _sut.TestElectedLeaderId); + } + } + + public class + and_previous_leader_is_present_and_alive_but_has_lower_priority_in_cluster_info_in_received_prepare_ok : + when_electing_a_leader_and_prepare_ok_is_not_received_from_previous_leader_in_epoch_record { + + public and_previous_leader_is_present_and_alive_but_has_lower_priority_in_cluster_info_in_received_prepare_ok() { + _sut.Handle(new ElectionMessage.PrepareOk(0, _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 10, 0, + _epochId, _nodeThree.InstanceId, 0, 0, 0, 0, + new ClusterInfo( + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, -1) + ))); + + _publisher.Messages.Clear(); + _sut.Handle(new ElectionMessage.Accept(_nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, + _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 0)); + } + + [Test] + public void previous_leader_should_not_be_elected() { + var expected = new Message[] { + new ElectionMessage.ElectionsDone(0, + MemberInfo.ForVNode( + _nodeTwo.InstanceId, _timeProvider.UtcNow, VNodeState.Unknown, true, + _nodeTwo.InternalTcp, + _nodeTwo.InternalSecureTcp, _nodeTwo.ExternalTcp, _nodeTwo.ExternalSecureTcp, + _nodeTwo.HttpEndPoint, + 0, 0, 0, 0, 0, _epochId, 0, + _nodeTwo.IsReadOnlyReplica)), + }; + + AssertEx.AssertUsingDeepCompare(_publisher.Messages.ToArray(), expected); + } + } + + public class + and_previous_leader_is_present_and_alive_in_cluster_info_in_received_prepare_ok_but_is_resigning : + when_electing_a_leader_and_prepare_ok_is_not_received_from_previous_leader_in_epoch_record { + + public and_previous_leader_is_present_and_alive_in_cluster_info_in_received_prepare_ok_but_is_resigning() { + _sut.Handle(new ElectionMessage.LeaderIsResigning(_nodeThree.InstanceId, _nodeThree.HttpEndPoint)); + + _sut.Handle(new ElectionMessage.PrepareOk(0, _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 10, 0, + _epochId, _nodeThree.InstanceId, 0, 0, 0, 0, + new ClusterInfo( + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0) + ))); + + _publisher.Messages.Clear(); + _sut.Handle(new ElectionMessage.Accept(_nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, + _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 0)); + } + + [Test] + public void previous_leader_should_not_be_elected() { + var expected = new Message[] { + new ElectionMessage.ElectionsDone(0, + MemberInfo.ForVNode( + _nodeTwo.InstanceId, _timeProvider.UtcNow, VNodeState.Unknown, true, + _nodeTwo.InternalTcp, + _nodeTwo.InternalSecureTcp, _nodeTwo.ExternalTcp, _nodeTwo.ExternalSecureTcp, + _nodeTwo.HttpEndPoint, + 0, 0, 0, 0, 0, _epochId, 0, + _nodeTwo.IsReadOnlyReplica)), + }; + + AssertEx.AssertUsingDeepCompare(_publisher.Messages.ToArray(), expected); + } + } + + public class + and_previous_leader_is_present_and_alive_in_cluster_info_in_received_prepare_ok_and_epoch_number_matches_but_not_epoch_id : + when_electing_a_leader_and_prepare_ok_is_not_received_from_previous_leader_in_epoch_record { + + public and_previous_leader_is_present_and_alive_in_cluster_info_in_received_prepare_ok_and_epoch_number_matches_but_not_epoch_id() { + _sut.Handle(new ElectionMessage.PrepareOk(0, _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 10, 0, + _epochId, _nodeThree.InstanceId, 0, 0, 0, 0, + new ClusterInfo( + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 10, Guid.NewGuid(), 0) + ))); + + _publisher.Messages.Clear(); + _sut.Handle(new ElectionMessage.Accept(_nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, + _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 0)); + } + + [Test] + public void previous_leader_should_not_be_elected() { + var expected = new Message[] { + new ElectionMessage.ElectionsDone(0, + MemberInfo.ForVNode( + _nodeTwo.InstanceId, _timeProvider.UtcNow, VNodeState.Unknown, true, + _nodeTwo.InternalTcp, + _nodeTwo.InternalSecureTcp, _nodeTwo.ExternalTcp, _nodeTwo.ExternalSecureTcp, + _nodeTwo.HttpEndPoint, + 0, 0, 0, 0, 0, _epochId, 0, + _nodeTwo.IsReadOnlyReplica)), + }; + + AssertEx.AssertUsingDeepCompare(_publisher.Messages.ToArray(), expected); + } + } + + public class + and_previous_leader_is_present_and_alive_in_cluster_info_in_received_prepare_ok_and_epoch_number_does_not_match : + when_electing_a_leader_and_prepare_ok_is_not_received_from_previous_leader_in_epoch_record { + private Guid _otherEpochId = Guid.NewGuid(); + + public and_previous_leader_is_present_and_alive_in_cluster_info_in_received_prepare_ok_and_epoch_number_does_not_match() { + _sut.Handle(new ElectionMessage.PrepareOk(0, _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 10, 0, + _epochId, _nodeThree.InstanceId, 0, 0, 0, 0, + new ClusterInfo( + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, true, 9, _otherEpochId , 0) + ))); + + _publisher.Messages.Clear(); + _sut.Handle(new ElectionMessage.Accept(_nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, + _nodeThree.InstanceId, _nodeThree.HttpEndPoint, 0)); + } + + [Test] + public void previous_leader_should_be_elected() { + //the TestElectedLeaderId property has been added for test visibility + //we cannot see the ElectionsDone message here since the leader of the elections thinks that the elected leader is dead + Assert.AreEqual(_nodeThree.InstanceId, _sut.TestElectedLeaderId); + } + } + + public class + and_previous_leader_is_not_present_in_cluster_info_in_received_prepare_ok : + when_electing_a_leader_and_prepare_ok_is_not_received_from_previous_leader_in_epoch_record { + + public and_previous_leader_is_not_present_in_cluster_info_in_received_prepare_ok() { + _sut.Handle(new ElectionMessage.PrepareOk(0, _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 10, 0, + _epochId, _nodeThree.InstanceId, 0, 0, 0, 0, new ClusterInfo())); + + _publisher.Messages.Clear(); + _sut.Handle(new ElectionMessage.Accept(_nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, + _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 0)); + } + + [Test] + public void previous_leader_should_not_be_elected() { + var expected = new Message[] { + new ElectionMessage.ElectionsDone(0, + MemberInfo.ForVNode( + _nodeTwo.InstanceId, _timeProvider.UtcNow, VNodeState.Unknown, true, + _nodeTwo.InternalTcp, + _nodeTwo.InternalSecureTcp, _nodeTwo.ExternalTcp, _nodeTwo.ExternalSecureTcp, + _nodeTwo.HttpEndPoint, + 0, 0, 0, 0, 0, _epochId, 0, + _nodeTwo.IsReadOnlyReplica)), + }; + + AssertEx.AssertUsingDeepCompare(_publisher.Messages.ToArray(), expected); + } + } + + public class + and_previous_leader_is_present_but_dead_in_cluster_info_in_received_prepare_ok : + when_electing_a_leader_and_prepare_ok_is_not_received_from_previous_leader_in_epoch_record { + + public and_previous_leader_is_present_but_dead_in_cluster_info_in_received_prepare_ok() { + _sut.Handle(new ElectionMessage.PrepareOk(0, _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 10, 0, + _epochId, _nodeThree.InstanceId, 0, 0, 0, 0, + new ClusterInfo( + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, false, 0, _epochId, 0) + ))); + + _publisher.Messages.Clear(); + _sut.Handle(new ElectionMessage.Accept(_nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, + _nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, 0)); + } + + [Test] + public void previous_leader_should_not_be_elected() { + var expected = new Message[] { + new ElectionMessage.ElectionsDone(0, + MemberInfo.ForVNode( + _nodeTwo.InstanceId, _timeProvider.UtcNow, VNodeState.Unknown, true, + _nodeTwo.InternalTcp, + _nodeTwo.InternalSecureTcp, _nodeTwo.ExternalTcp, _nodeTwo.ExternalSecureTcp, + _nodeTwo.HttpEndPoint, + 0, 0, 0, 0, 0, _epochId, 0, + _nodeTwo.IsReadOnlyReplica)), + }; + + AssertEx.AssertUsingDeepCompare(_publisher.Messages.ToArray(), expected); + } + } + } + + public class when_electing_a_leader_and_best_candidate_node_is_dead_in_gossip_info_of_leader_of_elections : ElectionsFixture { + public when_electing_a_leader_and_best_candidate_node_is_dead_in_gossip_info_of_leader_of_elections() : + base(NodeFactory(3), NodeFactory(2), NodeFactory(1)) { + + _sut.Handle(new GossipMessage.GossipUpdated(new ClusterInfo( + MemberInfoFromVNode(_node, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeTwo, _timeProvider.UtcNow, VNodeState.Unknown, true, 0, _epochId, 0), + MemberInfoFromVNode(_nodeThree, _timeProvider.UtcNow, VNodeState.Unknown, false, 0, _epochId, 0)))); + + _sut.Handle(new ElectionMessage.StartElections()); + _sut.Handle(new ElectionMessage.ViewChange(_nodeThree.InstanceId, _nodeThree.HttpEndPoint, 0)); + + _sut.Handle(new ElectionMessage.PrepareOk(0, _nodeThree.InstanceId, _nodeThree.HttpEndPoint, 10, 0, + _epochId, _nodeThree.InstanceId, 0, 0, 0, 0, new ClusterInfo())); + + _publisher.Messages.Clear(); + _sut.Handle(new ElectionMessage.Accept(_nodeTwo.InstanceId, _nodeTwo.HttpEndPoint, + _nodeThree.InstanceId, _nodeThree.HttpEndPoint, 0)); + } + + [Test] + public void no_leader_should_be_elected() { + Assert.AreEqual(0, _publisher.Messages.ToArray().Length); + } + } + } diff --git a/src/EventStore.Core/Services/ElectionsService.cs b/src/EventStore.Core/Services/ElectionsService.cs index 668732b11b7..791f72d2289 100644 --- a/src/EventStore.Core/Services/ElectionsService.cs +++ b/src/EventStore.Core/Services/ElectionsService.cs @@ -71,6 +71,7 @@ public class ElectionsService : IHandle, private LeaderCandidate _leaderProposal; private Guid? _leader; private Guid? _lastElectedLeader; + public Guid TestElectedLeaderId = Guid.Empty; //this property is used for test visibility purposes only private MemberInfo[] _servers; private Guid? _resigningLeaderInstanceId; @@ -601,6 +602,7 @@ public class ElectionsService : IHandle, message.ServerHttpEndPoint, message.ServerId, message.LeaderHttpEndPoint, message.LeaderId); if (_acceptsReceived.Add(message.ServerId) && _acceptsReceived.Count == _clusterSize / 2 + 1) { + TestElectedLeaderId = _leaderProposal.InstanceId; var leader = _servers.FirstOrDefault(x => x.InstanceId == _leaderProposal.InstanceId); if (leader != null) { _leader = _leaderProposal.InstanceId;