Example #1
0
            public async Task PutsServiceIntoSleepingStateWhenDequeueReturnsNoMessage()
            {
                // Arrange
                var cts        = new CancellationTokenSource();
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var dequeueTcs = runner.MockQueue
                                 .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                                 .WaitsForSignal();
                RunnerStatus statusAtLastHeartBeat = RunnerStatus.Working;

                runner.Heartbeat += (_, __) => statusAtLastHeartBeat = runner.Status;
                dequeueTcs.SetResult(null);

                // Act, run the task to the sleep
                var task = runner.Run(cts.Token);

                // Assert
                Assert.Equal(RunnerStatus.Sleeping, runner.Status);
                Assert.Equal(RunnerStatus.Sleeping, statusAtLastHeartBeat);

                // Abort the waiting threads
                runner.VirtualClock.Advance(TimeSpan.FromMinutes(10));
                cts.Cancel();
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }
            }
Example #2
0
            public async Task PutsServiceInDequeingStateUntilQueueReturnsMessage()
            {
                // Arrange
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var cts        = new CancellationTokenSource();
                var dequeueTcs = runner.MockQueue
                                 .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                                 .WaitsForSignal();
                RunnerStatus statusAtHeartBeat = RunnerStatus.Working;

                runner.Heartbeat += (_, __) => statusAtHeartBeat = runner.Status;

                // Act
                var task = runner.Run(cts.Token);

                // Assert
                Assert.Equal(RunnerStatus.Dequeuing, runner.Status);
                Assert.Equal(RunnerStatus.Dequeuing, statusAtHeartBeat);

                // Abort the waiting threads
                dequeueTcs.SetException(new OperationCanceledException());
                cts.Cancel();
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }
            }
            public async Task PutsServiceInDequeingStateUntilQueueReturnsMessage()
            {
                // Arrange
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var cts = new CancellationTokenSource();
                var dequeueTcs = runner.MockQueue
                    .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                    .WaitsForSignal();
                RunnerStatus statusAtHeartBeat = RunnerStatus.Working;
                runner.Heartbeat += (_, __) => statusAtHeartBeat = runner.Status;

                // Act
                var task = runner.Run(cts.Token);

                // Assert
                Assert.Equal(RunnerStatus.Dequeuing, runner.Status);
                Assert.Equal(RunnerStatus.Dequeuing, statusAtHeartBeat);

                // Abort the waiting threads
                dequeueTcs.SetException(new OperationCanceledException());
                cts.Cancel();
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }
            }
Example #4
0
            public async Task DispatchesRequestIfOneIsReceived()
            {
                // Arrange
                var cts        = new CancellationTokenSource();
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var dequeueTcs = runner.MockQueue
                                 .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                                 .WaitsForSignal();
                var request = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary <string, string>());

                // Act
                var task = runner.Run(cts.Token);

                dequeueTcs.SetResult(request);
                cts.Cancel();
                runner.DispatchTCS.TrySetResult(null);

                // Abort the waiting threads
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }

                // Assert
                Assert.Same(request, runner.LastDispatched);
            }
Example #5
0
            public async Task AcknowledgesMessageOnCompletionOfInvocation()
            {
                // Arrange
                var cts        = new CancellationTokenSource();
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary <string, string>());

                runner.MockDispatcher
                .Setup(d => d.Dispatch(It.IsAny <InvocationContext>()))
                .Completes(InvocationResult.Completed())
                .Verifiable();

                // Act
                await runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.Complete(invocation, ExecutionResult.Completed, null, null));
            }
Example #6
0
            public async Task DispatchesTheJobUsingTheDispatcher()
            {
                // Arrange
                var cts        = new CancellationTokenSource();
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary <string, string>());

                runner.MockDispatcher
                .Setup(d => d.Dispatch(It.IsAny <InvocationContext>()))
                .Completes(InvocationResult.Completed())
                .Verifiable();

                // Act
                await runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockDispatcher.VerifyAll();
            }
Example #7
0
            public async Task SleepsForPollIntervalWhenDequeueReturnsNoMessage()
            {
                // Arrange
                var cts        = new CancellationTokenSource();
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var dequeueTcs = new TaskCompletionSource <InvocationState>();

                runner.MockQueue
                .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                .Returns(async() =>
                {
                    var result = await dequeueTcs.Task;
                    dequeueTcs = new TaskCompletionSource <InvocationState>();
                    return(result);
                });
                RunnerStatus statusAtLastHeartBeat = RunnerStatus.Working;

                runner.Heartbeat += (_, __) => statusAtLastHeartBeat = runner.Status;
                dequeueTcs.SetResult(null);
                runner.DispatchTCS.TrySetResult(null);

                // Run to the sleep
                var task = runner.Run(cts.Token);

                runner.DispatchTCS = new TaskCompletionSource <object>();

                // Act
                runner.VirtualClock.Advance(TimeSpan.FromSeconds(5));

                // Assert
                Assert.Equal(RunnerStatus.Dequeuing, runner.Status);
                Assert.Equal(RunnerStatus.Dequeuing, statusAtLastHeartBeat);

                // Abort the waiting threads
                runner.DispatchTCS.SetResult(null);
                dequeueTcs.SetResult(null);
                cts.Cancel();
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }
            }
Example #8
0
            public async Task EnqueuesARescheduleIfTheResultRequestsIt(ExecutionResult result)
            {
                // Arrange
                var cts        = new CancellationTokenSource();
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary <string, string>());
                var repeat     = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary <string, string>());

                runner.MockDispatcher
                .Setup(d => d.Dispatch(It.IsAny <InvocationContext>()))
                .Completes(new InvocationResult(result, result == ExecutionResult.Faulted ? new Exception() : null, TimeSpan.FromDays(365)))
                .Verifiable();
                runner.MockQueue
                .Setup(q => q.Enqueue("test", Constants.Source_RepeatingJob, It.IsAny <Dictionary <string, string> >(), TimeSpan.FromDays(365), null))
                .Completes(repeat);

                // Act
                await runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.Enqueue(invocation.Job, Constants.Source_RepeatingJob, invocation.Payload, TimeSpan.FromDays(365), null));
            }
Example #9
0
            public async Task UpdatesTheStatusOfTheRequestToExecuting()
            {
                // Arrange
                var cts        = new CancellationTokenSource();
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary <string, string>());

                var dispatchTCS = runner
                                  .MockDispatcher
                                  .Setup(d => d.Dispatch(It.IsAny <InvocationContext>()))
                                  .WaitsForSignal();

                // Act
                var task = runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.UpdateStatus(invocation, InvocationStatus.Executing, ExecutionResult.Incomplete));

                dispatchTCS.SetResult(InvocationResult.Completed());

                await task;
            }
Example #10
0
            public async Task PutsServiceInDispatchingStateWhenQueueReturnsMessage()
            {
                // Arrange
                var cts        = new CancellationTokenSource();
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var dequeueTcs = new TaskCompletionSource <InvocationState>();

                runner.MockQueue
                .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                .Returns(async() =>
                {
                    var result = await dequeueTcs.Task;
                    dequeueTcs = new TaskCompletionSource <InvocationState>();
                    return(result);
                });
                RunnerStatus statusAtHeartBeat = RunnerStatus.Working;

                runner.Heartbeat += (_, __) => statusAtHeartBeat = runner.Status;

                // Act
                var task = runner.Run(cts.Token);

                dequeueTcs.SetResult(TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary <string, string>()));

                // Assert
                Assert.Equal(RunnerStatus.Dispatching, runner.Status);
                Assert.Equal(RunnerStatus.Dispatching, statusAtHeartBeat);

                // Abort the waiting threads
                cts.Cancel();
                runner.DispatchTCS.TrySetResult(null);
                dequeueTcs.SetResult(null);
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }
            }
Example #11
0
            public async Task SuspendsInvocationIfJobRemainsIncompleteWithAContinuation()
            {
                // Arrange
                var cts        = new CancellationTokenSource();
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary <string, string>());

                var continuationPayload = new Dictionary <string, string>()
                {
                    { "foo", "bar" }
                };

                runner.MockDispatcher
                .Setup(d => d.Dispatch(It.IsAny <InvocationContext>()))
                .Completes(InvocationResult.Suspended(new JobContinuation(TimeSpan.FromDays(365), continuationPayload)))
                .Verifiable();

                // Act
                await runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.Suspend(invocation, continuationPayload, TimeSpan.FromDays(365), null));
            }
Example #12
0
            public async Task CompletesWithResultMessageIfThereIsAnException(ExecutionResult result)
            {
                // Arrange
                var cts        = new CancellationTokenSource();
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary <string, string>());
                var exception  = new Exception("BORK!");

                runner.MockDispatcher
                .Setup(d => d.Dispatch(It.IsAny <InvocationContext>()))
                .Completes(() =>
                {
                    runner.VirtualClock.Advance(TimeSpan.FromDays(365));     // Wow this is a long job ;)
                    return(new InvocationResult(result, exception));
                })
                .Verifiable();

                // Act
                await runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.Complete(invocation, result, exception.ToString(), null));
            }
Example #13
0
            public async Task DequeuesMessageFromQueue()
            {
                // Arrange
                var runner     = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var cts        = new CancellationTokenSource();
                var dequeueTcs = runner.MockQueue
                                 .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                                 .WaitsForSignal();

                // Act
                var task = runner.Run(cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token));

                // Abort the waiting threads
                dequeueTcs.SetException(new OperationCanceledException());
                cts.Cancel();
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }
            }
            public async Task PutsServiceInDispatchingStateWhenQueueReturnsMessage()
            {
                // Arrange
                var cts = new CancellationTokenSource();
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var dequeueTcs = new TaskCompletionSource<InvocationState>();

                runner.MockQueue
                    .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                    .Returns(async () =>
                    {
                        var result = await dequeueTcs.Task;
                        dequeueTcs = new TaskCompletionSource<InvocationState>();
                        return result;
                    });
                RunnerStatus statusAtHeartBeat = RunnerStatus.Working;
                runner.Heartbeat += (_, __) => statusAtHeartBeat = runner.Status;

                // Act
                var task = runner.Run(cts.Token);
                dequeueTcs.SetResult(TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary<string, string>()));

                // Assert
                Assert.Equal(RunnerStatus.Dispatching, runner.Status);
                Assert.Equal(RunnerStatus.Dispatching, statusAtHeartBeat);

                // Abort the waiting threads
                cts.Cancel();
                runner.DispatchTCS.TrySetResult(null);
                dequeueTcs.SetResult(null);
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }
            }
            public async Task DequeuesMessageFromQueue()
            {
                // Arrange
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var cts = new CancellationTokenSource();
                var dequeueTcs = runner.MockQueue
                    .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                    .WaitsForSignal();

                // Act
                var task = runner.Run(cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token));

                // Abort the waiting threads
                dequeueTcs.SetException(new OperationCanceledException());
                cts.Cancel();
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }
            }
            public async Task DispatchesRequestIfOneIsReceived()
            {
                // Arrange
                var cts = new CancellationTokenSource();
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var dequeueTcs = runner.MockQueue
                    .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                    .WaitsForSignal();
                var request = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary<string, string>());

                // Act
                var task = runner.Run(cts.Token);
                dequeueTcs.SetResult(request);
                cts.Cancel();
                runner.DispatchTCS.TrySetResult(null);

                // Abort the waiting threads
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }

                // Assert
                Assert.Same(request, runner.LastDispatched);
            }
            public async Task SleepsForPollIntervalWhenDequeueReturnsNoMessage()
            {
                // Arrange
                var cts = new CancellationTokenSource();
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var dequeueTcs = new TaskCompletionSource<InvocationState>();

                runner.MockQueue
                    .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                    .Returns(async () =>
                    {
                        var result = await dequeueTcs.Task;
                        dequeueTcs = new TaskCompletionSource<InvocationState>();
                        return result;
                    });
                RunnerStatus statusAtLastHeartBeat = RunnerStatus.Working;
                runner.Heartbeat += (_, __) => statusAtLastHeartBeat = runner.Status;
                dequeueTcs.SetResult(null);
                runner.DispatchTCS.TrySetResult(null);

                // Run to the sleep
                var task = runner.Run(cts.Token);
                runner.DispatchTCS = new TaskCompletionSource<object>();

                // Act
                runner.VirtualClock.Advance(TimeSpan.FromSeconds(5));

                // Assert
                Assert.Equal(RunnerStatus.Dequeuing, runner.Status);
                Assert.Equal(RunnerStatus.Dequeuing, statusAtLastHeartBeat);

                // Abort the waiting threads
                runner.DispatchTCS.SetResult(null);
                dequeueTcs.SetResult(null);
                cts.Cancel();
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }
            }
            public async Task EnqueuesARescheduleIfTheResultRequestsIt(ExecutionResult result)
            {
                // Arrange
                var cts = new CancellationTokenSource();
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary<string, string>());
                var repeat = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary<string,string>());
                
                runner.MockDispatcher
                    .Setup(d => d.Dispatch(It.IsAny<InvocationContext>()))
                    .Completes(new InvocationResult(result, result == ExecutionResult.Faulted ? new Exception() : null, TimeSpan.FromDays(365)))
                    .Verifiable();
                runner.MockQueue
                    .Setup(q => q.Enqueue("test", Constants.Source_RepeatingJob, It.IsAny<Dictionary<string, string>>(), TimeSpan.FromDays(365), null))
                    .Completes(repeat);

                // Act
                await runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.Enqueue(invocation.Job, Constants.Source_RepeatingJob, invocation.Payload, TimeSpan.FromDays(365), null));
            }
            public async Task SuspendsInvocationIfJobRemainsIncompleteWithAContinuation()
            {
                // Arrange
                var cts = new CancellationTokenSource();
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary<string, string>());
                
                var continuationPayload = new Dictionary<string, string>() { { "foo", "bar" } };
                runner.MockDispatcher
                    .Setup(d => d.Dispatch(It.IsAny<InvocationContext>()))
                    .Completes(InvocationResult.Suspended(new JobContinuation(TimeSpan.FromDays(365), continuationPayload)))
                    .Verifiable();

                // Act
                await runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.Suspend(invocation, continuationPayload, TimeSpan.FromDays(365), null));
            }
            public async Task CompletesWithResultMessageIfThereIsAnException(ExecutionResult result)
            {
                // Arrange
                var cts = new CancellationTokenSource();
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary<string, string>());
                var exception = new Exception("BORK!");
                
                runner.MockDispatcher
                    .Setup(d => d.Dispatch(It.IsAny<InvocationContext>()))
                    .Completes(() =>
                    {
                        runner.VirtualClock.Advance(TimeSpan.FromDays(365)); // Wow this is a long job ;)
                        return new InvocationResult(result, exception);
                    })
                    .Verifiable();

                // Act
                await runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.Complete(invocation, result, exception.ToString(), null));
            }
            public async Task AcknowledgesMessageOnCompletionOfInvocation()
            {
                // Arrange
                var cts = new CancellationTokenSource();
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary<string, string>());
                
                runner.MockDispatcher
                    .Setup(d => d.Dispatch(It.IsAny<InvocationContext>()))
                    .Completes(InvocationResult.Completed())
                    .Verifiable();

                // Act
                await runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.Complete(invocation, ExecutionResult.Completed, null, null));
            }
            public async Task DispatchesTheJobUsingTheDispatcher()
            {
                // Arrange
                var cts = new CancellationTokenSource();
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary<string, string>());
                
                runner.MockDispatcher
                    .Setup(d => d.Dispatch(It.IsAny<InvocationContext>()))
                    .Completes(InvocationResult.Completed())
                    .Verifiable();

                // Act
                await runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockDispatcher.VerifyAll();
            }
            public async Task UpdatesTheStatusOfTheRequestToExecuting()
            {
                // Arrange
                var cts = new CancellationTokenSource();
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5));
                var invocation = TestHelpers.CreateInvocation(Guid.NewGuid(), "test", "test", new Dictionary<string, string>());
                
                var dispatchTCS = runner
                    .MockDispatcher
                    .Setup(d => d.Dispatch(It.IsAny<InvocationContext>()))
                    .WaitsForSignal();

                // Act
                var task = runner.Dispatch(invocation, cts.Token);

                // Assert
                runner.MockQueue.Verify(q => q.UpdateStatus(invocation, InvocationStatus.Executing, ExecutionResult.Incomplete));

                dispatchTCS.SetResult(InvocationResult.Completed());

                await task;
            }
            public async Task PutsServiceIntoSleepingStateWhenDequeueReturnsNoMessage()
            {
                // Arrange
                var cts = new CancellationTokenSource();
                var runner = new TestableJobRunner(TimeSpan.FromSeconds(5), skipDispatch: true);
                var dequeueTcs = runner.MockQueue
                    .Setup(q => q.Dequeue(JobRunner.DefaultInvisibilityPeriod, cts.Token))
                    .WaitsForSignal();
                RunnerStatus statusAtLastHeartBeat = RunnerStatus.Working;
                runner.Heartbeat += (_, __) => statusAtLastHeartBeat = runner.Status;
                dequeueTcs.SetResult(null);

                // Act, run the task to the sleep
                var task = runner.Run(cts.Token);

                // Assert
                Assert.Equal(RunnerStatus.Sleeping, runner.Status);
                Assert.Equal(RunnerStatus.Sleeping, statusAtLastHeartBeat);

                // Abort the waiting threads
                runner.VirtualClock.Advance(TimeSpan.FromMinutes(10));
                cts.Cancel();
                try
                {
                    await task;
                }
                catch (TaskCanceledException) { }
            }