public void OperationState_Can_Concurrently_Get_Calls_To_SetCompleted() { var counter = 0; var clientCallbackCounter = 0L; const int times = 40; TestHelper.Invoke(() => { Action <Exception, Response> clientCallback = (ex, r) => { // ReSharper disable once AccessToModifiedClosure Interlocked.Increment(ref clientCallbackCounter); }; var state = new OperationState(clientCallback); var actions = Enumerable.Repeat <Action>(() => { var cb = state.SetCompleted(); cb(null, null); }, 2); if ((counter++) % 2 == 0) { //invert order actions = actions.Reverse(); } TestHelper.ParallelInvoke(actions.ToArray()); }, times); //Allow callbacks to be called using the default scheduler Thread.Sleep(1000); Assert.AreEqual(times, Interlocked.Read(ref clientCallbackCounter)); }
private static void TimestampGeneratorLogAfterCooldownTest(ITimestampGenerator generator, TestHelper.TestLoggerHandler loggerHandler) { // It should generate a warning initially and then 1 more var maxElapsed = TimeSpan.FromSeconds(1.8); Action action = () => { var stopWatch = new Stopwatch(); stopWatch.Start(); // ReSharper disable once AccessToModifiedClosure while (stopWatch.Elapsed < maxElapsed) { for (var i = 0; i < 5000; i++) { generator.Next(); } } }; TestHelper.ParallelInvoke(action, 2); Assert.AreEqual(2, loggerHandler.DequeueAllMessages().Count(i => i.Item1 == "warning")); // Cooldown: make current time > last generated value Thread.Sleep(3000); // It should generate a warning initially maxElapsed = TimeSpan.FromSeconds(0.8); TestHelper.ParallelInvoke(action, 2); Assert.AreEqual(1, loggerHandler.DequeueAllMessages().Count(i => i.Item1 == "warning")); }
public void HashedWheelTimer_Should_Schedule_In_Order() { var results = new List <int>(); var actions = new Action[10]; var timer = new HashedWheelTimer(200, 8); for (var i = 0; i < actions.Length; i++) { var index = i; actions[i] = () => { // ReSharper disable once AccessToDisposedClosure timer.NewTimeout(_ => { results.Add(index); }, null, 200 * (actions.Length - index)); }; } TestHelper.ParallelInvoke(actions); var counter = 0; while (results.Count < actions.Length && ++counter < 20) { Thread.Sleep(500); Trace.WriteLine("Slept " + counter); } Assert.AreEqual(actions.Length, results.Count); counter = 10; CollectionAssert.AreEqual(Enumerable.Repeat(0, actions.Length).Select(_ => -- counter), results); timer.Dispose(); }
private static void TimestampGeneratorLogAfterCooldownTest(ITimestampGenerator generator, TestHelper.TestLoggerHandler loggerHandler) { // It should generate a warning initially and then 1 more var maxElapsed = TimeSpan.FromSeconds(1.8); var counter = 0; Action action = () => { var stopWatch = new Stopwatch(); stopWatch.Start(); // ReSharper disable once AccessToModifiedClosure while (stopWatch.Elapsed < maxElapsed) { for (var i = 0; i < 5000; i++) { generator.Next(); Interlocked.Increment(ref counter); } } }; TestHelper.ParallelInvoke(action, 2); if (Volatile.Read(ref counter) < 5000000) { // if during this time, we weren't able to generate a lot of values, don't mind Assert.Ignore("It was not able to generate 5M values"); } Assert.AreEqual(2, loggerHandler.DequeueAllMessages().Count(i => i.Item1 == "warning")); // Cooldown: make current time > last generated value Thread.Sleep(3000); // It should generate a warning initially maxElapsed = TimeSpan.FromSeconds(0.8); TestHelper.ParallelInvoke(action, 2); Assert.AreEqual(1, loggerHandler.DequeueAllMessages().Count(i => i.Item1 == "warning")); }
public void OperationState_Can_Concurrently_Get_Timeout_And_Response() { var counter = 0; var timedOutReceived = 0; TestHelper.Invoke(() => { var clientCallbackCounter = 0; Action <Exception, AbstractResponse> clientCallback = (ex, r) => { Interlocked.Increment(ref clientCallbackCounter); }; var state = new OperationState(clientCallback); var actions = new Action[] { () => state.SetTimedOut(new OperationTimedOutException(new IPEndPoint(0, 1), 200), () => Interlocked.Increment(ref timedOutReceived)), () => { state.InvokeCallback(null); } }; if ((counter++) % 2 == 0) { //invert order actions = actions.Reverse().ToArray(); } TestHelper.ParallelInvoke(actions); //Allow callbacks to be called using the default scheduler Thread.Sleep(20); Assert.AreEqual(1, clientCallbackCounter); }, 50); Trace.WriteLine(timedOutReceived); }
public void DCAwareRoundRobinPolicyCachesLocalNodes() { 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") }; 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 instances = new ConcurrentBag <object>(); Action action = () => instances.Add(policy.GetHosts()); TestHelper.ParallelInvoke(action, 100); Assert.AreEqual(1, instances.GroupBy(i => i.GetHashCode()).Count()); }
public void FactoryBasedLoggerHandler_LogError_Handles_Concurrent_Calls() { var originalLevel = Diagnostics.CassandraTraceSwitch.Level; try { Diagnostics.CassandraTraceSwitch.Level = TraceLevel.Verbose; var listener = new TestTraceListener(); Trace.Listeners.Add(listener); var loggerHandler = new Logger.TraceBasedLoggerHandler(typeof(int)); UseAllMethods(loggerHandler); Trace.Listeners.Remove(listener); Assert.AreEqual(6, listener.Messages.Count); var actions = Enumerable .Repeat(true, 1000) .Select <bool, Action>((_, index) => () => { loggerHandler.Error(new ArgumentException("Test exception " + index, new Exception("Test inner exception"))); }); TestHelper.ParallelInvoke(actions); } finally { Diagnostics.CassandraTraceSwitch.Level = originalLevel; } }
private static void TimestampGeneratorLogDriftingTest( ITimestampGenerator generator, TestHelper.TestLoggerHandler loggerHandler, int logIntervalMs) { var timestamp = DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond; TestHelper.ParallelInvoke( () => { generator.Next(); }, 1000000); var elapsed = (DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond) - timestamp; if (elapsed > 3000) { Assert.Ignore("Generated numbers too slowly for this test to work."); } else { var count = elapsed / logIntervalMs; Assert.That(Interlocked.Read(ref loggerHandler.WarningCount), Is.InRange(count + 1, count + 2)); } }
public void EnsureCreate_Parallel_Calls_Should_Yield_First() { var mock = GetPoolMock(); var lastByte = 0; mock.Setup(p => p.DoCreateAndOpen()).Returns(() => TestHelper.DelayedTask(CreateConnection((byte)++lastByte), 100 + (lastByte > 1 ? 10000 : 0))); var pool = mock.Object; var creationTasks = new Task <Connection[]> [10]; var counter = -1; var initialCreate = pool.EnsureCreate(); TestHelper.ParallelInvoke(() => { creationTasks[Interlocked.Increment(ref counter)] = pool.EnsureCreate(); }, 10); // ReSharper disable once CoVariantArrayConversion Task.WaitAll(creationTasks); Assert.AreEqual(1, TaskHelper.WaitToComplete(initialCreate).Length); foreach (var t in creationTasks) { Assert.AreEqual(1, TaskHelper.WaitToComplete(t).Length); } Assert.AreEqual(1, lastByte); }
private static void TimestampGeneratorLogDriftingTest(ITimestampGenerator generator, TestHelper.TestLoggerHandler loggerHandler) { // A little less than 3 seconds // It should generate a warning initially and then next 2 after 1 second each var maxElapsed = TimeSpan.FromSeconds(2.8); var counter = 0; TestHelper.ParallelInvoke(() => { var stopWatch = new Stopwatch(); stopWatch.Start(); while (stopWatch.Elapsed < maxElapsed) { for (var i = 0; i < 10000; i++) { generator.Next(); Interlocked.Increment(ref counter); } } }, 2); if (Volatile.Read(ref counter) < 5000000) { // if during this time, we weren't able to generate a lot of values, don't mind Assert.Ignore("It was not able to generate 5M values"); } Assert.AreEqual(3, loggerHandler.DequeueAllMessages().Count(i => i.Item1 == "warning")); }
public void BringUpIfDown_Should_Allow_Multiple_Concurrent_Calls() { var host = new Host(Address); var counter = 0; host.Up += _ => Interlocked.Increment(ref counter); host.SetDown(); TestHelper.ParallelInvoke(() => { host.BringUpIfDown(); }, 100); //Should fire event only once Assert.AreEqual(1, counter); }
public void DCAwareRoundRobinYieldsRemoteNodesAtTheEnd() { var hostList = new List <Host> { //5 local nodes and 4 remote 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); Action action = () => { var hosts = policy.NewQueryPlan(null, null).ToList(); for (var i = 0; i < hosts.Count; i++) { var h = hosts[i]; if (i < localHostsLength) { Assert.AreEqual(localDc, h.Datacenter); } else { Assert.AreNotEqual(localDc, h.Datacenter); } } }; TestHelper.ParallelInvoke(action, 100); }
private static void TimestampGeneratorMonitonicityTest(ITimestampGenerator generator) { // Use a set to determine the amount of different values const int iterations = 5000; const int threads = 8; var values = new ConcurrentDictionary <long, bool>(); TestHelper.ParallelInvoke(() => { var lastValue = 0L; for (var i = 0; i < iterations; i++) { var value = generator.Next(); Assert.Greater(value, lastValue); lastValue = value; values.TryAdd(value, true); } }, threads); Assert.AreEqual(iterations * threads, values.Count); }
public void CopyOnWriteList_Should_Allow_Parallel_Calls_To_Remove() { var actions = new List<Action>(); var list = new CopyOnWriteList<int>(); for (var i = 0; i < 100; i++) { list.Add(i); } Assert.AreEqual(100, list.Count); for (var i = 0; i < 100; i++) { var item = i; actions.Add(() => { list.Remove(item); }); } TestHelper.ParallelInvoke(actions); Assert.AreEqual(0, list.Count); }
public void CopyOnWriteDictionary_Should_Allow_Parallel_Calls_To_Add() { var actions = new List<Action>(); var map = new CopyOnWriteDictionary<int, int>(); for (var i = 0; i < 100; i++) { var item = i; actions.Add(() => { map.Add(item, item * 1000); }); } TestHelper.ParallelInvoke(actions); Assert.AreEqual(100, map.Count); for (var i = 0; i < 100; i++) { Assert.AreEqual(i * 1000, map[i]); } var counter = 0; CollectionAssert.AreEquivalent(Enumerable.Repeat(0, 100).Select(_ => counter++), map.Keys); }
private static void TimestampGeneratorLogDriftingTest(ITimestampGenerator generator, TestHelper.TestLoggerHandler loggerHandler) { // A little less than 3 seconds // It should generate a warning initially and then next 2 after 1 second each var maxElapsed = TimeSpan.FromSeconds(2.8); TestHelper.ParallelInvoke(() => { var stopWatch = new Stopwatch(); stopWatch.Start(); while (stopWatch.Elapsed < maxElapsed) { for (var i = 0; i < 10000; i++) { generator.Next(); } } }, 2); Assert.AreEqual(3, loggerHandler.DequeueAllMessages().Count(i => i.Item1 == "warning")); }
public void CopyOnWriteList_Should_Allow_Parallel_Calls_To_Add() { var actions = new List<Action>(); var list = new CopyOnWriteList<int>(); for (var i = 0; i < 100; i++) { var item = i; actions.Add(() => { list.Add(item); }); } TestHelper.ParallelInvoke(actions); Assert.AreEqual(100, list.Count); for (var i = 0; i < 100; i++) { Assert.True(list.Contains(i)); } var counter = 0; CollectionAssert.AreEquivalent(Enumerable.Repeat(0, 100).Select(_ => counter++), list); }
public void OperationState_Can_Concurrently_Get_Timeout_And_Response() { var counter = 0; var timedOutReceived = 0; var clientCallbackCounter = 0; const int times = 40; var expectedTimedout = 0; TestHelper.Invoke(() => { Action <Exception, Response> clientCallback = (ex, r) => { Interlocked.Increment(ref clientCallbackCounter); }; var state = new OperationState(clientCallback); var actions = new Action[] { () => { var timedout = state.MarkAsTimedOut( new OperationTimedOutException(new IPEndPoint(0, 1), 200), () => Interlocked.Increment(ref timedOutReceived)); Interlocked.Add(ref expectedTimedout, timedout ? 1 : 0); }, () => { state.InvokeCallback(null); } }; if ((counter++) % 2 == 0) { //invert order actions = actions.Reverse().ToArray(); } TestHelper.ParallelInvoke(actions); }, times); //Allow callbacks to be called using the default scheduler Thread.Sleep(1000); Assert.AreEqual(times, clientCallbackCounter); Assert.AreEqual(expectedTimedout, timedOutReceived); }
public void EnsureCreate_Parallel_Calls_Failing_Should_Only_Attempt_Creation_Once() { // Use a reconnection policy that never attempts var mock = GetPoolMock(null, GetConfig(3, 3, new ConstantReconnectionPolicy(int.MaxValue))); var openConnectionAttempts = 0; mock.Setup(p => p.DoCreateAndOpen()).Returns(() => { Interlocked.Increment(ref openConnectionAttempts); return(TaskHelper.FromException <Connection>(new Exception("Test Exception"))); }); var pool = mock.Object; const int times = 5; var creationTasks = new Task[times]; var counter = -1; var initialCreate = pool.EnsureCreate(); TestHelper.ParallelInvoke(() => { creationTasks[Interlocked.Increment(ref counter)] = pool.EnsureCreate(); }, times); Assert.Throws <AggregateException>(() => initialCreate.Wait()); var aggregateException = Assert.Throws <AggregateException>(() => Task.WaitAll(creationTasks)); Assert.AreEqual(times, aggregateException.InnerExceptions.Count); Assert.AreEqual(1, Volatile.Read(ref openConnectionAttempts)); // Serially, attempt calls to create Interlocked.Exchange(ref counter, -1); TestHelper.ParallelInvoke(() => { creationTasks[Interlocked.Increment(ref counter)] = pool.EnsureCreate(); }, times); aggregateException = Assert.Throws <AggregateException>(() => Task.WaitAll(creationTasks)); Assert.AreEqual(times, aggregateException.InnerExceptions.Count); Assert.AreEqual(1, Volatile.Read(ref openConnectionAttempts)); }
private static void TimestampGeneratorLogAfterCooldownTest(ITimestampGenerator generator, TestHelper.TestLoggerHandler loggerHandler) { // It should generate a warning initially and then 1 more var counter = 0; void Action(TimeSpan maxElapsed) { var stopWatch = new Stopwatch(); stopWatch.Start(); while (stopWatch.Elapsed < maxElapsed) { for (var i = 0; i < 5000; i++) { generator.Next(); // ReSharper disable once AccessToModifiedClosure Interlocked.Increment(ref counter); } } } TestHelper.ParallelInvoke(() => Action(TimeSpan.FromSeconds(1.8)), 2); if (Volatile.Read(ref counter) < 5000000) { // if during this time, we weren't able to generate a lot of values, don't mind Assert.Ignore("It was not able to generate 5M values"); } Assert.That(Interlocked.Read(ref loggerHandler.WarningCount), Is.GreaterThanOrEqualTo(2)); // Cooldown: make current time > last generated value Thread.Sleep(4000); // It should generate a warning initially TestHelper.ParallelInvoke(() => Action(TimeSpan.FromSeconds(0.8)), 2); Assert.That(Interlocked.Read(ref loggerHandler.WarningCount), Is.GreaterThanOrEqualTo(1)); }
public void CopyOnWriteDictionary_Should_Allow_Parallel_Calls_To_Remove() { var actions = new List<Action>(); var map = new CopyOnWriteDictionary<int, int>(); for (var i = 0; i < 100; i++) { map.Add(i, i * 2000); } Assert.AreEqual(100, map.Count); //remove everything except 0 and 1 for (var i = 2; i < 100; i++) { var item = i; actions.Add(() => { map.Remove(item); }); } TestHelper.ParallelInvoke(actions); Assert.AreEqual(2, map.Count); Assert.AreEqual(0, map[0]); Assert.AreEqual(2000, map[1]); }
public void SetDown_Should_Get_The_Next_Delay_Once_The_Time_Passes() { var policy = new CountReconnectionPolicy(3000); var host = new Host(Address, policy); TestHelper.ParallelInvoke(() => { host.SetDown(); }, 5); //Should call the Schedule#NextDelayMs() Assert.AreEqual(1, policy.CallsCount); //SetDown should do nothing as the time has not passed host.SetDown(); Assert.AreEqual(1, policy.CallsCount); Thread.Sleep(3000); Assert.True(host.IsConsiderablyUp); //The nextUpTime passed TestHelper.ParallelInvoke(() => { host.SetDown(); }, 5); Assert.AreEqual(2, policy.CallsCount); }
public void MaybeCreateCorePool_Parallel_Calls_Should_Yield_First() { var mock = new Mock <HostConnectionPool>(Host1, HostDistance.Local, GetConfig()); var lastByte = 1; mock.Setup(p => p.CreateConnection()).Returns(() => TestHelper.DelayedTask(new Connection(ProtocolVersion, GetIpEndPoint((byte)lastByte++), GetConfig()), 1000)); var pool = mock.Object; var creationTasks = new Task <Connection[]> [10]; var counter = -1; var initialCreate = pool.MaybeCreateCorePool(); TestHelper.ParallelInvoke(() => { creationTasks[Interlocked.Increment(ref counter)] = pool.MaybeCreateCorePool(); }, 10); // ReSharper disable once CoVariantArrayConversion Task.WaitAll(creationTasks); Assert.AreEqual(1, TaskHelper.WaitToComplete(initialCreate).Length); foreach (var t in creationTasks) { Assert.AreEqual(1, TaskHelper.WaitToComplete(t).Length); } }
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 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(); }