Пример #1
0
        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);
                }
            }
        }
Пример #2
0
        public void CheckThatExceptionsAreFiltered()
        {
            var test = new Middleware(false);

            test.RegisterEndPoint("test", x => { throw new Exception(); });
            Check.That( ()=> test.SendMessage("test", 1)).DoesNotThrow();
        }
Пример #3
0
        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);
                    }
                }
            }
        }
Пример #4
0
        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);
                    }
                }
            }
        }
Пример #5
0
 public void CheckThatDoubleRegisterFails()
 {
     var test = new Middleware(false);
     test.RegisterEndPoint("test", this.MessageReceived);
     Check.ThatCode(() => test.RegisterEndPoint("test", this.MessageReceived))
         .Throws<InvalidOperationException>();
     ;
 }
Пример #6
0
        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());
        }
Пример #7
0
        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);
        }
Пример #8
0
 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();
     }
 }
Пример #9
0
        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"));
        }
Пример #10
0
        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();
                }
            }
        }
Пример #11
0
        // 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;
        }
Пример #12
0
        public void InitializationTests()
        {
            var test = new Middleware(false);

            Check.That(() => test.RegisterEndPoint("testPoint", this.MessageReceived)).DoesNotThrow();
        }
Пример #13
0
 public void CheckThatRegisterEndPointFailsForNullOrEmptyAddress()
 {
     var test = new Middleware(false);
     Check.ThatCode(() => test.RegisterEndPoint(string.Empty, this.MessageReceived)).Throws<ArgumentNullException>();
 }
Пример #14
0
 public void CheckThatRegisterEndPointFailsForNullHandler()
 {
     var test = new Middleware(false);
     Check.ThatCode( () => test.RegisterEndPoint("test", null)) .Throws<ArgumentNullException>();
 }
Пример #15
0
        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;
        }