public LeaderElectionTests(ITestOutputHelper output) { ThreadPool.SetMaxThreads(32, 32); ThreadPool.SetMinThreads(32, 32); this.output = output; MockResourceLock.ResetGloablRecord(); }
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", })); }
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" })); }
public LeaderElectionTests() { MockResourceLock.ResetGloablRecord(); }