public void should_aggregate_attempt_errors() { const int Count = 5; var producers = Enumerable.Range(0, Count).Select(i => { var mock = new Mock <IProducer>(); mock .Setup(p => p.Publish(It.IsAny <IMessage>())) .Throws(new Exception("Publish error")); mock .Setup(p => p.BrokerUrl).Returns(() => $"fake.url.{DateTime.Now.Ticks}"); return(mock.Object); }); var selector = new RoundRobinSelector(new ConcurrentQueue <IProducer>(producers)); var producer = new FaultTolerantProducer(selector, Count, 0, 0); var message = new Message <DummyRequest>(MessageLabel.Any, new DummyRequest(1)); var exchange = new MessageExchange(message); try { producer.Send(exchange); Assert.Fail(); } catch (FailoverException fex) { fex.InnerException.Should().BeOfType <AggregateException>(); var errors = (AggregateException)fex.InnerException; errors.InnerExceptions.Count.Should().Be(Count); } }
public void should_update_sequence_on_full_round_if_producer_is_added() { const int Count = 3; const int LoopFactor = 5; var producers = Enumerable.Range(0, Count).Select(i => new Mock <IProducer>().Object); var queue = new ConcurrentQueue <IProducer>(producers); var selector = new RoundRobinSelector(queue); for (var i = 0; i < Count; i++) { selector.Next(); if (i == Count - 1) { queue.Enqueue(new Mock <IProducer>().Object); } } var size = (Count + 1) * LoopFactor; var list = queue.ToList(); for (int i = 0; i < size; i++) { var producer = selector.Next(); var index = list.IndexOf(producer); index.Should().Be(i % (Count + 1)); } }
public void NextSelectionWontReSelectExistingSelectionsWithDuplicatesTest() { var duplicateResources = new List <string>(this.resources); duplicateResources.AddRange(this.resources); var resourceSelectorWithDuplicates = new RoundRobinSelector <string>(duplicateResources); base.NextSelectionWontReSelectExistingSelections(this.resources, resourceSelectorWithDuplicates); }
public void should_return_producers_sequentially_in_a_loop() { const int Count = 3; const int LoopFactor = 5; const int Size = Count * LoopFactor; var producers = Enumerable.Range(0, Count).Select(i => new Mock <Producer>()).ToList(); var selector = new RoundRobinSelector(producers); for (var i = 0; i < Size; i++) { var producer = selector.Next <Mock <Producer> >(); var index = producers.IndexOf(producer); index.Should().Be(i % Count); } }
public void should_be_thread_safe() { const int ProducerCount = 1; const int MaxDelay = 5; const int ThreadCount = 200; var tcs = new TaskCompletionSource <bool>(); var result = true; var producers = Enumerable.Range(0, ProducerCount).Select(i => new Mock <IProducer>().Object); var queue = new ConcurrentQueueWithDelays <IProducer>(producers, MaxDelay); var selector = new RoundRobinSelector(queue); var accessors = Enumerable.Range(0, ThreadCount).Select(i => new Thread(() => { while (true) { try { var producer = selector.Next(); producer.Should().NotBeNull(); Debug.WriteLine("Accessor succeeded"); } catch (Exception ex) { result = false; tcs.SetResult(false); Debug.WriteLine($"Accessor failed: {ex.Message}"); } } })); accessors.All(t => { t.Start(); return(true); }).Should().BeTrue(); var task = tcs.Task; task.Wait(1.Minutes()).Should().BeFalse(); result.Should().BeTrue(); }
public void should_raise_error_if_all_producers_have_been_removed() { const int Count = 3; var producers = Enumerable.Range(0, Count).Select(i => new Mock <IProducer>().Object); var queue = new ConcurrentQueue <IProducer>(producers); var selector = new RoundRobinSelector(queue); IProducer p; while (queue.TryDequeue(out p)) { } for (var i = 0; i < Count; i++) { selector.Next(); } Assert.Throws <Exception>(() => { selector.Next(); }); }