public void SetMaximumWorkerThreadsCountShouldThrowExceptionWhenMaximumThreadsCountIsLessThanZero()
        {
            WorkerThreadPool workerThreadPool = new WorkerThreadPool(0, 1);

            Assert.Throws <ArgumentOutOfRangeException>(() => workerThreadPool.SetMaximumWorkerThreadsCount(0));
            Assert.Throws <ArgumentOutOfRangeException>(() => workerThreadPool.SetMaximumWorkerThreadsCount(-1));

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldAddNoWorkerThreadsToReachTheMaximumThreadCountWhenMaximumThreadsCountIncreasesAndThereAreWorkItemsInTheQueue()
        {
            ManualFinishWorkItemQueueStub manualFinishWorkItemQueueStub = new ManualFinishWorkItemQueueStub();

            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());

            WorkerThreadPool workerThreadPool = new WorkerThreadPool(manualFinishWorkItemQueueStub, 1, 2);

            manualFinishWorkItemQueueStub.WaitAllStart(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workerThreadPool.QueueWorkItem(new ManualFinishWorkItem());
            workerThreadPool.QueueWorkItem(new ManualFinishWorkItem());

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            Assert.AreEqual(2, manualFinishWorkItemQueueStub.Count);

            workerThreadPool.SetMaximumWorkerThreadsCount(4);

            manualFinishWorkItemQueueStub.WaitAllStart(500);

            Assert.AreEqual(4, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(4, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            Assert.AreEqual(0, manualFinishWorkItemQueueStub.Count);

            manualFinishWorkItemQueueStub.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldRemoveWorkerThreadsWhenMaximumThreadsCountDecreases()
        {
            ManualFinishWorkItemQueueStub manualFinishWorkItemQueueStub = new ManualFinishWorkItemQueueStub();

            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());

            AutoResetEvent   autoResetEvent   = new AutoResetEvent(false);
            WorkerThreadPool workerThreadPool = new WorkerThreadPool(manualFinishWorkItemQueueStub, 1, 3);

            workerThreadPool.WorkerThreadExiting += (sender, args) => { autoResetEvent.Set(); };

            manualFinishWorkItemQueueStub.WaitAllStart(500);

            Assert.AreEqual(3, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(3, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workerThreadPool.SetMaximumWorkerThreadsCount(2);

            manualFinishWorkItemQueueStub.WorkItems[0].Stop();
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());

            autoResetEvent.WaitOne(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            manualFinishWorkItemQueueStub.WorkItems[1].Stop();

            autoResetEvent.WaitOne(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            manualFinishWorkItemQueueStub.WorkItems[2].Stop();

            autoResetEvent.WaitOne(500);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(1, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            manualFinishWorkItemQueueStub.WorkItems[3].Stop();

            autoResetEvent.WaitOne(500);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(0, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            manualFinishWorkItemQueueStub.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldAddNoWorkerThreadsWhenMaximumThreadsCountIncreasesAndThereIsNoWorkItemsInTheQueue()
        {
            ManualFinishWorkItemQueueStub manualFinishWorkItemQueueStub = new ManualFinishWorkItemQueueStub();

            WorkerThreadPool workerThreadPool = new WorkerThreadPool(manualFinishWorkItemQueueStub, 1, 3);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(0, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workerThreadPool.SetMaximumWorkerThreadsCount(4);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(0, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            manualFinishWorkItemQueueStub.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldAddNoNewWorkerThreadWhenMaxThreadCountIncreasedAndThereIsNoWorkItemsInTheQueue()
        {
            ManualFinishWorkItemQueueStub workItemQueue = new ManualFinishWorkItemQueueStub();

            workItemQueue.Enqueue(new ManualFinishWorkItem());

            WorkerThreadPool workerThreadPool = new WorkerThreadPool(workItemQueue, 0, 1);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);

            workItemQueue.WaitAllStart(500);
            workerThreadPool.SetMaximumWorkerThreadsCount(2);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(1, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workItemQueue.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldRemoveIdleWorkerThreadsWhenDecreased()
        {
            ManualFinishWorkItemQueueStub workItemQueue = new ManualFinishWorkItemQueueStub();

            workItemQueue.Enqueue(new ManualFinishWorkItem());
            workItemQueue.Enqueue(new ManualFinishWorkItem());

            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            WorkerThreadPool workerThreadPool = new WorkerThreadPool(workItemQueue, 0, 2);

            workerThreadPool.WorkerThreadExiting += (sender, args) =>
            {
                manualResetEvent.Set();
            };

            workItemQueue.WaitAllStart(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workerThreadPool.SetMaximumWorkerThreadsCount(1);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workItemQueue.WorkItems[0].Stop();
            workItemQueue.Enqueue(new ManualFinishWorkItem());

            Assert.AreEqual(1, workItemQueue.Count);

            manualResetEvent.WaitOne(300);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(1, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workItemQueue.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldRemoveIdleWorkerThreadsWhenDecreased()
        {
            ManualFinishWorkItemQueueStub workItemQueue = new ManualFinishWorkItemQueueStub();
            workItemQueue.Enqueue(new ManualFinishWorkItem());
            workItemQueue.Enqueue(new ManualFinishWorkItem());

            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            WorkerThreadPool workerThreadPool = new WorkerThreadPool(workItemQueue, 0, 2);
            workerThreadPool.WorkerThreadExiting += (sender, args) =>
                {
                    manualResetEvent.Set();
                };

            workItemQueue.WaitAllStart(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workerThreadPool.SetMaximumWorkerThreadsCount(1);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workItemQueue.WorkItems[0].Stop();
            workItemQueue.Enqueue(new ManualFinishWorkItem());

            Assert.AreEqual(1, workItemQueue.Count);

            manualResetEvent.WaitOne(300);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(1, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workItemQueue.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldAddANewWorkerThreadWhenMaxThreadCountIncreasedAndThereAreWorkItemsInTheQueue()
        {
            ManualFinishWorkItemQueueStub workItemQueue = new ManualFinishWorkItemQueueStub();
            workItemQueue.Enqueue(new ManualFinishWorkItem());
            workItemQueue.Enqueue(new ManualFinishWorkItem());

            WorkerThreadPool workerThreadPool = new WorkerThreadPool(workItemQueue, 0, 1);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);

            workerThreadPool.SetMaximumWorkerThreadsCount(2);

            workItemQueue.WaitAllStart(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workItemQueue.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldThrowExceptionWhenMaximumThreadsCountIsLessThanMinimumCount()
        {
            WorkerThreadPool workerThreadPool = new WorkerThreadPool(2, 3);

            Assert.Throws<ArgumentOutOfRangeException>(() => workerThreadPool.SetMaximumWorkerThreadsCount(1));

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldAddNoWorkerThreadsToReachTheMaximumThreadCountWhenMaximumThreadsCountIncreasesAndThereAreWorkItemsInTheQueue()
        {
            ManualFinishWorkItemQueueStub manualFinishWorkItemQueueStub = new ManualFinishWorkItemQueueStub();
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());

            WorkerThreadPool workerThreadPool = new WorkerThreadPool(manualFinishWorkItemQueueStub, 1, 2);

            manualFinishWorkItemQueueStub.WaitAllStart(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workerThreadPool.QueueWorkItem(new ManualFinishWorkItem());
            workerThreadPool.QueueWorkItem(new ManualFinishWorkItem());

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            Assert.AreEqual(2, manualFinishWorkItemQueueStub.Count);

            workerThreadPool.SetMaximumWorkerThreadsCount(4);

            manualFinishWorkItemQueueStub.WaitAllStart(500);

            Assert.AreEqual(4, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(4, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            Assert.AreEqual(0, manualFinishWorkItemQueueStub.Count);

            manualFinishWorkItemQueueStub.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldAddNoWorkerThreadsWhenMaximumThreadsCountIncreasesAndThereIsNoWorkItemsInTheQueue()
        {
            ManualFinishWorkItemQueueStub manualFinishWorkItemQueueStub = new ManualFinishWorkItemQueueStub();

            WorkerThreadPool workerThreadPool = new WorkerThreadPool(manualFinishWorkItemQueueStub, 1, 3);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(0, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workerThreadPool.SetMaximumWorkerThreadsCount(4);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(0, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            manualFinishWorkItemQueueStub.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }
        public void SetMaximumWorkerThreadsCountShouldRemoveWorkerThreadsWhenMaximumThreadsCountDecreases()
        {
            ManualFinishWorkItemQueueStub manualFinishWorkItemQueueStub = new ManualFinishWorkItemQueueStub();
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());

            AutoResetEvent autoResetEvent = new AutoResetEvent(false);
            WorkerThreadPool workerThreadPool = new WorkerThreadPool(manualFinishWorkItemQueueStub, 1, 3);
            workerThreadPool.WorkerThreadExiting += (sender, args) => { autoResetEvent.Set(); };

            manualFinishWorkItemQueueStub.WaitAllStart(500);

            Assert.AreEqual(3, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(3, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            workerThreadPool.SetMaximumWorkerThreadsCount(2);

            manualFinishWorkItemQueueStub.WorkItems[0].Stop();
            manualFinishWorkItemQueueStub.Enqueue(new ManualFinishWorkItem());

            autoResetEvent.WaitOne(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            manualFinishWorkItemQueueStub.WorkItems[1].Stop();

            autoResetEvent.WaitOne(500);

            Assert.AreEqual(2, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(2, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            manualFinishWorkItemQueueStub.WorkItems[2].Stop();

            autoResetEvent.WaitOne(500);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(1, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            manualFinishWorkItemQueueStub.WorkItems[3].Stop();

            autoResetEvent.WaitOne(500);

            Assert.AreEqual(1, workerThreadPool.WorkerThreadsCount);
            Assert.AreEqual(0, workerThreadPool.WorkerThreads.Count(x => x.IsBusy));

            manualFinishWorkItemQueueStub.StopAll();

            workerThreadPool.Shutdown(true, 500);
        }