Example #1
0
        public void Start_IfStarted_Throws()
        {
            // Arrange
            ITaskSeriesCommand command = CreateStubCommand(TimeSpan.FromDays(1));

            using (ITaskSeriesTimer product = CreateProductUnderTest(command))
            {
                product.Start();

                // Act & Assert
                ExceptionAssert.ThrowsInvalidOperation(() => product.Start(),
                                                       "The timer has already been started; it cannot be restarted.");
            }
        }
Example #2
0
        public void StopAsync_TriggersCommandCancellationToken()
        {
            // Arrange
            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
                using (EventWaitHandle executeFinished = new ManualResetEvent(initialState: false))
                {
                    bool cancellationTokenSignalled = false;

                    ITaskSeriesCommand command = CreateCommand((cancellationToken) =>
                    {
                        Assert.True(executeStarted.Set());  // Guard
                        cancellationTokenSignalled = cancellationToken.WaitHandle.WaitOne(1000);
                        Assert.True(executeFinished.Set()); // Guard
                        return(new TaskSeriesCommandResult(wait: Task.Delay(0)));
                    });

                    using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                    {
                        product.Start();
                        Assert.True(executeStarted.WaitOne(1000)); // Guard

                        CancellationToken cancellationToken = CancellationToken.None;

                        // Act
                        Task task = product.StopAsync(cancellationToken);

                        // Assert
                        Assert.NotNull(task);
                        task.GetAwaiter().GetResult();
                        Assert.True(executeFinished.WaitOne(1000)); // Guard
                        Assert.True(cancellationTokenSignalled);
                    }
                }
        }
Example #3
0
        public void StopAsync_DoesNotWaitForSubsequentWaitToCompleteTask()
        {
            // Arrange
            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
            {
                ITaskSeriesCommand command = CreateCommand(() =>
                {
                    Assert.True(executeStarted.Set()); // Guard
                    return(new TaskSeriesCommandResult(wait: Task.Delay(2000)));
                });

                using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                {
                    product.Start();
                    Assert.True(executeStarted.WaitOne(1000)); // Guard

                    // Wait for the background thread to enter the long wait.
                    Thread.Sleep(5);

                    CancellationToken cancellationToken = CancellationToken.None;

                    // Act
                    Task task = product.StopAsync(cancellationToken);

                    // Assert
                    Assert.NotNull(task);
                    Assert.True(task.WaitUntilCompleted(1000));
                    Assert.True(task.IsCompleted);
                }
            }
        }
Example #4
0
        public void Start_AfterInitialWait_Executes()
        {
            // Arrange
            // Detect the difference between waiting and not waiting, but keep the test execution time fast.
            TimeSpan initialDelay = TimeSpan.FromMilliseconds(50);

            using (EventWaitHandle executedWaitHandle = new ManualResetEvent(initialState: false))
            {
                ITaskSeriesCommand command = CreateCommand(() =>
                {
                    Assert.True(executedWaitHandle.Set()); // Guard
                    return(new TaskSeriesCommandResult(wait: Task.Delay(TimeSpan.FromDays(1))));
                });

                using (ITaskSeriesTimer product = CreateProductUnderTest(command, Task.Delay(initialDelay)))
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();

                    // Act
                    product.Start();

                    // Assert
                    Assert.True(executedWaitHandle.WaitOne(1000)); // Guard
                    stopwatch.Stop();
                    // Account for the resolution of the system timer; otherwise, the test may fail intermittently
                    // (as the timer may fire slightly before the precise expected value).
                    TimeSpan effectiveActualDelay = AddSystemTimerResolution(stopwatch.Elapsed);
                    AssertGreaterThan(initialDelay, effectiveActualDelay);
                }
            }
        }
        internal async Task ProcessMessageAsync(IStorageQueueMessage message, TimeSpan visibilityTimeout, CancellationToken cancellationToken)
        {
            try
            {
                if (!await _queueProcessor.BeginProcessingMessageAsync(message.SdkObject, cancellationToken))
                {
                    return;
                }

                FunctionResult result = null;
                using (ITaskSeriesTimer timer = CreateUpdateMessageVisibilityTimer(_queue, message, visibilityTimeout, _backgroundExceptionDispatcher))
                {
                    timer.Start();

                    result = await _triggerExecutor.ExecuteAsync(message, cancellationToken);

                    await timer.StopAsync(cancellationToken);
                }

                await _queueProcessor.CompleteProcessingMessageAsync(message.SdkObject, result, cancellationToken);
            }
            catch (OperationCanceledException)
            {
                // Don't fail the top-level task when an inner task cancels.
            }
            catch (Exception exception)
            {
                // Immediately report any unhandled exception from this background task.
                // (Don't capture the exception as a fault of this Task; that would delay any exception reporting until
                // Stop is called, which might never happen.)
                _backgroundExceptionDispatcher.Throw(ExceptionDispatchInfo.Capture(exception));
            }
        }
Example #6
0
        public void Dispose_TriggersCommandCancellationToken()
        {
            // Arrange
            TimeSpan interval = TimeSpan.Zero;

            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
                using (EventWaitHandle executeFinished = new ManualResetEvent(initialState: false))
                {
                    bool cancellationTokenSignalled = false;

                    ITaskSeriesCommand command = CreateCommand((cancellationToken) =>
                    {
                        Assert.True(executeStarted.Set());  // Guard
                        cancellationTokenSignalled = cancellationToken.WaitHandle.WaitOne(1000);
                        Assert.True(executeFinished.Set()); // Guard
                        return(new TaskSeriesCommandResult(wait: Task.Delay(0)));
                    });

                    using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                    {
                        product.Start();
                        Assert.True(executeStarted.WaitOne(1000)); // Guard

                        // Act
                        product.Dispose();

                        // Assert
                        Assert.True(executeFinished.WaitOne(1000)); // Guard
                        Assert.True(cancellationTokenSignalled);
                    }
                }
        }
Example #7
0
        public void Dispose_IfStarted_DoesNotWaitForExecuteToFinish()
        {
            // Arrange
            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
                using (EventWaitHandle stopExecute = new ManualResetEvent(initialState: false))
                {
                    bool waitedForCommandToFinish = false;

                    ITaskSeriesCommand command = CreateCommand(() =>
                    {
                        Assert.True(executeStarted.Set()); // Guard
                        stopExecute.WaitOne(1000);
                        waitedForCommandToFinish = true;
                        return(new TaskSeriesCommandResult(wait: Task.Delay(0)));
                    });

                    using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                    {
                        product.Start();
                        Assert.True(executeStarted.WaitOne(1000)); // Guard

                        // Act & Assert
                        product.Dispose();

                        // Assert
                        Assert.False(waitedForCommandToFinish);

                        // Cleanup
                        Assert.True(stopExecute.Set()); // Guard
                    }
                }
        }
Example #8
0
        public void StopAsync_WhenCanceled_DoesNotWaitForExecuteToFinishToCompleteTask()
        {
            // Arrange
            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
            {
                ITaskSeriesCommand command = CreateCommand(() =>
                {
                    Assert.True(executeStarted.Set()); // Guard
                    return(new TaskSeriesCommandResult(wait: Task.Delay(2000)));
                });

                using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                {
                    product.Start();
                    Assert.True(executeStarted.WaitOne(1000)); // Guard

                    CancellationToken cancellationToken = new CancellationToken(canceled: true);

                    // Act
                    Task task = product.StopAsync(cancellationToken);

                    // Assert
                    Assert.NotNull(task);
                    Assert.True(task.WaitUntilCompleted(1000));
                    Assert.True(task.IsCompleted);
                }
            }
        }
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            await _innerListener.StartAsync(cancellationToken);

            await _heartbeatCommand.TryExecuteAsync(cancellationToken);

            _timer.Start();
        }
 // Begin watchers.
 public ValueWatcher(IReadOnlyDictionary<string, IWatcher> watches, CloudBlockBlob blobResults,
     TextWriter consoleOutput, IBackgroundExceptionDispatcher backgroundExceptionDispatcher)
 {
     ValueWatcherCommand command = new ValueWatcherCommand(watches, blobResults, consoleOutput);
     _command = command;
     _timer = ValueWatcherCommand.CreateTimer(command, backgroundExceptionDispatcher);
     _timer.Start();
 }
        // Begin watchers.
        public ValueWatcher(IReadOnlyDictionary <string, IWatcher> watches, CloudBlockBlob blobResults,
                            TextWriter consoleOutput, IBackgroundExceptionDispatcher backgroundExceptionDispatcher)
        {
            ValueWatcherCommand command = new ValueWatcherCommand(watches, blobResults, consoleOutput);

            _command = command;
            _timer   = ValueWatcherCommand.CreateTimer(command, backgroundExceptionDispatcher);
            _timer.Start();
        }
    public static RenewableLockHandle CreateRenewableLockHandle(TimeSpan leasePeriod,
                                                                IDistributedLockManager distributedLockManager, IDistributedLock lockHandle, Func <bool> preExecuteCheck)
    {
        ITaskSeriesTimer renewal =
            CreateLeaseRenewalTimer(leasePeriod, distributedLockManager, lockHandle, preExecuteCheck);

        renewal.Start();
        return(new RenewableLockHandle(lockHandle, renewal));
    }
Example #13
0
        private async Task ProcessMessageAsync(IStorageQueueMessage message, TimeSpan visibilityTimeout,
                                               CancellationToken cancellationToken)
        {
            try
            {
                bool succeeded;

                using (ITaskSeriesTimer timer = CreateUpdateMessageVisibilityTimer(_queue, message, visibilityTimeout,
                                                                                   _backgroundExceptionDispatcher))
                {
                    timer.Start();

                    succeeded = await _triggerExecutor.ExecuteAsync(message, cancellationToken);

                    await timer.StopAsync(cancellationToken);
                }

                // Need to call Delete message only if function succeeded.
                if (succeeded)
                {
                    await DeleteMessageAsync(message, cancellationToken);
                }
                else if (_poisonQueue != null)
                {
                    if (message.DequeueCount >= _maxDequeueCount)
                    {
                        _log.WriteLine("Message has reached MaxDequeueCount of {0}. Moving message to queue '{1}'.",
                                       _maxDequeueCount,
                                       _poisonQueue.Name);
                        await CopyToPoisonQueueAsync(message, cancellationToken);
                        await DeleteMessageAsync(message, cancellationToken);
                    }
                    else
                    {
                        await ReleaseMessageAsync(message, cancellationToken);
                    }
                }
                else
                {
                    // For queues without a corresponding poison queue, leave the message invisible when processing
                    // fails to prevent a fast infinite loop.
                    // Specifically, don't call ReleaseMessage(message)
                }
            }
            catch (OperationCanceledException)
            {
                // Don't fail the top-level task when an inner task cancels.
            }
            catch (Exception exception)
            {
                // Immediately report any unhandled exception from this background task.
                // (Don't capture the exception as a fault of this Task; that would delay any exception reporting until
                // Stop is called, which might never happen.)
                _backgroundExceptionDispatcher.Throw(ExceptionDispatchInfo.Capture(exception));
            }
        }
Example #14
0
        public Task EnsureAllStartedAsync(CancellationToken cancellationToken)
        {
            if (!_started)
            {
                _timer.Start();
                _strategy.Start();
                _started = true;
            }

            return(Task.FromResult(0));
        }
Example #15
0
        public void Start_IfDisposed_Throws()
        {
            // Arrange
            ITaskSeriesCommand command = CreateDummyCommand();
            ITaskSeriesTimer   product = CreateProductUnderTest(command);

            product.Dispose();

            // Act & Assert
            ExceptionAssert.ThrowsObjectDisposed(() => product.Start());
        }
Example #16
0
        public void Dispose_IfStopped_DoesNotThrow()
        {
            // Arrange
            ITaskSeriesCommand command = CreateStubCommand(TimeSpan.Zero);
            ITaskSeriesTimer   product = CreateProductUnderTest(command);

            product.Start();
            product.StopAsync(CancellationToken.None).GetAwaiter().GetResult();

            // Act & Assert
            ExceptionAssert.DoesNotThrow(() => product.Dispose());
        }
        private static ITaskSeriesTimer StartParameterLogTimer(IRecurrentCommand updateCommand, IWebJobsExceptionHandler exceptionHandler)
        {
            if (updateCommand == null)
            {
                return(null);
            }

            TimeSpan         initialDelay = FunctionParameterLogIntervals.InitialDelay;
            TimeSpan         refreshRate  = FunctionParameterLogIntervals.RefreshRate;
            ITaskSeriesTimer timer        = FixedDelayStrategy.CreateTimer(updateCommand, initialDelay, refreshRate, exceptionHandler);

            timer.Start();

            return(timer);
        }
        private static ITaskSeriesTimer StartOutputTimer(IRecurrentCommand updateCommand, IBackgroundExceptionDispatcher backgroundExceptionDispatcher)
        {
            if (updateCommand == null)
            {
                return(null);
            }

            TimeSpan         initialDelay = FunctionOutputIntervals.InitialDelay;
            TimeSpan         refreshRate  = FunctionOutputIntervals.RefreshRate;
            ITaskSeriesTimer timer        = FixedDelayStrategy.CreateTimer(updateCommand, initialDelay, refreshRate, backgroundExceptionDispatcher);

            timer.Start();

            return(timer);
        }
        public async Task <IDelayedException> TryExecuteAsync(IFunctionInstance instance, CancellationToken cancellationToken)
        {
            IDelayedException result;

            using (ITaskSeriesTimer timer = CreateHeartbeatTimer(_exceptionHandler))
            {
                await _heartbeatCommand.TryExecuteAsync(cancellationToken);

                timer.Start();

                result = await _innerExecutor.TryExecuteAsync(instance, cancellationToken);

                await timer.StopAsync(cancellationToken);
            }

            return(result);
        }
Example #20
0
        public void StopAsync_IfAlreadyStopped_Throws()
        {
            // Arrange
            ITaskSeriesCommand command = CreateStubCommand(TimeSpan.Zero);

            using (ITaskSeriesTimer product = CreateProductUnderTest(command))
            {
                product.Start();
                product.StopAsync(CancellationToken.None).GetAwaiter().GetResult();

                CancellationToken cancellationToken = CancellationToken.None;

                // Act & Assert
                ExceptionAssert.ThrowsInvalidOperation(() => product.StopAsync(cancellationToken),
                                                       "The timer has already been stopped.");
            }
        }
Example #21
0
        public void Start_AfterExecute_WaitsForReturnedWait()
        {
            // Arrange
            bool     executedOnce    = false;
            bool     executedTwice   = false;
            TimeSpan initialInterval = TimeSpan.Zero;
            // Detect the difference between waiting and not waiting, but keep the test execution time fast.
            TimeSpan  subsequentInterval = TimeSpan.FromMilliseconds(5);
            Stopwatch stopwatch          = new Stopwatch();

            using (EventWaitHandle waitForSecondExecution = new ManualResetEvent(initialState: false))
            {
                ITaskSeriesCommand command = CreateCommand(() =>
                {
                    if (executedTwice)
                    {
                        return(new TaskSeriesCommandResult(wait: Task.Delay(TimeSpan.FromDays(1))));
                    }

                    if (!executedOnce)
                    {
                        stopwatch.Start();
                        executedOnce = true;
                        return(new TaskSeriesCommandResult(wait: Task.Delay(subsequentInterval)));
                    }
                    else
                    {
                        stopwatch.Stop();
                        executedTwice = true;
                        Assert.True(waitForSecondExecution.Set()); // Guard
                        return(new TaskSeriesCommandResult(wait: Task.Delay(initialInterval)));
                    }
                });

                using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                {
                    // Act
                    product.Start();

                    // Assert
                    Assert.True(waitForSecondExecution.WaitOne(1000)); // Guard
                    AssertGreaterThan(subsequentInterval, stopwatch.Elapsed);
                }
            }
        }
Example #22
0
        internal async Task ProcessMessageAsync(QueueMessage message, TimeSpan visibilityTimeout, CancellationToken cancellationToken)
        {
            try
            {
                if (!await _queueProcessor.BeginProcessingMessageAsync(message, cancellationToken).ConfigureAwait(false))
                {
                    return;
                }

                FunctionResult         result          = null;
                Action <UpdateReceipt> onUpdateReceipt = updateReceipt => { message = message.Update(updateReceipt); };
                using (ITaskSeriesTimer timer = CreateUpdateMessageVisibilityTimer(_queue, message, visibilityTimeout, _exceptionHandler, onUpdateReceipt))
                {
                    timer.Start();

                    result = await _triggerExecutor.ExecuteAsync(message, cancellationToken).ConfigureAwait(false);

                    await timer.StopAsync(cancellationToken).ConfigureAwait(false);
                }

                // Use a different cancellation token for shutdown to allow graceful shutdown.
                // Specifically, don't cancel the completion or update of the message itself during graceful shutdown.
                // Only cancel completion or update of the message if a non-graceful shutdown is requested via _shutdownCancellationTokenSource.
                await _queueProcessor.CompleteProcessingMessageAsync(message, result, _shutdownCancellationTokenSource.Token).ConfigureAwait(false);
            }
            catch (TaskCanceledException)
            {
                // Don't fail the top-level task when an inner task cancels.
            }
            catch (OperationCanceledException)
            {
                // Don't fail the top-level task when an inner task cancels.
            }
            catch (Exception exception)
            {
                // Immediately report any unhandled exception from this background task.
                // (Don't capture the exception as a fault of this Task; that would delay any exception reporting until
                // Stop is called, which might never happen.)
#pragma warning disable AZC0103 // Do not wait synchronously in asynchronous scope.
                _exceptionHandler.OnUnhandledExceptionAsync(ExceptionDispatchInfo.Capture(exception)).GetAwaiter().GetResult();
#pragma warning restore AZC0103 // Do not wait synchronously in asynchronous scope.
            }
        }
Example #23
0
        public void StopAsync_WaitsForTaskCompletionToCompleteTask()
        {
            // Arrange
            bool executedOnce  = false;
            bool taskCompleted = false;

            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
                using (EventWaitHandle stopExecuteInFiveMilliseconds = new ManualResetEvent(initialState: false))
                {
                    ITaskSeriesCommand command = CreateCommand(async() =>
                    {
                        if (executedOnce)
                        {
                            return(new TaskSeriesCommandResult(wait: Task.Delay(0)));
                        }

                        executedOnce = true;
                        Assert.True(executeStarted.Set()); // Guard
                        // Detect the difference between waiting and not waiting, but keep the test execution time fast.
                        await Task.Delay(5);
                        taskCompleted = true;
                        return(new TaskSeriesCommandResult(wait: Task.Delay(0)));
                    });

                    using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                    {
                        product.Start();
                        Assert.True(executeStarted.WaitOne(1000));        // Guard
                        Assert.True(stopExecuteInFiveMilliseconds.Set()); // Guard

                        CancellationToken cancellationToken = CancellationToken.None;

                        // Act
                        Task stopTask = product.StopAsync(cancellationToken);

                        // Assert
                        Assert.NotNull(stopTask);
                        stopTask.GetAwaiter().GetResult();
                        Assert.True(taskCompleted);
                    }
                }
        }
Example #24
0
        public void Start_IfCommandExecuteAsyncsReturnsCanceledTask_DoesNotCallBackgroundExceptionDispatcher()
        {
            // Arrange
            bool executedOnce = false;

            using (EventWaitHandle executedTwiceWaitHandle = new ManualResetEvent(initialState: false))
            {
                ITaskSeriesCommand command = CreateCommand(() =>
                {
                    if (executedOnce)
                    {
                        Assert.True(executedTwiceWaitHandle.Set()); // Guard
                        return(Task.FromResult(new TaskSeriesCommandResult(Task.Delay(TimeSpan.FromDays(1)))));
                    }

                    executedOnce = true;
                    TaskCompletionSource <TaskSeriesCommandResult> taskSource =
                        new TaskCompletionSource <TaskSeriesCommandResult>();
                    taskSource.SetCanceled();
                    return(taskSource.Task);
                });

                Mock <IWebJobsExceptionHandler> exceptionHandlerMock =
                    new Mock <IWebJobsExceptionHandler>(MockBehavior.Strict);
                int backgroundExceptionCalls = 0;
                exceptionHandlerMock
                .Setup(d => d.OnUnhandledExceptionAsync(It.IsAny <ExceptionDispatchInfo>()))
                .Callback(() => backgroundExceptionCalls++);
                IWebJobsExceptionHandler exceptionHandler = exceptionHandlerMock.Object;

                using (ITaskSeriesTimer product = CreateProductUnderTest(command, exceptionHandler))
                {
                    // Act
                    product.Start();

                    // Assert
                    Assert.True(executedTwiceWaitHandle.WaitOne(1000)); // Guard
                    Assert.Equal(0, backgroundExceptionCalls);
                }
            }
        }
Example #25
0
        public void StopAsync_WhenExecuteTaskCompletesFaulted_DoesNotThrowOrFault()
        {
            // Arrange
            bool executedOnce = false;

            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
                using (EventWaitHandle stopExecuteInFiveMilliseconds = new ManualResetEvent(initialState: false))
                {
                    ITaskSeriesCommand command = CreateCommand(() =>
                    {
                        if (executedOnce)
                        {
                            return(Task.FromResult(new TaskSeriesCommandResult(wait: Task.Delay(0))));
                        }

                        executedOnce = true;
                        Assert.True(executeStarted.Set()); // Guard
                        TaskCompletionSource <TaskSeriesCommandResult> taskSource =
                            new TaskCompletionSource <TaskSeriesCommandResult>();
                        taskSource.SetException(new InvalidOperationException());
                        return(taskSource.Task);
                    });

                    IWebJobsExceptionHandler ignoreDispatcher = CreateIgnoreBackgroundExceptionDispatcher();

                    using (ITaskSeriesTimer product = CreateProductUnderTest(command, ignoreDispatcher))
                    {
                        product.Start();
                        Assert.True(executeStarted.WaitOne(1000)); // Guard

                        CancellationToken cancellationToken = CancellationToken.None;

                        // Act
                        Task task = product.StopAsync(cancellationToken);

                        // Assert
                        Assert.NotNull(task);
                        task.GetAwaiter().GetResult();
                    }
                }
        }
Example #26
0
        public void StopAsync_TriggersNotExecutingAgain()
        {
            // Arrange
            using (EventWaitHandle executedOnceWaitHandle = new ManualResetEvent(initialState: false))
            {
                ITaskSeriesTimer product       = null;
                Task             stop          = null;
                bool             executedOnce  = false;
                bool             executedTwice = false;

                ITaskSeriesCommand command = CreateCommand(() =>
                {
                    if (!executedOnce)
                    {
                        stop = product.StopAsync(CancellationToken.None);
                        Assert.True(executedOnceWaitHandle.Set()); // Guard
                        executedOnce = true;
                        return(new TaskSeriesCommandResult(wait: Task.Delay(0)));
                    }
                    else
                    {
                        executedTwice = true;
                        return(new TaskSeriesCommandResult(wait: Task.Delay(0)));
                    }
                });

                using (product = CreateProductUnderTest(command))
                {
                    product.Start();

                    // Act
                    bool executed = executedOnceWaitHandle.WaitOne(1000);

                    // Assert
                    Assert.True(executed); // Guard
                    Assert.NotNull(stop);
                    stop.GetAwaiter().GetResult();
                    Assert.False(executedTwice);
                }
            }
        }
Example #27
0
        public void Start_IfCommandExecuteAsyncsReturnsFaultedTask_CallsBackgroundExceptionDispatcher()
        {
            // Arrange
            Exception expectedException = new Exception();

            ITaskSeriesCommand command = CreateCommand(() =>
            {
                TaskCompletionSource <TaskSeriesCommandResult> taskSource =
                    new TaskCompletionSource <TaskSeriesCommandResult>();
                taskSource.SetException(expectedException);
                return(taskSource.Task);
            });

            using (EventWaitHandle exceptionDispatchedWaitHandle = new ManualResetEvent(initialState: false))
            {
                Mock <IWebJobsExceptionHandler> exceptionHandlerMock =
                    new Mock <IWebJobsExceptionHandler>(MockBehavior.Strict);
                ExceptionDispatchInfo exceptionInfo = null;
                exceptionHandlerMock
                .Setup(d => d.OnUnhandledExceptionAsync(It.IsAny <ExceptionDispatchInfo>()))
                .Callback <ExceptionDispatchInfo>((i) =>
                {
                    exceptionInfo = i;
                    Assert.True(exceptionDispatchedWaitHandle.Set());     // Guard
                });
                IWebJobsExceptionHandler exceptionHandler = exceptionHandlerMock.Object;

                using (ITaskSeriesTimer product = CreateProductUnderTest(command, exceptionHandler))
                {
                    // Act
                    product.Start();

                    // Assert
                    Assert.True(exceptionDispatchedWaitHandle.WaitOne(1000)); // Guard
                    Assert.NotNull(exceptionInfo);
                    Assert.Same(expectedException, exceptionInfo.SourceException);
                }
            }
        }
Example #28
0
        public void StopAsync_DoesNotWaitForInitialWaitToCompleteTask()
        {
            // Arrange
            ITaskSeriesCommand command = CreateStubCommand(TimeSpan.Zero);

            using (ITaskSeriesTimer product = CreateProductUnderTest(command, initialWait: Task.Delay(2000)))
            {
                product.Start();

                // Wait for the background thread to enter the initialWait.
                Thread.Sleep(5);

                CancellationToken cancellationToken = CancellationToken.None;

                // Act
                Task task = product.StopAsync(cancellationToken);

                // Assert
                Assert.NotNull(task);
                Assert.True(task.WaitUntilCompleted(1000));
                Assert.True(task.IsCompleted);
            }
        }
Example #29
0
        public void Start_IfCommandExecuteAsyncsThrows_CallsBackgroundExceptionDispatcher()
        {
            // Arrange
            Exception expectedException = new Exception();

            TimeSpan interval = TimeSpan.Zero;

            using (EventWaitHandle exceptionDispatchedWaitHandle = new ManualResetEvent(initialState: false))
            {
                Func <Task <TaskSeriesCommandResult> > execute = () => { throw expectedException; };
                ITaskSeriesCommand command = CreateCommand(execute);

                Mock <IWebJobsExceptionHandler> exceptionHandlerMock =
                    new Mock <IWebJobsExceptionHandler>(MockBehavior.Strict);
                ExceptionDispatchInfo exceptionInfo = null;
                exceptionHandlerMock
                .Setup(d => d.OnUnhandledExceptionAsync(It.IsAny <ExceptionDispatchInfo>()))
                .Callback <ExceptionDispatchInfo>((i) =>
                {
                    exceptionInfo = i;
                    Assert.True(exceptionDispatchedWaitHandle.Set());     // Guard
                });
                IWebJobsExceptionHandler exceptionHandler = exceptionHandlerMock.Object;

                using (ITaskSeriesTimer product = CreateProductUnderTest(command, exceptionHandler))
                {
                    // Act
                    product.Start();

                    // Assert
                    bool executed = exceptionDispatchedWaitHandle.WaitOne(1000);
                    Assert.True(executed);
                    Assert.NotNull(exceptionInfo);
                    Assert.Same(expectedException, exceptionInfo.SourceException);
                }
            }
        }
Example #30
0
 public Task StartAsync(CancellationToken cancellationToken)
 {
     ThrowIfDisposed();
     _timer.Start();
     return(Task.FromResult(0));
 }