public async Task SimulatedListenLoop_WhenThrottlingDoesNotOccur_DoNotCallMessageMonitor(int messageCount, int capacity)
        {
            Assert.That(messageCount, Is.LessThanOrEqualTo(capacity), "To avoid throttling, message count must be not be over capacity");

            var fakeMonitor = Substitute.For <IMessageMonitor>();
            var messageProcessingStrategy = new Throttled(capacity, fakeMonitor);
            var counter = new ThreadSafeCounter();

            var actions = BuildFakeIncomingMessages(messageCount, counter);

            await ListenLoopExecuted(actions, messageProcessingStrategy);

            fakeMonitor.DidNotReceive().IncrementThrottlingStatistic();
        }
        public async Task SimulatedListenLoop_WhenThrottlingOccurs_CallsMessageMonitor(int messageCount, int capacity)
        {
            Assert.That(messageCount, Is.GreaterThan(capacity), "To cause throttling, message count must be over capacity");

            var fakeMonitor = Substitute.For<IMessageMonitor>();
            var messageProcessingStrategy = new Throttled(capacity, fakeMonitor);
            var counter = new ThreadSafeCounter();

            var actions = BuildFakeIncomingMessages(messageCount, counter);

            await ListenLoopExecuted(actions, messageProcessingStrategy);

            fakeMonitor.Received().IncrementThrottlingStatistic();
            fakeMonitor.Received().HandleThrottlingTime(Arg.Any<long>());
        }
        public async Task SimulatedListenLoop_WhenThrottlingOccurs_CallsMessageMonitor(int messageCount, int capacity)
        {
            Assert.That(messageCount, Is.GreaterThan(capacity), "To cause throttling, message count must be over capacity");

            var fakeMonitor = Substitute.For <IMessageMonitor>();
            var messageProcessingStrategy = new Throttled(capacity, fakeMonitor);
            var counter = new ThreadSafeCounter();

            var actions = BuildFakeIncomingMessages(messageCount, counter);

            await ListenLoopExecuted(actions, messageProcessingStrategy);

            fakeMonitor.Received().IncrementThrottlingStatistic();
            fakeMonitor.Received().HandleThrottlingTime(Arg.Any <long>());
        }
        public async Task SimulatedListenLoop_ProcessedAllMessages(int numberOfMessagesToProcess)
        {
            var fakeMonitor = Substitute.For<IMessageMonitor>();
            var messageProcessingStrategy = new Throttled(ConcurrencyLevel, fakeMonitor);
            var counter = new ThreadSafeCounter();

            var watch = new Stopwatch();
            watch.Start();

            var actions = BuildFakeIncomingMessages(numberOfMessagesToProcess, counter);
            await ListenLoopExecuted(actions, messageProcessingStrategy);

            watch.Stop();

            await Task.Yield();
            await Task.Delay(2000);
            await Task.Yield();

            Assert.That(counter.Count, Is.EqualTo(numberOfMessagesToProcess));
        }
        public async Task SimulatedListenLoop_ProcessedAllMessages(int numberOfMessagesToProcess)
        {
            var fakeMonitor = Substitute.For <IMessageMonitor>();
            var messageProcessingStrategy = new Throttled(ConcurrencyLevel, fakeMonitor);
            var counter = new ThreadSafeCounter();

            var watch = new Stopwatch();

            watch.Start();

            var actions = BuildFakeIncomingMessages(numberOfMessagesToProcess, counter);

            await ListenLoopExecuted(actions, messageProcessingStrategy);

            watch.Stop();

            await Task.Yield();

            await Task.Delay(2000);

            await Task.Yield();

            Assert.That(counter.Count, Is.EqualTo(numberOfMessagesToProcess));
        }
        private Queue <Func <Task> > BuildFakeIncomingMessages(int numberOfMessagesToCreate, ThreadSafeCounter counter)
        {
            var random  = new Random();
            var actions = new Queue <Func <Task> >();

            for (var i = 0; i != numberOfMessagesToCreate; i++)
            {
                var duration = MinTaskDuration + random.Next(TaskDurationVariance);

                var action = new Func <Task>(async() =>
                {
                    await Task.Delay(duration);
                    counter.Increment();
                });
                actions.Enqueue(action);
            }

            return(actions);
        }
        public async Task SimulatedListenLoop_WhenThrottlingDoesNotOccur_DoNotCallMessageMonitor(int messageCount, int capacity)
        {
            Assert.That(messageCount, Is.LessThanOrEqualTo(capacity), "To avoid throttling, message count must be not be over capacity");

            var fakeMonitor = Substitute.For<IMessageMonitor>();
            var messageProcessingStrategy = new Throttled(capacity, fakeMonitor);
            var counter = new ThreadSafeCounter();

            var actions = BuildFakeIncomingMessages(messageCount, counter);

            await ListenLoopExecuted(actions, messageProcessingStrategy);

            fakeMonitor.DidNotReceive().IncrementThrottlingStatistic();
        }
        private Queue<Func<Task>> BuildFakeIncomingMessages(int numberOfMessagesToCreate, ThreadSafeCounter counter)
        {
            var random = new Random();
            var actions = new Queue<Func<Task>>();
            for (var i = 0; i != numberOfMessagesToCreate; i++)
            {
                var duration = MinTaskDuration + random.Next(TaskDurationVariance);

                var action = new Func<Task>(async () =>
                    {
                        await Task.Delay(duration);
                        counter.Increment();
                    });
                actions.Enqueue(action);
            }

            return actions;
        }