Exemple #1
0
        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();
        }
Exemple #2
0
        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();
        }
Exemple #3
0
        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();
        }
Exemple #4
0
        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();
        }