Esempio n. 1
0
 public LeaderElectionTests(ITestOutputHelper output)
 {
     ThreadPool.SetMaxThreads(32, 32);
     ThreadPool.SetMinThreads(32, 32);
     this.output = output;
     MockResourceLock.ResetGloablRecord();
 }
Esempio n. 2
0
        public void LeaderElection()
        {
            var electionHistory   = new List <string>();
            var leadershipHistory = new List <string>();

            var renewCountA = 3;
            var mockLockA   = new MockResourceLock("mockA")
            {
                UpdateWillFail = () => renewCountA <= 0
            };

            mockLockA.OnCreate += (_) =>
            {
                renewCountA--;

                electionHistory.Add("A creates record");
                leadershipHistory.Add("A gets leadership");
            };

            mockLockA.OnUpdate += (_) =>
            {
                renewCountA--;
                electionHistory.Add("A updates record");
            };

            mockLockA.OnChange += (_) => { leadershipHistory.Add("A gets leadership"); };

            var leaderElectionConfigA = new LeaderElectionConfig(mockLockA)
            {
                LeaseDuration = TimeSpan.FromMilliseconds(500),
                RetryPeriod   = TimeSpan.FromMilliseconds(300),
                RenewDeadline = TimeSpan.FromMilliseconds(400),
            };

            var renewCountB = 4;
            var mockLockB   = new MockResourceLock("mockB")
            {
                UpdateWillFail = () => renewCountB <= 0
            };

            mockLockB.OnCreate += (_) =>
            {
                renewCountB--;

                electionHistory.Add("B creates record");
                leadershipHistory.Add("B gets leadership");
            };

            mockLockB.OnUpdate += (_) =>
            {
                renewCountB--;
                electionHistory.Add("B updates record");
            };

            mockLockB.OnChange += (_) => { leadershipHistory.Add("B gets leadership"); };

            var leaderElectionConfigB = new LeaderElectionConfig(mockLockB)
            {
                LeaseDuration = TimeSpan.FromMilliseconds(500),
                RetryPeriod   = TimeSpan.FromMilliseconds(300),
                RenewDeadline = TimeSpan.FromMilliseconds(400),
            };

            var lockAStopLeading        = new ManualResetEvent(false);
            var testLeaderElectionLatch = new CountdownEvent(4);

            Task.Run(() =>
            {
                var leaderElector = new LeaderElector(leaderElectionConfigA);

                leaderElector.OnStartedLeading += () =>
                {
                    leadershipHistory.Add("A starts leading");
                    testLeaderElectionLatch.Signal();
                };

                leaderElector.OnStoppedLeading += () =>
                {
                    leadershipHistory.Add("A stops leading");
                    testLeaderElectionLatch.Signal();
                    lockAStopLeading.Set();
                };

                leaderElector.RunAsync().Wait();
            });


            lockAStopLeading.WaitOne(TimeSpan.FromSeconds(3));

            Task.Run(() =>
            {
                var leaderElector = new LeaderElector(leaderElectionConfigB);

                leaderElector.OnStartedLeading += () =>
                {
                    leadershipHistory.Add("B starts leading");
                    testLeaderElectionLatch.Signal();
                };

                leaderElector.OnStoppedLeading += () =>
                {
                    leadershipHistory.Add("B stops leading");
                    testLeaderElectionLatch.Signal();
                };

                leaderElector.RunAsync().Wait();
            });

            testLeaderElectionLatch.Wait(TimeSpan.FromSeconds(10));

            Assert.Equal(7, electionHistory.Count);


            Assert.True(electionHistory.SequenceEqual(
                            new[]
            {
                "A creates record", "A updates record", "A updates record",
                "B updates record", "B updates record", "B updates record", "B updates record",
            }));

            Assert.True(leadershipHistory.SequenceEqual(
                            new[]
            {
                "A gets leadership", "A starts leading", "A stops leading",
                "B gets leadership", "B starts leading", "B stops leading",
            }));
        }
Esempio n. 3
0
        public void LeaderElectionWithRenewDeadline()
        {
            var electionHistory   = new List <string>();
            var leadershipHistory = new List <string>();

            var renewCount = 3;
            var mockLock   = new MockResourceLock("mock")
            {
                UpdateWillFail = () => renewCount <= 0,
            };

            mockLock.OnCreate += _ =>
            {
                renewCount--;
                electionHistory.Add("create record");
                leadershipHistory.Add("get leadership");
            };

            mockLock.OnUpdate += _ =>
            {
                renewCount--;
                electionHistory.Add("update record");
            };

            mockLock.OnChange += _ => { electionHistory.Add("change record"); };

            mockLock.OnTryUpdate += _ => { electionHistory.Add("try update record"); };


            var leaderElectionConfig = new LeaderElectionConfig(mockLock)
            {
                LeaseDuration = TimeSpan.FromMilliseconds(1000),
                RetryPeriod   = TimeSpan.FromMilliseconds(200),
                RenewDeadline = TimeSpan.FromMilliseconds(650),
            };

            var countdown = new CountdownEvent(2);

            Task.Run(() =>
            {
                var leaderElector = new LeaderElector(leaderElectionConfig);

                leaderElector.OnStartedLeading += () =>
                {
                    leadershipHistory.Add("start leading");
                    countdown.Signal();
                };

                leaderElector.OnStoppedLeading += () =>
                {
                    leadershipHistory.Add("stop leading");
                    countdown.Signal();
                };

                leaderElector.RunAsync().Wait();
            });

            countdown.Wait(TimeSpan.FromSeconds(10));

            // TODO flasky
            // Assert.Equal(9, electionHistory.Count);

            // Assert.True(electionHistory.SequenceEqual(new[]
            // {
            //     "create record", "try update record", "update record", "try update record", "update record",
            //     "try update record", "try update record", "try update record", "try update record",
            // }));

            Assert.True(electionHistory.Take(7).SequenceEqual(new[]
            {
                "create record", "try update record", "update record", "try update record", "update record",
                "try update record", "try update record",
            }));

            Assert.True(leadershipHistory.SequenceEqual(new[] { "get leadership", "start leading", "stop leading" }));
        }
Esempio n. 4
0
 public LeaderElectionTests()
 {
     MockResourceLock.ResetGloablRecord();
 }