예제 #1
0
        public static void TestObjectDisposedException()
        {
            ThreadWorker worker = new ThreadWorker(new ProgressContext());

            worker.Work += (object sender, ThreadWorkerEventArgs e) =>
            {
                e.Result = FileOperationStatus.Success;
            };
            try
            {
                worker.Run();
                worker.Join();
            }
            finally
            {
                worker.Dispose();
            }

            bool hasCompleted = false;

            Assert.Throws <ObjectDisposedException>(() => { worker.Run(); });
            Assert.Throws <ObjectDisposedException>(() => { worker.Join(); });
            Assert.Throws <ObjectDisposedException>(() => { hasCompleted = worker.HasCompleted; });
            Assert.That(!hasCompleted, "Although the thread has completed, the variable should still be false since the attempt to set it is after Dispose().");
            Assert.DoesNotThrow(() => { worker.Dispose(); });
        }
예제 #2
0
        public void Dispose_WaitsForTaskToComplete_WhenItTakesLessThanDefinedTimeout()
        {
            var workerName = $"worker-{DateTime.Now}";

            // arrange
            var transport       = A.Fake <ITransport>();
            var pipeline        = A.Fake <IPipeline>();
            var pipelineInvoker = A.Fake <IPipelineInvoker>();
            var context         = A.Fake <ThreadWorkerSynchronizationContext>();
            var manager         = A.Fake <ParallelOperationsManager>(fake => fake.WithArgumentsForConstructor(() => new ParallelOperationsManager(1)));
            var backOff         = A.Fake <IBackoffStrategy>();
            var logFactory      = A.Fake <IRebusLoggerFactory>();
            var log             = A.Fake <ILog>();
            var timeout         = TimeSpan.FromSeconds(10);
            var owningBus       = A.Fake <RebusBus>();

            A.CallTo(() => logFactory.GetCurrentClassLogger())
            .Returns(log);

            // have stuff to do
            A.CallTo(() => manager.HasPendingTasks)
            .Returns(true);

            var taskTakingTime = TimeSpan.FromSeconds(5);

            // wait a bit, then simulate task completion.
            Task.Run(async() =>
            {
                await Task.Delay(taskTakingTime)
                .ConfigureAwait(true);     // forcing sync context for the same thread

                A.CallTo(() => manager.HasPendingTasks)
                .Returns(false);
            });

            // system under test
            var sut = new ThreadWorker(transport, pipeline, pipelineInvoker, workerName, context, manager, backOff, logFactory, timeout, owningBus);

            // act

            var timer = Stopwatch.StartNew();

            sut.Dispose();

            timer.Stop();

            // assert

            timer.Elapsed
            .Should().BeCloseTo(taskTakingTime, 1000);

            // NO logs.
            A.CallTo(() =>
                     log.Warn("Not all async tasks were able to finish within given timeout of {0} seconds!", timeout.TotalSeconds))
            .MustNotHaveHappened();

            A.CallTo(() =>
                     log.Warn("Worker {0} did not stop withing {1} seconds timeout!", workerName, timeout.TotalSeconds))
            .MustNotHaveHappened();
        }
예제 #3
0
        public void Dispose_WaitsDefinedTimeout_WhenPendingTasksTakeLonger()
        {
            var workerName = $"worker-{DateTime.Now}";

            // arrange
            var transport       = A.Fake <ITransport>();
            var pipeline        = A.Fake <IPipeline>();
            var pipelineInvoker = A.Fake <IPipelineInvoker>();
            var context         = A.Fake <ThreadWorkerSynchronizationContext>();
            var manager         = A.Fake <ParallelOperationsManager>(fake => fake.WithArgumentsForConstructor(() => new ParallelOperationsManager(1)));
            var backOff         = A.Fake <IBackoffStrategy>();
            var logFactory      = A.Fake <IRebusLoggerFactory>();
            var log             = A.Fake <ILog>();
            var owningBus       = A.Fake <RebusBus>();

            var timeout = TimeSpan.FromSeconds(5);

            A.CallTo(() => logFactory.GetCurrentClassLogger())
            .Returns(log);

            // Have stuff to do
            A.CallTo(() => manager.HasPendingTasks)
            .Returns(true);

            // system under test
            var sut = new ThreadWorker(transport, pipeline, pipelineInvoker, workerName, context, manager, backOff, logFactory, timeout, owningBus);

            // act

            var timer = Stopwatch.StartNew();

            sut.Dispose();

            timer.Stop();

            // assert

            // assuming +- 1 second.
            timer.Elapsed
            .Should().BeCloseTo(timeout, 1000);

            // Must have logs
            A.CallTo(() =>
                     log.Warn("Not all async tasks were able to finish within given timeout of {0} seconds!", timeout.TotalSeconds))
            .MustHaveHappened();

            A.CallTo(() =>
                     log.Warn("Worker {0} did not stop withing {1} seconds timeout!", workerName, timeout.TotalSeconds))
            .MustHaveHappened();
        }
예제 #4
0
        public void Dispose_WaitsDefinedTimeout_WhenPendingTasksTakeLonger(string workerName)
        {
            // arrange
            var transport = A.Fake<ITransport>();
            var pipeline = A.Fake<IPipeline>();
            var pipelineInvoker = A.Fake<IPipelineInvoker>();
            var context = A.Fake<ThreadWorkerSynchronizationContext>();
            var manager = A.Fake<ParallelOperationsManager>(fake => fake.WithArgumentsForConstructor(() => new ParallelOperationsManager(1)));
            var backOff = A.Fake<IBackoffStrategy>();
            var logFactory = A.Fake<IRebusLoggerFactory>();
            var log = A.Fake<ILog>();

            var timeout = TimeSpan.FromSeconds(5);

            A.CallTo(() => logFactory.GetCurrentClassLogger())
                .Returns(log);

            // Have stuff to do
            A.CallTo(() => manager.HasPendingTasks)
                .Returns(true); 

            // system under test
            var sut = new ThreadWorker(transport, pipeline, pipelineInvoker, workerName, context, manager, backOff, logFactory, timeout);

            // act

            var timer = Stopwatch.StartNew();

            sut.Dispose();

            timer.Stop();

            // assert

            // assuming +- 1 second.
            timer.Elapsed
                .Should().BeCloseTo(timeout, 1000);

            // Must have logs
            A.CallTo(() => 
                log.Warn("Not all async tasks were able to finish within given timeout of {0} seconds!", timeout.TotalSeconds))
                    .MustHaveHappened();

            A.CallTo(() => 
                log.Warn("Worker {0} did not stop withing {1} seconds timeout!", workerName, timeout.TotalSeconds))
                    .MustHaveHappened();

        }
예제 #5
0
        public void Dispose_WaitsForTaskToComplete_WhenItTakesLessThanDefinedTimeout(string workerName)
        {
            // arrange
            var transport = A.Fake<ITransport>();
            var pipeline = A.Fake<IPipeline>();
            var pipelineInvoker = A.Fake<IPipelineInvoker>();
            var context = A.Fake<ThreadWorkerSynchronizationContext>();
            var manager = A.Fake<ParallelOperationsManager>(fake => fake.WithArgumentsForConstructor(() => new ParallelOperationsManager(1)));
            var backOff = A.Fake<IBackoffStrategy>();
            var logFactory = A.Fake<IRebusLoggerFactory>();
            var log = A.Fake<ILog>();
            var timeout = TimeSpan.FromSeconds(10);

            A.CallTo(() => logFactory.GetCurrentClassLogger())
                .Returns(log);

            // have stuff to do
            A.CallTo(() => manager.HasPendingTasks)
                .Returns(true);
            
            var taskTakingTime = TimeSpan.FromSeconds(5);

            // wait a bit, then simulate task completion.
            Task.Run(async () =>
            {
                await Task.Delay(taskTakingTime)
                    .ConfigureAwait(true); // forcing sync context for the same thread

                A.CallTo(() => manager.HasPendingTasks)
                    .Returns(false);
            });

            // system under test
            var sut = new ThreadWorker(transport, pipeline, pipelineInvoker, workerName, context, manager, backOff, logFactory, timeout);

            // act

            var timer = Stopwatch.StartNew();

            sut.Dispose();

            timer.Stop();

            // assert

            timer.Elapsed
                .Should().BeCloseTo(taskTakingTime, 1000);

            // NO logs.
            A.CallTo(() =>
                log.Warn("Not all async tasks were able to finish within given timeout of {0} seconds!", timeout.TotalSeconds))
                    .MustNotHaveHappened();

            A.CallTo(() =>
                log.Warn("Worker {0} did not stop withing {1} seconds timeout!", workerName, timeout.TotalSeconds))
                    .MustNotHaveHappened();
        }
예제 #6
0
        private void handle_thread_404(ThreadWorker instance)
        {
            this.watched_threads.Remove(instance.ID);
            this._404_threads.Add(instance.ID);
            instance.Dispose();
            instance.Thread404 -= this.handle_thread_404;

            Log(new LogEntry()
            {
                Level = LogEntry.LogLevel.Info,
                Message = string.Format("Thread '{0}' has 404'ed", instance.ID),
                Sender = "BoardWatcher",
                Title = string.Format("/{0}/", this.Board)
            });
        }