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 TokenMap_NetworkTopologyStrategy_With_Keyspace_Test() { var hosts = new List <Host> { { TestHelper.CreateHost("192.168.0.0", "dc1", "rack1", new HashSet <string> { "0" }) }, { TestHelper.CreateHost("192.168.0.1", "dc1", "rack1", new HashSet <string> { "100" }) }, { TestHelper.CreateHost("192.168.0.2", "dc1", "rack1", new HashSet <string> { "200" }) }, { TestHelper.CreateHost("192.168.0.100", "dc2", "rack1", new HashSet <string> { "1" }) }, { TestHelper.CreateHost("192.168.0.101", "dc2", "rack1", new HashSet <string> { "101" }) }, { TestHelper.CreateHost("192.168.0.102", "dc2", "rack1", new HashSet <string> { "201" }) } }; const string strategy = ReplicationStrategies.NetworkTopologyStrategy; var keyspaces = new List <KeyspaceMetadata> { //network strategy with rf 2 per dc new KeyspaceMetadata(null, "ks1", true, strategy, new Dictionary <string, int> { { "dc1", 2 }, { "dc2", 2 } }), //Testing simple (even it is not supposed to be) new KeyspaceMetadata(null, "ks2", true, ReplicationStrategies.SimpleStrategy, new Dictionary <string, int> { { "replication_factor", 3 } }), //network strategy with rf 3 dc1 and 1 dc2 new KeyspaceMetadata(null, "ks3", true, strategy, new Dictionary <string, int> { { "dc1", 3 }, { "dc2", 1 }, { "dc3", 5 } }), //network strategy with rf 4 dc1 new KeyspaceMetadata(null, "ks4", true, strategy, new Dictionary <string, int> { { "dc1", 5 } }) }; var tokenMap = TokenMap.Build("Murmur3Partitioner", hosts, keyspaces); //KS1 //the primary replica and the next var replicas = tokenMap.GetReplicas("ks1", new M3PToken(0)); Assert.AreEqual("0,100,1,101", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte))); //The next replica should be the first replicas = tokenMap.GetReplicas("ks1", new M3PToken(200)); Assert.AreEqual("2,102,0,100", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte))); //The closest replica and the next replicas = tokenMap.GetReplicas("ks1", new M3PToken(190)); Assert.AreEqual("2,102,0,100", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte))); //KS2 //Simple strategy: 3 tokens no matter which dc replicas = tokenMap.GetReplicas("ks2", new M3PToken(5000)); Assert.AreEqual("0,100,1", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte))); //KS3 replicas = tokenMap.GetReplicas("ks3", new M3PToken(0)); Assert.AreEqual("0,100,1,2", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte))); replicas = tokenMap.GetReplicas("ks3", new M3PToken(201)); Assert.AreEqual("102,0,1,2", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte))); //KS4 replicas = tokenMap.GetReplicas("ks4", new M3PToken(0)); Assert.AreEqual("0,1,2", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte))); }
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 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 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 Build_Should_OnlyCallOncePerReplicationConfiguration_When_MultipleKeyspacesWithSameReplicationOptions() { var hosts = new List <Host> { { TestHelper.CreateHost("192.168.0.0", "dc1", "rack", new HashSet <string> { "0" }) }, { TestHelper.CreateHost("192.168.0.1", "dc1", "rack", new HashSet <string> { "10" }) }, { TestHelper.CreateHost("192.168.0.2", "dc1", "rack", new HashSet <string> { "20" }) }, { TestHelper.CreateHost("192.168.0.3", "dc2", "rack", new HashSet <string> { "30" }) }, { TestHelper.CreateHost("192.168.0.4", "dc2", "rack", new HashSet <string> { "40" }) } }; var factory = new ProxyReplicationStrategyFactory(); var keyspaces = new List <KeyspaceMetadata> { // unique configurations TokenTests.CreateSimpleKeyspace("ks1", 2, factory), TokenTests.CreateSimpleKeyspace("ks2", 10, factory), TokenTests.CreateSimpleKeyspace("ks3", 5, factory), TokenTests.CreateNetworkTopologyKeyspace("ks4", new Dictionary <string, int> { { "dc1", 2 }, { "dc2", 2 } }, factory), TokenTests.CreateNetworkTopologyKeyspace("ks5", new Dictionary <string, int> { { "dc1", 1 }, { "dc2", 2 } }, factory), TokenTests.CreateNetworkTopologyKeyspace("ks6", new Dictionary <string, int> { { "dc1", 1 } }, factory), // duplicate configurations TokenTests.CreateNetworkTopologyKeyspace("ks7", new Dictionary <string, int> { { "dc1", 2 }, { "dc2", 2 } }, factory), TokenTests.CreateNetworkTopologyKeyspace("ks8", new Dictionary <string, int> { { "dc1", 1 } }, factory), TokenTests.CreateNetworkTopologyKeyspace("ks9", new Dictionary <string, int> { { "dc1", 1 }, { "dc2", 2 } }, factory), TokenTests.CreateSimpleKeyspace("ks10", 10, factory), TokenTests.CreateSimpleKeyspace("ks11", 2, factory) }; var tokenMap = TokenMap.Build("Murmur3Partitioner", hosts, keyspaces); var proxyStrategies = keyspaces.Select(k => (ProxyReplicationStrategy)k.Strategy).ToList(); Assert.AreEqual(6, proxyStrategies.Count(strategy => strategy.Calls > 0)); AssertOnlyOneStrategyIsCalled(proxyStrategies, 0, 10); AssertOnlyOneStrategyIsCalled(proxyStrategies, 1, 9); AssertOnlyOneStrategyIsCalled(proxyStrategies, 2); AssertOnlyOneStrategyIsCalled(proxyStrategies, 3, 6); AssertOnlyOneStrategyIsCalled(proxyStrategies, 4, 8); AssertOnlyOneStrategyIsCalled(proxyStrategies, 5, 7); }
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(); }