public void NodeStaysAFollowerWhenReceiveAppendEntries() { using (Helpers.InitLog4Net()) { var settings = Helpers.BuildNodeSettings("1", new[] { "1", "2", "3", "4", "5" }); settings.TimeoutInMs = 20; var middleware = new Middleware(); var node = new Node<string>(TestHelpers.GetPool().BuildSequencer(), settings, middleware, new StateMachine()); using (node) { node.Initialize(); // should switch to candidate Check.That(this.WaitState(node, NodeStatus.Candidate, 40)).IsTrue(); // now we pretend there is a leader var message = new AppendEntries<string> { LeaderId = "2", LeaderTerm = 5, PrevLogIndex = -1, PrevLogTerm = 0 }; var entry = new LogEntry<string>("dummy", 1L); message.Entries = new[] { entry }; middleware.SendMessage("1", message); Check.That(this.WaitState(node, NodeStatus.Follower, 30)).IsTrue(); Check.That(node.State.LogEntries.Count).IsEqualTo(1); } } }
public void CheckThatExceptionsAreFiltered() { var test = new Middleware(false); test.RegisterEndPoint("test", x => { throw new Exception(); }); Check.That( ()=> test.SendMessage("test", 1)).DoesNotThrow(); }
public void EmptyLogIsfilledTest() { using (Helpers.InitLog4Net()) { var middleware = new Middleware(); var settings = Helpers.BuildNodeSettings("1", new[] { "1", "2" }); settings.TimeoutInMs = 10; using (var leader = new Node<string>(TestHelpers.GetPool().BuildSequencer(), settings, middleware, new StateMachine())) { // we inject leader.State.AppendEntries( -1, new[] { new LogEntry<string>("one"), new LogEntry<string>("two"), }); middleware.RegisterEndPoint("2", this.OnMessage); lock (this.synchro) { leader.Initialize(); const int MaxDelay = 3000; var initIndex = this.WaitForLogSynchro(MaxDelay, middleware, leader); Check.That(initIndex).IsEqualTo(2); } } } }
public void CommitIndexIsProperlyEstablished() { using (Helpers.InitLog4Net()) { var middleware = new Middleware(); var settings = Helpers.BuildNodeSettings("1", new[] { "1", "2" }); settings.TimeoutInMs = 1; using (var leader = new Node<string>(TestHelpers.GetPool().BuildSequencer(), settings, middleware, new StateMachine())) { // we inject leader.State.AppendEntries(-1, new[] { new LogEntry<string>("one"), new LogEntry<string>("two"), new LogEntry<string>("3") }); middleware.RegisterEndPoint("2", this.OnMessage); lock (this.synchro) { leader.Initialize(); const int MaxDelay = 300000; var initIndex = this.WaitForLogSynchro(MaxDelay, middleware, leader); Check.That(initIndex).IsEqualTo(3); // let sometime for the leader to commit entries Thread.Sleep(50); Check.That(leader.LastCommit).IsEqualTo(2); } } } }
public void CheckThatDoubleRegisterFails() { var test = new Middleware(false); test.RegisterEndPoint("test", this.MessageReceived); Check.ThatCode(() => test.RegisterEndPoint("test", this.MessageReceived)) .Throws<InvalidOperationException>(); ; }
public void SendCommandToASingleNode() { var middleware = new Middleware(); // have a cluster of one var settings = Helpers.BuildNodeSettings("1", new[] { "1" }); settings.TimeoutInMs = 10; // create a cluster of one node, so there is no ambiguity about who is the leader var leader = new Node<string>(TestHelpers.GetPool().BuildSequencer(), settings, middleware, new StateMachine()); }
public void CheckThatMessageIsReceived() { this.lastMessage = null; var test = new Middleware(false); test.RegisterEndPoint("point", this.MessageReceived); var newMessage = new object(); test.SendMessage("point", newMessage); Check.That(this.lastMessage).IsSameReferenceThan(newMessage); }
public void GivenIHaveDeployedInstance(int p0) { var nodeIds = new[] { "1", "2", "3", "4", "5" }; this.middleware = new Middleware(); this.testedNodes = new Node<string>[p0]; for (var i = 0; i < p0; i++) { var testedNode = new Node<string>(TestHelpers.GetPool().BuildSequencer(), Helpers.BuildNodeSettings(nodeIds[i], nodeIds), middleware, new StateMachine()); this.testedNodes[i] = testedNode; testedNode.Initialize(); } }
public void ProtocolTest() { var settings = Helpers.BuildNodeSettings("1", new[] { "1" }); settings.TimeoutInMs = 5; var raftMiddleware = new Middleware(); var node = new Node<string>(TestHelpers.GetPool().BuildSequencer(), settings, raftMiddleware, new StateMachine()); node.Initialize(); Thread.Sleep(50); Check.ThatEnum(node.Status).IsEqualTo(NodeStatus.Leader); raftMiddleware.SendMessage("1", new SendCommand<string>("test")); }
private void RequestAndGetVote(Middleware middleware, Node<string> node, bool succeed) { lock (this.synchro) { // request a vote, and lie about our capacity middleware.SendMessage("1", new RequestVote(3, "2", 2, 2)); if (this.lastMessage == null) { Monitor.Wait(this.synchro, 100); } Check.That(this.lastMessage).IsNotEqualTo(null).And.IsInstanceOf<GrantVote>(); var answer = this.lastMessage as GrantVote; if (succeed) { Check.That(node.State.VotedFor).IsEqualTo("2"); // did we get the vote? Check.That(answer.VoteGranted).IsTrue(); } else { Check.That(answer.VoteGranted).IsFalse(); } } }
// helper to initilize setip private Middleware InitNodes(out Node<string> node) { var middleware = new Middleware(false); var settings = Helpers.BuildNodeSettings("1", new[] { "1", "2", "3", "4", "5" }); settings.TimeoutInMs = Timeout.Infinite; // no timeout node = new Node<string>(middleware.RootUnitOfExecution.BuildSequencer(), settings, middleware, new StateMachine()); node.Initialize(); middleware.RegisterEndPoint("2", this.MessageReceived); return middleware; }
public void InitializationTests() { var test = new Middleware(false); Check.That(() => test.RegisterEndPoint("testPoint", this.MessageReceived)).DoesNotThrow(); }
public void CheckThatRegisterEndPointFailsForNullOrEmptyAddress() { var test = new Middleware(false); Check.ThatCode(() => test.RegisterEndPoint(string.Empty, this.MessageReceived)).Throws<ArgumentNullException>(); }
public void CheckThatRegisterEndPointFailsForNullHandler() { var test = new Middleware(false); Check.ThatCode( () => test.RegisterEndPoint("test", null)) .Throws<ArgumentNullException>(); }
private int WaitForLogSynchro(int maxDelay, Middleware middleware, Node<string> leader) { var initIndex = 0; var timer = new Stopwatch(); timer.Start(); for (;;) { var millisecondsTimeout = Math.Max(maxDelay - (int)timer.ElapsedMilliseconds, 0); if (Debugger.IsAttached) { millisecondsTimeout = Timeout.Infinite; } if (this.lastMessage == null && !Monitor.Wait(this.synchro, millisecondsTimeout)) { break; } var message = this.lastMessage; this.lastMessage = null; if (message is RequestVote) { // we vote for the leader middleware.SendMessage("1", new GrantVote(true, "2", 0)); } if (message is AppendEntries<string>) { var appendMessage = message as AppendEntries<string>; if (appendMessage.PrevLogIndex != initIndex - 1) { middleware.SendMessage("1", new AppendEntriesAck("2", 0, false)); } else { initIndex += (int)appendMessage.Entries.Count(); middleware.SendMessage("1", new AppendEntriesAck("2", 0, true)); if (initIndex == leader.State.LogEntries.Count) { break; } } } if (millisecondsTimeout == 0) { break; } } return initIndex; }