public void TokenAwarePolicyRoundRobinsOnLocalReplicas() { var hostList = new List <Host> { //5 local nodes and 4 remote TestHelper.CreateHost("0.0.0.1", "dc1"), TestHelper.CreateHost("0.0.0.2", "dc1"), TestHelper.CreateHost("0.0.0.3", "dc2"), TestHelper.CreateHost("0.0.0.4", "dc2"), TestHelper.CreateHost("0.0.0.5", "dc1"), TestHelper.CreateHost("0.0.0.6", "dc1"), TestHelper.CreateHost("0.0.0.7", "dc2"), TestHelper.CreateHost("0.0.0.8", "dc2"), TestHelper.CreateHost("0.0.0.9", "dc1") }; var clusterMock = new Mock <ICluster>(MockBehavior.Strict); clusterMock .Setup(c => c.AllHosts()) .Returns(hostList) .Verifiable(); clusterMock .Setup(c => c.GetReplicas(It.IsAny <string>(), It.IsAny <byte[]>())) .Returns <string, byte[]>((keyspace, key) => { var i = key[0]; return(hostList.Where(h => { //The host at with address == k and the next one var address = TestHelper.GetLastAddressByte(h); return address == i || address == i + 1; }).ToList()); }) .Verifiable(); var policy = new TokenAwarePolicy(new DCAwareRoundRobinPolicy("dc1", 2)); policy.Initialize(clusterMock.Object); var firstHosts = new ConcurrentBag <Host>(); var k = new RoutingKey { RawRoutingKey = new byte[] { 1 } }; // key for host :::1 and :::2 const int times = 10000; Action action = () => { var h = policy.NewQueryPlan(null, new SimpleStatement().SetRoutingKey(k)).First(); firstHosts.Add(h); }; TestHelper.ParallelInvoke(action, times); Assert.AreEqual(times, firstHosts.Count); double queryPlansWithHost1AsFirst = firstHosts.Count(h => TestHelper.GetLastAddressByte(h) == 1); double queryPlansWithHost2AsFirst = firstHosts.Count(h => TestHelper.GetLastAddressByte(h) == 2); Assert.AreEqual(times, queryPlansWithHost1AsFirst + queryPlansWithHost2AsFirst); // Around half will to one and half to the other Assert.That(queryPlansWithHost1AsFirst / times, Is.GreaterThan(0.45).And.LessThan(0.55)); Assert.That(queryPlansWithHost2AsFirst / times, Is.GreaterThan(0.45).And.LessThan(0.55)); clusterMock.Verify(); }
public void TokenAwarePolicyReturnsLocalReplicasFirst() { var hostList = new List <Host> { //5 local nodes and 4 remote TestHelper.CreateHost("0.0.0.1", "dc1"), TestHelper.CreateHost("0.0.0.2", "dc1"), TestHelper.CreateHost("0.0.0.3", "dc2"), TestHelper.CreateHost("0.0.0.4", "dc2"), TestHelper.CreateHost("0.0.0.5", "dc1"), TestHelper.CreateHost("0.0.0.6", "dc1"), TestHelper.CreateHost("0.0.0.7", "dc2"), TestHelper.CreateHost("0.0.0.8", "dc2"), TestHelper.CreateHost("0.0.0.9", "dc1") }; var n = 2; var clusterMock = new Mock <ICluster>(); clusterMock .Setup(c => c.AllHosts()) .Returns(hostList) .Verifiable(); clusterMock .Setup(c => c.GetReplicas(It.IsAny <string>(), It.IsAny <byte[]>())) .Returns <string, byte[]>((keyspace, key) => { var i = key[0]; return(hostList.Where(h => { //The host at with address == k || address == k + n var address = TestHelper.GetLastAddressByte(h); return address == i || address == i + n; }).ToList()); }) .Verifiable(); var policy = new TokenAwarePolicy(new DCAwareRoundRobinPolicy("dc1", 2)); policy.Initialize(clusterMock.Object); //key for host :::1 and :::3 var k = new RoutingKey { RawRoutingKey = new byte[] { 1 } }; var hosts = policy.NewQueryPlan(null, new SimpleStatement().SetRoutingKey(k)).ToList(); //5 local hosts + 2 remote hosts Assert.AreEqual(7, hosts.Count); //local replica first Assert.AreEqual(1, TestHelper.GetLastAddressByte(hosts[0])); clusterMock.Verify(); //key for host :::2 and :::5 k = new RoutingKey { RawRoutingKey = new byte[] { 2 } }; n = 3; hosts = policy.NewQueryPlan(null, new SimpleStatement().SetRoutingKey(k)).ToList(); Assert.AreEqual(7, hosts.Count); //local replicas first CollectionAssert.AreEquivalent(new[] { 2, 5 }, hosts.Take(2).Select(TestHelper.GetLastAddressByte)); //next should be local nodes Assert.AreEqual("dc1", hosts[2].Datacenter); Assert.AreEqual("dc1", hosts[3].Datacenter); Assert.AreEqual("dc1", hosts[4].Datacenter); clusterMock.Verify(); }
public void DCAwareRoundRobinPolicyTestInParallel() { var hostList = new List <Host> { TestHelper.CreateHost("0.0.0.1", "dc1"), TestHelper.CreateHost("0.0.0.2", "dc2"), TestHelper.CreateHost("0.0.0.3", "dc1"), TestHelper.CreateHost("0.0.0.4", "dc2"), TestHelper.CreateHost("0.0.0.5", "dc1"), TestHelper.CreateHost("0.0.0.6", "dc2"), TestHelper.CreateHost("0.0.0.7", "dc1"), TestHelper.CreateHost("0.0.0.8", "dc2"), TestHelper.CreateHost("0.0.0.9", "dc1"), TestHelper.CreateHost("0.0.0.10", "dc2") }; var localHostsLength = hostList.Count(h => h.Datacenter == "dc1"); const string localDc = "dc1"; var clusterMock = new Mock <ICluster>(); clusterMock .Setup(c => c.AllHosts()) .Returns(hostList); //Initialize the balancing policy var policy = new DCAwareRoundRobinPolicy(localDc, 1); policy.Initialize(clusterMock.Object); var allHosts = new ConcurrentBag <Host>(); var firstHosts = new ConcurrentBag <Host>(); Action action = () => { var hosts = policy.NewQueryPlan(null, null).ToList(); //Check that the value is not repeated Assert.AreEqual(0, hosts.GroupBy(x => x) .Where(g => g.Count() > 1) .Select(y => y.Key) .Count()); firstHosts.Add(hosts[0]); //Add to the general list foreach (var h in hosts) { allHosts.Add(h); } }; var actions = new List <Action>(); const int times = 100; for (var i = 0; i < times; i++) { actions.Add(action); } TestHelper.ParallelInvoke(actions); //Check that the first nodes where different foreach (var h in hostList) { if (h.Datacenter == localDc) { Assert.AreEqual(times / localHostsLength, firstHosts.Count(hc => hc == h)); } else { Assert.AreEqual(0, firstHosts.Count(hc => hc == h)); } } clusterMock.Verify(); }
public void DCAwareRoundRobinPolicyWithNodesChanging() { var hostList = new ConcurrentBag <Host> { TestHelper.CreateHost("0.0.0.1", "dc1"), TestHelper.CreateHost("0.0.0.2", "dc2"), TestHelper.CreateHost("0.0.0.3", "dc1"), TestHelper.CreateHost("0.0.0.4", "dc2"), TestHelper.CreateHost("0.0.0.5", "dc1"), TestHelper.CreateHost("0.0.0.6", "dc2"), TestHelper.CreateHost("0.0.0.7", "dc1"), TestHelper.CreateHost("0.0.0.8", "dc2"), TestHelper.CreateHost("0.0.0.9", "dc1"), TestHelper.CreateHost("0.0.0.10", "dc2") }; const string localDc = "dc1"; //to remove the host 3 var hostToRemove = hostList.First(h => TestHelper.GetLastAddressByte(h) == 3); var clusterMock = new Mock <ICluster>(); clusterMock .Setup(c => c.AllHosts()) .Returns(() => { return(hostList.ToList()); }); //Initialize the balancing policy var policy = new DCAwareRoundRobinPolicy(localDc, 1); policy.Initialize(clusterMock.Object); var hostYielded = new ConcurrentBag <IEnumerable <Host> >(); Action action = () => hostYielded.Add(policy.NewQueryPlan(null, null).ToList()); //Invoke without nodes changing TestHelper.ParallelInvoke(action, 100); Assert.True(hostYielded.Any(hl => hl.Any(h => h == hostToRemove))); var actionList = new List <Action>(Enumerable.Repeat <Action>(action, 1000)); actionList.Insert(200, () => { var host = TestHelper.CreateHost("0.0.0.11", "dc1"); //raise event and then add clusterMock.Raise(c => c.HostAdded += null, host); hostList.Add(host); }); actionList.Insert(400, () => { var host = TestHelper.CreateHost("0.0.0.12", "dc1"); //first add and then raise event hostList.Add(host); clusterMock.Raise(c => c.HostAdded += null, host); }); actionList.Insert(400, () => { var host = hostToRemove; hostList = new ConcurrentBag <Host>(hostList.Where(h => h != hostToRemove)); clusterMock.Raise(c => c.HostRemoved += null, host); }); //Invoke it with nodes being modified TestHelper.ParallelInvoke(actionList); //Clear the host yielded so far hostYielded = new ConcurrentBag <IEnumerable <Host> >(); //Invoke it a some of times more in parallel TestHelper.ParallelInvoke(action, 100); //The removed node should not be returned Assert.False(hostList.Any(h => h == hostToRemove)); Assert.False(hostYielded.Any(hl => hl.Any(h => h == hostToRemove))); }
public void TokenAwarePolicyRoundRobinsOnLocalReplicas() { var hostList = new List <Host> { //5 local nodes and 4 remote TestHelper.CreateHost("0.0.0.1", "dc1"), TestHelper.CreateHost("0.0.0.2", "dc1"), TestHelper.CreateHost("0.0.0.3", "dc2"), TestHelper.CreateHost("0.0.0.4", "dc2"), TestHelper.CreateHost("0.0.0.5", "dc1"), TestHelper.CreateHost("0.0.0.6", "dc1"), TestHelper.CreateHost("0.0.0.7", "dc2"), TestHelper.CreateHost("0.0.0.8", "dc2"), TestHelper.CreateHost("0.0.0.9", "dc1") }; var clusterMock = new Mock <ICluster>(MockBehavior.Strict); clusterMock .Setup(c => c.AllHosts()) .Returns(hostList) .Verifiable(); clusterMock .Setup(c => c.GetReplicas(It.IsAny <string>(), It.IsAny <byte[]>())) .Returns <string, byte[]>((keyspace, key) => { var i = key[0]; return(hostList.Where(h => { //The host at with address == k and the next one var address = TestHelper.GetLastAddressByte(h); return address == i || address == i + 1; }).ToList()); }) .Verifiable(); var policy = new TokenAwarePolicy(new DCAwareRoundRobinPolicy("dc1", 2)); policy.Initialize(clusterMock.Object); var firstHosts = new ConcurrentBag <Host>(); var k = new RoutingKey { RawRoutingKey = new byte[] { 1 } }; //key for host :::1 and :::2 var actions = new List <Action>(); const int times = 100; for (var i = 0; i < times; i++) { actions.Add(() => { var h = policy.NewQueryPlan(null, new SimpleStatement().SetRoutingKey(k)).First(); firstHosts.Add(h); }); } var parallelOptions = new ParallelOptions(); parallelOptions.TaskScheduler = new ThreadPerTaskScheduler(); parallelOptions.MaxDegreeOfParallelism = 1000; Parallel.Invoke(parallelOptions, actions.ToArray()); Assert.AreEqual(times, firstHosts.Count); //Half the times Assert.AreEqual(times / 2, firstHosts.Count(h => TestHelper.GetLastAddressByte(h) == 1)); Assert.AreEqual(times / 2, firstHosts.Count(h => TestHelper.GetLastAddressByte(h) == 2)); clusterMock.Verify(); }