Exemple #1
0
 public void Test_TryGet_FromEmptyBuffer(int capacity)
 {
     using (StandardTaskBuffer buffer = new StandardTaskBuffer(capacity))
     {
         Assert.IsNull(buffer.TryGetNextTask());
     }
 }
Exemple #2
0
        public void Test_CanGet_FromNonEmptyBuffer(int capacity)
        {
            using (StandardTaskBuffer buffer = new StandardTaskBuffer(capacity))
            {
                //Add some items
                int actualItemNumber = ProduceItemNumber(capacity);
                List <IQueuedTaskToken> addedTasks = new List <IQueuedTaskToken>();

                for (int i = 0; i < actualItemNumber; i++)
                {
                    addedTasks.Add(new MockQueuedTaskToken(Guid.NewGuid()));
                    buffer.TryAddNewTask(addedTasks[i]);
                }

                for (int i = 0; i < actualItemNumber; i++)
                {
                    IQueuedTaskToken queuedTaskToken = buffer.TryGetNextTask();

                    Assert.NotNull(queuedTaskToken);
                    Assert.IsTrue(addedTasks.Any(t => t.DequeuedTask.Id == queuedTaskToken.DequeuedTask.Id));
                }

                Assert.IsFalse(buffer.IsFull);
                Assert.IsFalse(buffer.IsCompleted);
            }
        }
Exemple #3
0
        public async Task Test_CanPoll(int bufferCapacity, int numberOfTasks)
        {
            TaskProcessingOptions processingOpts =
                TestOptions.GetDefaultTaskProcessingOptions();

            using (StandardTaskBuffer taskBuffer = new StandardTaskBuffer(bufferCapacity))
                using (MockTaskQueueConsumer taskQueue = new MockTaskQueueConsumer(numberOfTasks, new UtcNowTimestampProvider()))
                    using (StandardTaskPoller poller = new StandardTaskPoller(processingOpts,
                                                                              taskQueue,
                                                                              taskBuffer))
                    {
                        TestBufferConsumer consumer =
                            new TestBufferConsumer(taskBuffer);

                        await poller.StartAsync();

                        //Poller is filling up the buffer.
                        //We need to check the buffer to see whether
                        //	the poller produced the appropriate data
                        consumer.ConsumeBuffer();

                        taskQueue.WaitForQueueToBeDepleted();
                        await poller.StopAync();

                        consumer.WaitForBufferToBeConsumed();

                        Assert.IsFalse(taskBuffer.HasTasks);
                        Assert.IsTrue(taskBuffer.IsCompleted);

                        consumer.AssertMatchesProducedTasks(taskQueue
                                                            .DequeuedTasksHistory);
                    }
        }
Exemple #4
0
 public void Test_DefaultTaskBuffer_InitialStateIsCorrect(int capacity)
 {
     using (StandardTaskBuffer buffer = new StandardTaskBuffer(capacity))
     {
         Assert.IsFalse(buffer.HasTasks);
         Assert.IsFalse(buffer.IsFull);
         Assert.AreEqual(capacity, buffer.Capacity);
         Assert.IsFalse(buffer.IsCompleted);
     }
 }
Exemple #5
0
        public void Test_CanRaiseItemAdditionEvents()
        {
            bool handlerCalled = false;

            using (StandardTaskBuffer buffer = new StandardTaskBuffer(10))
            {
                buffer.QueuedTaskAdded += (s, e) => handlerCalled = true;
                buffer.TryAddNewTask(new MockQueuedTaskToken(Guid.NewGuid()));
            }

            Assert.IsTrue(handlerCalled);
        }
Exemple #6
0
        public void Test_CanAdd_NonFullBuffer(int capacity)
        {
            using (StandardTaskBuffer buffer = new StandardTaskBuffer(capacity))
            {
                for (int i = 0; i < buffer.Capacity; i++)
                {
                    Assert.IsTrue(buffer.TryAddNewTask(new MockQueuedTaskToken(Guid.NewGuid())));
                }

                Assert.AreEqual(buffer.Capacity, buffer.Count);
                Assert.IsTrue(buffer.IsFull);
                Assert.IsFalse(buffer.IsCompleted);
            }
        }
Exemple #7
0
        public void Test_TryAdd_ToFullBuffer(int capacity)
        {
            using (StandardTaskBuffer buffer = new StandardTaskBuffer(capacity))
            {
                //Fill buffer
                for (int i = 0; i < buffer.Capacity; i++)
                {
                    buffer.TryAddNewTask(new MockQueuedTaskToken(Guid.NewGuid()));
                }

                //Now attempt to add one more
                Assert.IsFalse(buffer.TryAddNewTask(new MockQueuedTaskToken(Guid.NewGuid())));
            }
        }
Exemple #8
0
        public async Task Test_CanStartStop()
        {
            TaskProcessingOptions processingOpts =
                TestOptions.GetDefaultTaskProcessingOptions();

            using (StandardTaskBuffer taskBuffer = new StandardTaskBuffer(100))
                using (MockTaskQueueConsumer taskQueue = new MockTaskQueueConsumer(0, new UtcNowTimestampProvider()))
                    using (StandardTaskPoller poller = new StandardTaskPoller(processingOpts,
                                                                              taskQueue,
                                                                              taskBuffer))
                    {
                        await poller.StartAsync();

                        Assert.IsTrue(poller.IsRunning);
                        Assert.IsTrue(taskQueue.IsReceivingNewTaskUpdates);

                        await poller.StopAync();

                        Assert.IsFalse(poller.IsRunning);
                        Assert.IsFalse(taskQueue.IsReceivingNewTaskUpdates);
                    }
        }
Exemple #9
0
        public void Test_CanCompleteAdding(int capacity)
        {
            using (StandardTaskBuffer buffer = new StandardTaskBuffer(capacity))
            {
                int actualItemNumber = ProduceItemNumber(capacity);

                for (int i = 0; i < actualItemNumber; i++)
                {
                    Assert.IsTrue(buffer.TryAddNewTask(new MockQueuedTaskToken(Guid.NewGuid())));
                }

                //Complete adding
                buffer.CompleteAdding();

                if (buffer.Count > 0)
                {
                    Assert.IsFalse(buffer.IsCompleted);
                }
                else
                {
                    Assert.IsTrue(buffer.IsCompleted);
                }

                //We can no longer add items
                Assert.IsFalse(buffer.TryAddNewTask(new MockQueuedTaskToken(Guid.NewGuid())));

                //We must be able to retrieve the other items
                for (int i = 0; i < actualItemNumber; i++)
                {
                    Assert.NotNull(buffer.TryGetNextTask());
                }

                //Now it must be marked as completed
                Assert.IsTrue(buffer.IsCompleted);
            }
        }
Exemple #10
0
        public void Test_ConsumerProducerScenario(int nProducers, int nConsumers)
        {
            Task coordinator;

            Task[] allProducers = new Task[nProducers];
            Task[] allConsumers = new Task[nConsumers];

            int expectedTotal = 0;
            ConcurrentBag <IQueuedTaskToken> processedTasks = new ConcurrentBag <IQueuedTaskToken>();

            using (StandardTaskBuffer buffer = new StandardTaskBuffer(10))
            {
                for (int iProducer = 0; iProducer < nProducers; iProducer++)
                {
                    allProducers[iProducer] = Task.Run(() =>
                    {
                        //Generate a number of items to produce
                        // and add that to the expected total
                        int nItems = new Random().Next(1, 100);
                        Interlocked.Add(ref expectedTotal, nItems);

                        while (nItems > 0)
                        {
                            bool isAdded = buffer.TryAddNewTask(new MockQueuedTaskToken(Guid.NewGuid()));
                            if (isAdded)
                            {
                                nItems--;
                            }
                            else
                            {
                                Task.Delay(10).Wait();
                            }
                        }
                    });
                }

                for (int iConsumer = 0; iConsumer < nConsumers; iConsumer++)
                {
                    allConsumers[iConsumer] = Task.Run(() =>
                    {
                        //Consumers run until the buffer is completed:
                        //  - marked as completed with respect to additons
                        //      AND
                        //  - has no more items
                        while (!buffer.IsCompleted)
                        {
                            IQueuedTaskToken queuedTaskToken = buffer.TryGetNextTask();
                            if (queuedTaskToken != null)
                            {
                                processedTasks.Add(queuedTaskToken);
                            }
                            else
                            {
                                Task.Delay(10).Wait();
                            }
                        }
                    });
                }

                coordinator = Task.Run(() =>
                {
                    //The coordinator waits for all producers
                    //  to finish and then marks buffer
                    //  addition operations as being completed
                    Task.WaitAll(allProducers);
                    buffer.CompleteAdding();
                });

                //Wait for all threads to stop
                Task.WaitAll(coordinator);
                Task.WaitAll(allConsumers);

                //Check that:
                //  a) we have the exact number of items we added
                //  b) there are no items that have been processed two times

                Assert.AreEqual(expectedTotal,
                                processedTasks.Count);

                foreach (IQueuedTaskToken queuedTaskToken in processedTasks)
                {
                    Assert.AreEqual(1, processedTasks.Count(t => t.DequeuedTask.Id == queuedTaskToken.DequeuedTask.Id));
                }
            }
        }
Exemple #11
0
        public async Task Test_CanWork(int bufferCapacity, int workerCount, int numberOfTasks)
        {
            ConcurrentBag <IQueuedTaskToken> processedTaskTokens =
                new ConcurrentBag <IQueuedTaskToken>();

            TaskProcessingOptions processingOpts =
                TestOptions.GetDefaultTaskProcessingOptions();

            Mock <IExecutionPerformanceMonitor> executionPerformanceMonitorMock =
                new Mock <IExecutionPerformanceMonitor>();

            Mock <ITaskQueueProducer> producerMock =
                new Mock <ITaskQueueProducer>(MockBehavior.Loose);

            Mock <ITaskResultQueue> resultQueueMock =
                new Mock <ITaskResultQueue>(MockBehavior.Loose);

            List <StandardTaskWorker> workers
                = new List <StandardTaskWorker>();

            executionPerformanceMonitorMock.Setup(m => m.ReportExecutionTimeAsync(
                                                      It.IsIn(mPayloadTypes.Select(t => t.FullName).ToArray()),
                                                      It.IsAny <long>(),
                                                      It.IsAny <int>()));

            resultQueueMock.Setup(rq => rq.PostResultAsync(It.IsAny <IQueuedTaskToken>()))
            .Callback <IQueuedTaskToken>(t => processedTaskTokens.Add(t));

            //TODO: must also test that, for failed tasks that can be re-posted,
            //	the tasks is actually reposted
            using (StandardTaskBuffer taskBuffer = new StandardTaskBuffer(bufferCapacity))
            {
                TestBufferProducer producer =
                    new TestBufferProducer(taskBuffer, mPayloadTypes);

                for (int i = 0; i < workerCount; i++)
                {
                    workers.Add(new StandardTaskWorker(processingOpts,
                                                       taskBuffer,
                                                       CreateTaskExecutorRegistry(),
                                                       executionPerformanceMonitorMock.Object,
                                                       producerMock.Object,
                                                       resultQueueMock.Object));
                }

                foreach (StandardTaskWorker w in workers)
                {
                    await w.StartAsync();
                }

                await producer.ProduceTasksAsync(numberOfTasks);

                while (!taskBuffer.IsCompleted)
                {
                    await Task.Delay(50);
                }

                await Task.Delay(250);

                foreach (StandardTaskWorker w in workers)
                {
                    await w.StopAync();
                }

                foreach (StandardTaskWorker w in workers)
                {
                    w.Dispose();
                }

                producer.AssertMatchesProcessedTasks(processedTaskTokens);
                executionPerformanceMonitorMock.VerifyAll();
            }
        }