Example #1
0
        public void StopAndInitiateDurableTaskOrReplay_UpdatesCurrentUtcDateTimeToNextOrchestratorStartedTimestamp_OnlyIfTimerCreatedAndFired(bool timerCreated, bool timerFired)
        {
            var history = DurableTestUtilities.MergeHistories(
                CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true),
                CreateDurableTimerHistory(timerCreated: timerCreated, timerFired: timerFired, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false),
                CreateOrchestratorStartedHistory(date: _shouldNotHitTime, isProcessed: false)
                );
            var context = new OrchestrationContext {
                History = history, CurrentUtcDateTime = _startTime
            };

            var durableTaskHandler = new DurableTaskHandler();
            var task = new DurableTimerTask(_fireAt);

            if (!timerCreated || !timerFired)
            {
                DurableTestUtilities.EmulateStop(durableTaskHandler);
                durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                    task: task, context: context, noWait: false,
                    output: _ => { Assert.True(false, "Unexpected output"); },
                    onFailure: _ => { });
                Assert.Equal(_startTime, context.CurrentUtcDateTime);
            }
            else
            {
                durableTaskHandler.StopAndInitiateDurableTaskOrReplay(task: task, context: context, noWait: false, _ => { Assert.True(false, "Unexpected output"); }, errorMessage => { });
                Assert.Equal(_restartTime, context.CurrentUtcDateTime);
            }
            VerifyCreateDurableTimerActionAdded(context, _fireAt);
        }
Example #2
0
        public void StopAndInitiateDurableTaskOrReplay_ContinuesToNextTimer_IfTimersHaveIdenticalFireAt()
        {
            var history = DurableTestUtilities.MergeHistories(
                CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true),
                CreateDurableTimerHistory(timerCreated: true, timerFired: true, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false),
                CreateDurableTimerHistory(timerCreated: true, timerFired: true, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false),
                CreateDurableTimerHistory(timerCreated: true, timerFired: true, fireAt: _fireAt, restartTime: _shouldNotHitTime, orchestratorStartedIsProcessed: false)
                );
            var context = new OrchestrationContext {
                History = history
            };

            var durableTaskHandler = new DurableTaskHandler();

            for (int i = 0; i < 2; i++)
            {
                durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                    task: new DurableTimerTask(_fireAt), context: context, noWait: false,
                    output: _ => { Assert.True(false, "Unexpected output"); },
                    onFailure: _ => { });
                Assert.Equal(_restartTime, context.CurrentUtcDateTime);
            }

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                task: new DurableTimerTask(_fireAt), context: context, noWait: false,
                output: _ => { Assert.True(false, "Unexpected output"); },
                onFailure: _ => { });
            Assert.Equal(_shouldNotHitTime, context.CurrentUtcDateTime);
        }
Example #3
0
        public void StopAndInitiateDurableTaskOrReplay_ReplaysMultipleActivitiesWithTheSameName()
        {
            var loadedFunctions = new[]
            {
                DurableTestUtilities.CreateFakeActivityTriggerAzFunctionInfo("FunctionA"),
                DurableTestUtilities.CreateFakeActivityTriggerAzFunctionInfo("FunctionB")
            };

            var history = DurableTestUtilities.MergeHistories(
                CreateHistory("FunctionA", scheduled: true, completed: true, output: "\"Result1\""),
                CreateHistory("FunctionB", scheduled: true, completed: true, output: "\"Result2\""),
                CreateHistory("FunctionA", scheduled: true, completed: true, output: "\"Result3\"")
                );
            var orchestrationContext = new OrchestrationContext {
                History = history
            };
            var allOutput = new List <object>();

            var durableTaskHandler = new DurableTaskHandler();

            // Replay FunctionA only
            for (var i = 0; i < 2; ++i)
            {
                durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                    new ActivityInvocationTask("FunctionA", FunctionInput), orchestrationContext, noWait: false,
                    output => { allOutput.Add(output); });
            }

            // Expect FunctionA results only
            Assert.Equal(new[] { "Result1", "Result3" }, allOutput);
        }
        protected override void EndProcessing()
        {
            var privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData;
            var context     = (OrchestrationContext)privateData[SetFunctionInvocationContextCommand.ContextKey];

            var task = new ExternalEventTask(EventName);

            _durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                task, context, NoWait.IsPresent, WriteObject, failureReason => DurableActivityErrorHandler.Handle(this, failureReason));
        }
Example #5
0
        protected override void EndProcessing()
        {
            var privateData = (Hashtable)MyInvocation.MyCommand.Module.PrivateData;
            var context     = (OrchestrationContext)privateData[SetFunctionInvocationContextCommand.ContextKey];

            DateTime fireAt = context.CurrentUtcDateTime.Add(Duration);
            var      task   = new DurableTimerTask(fireAt);

            _durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                task, context, NoWait.IsPresent, WriteObject, failureReason => DurableActivityErrorHandler.Handle(this, failureReason));
        }
        public void StopAndInitiateDurableTaskOrReplay_RetriesOnFailure()
        {
            const string FunctionName  = "Function";
            const string FunctionInput = "Input";

            var history = new[]
            {
                new HistoryEvent {
                    EventType = HistoryEventType.TaskScheduled, Name = FunctionName, EventId = 1
                },
                new HistoryEvent {
                    EventType = HistoryEventType.TaskFailed, TaskScheduledId = 1
                },
                new HistoryEvent {
                    EventType = HistoryEventType.TimerCreated, EventId = 2
                },
                new HistoryEvent {
                    EventType = HistoryEventType.TimerFired, TimerId = 2
                },
                new HistoryEvent {
                    EventType = HistoryEventType.TaskScheduled, Name = FunctionName, EventId = 3
                },
                new HistoryEvent {
                    EventType = HistoryEventType.TaskCompleted, Result = "\"OK\"", TaskScheduledId = 3
                },
            };

            var orchestrationContext = new OrchestrationContext {
                History = history
            };
            var durableTaskHandler = new DurableTaskHandler();

            var retryOptions = new RetryOptions(TimeSpan.FromSeconds(1), 2, null, null, null);

            object result = null;

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                new ActivityInvocationTask(FunctionName, FunctionInput, retryOptions),
                orchestrationContext,
                noWait: false,
                output: output => { result = output; },
                onFailure: _ => { Assert.True(false, "Unexpected failure"); },
                retryOptions: retryOptions
                );

            Assert.Equal("OK", result);

            var(_, actions) = orchestrationContext.OrchestrationActionCollector.WaitForActions(new AutoResetEvent(initialState: true));
            var action = (CallActivityWithRetryAction)actions.Single().Single();

            Assert.Equal(FunctionName, action.FunctionName);
            Assert.Equal(FunctionInput, action.Input);
            Assert.NotEmpty(action.RetryOptions);
        }
        public void WaitAll_And_WaitAny_StartNewActivityBatch(bool invokeWaitAll, bool invokeWaitAny, int expectedNumberOfBatches)
        {
            var orchestrationContext = new OrchestrationContext {
                History = new HistoryEvent[0]
            };
            var durableTaskHandler = new DurableTaskHandler();

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                new ActivityInvocationTask("Function", "Input"),
                orchestrationContext,
                noWait: true,
                output: _ => {},
                onFailure: _ => {}
                );

            if (invokeWaitAll)
            {
                durableTaskHandler.Stop(); // just to avoid the next call getting stuck waiting for a stop event
                durableTaskHandler.WaitAll(new DurableTask[0], orchestrationContext, output: _ => {});
            }

            if (invokeWaitAny)
            {
                durableTaskHandler.Stop(); // just to avoid the next call getting stuck waiting for a stop event
                durableTaskHandler.WaitAny(new DurableTask[0], orchestrationContext, output: _ => {});
            }

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                new ActivityInvocationTask("Function", "Input"),
                orchestrationContext,
                noWait: true,
                output: _ => {},
                onFailure: _ => {}
                );

            var(_, actions) = orchestrationContext.OrchestrationActionCollector.WaitForActions(new AutoResetEvent(initialState: true));
            Assert.Equal(expectedNumberOfBatches, actions.Count);
        }
Example #8
0
        public void StopAndInitiateDurableTaskOrReplay_OutputsDurableTimerTask_IfNoWaitRequested()
        {
            var history = CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true);
            var context = new OrchestrationContext {
                History = history
            };
            var allOutput = new List <DurableTimerTask>();

            var durableTaskHandler = new DurableTaskHandler();

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(task: new DurableTimerTask(_fireAt), context: context, noWait: true, output => { allOutput.Add((DurableTimerTask)output); });
            Assert.Equal(_fireAt, allOutput.Single().FireAt);
            VerifyCreateDurableTimerActionAdded(context, _fireAt);
        }
Example #9
0
        protected override void EndProcessing()
        {
            var privateData     = (Hashtable)MyInvocation.MyCommand.Module.PrivateData;
            var context         = (OrchestrationContext)privateData[SetFunctionInvocationContextCommand.ContextKey];
            var loadedFunctions = FunctionLoader.GetLoadedFunctions();

            var task = new ActivityInvocationTask(FunctionName, Input, RetryOptions);

            ActivityInvocationTask.ValidateTask(task, loadedFunctions);

            _durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                task, context, NoWait.IsPresent,
                output: WriteObject,
                onFailure: failureReason => DurableActivityErrorHandler.Handle(this, failureReason),
                retryOptions: RetryOptions);
        }
Example #10
0
        public void CurrentUtcDateTime_UpdatesToNextOrchestratorStartedTimestamp_IfActivityFunctionCompleted(bool completed)
        {
            var history = DurableTestUtilities.MergeHistories(
                CreateOrchestratorStartedHistory(startTime: _startTime, isProcessed: true),
                CreateActivityHistory(
                    name: FunctionName,
                    scheduled: true,
                    completed: completed,
                    output: InvocationResultJson,
                    date: _restartTime,
                    orchestratorStartedIsProcessed: false)
                );

            OrchestrationContext context = new OrchestrationContext {
                History = history, CurrentUtcDateTime = _startTime
            };
            var durableTaskHandler = new DurableTaskHandler();
            var allOutput          = new List <object>();

            if (completed)
            {
                history = DurableTestUtilities.MergeHistories(history, CreateActivityHistory(
                                                                  name: FunctionName,
                                                                  scheduled: true,
                                                                  completed: true,
                                                                  output: InvocationResultJson,
                                                                  date: _shouldNotHitTime,
                                                                  orchestratorStartedIsProcessed: false));
            }
            else
            {
                DurableTestUtilities.EmulateStop(durableTaskHandler);
            }

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                new ActivityInvocationTask(FunctionName, FunctionInput), context, noWait: false,
                output: output => allOutput.Add(output), onFailure: _ => { });
            if (completed)
            {
                Assert.Equal(_restartTime, context.CurrentUtcDateTime);
            }
            else
            {
                Assert.Equal(_startTime, context.CurrentUtcDateTime);
            }
        }
Example #11
0
        public void CurrentUtcDateTime_UpdatesToNextOrchestratorStartedTimestamp_IfTimestampsAreIdentical()
        {
            var history = DurableTestUtilities.MergeHistories(
                CreateActivityHistory(
                    name: FunctionName,
                    scheduled: true,
                    completed: true,
                    date: _startTime,
                    output: InvocationResultJson,
                    orchestratorStartedIsProcessed: true),
                CreateActivityHistory(
                    name: FunctionName,
                    scheduled: true,
                    completed: true,
                    date: _startTime,
                    output: InvocationResultJson,
                    orchestratorStartedIsProcessed: false),
                CreateActivityHistory(
                    name: FunctionName,
                    scheduled: true,
                    completed: true,
                    date: _shouldNotHitTime,
                    output: InvocationResultJson,
                    orchestratorStartedIsProcessed: false)
                );
            var context = new OrchestrationContext {
                History = history, CurrentUtcDateTime = _startTime
            };
            var willHitEvent = context.History.First(
                e => e.EventType == HistoryEventType.OrchestratorStarted &&
                e.IsProcessed);
            var allOutput          = new List <object>();
            var durableTaskHandler = new DurableTaskHandler();

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                new ActivityInvocationTask(FunctionName, FunctionInput), context, noWait: false,
                output: output => allOutput.Add(output), onFailure: _ => { });

            Assert.Equal(_startTime, context.CurrentUtcDateTime);
            var shouldNotHitEvent = context.History.First(
                e => e.Timestamp.Equals(_shouldNotHitTime));

            Assert.True(willHitEvent.IsProcessed);
            Assert.False(shouldNotHitEvent.IsProcessed);
        }
Example #12
0
        public void StopAndInitiateDurableTaskOrReplay_OutputsNothing_IfActivityNotCompleted(
            bool scheduled, bool completed)
        {
            var history = CreateHistory(scheduled: scheduled, completed: completed, output: InvocationResultJson);
            var orchestrationContext = new OrchestrationContext {
                History = history
            };

            var durableTaskHandler = new DurableTaskHandler();

            DurableTestUtilities.EmulateStop(durableTaskHandler);

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                new ActivityInvocationTask(FunctionName, FunctionInput), orchestrationContext, noWait: false,
                _ => { Assert.True(false, "Unexpected output"); });

            VerifyCallActivityActionAdded(orchestrationContext);
        }
Example #13
0
        public void StopAndInitiateDurableTaskOrReplay_ReplaysActivity_IfActivityCompleted(
            bool scheduled, bool completed)
        {
            var history = CreateHistory(scheduled: scheduled, completed: completed, output: InvocationResultJson);
            var orchestrationContext = new OrchestrationContext {
                History = history
            };
            var allOutput = new List <object>();

            var durableTaskHandler = new DurableTaskHandler();

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                task: new ActivityInvocationTask(FunctionName, FunctionInput), orchestrationContext, noWait: false,
                output => { allOutput.Add(output); });

            VerifyCallActivityActionAdded(orchestrationContext);
            Assert.Equal(InvocationResult, allOutput.Single());
        }
Example #14
0
        public void StopAndInitiateDurableTaskOrReplay_OutputsActivityInvocationTask_WhenNoWaitRequested(
            bool scheduled, bool completed)
        {
            var history = CreateHistory(scheduled: scheduled, completed: completed, output: InvocationResultJson);
            var orchestrationContext = new OrchestrationContext {
                History = history
            };
            var allOutput = new List <ActivityInvocationTask>();

            var durableTaskHandler = new DurableTaskHandler();

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                new ActivityInvocationTask(FunctionName, FunctionInput), orchestrationContext, noWait: true,
                output => { allOutput.Add((ActivityInvocationTask)output); });

            VerifyCallActivityActionAdded(orchestrationContext);
            Assert.Equal(FunctionName, allOutput.Single().FunctionName);
        }
Example #15
0
        public void StopAndInitiateDurableTaskOrReplay_OutputsError_IfActivityFailed()
        {
            const string FailureReason        = "Failure reason";
            var          history              = CreateHistory(scheduled: true, completed: false, failed: true, output: InvocationResultJson, failureReason: FailureReason);
            var          orchestrationContext = new OrchestrationContext {
                History = history
            };
            var allErrors = new List <object>();

            var durableTaskHandler = new DurableTaskHandler();

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                task: new ActivityInvocationTask(FunctionName, FunctionInput), orchestrationContext, noWait: false,
                output: _ => { Assert.True(false, "Unexpected output"); },
                onFailure: reason => { allErrors.Add(reason); });

            VerifyCallActivityActionAdded(orchestrationContext);
            Assert.Equal(FailureReason, allErrors.Single());
        }
Example #16
0
        public void StopAndInitiateDurableTaskOrReplay_OutputsNothing_IfNoWaitNotRequested(bool timerCreated, bool timerFired)
        {
            var history = DurableTestUtilities.MergeHistories(
                CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true),
                CreateDurableTimerHistory(timerCreated: timerCreated, timerFired: timerFired, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false)
                );
            var context = new OrchestrationContext {
                History = history
            };

            var durableTaskHandler = new DurableTaskHandler();

            if (!timerCreated || !timerFired)
            {
                DurableTestUtilities.EmulateStop(durableTaskHandler);
            }

            durableTaskHandler.StopAndInitiateDurableTaskOrReplay(task: new DurableTimerTask(_fireAt), context: context, noWait: false, _ => { Assert.True(false, "Unexpected output"); });
            VerifyCreateDurableTimerActionAdded(context, _fireAt);
        }
Example #17
0
        public void StopAndCreateTimerOrContinue_WaitsUntilTimerFires_IfNoWaitNotRequested(bool timerCreated, bool timerFired, bool expectedWaitForStop)
        {
            var history = DurableTestUtilities.MergeHistories(
                CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true),
                CreateDurableTimerHistory(timerCreated: timerCreated, timerFired: timerFired, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false)
                );
            var context = new OrchestrationContext {
                History = history, CurrentUtcDateTime = _startTime
            };

            var durableTaskHandler = new DurableTaskHandler();

            DurableTestUtilities.VerifyWaitForDurableTasks(
                durableTaskHandler,
                delayBeforeStopping: _longInterval,
                expectedWaitForStop: expectedWaitForStop,
                () =>
            {
                durableTaskHandler.StopAndInitiateDurableTaskOrReplay(task: new DurableTimerTask(_fireAt), context: context, noWait: false, _ => { Assert.True(false, "Unexpected output"); });
            });
        }
Example #18
0
        public void StopAndInitiateDurableTaskOrReplay_WaitsForStop_IfActivityNotCompleted(bool scheduledAndCompleted, bool expectedWaitForStop)
        {
            var durableTaskHandler = new DurableTaskHandler();

            var history = CreateHistory(
                scheduled: scheduledAndCompleted, completed: scheduledAndCompleted, output: InvocationResultJson);

            var orchestrationContext = new OrchestrationContext {
                History = history
            };

            DurableTestUtilities.VerifyWaitForDurableTasks(
                durableTaskHandler,
                _delayBeforeStopping,
                expectedWaitForStop,
                () =>
            {
                durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                    new ActivityInvocationTask(FunctionName, FunctionInput), orchestrationContext, noWait: false, _ => { });
            });
        }
        public void StopAndInitiateDurableTaskOrReplay_AddsActivityBatch_UnlessNoWait(bool noWait, int numberOfActions, int expectedNumberOfBatches)
        {
            var orchestrationContext = new OrchestrationContext {
                History = new HistoryEvent[0]
            };
            var durableTaskHandler = new DurableTaskHandler();

            for (var i = 0; i < numberOfActions; ++i)
            {
                durableTaskHandler.Stop(); // just to avoid the next call getting stuck waiting for a stop event

                durableTaskHandler.StopAndInitiateDurableTaskOrReplay(
                    new ActivityInvocationTask("Function", "Input"),
                    orchestrationContext,
                    noWait: noWait,
                    output: _ => {},
                    onFailure: _ => {}
                    );
            }

            var(_, actions) = orchestrationContext.OrchestrationActionCollector.WaitForActions(new AutoResetEvent(initialState: true));
            Assert.Equal(expectedNumberOfBatches, actions.Count);
        }