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()))); } }
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); } }
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); }
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); } }
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); } }
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)); } } }