Example #1
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);
        }
        public void WaitAll_OutputsNothing_WhenAnyTaskIsNotCompleted(
            bool scheduled, bool completed)
        {
            var history = DurableTestUtilities.MergeHistories(
                CreateActivityHistory("FunctionA", scheduled: true, completed: true, output: "\"Result1\""), // completed
                CreateActivityHistory("FunctionA", scheduled: true, completed: true, output: "\"Result2\""),
                CreateDurableTimerHistory(timerCreated: scheduled, timerFired: completed, fireAt: _fireAt, _restartTime, orchestratorStartedIsProcessed: false),
                CreateActivityHistory("FunctionB", scheduled: true, completed: true, output: "\"Result3\"") // completed
                );

            var orchestrationContext = new OrchestrationContext {
                History = history
            };
            var tasksToWaitFor =
                new ReadOnlyCollection <DurableTask>(
                    new DurableTask[] {
                new ActivityInvocationTask("FunctionA", FunctionInput),
                new ActivityInvocationTask("FunctionA", FunctionInput),
                new DurableTimerTask(_fireAt),
                new ActivityInvocationTask("FunctionB", FunctionInput)
            });

            var durableTaskHandler = new DurableTaskHandler();

            DurableTestUtilities.EmulateStop(durableTaskHandler);

            durableTaskHandler.WaitAll(tasksToWaitFor, orchestrationContext,
                                       _ => { Assert.True(false, "Unexpected output"); });

            VerifyNoOrchestrationActionAdded(orchestrationContext);
        }
        public void WaitAll_WaitsForStop_WhenAnyTaskIsNotCompleted(bool scheduledAndCompleted, bool expectedWaitForStop)
        {
            var history = DurableTestUtilities.MergeHistories(
                CreateActivityHistory("FunctionA", scheduled: true, completed: true, output: "\"Result1\""),
                CreateActivityHistory("FunctionA", scheduled: scheduledAndCompleted, completed: scheduledAndCompleted, output: "\"Result2\""),
                CreateDurableTimerHistory(timerCreated: scheduledAndCompleted, timerFired: scheduledAndCompleted, fireAt: _fireAt, _restartTime, orchestratorStartedIsProcessed: false),
                CreateActivityHistory("FunctionB", scheduled: true, completed: true, output: "\"Result3\"")
                );

            var durableTaskHandler = new DurableTaskHandler();

            var orchestrationContext = new OrchestrationContext {
                History = history
            };
            var tasksToWaitFor =
                new ReadOnlyCollection <DurableTask>(
                    new DurableTask[] {
                new ActivityInvocationTask("FunctionA", FunctionInput),
                new ActivityInvocationTask("FunctionA", FunctionInput),
                new DurableTimerTask(_fireAt),
                new ActivityInvocationTask("FunctionB", FunctionInput)
            });

            DurableTestUtilities.VerifyWaitForDurableTasks(
                durableTaskHandler,
                _delayBeforeStopping,
                expectedWaitForStop,
                () =>
            {
                durableTaskHandler.WaitAll(tasksToWaitFor, orchestrationContext, _ => { });
            });
        }
        public static void VerifyWaitForDurableTasks(
            DurableTaskHandler durableTaskHandler,
            TimeSpan delayBeforeStopping,
            bool expectedWaitForStop,
            Action action
            )
        {
            // action() call may block until Stop is invoked from another thread.
            var thread = new Thread(() =>
            {
                Thread.Sleep(delayBeforeStopping);
                durableTaskHandler.Stop();
            });

            thread.Start();
            try
            {
                var elapsedMilliseconds = MeasureExecutionTimeInMilliseconds(action);

                if (expectedWaitForStop)
                {
                    Assert.True(elapsedMilliseconds > delayBeforeStopping.TotalMilliseconds * 0.8);
                }
                else
                {
                    Assert.True(elapsedMilliseconds < delayBeforeStopping.TotalMilliseconds * 0.2);
                }
            }
            finally
            {
                thread.Join();
            }
        }
Example #5
0
        public void ValidateTask_Throws_WhenActivityFunctionHasNoProperBinding(
            string bindingType, BindingInfo.Types.Direction bindingDirection)
        {
            var history = CreateHistory(scheduled: false, completed: false, output: InvocationResultJson);
            var orchestrationContext = new OrchestrationContext {
                History = history
            };

            var loadedFunctions = new[]
            {
                DurableTestUtilities.CreateFakeAzFunctionInfo(FunctionName, "fakeTriggerBindingName", bindingType, bindingDirection)
            };

            var durableTaskHandler = new DurableTaskHandler();

            var exception =
                Assert.Throws <InvalidOperationException>(
                    () => ActivityInvocationTask.ValidateTask(
                        new ActivityInvocationTask(FunctionName, FunctionInput), loadedFunctions));

            Assert.Contains(FunctionName, exception.Message);
            Assert.Contains(ActivityTriggerBindingType, exception.Message);

            DurableTestUtilities.VerifyNoActionAdded(orchestrationContext);
        }
Example #6
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);
        }
        public void WaitAny_WaitsForStop_WhenAllTasksAreNotCompleted(bool completed, bool expectedWaitForStop)
        {
            var history = DurableTestUtilities.MergeHistories(
                CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true),
                CreateActivityHistory("FunctionA", scheduled: true, completed: false, output: "\"Result1\""),
                CreateActivityHistory("FunctionA", scheduled: true, completed: completed, output: "\"Result2\"")
                );

            var durableTaskHandler = new DurableTaskHandler();

            var orchestrationContext = new OrchestrationContext {
                History = history
            };
            var tasksToWaitFor =
                new ReadOnlyCollection <DurableTask>(
                    new DurableTask[] {
                new ActivityInvocationTask("FunctionA", FunctionInput),
                new ActivityInvocationTask("FunctionA", FunctionInput)
            });

            DurableTestUtilities.VerifyWaitForDurableTasks(
                durableTaskHandler,
                _delayBeforeStopping,
                expectedWaitForStop,
                () =>
            {
                durableTaskHandler.WaitAny(tasksToWaitFor, orchestrationContext, _ => { });
            });
        }
Example #8
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);
        }
        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 static void EmulateStop(DurableTaskHandler durableTaskHandler)
 {
     // In the actual usage, Stop is supposed to be invoked from another thread.
     // However, in order to simplify tests and avoid spawning threads, waiting for
     // them to finish, and handling potentially non-deterministic behavior,
     // we cheat a little and invoke Stop _before_ invoking WaitAll/WaitAny,
     // just to let WaitAll/WaitAny finish soon.
     // The fact that WaitAll/WaitAny _actually_ blocks until Stop is invoked
     // is verified by dedicated tests.
     durableTaskHandler.Stop();
 }
Example #11
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 #12
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 #13
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 #14
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 #15
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 #16
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 #17
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 #18
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 #19
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, _ => { });
            });
        }
Example #20
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"); });
            });
        }
        public void WaitAny_OutputsEarliestCompletedTask_WhenAnyTaskCompleted(bool completed)
        {
            var history = DurableTestUtilities.MergeHistories(
                CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true),
                CreateActivityHistory("FunctionA", scheduled: true, restartTime: _restartTime, completed: completed, output: "\"Result1\"", orchestratorStartedIsProcessed: false),
                CreateActivityHistory("FunctionA", scheduled: false, completed: false, output: "\"Result2\""),
                CreateDurableTimerHistory(timerCreated: true, timerFired: true, fireAt: _fireAt, restartTime: _restartTime, orchestratorStartedIsProcessed: false)
                );

            var orchestrationContext = new OrchestrationContext {
                History = history
            };
            var firedTimer        = new DurableTimerTask(_fireAt);
            var completedActivity = new ActivityInvocationTask("FunctionA", FunctionInput);
            var tasksToWaitFor    =
                new ReadOnlyCollection <DurableTask>(
                    new DurableTask[] {
                completedActivity,
                new ActivityInvocationTask("FunctionA", FunctionInput),
                firedTimer
            });

            var allOutput = new List <object>();

            var durableTaskHandler = new DurableTaskHandler();

            durableTaskHandler.WaitAny(tasksToWaitFor, orchestrationContext, output => { allOutput.Add(output); });

            if (completed)
            {
                Assert.Equal(new[] { completedActivity }, allOutput);
            }
            else
            {
                Assert.Equal(new[] { firedTimer }, allOutput);
            }
            VerifyNoOrchestrationActionAdded(orchestrationContext);
        }
        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);
        }
        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);
        }
        public void WaitAll_OutputsTaskResults_WhenAllTasksCompleted(
            bool scheduled, bool completed)
        {
            var history = DurableTestUtilities.MergeHistories(
                // Emulate invoking the same function (FunctionA) twice. This is to make sure that
                // both invocations are accounted for, and both results are preserved separately.
                // Without this test, the history lookup algorithm in the WaitForActivityTasks method
                // could just look for the the first history event by function name, and this error
                // would not be detected.
                CreateOrchestratorStartedHistory(date: _startTime, isProcessed: true),
                CreateActivityHistory("FunctionA", scheduled: scheduled, completed: completed, output: "\"Result1\""),
                CreateActivityHistory("FunctionA", scheduled: scheduled, completed: completed, output: "\"Result2\""),
                CreateDurableTimerHistory(timerCreated: scheduled, timerFired: completed, fireAt: _fireAt, _restartTime, orchestratorStartedIsProcessed: false),
                CreateActivityHistory("FunctionB", scheduled: scheduled, completed: completed, output: "\"Result3\"")
                );

            var orchestrationContext = new OrchestrationContext {
                History = history
            };
            var tasksToWaitFor =
                new ReadOnlyCollection <DurableTask>(
                    new DurableTask[] {
                new ActivityInvocationTask("FunctionA", FunctionInput),
                new ActivityInvocationTask("FunctionA", FunctionInput),
                new DurableTimerTask(_fireAt),
                new ActivityInvocationTask("FunctionB", FunctionInput)
            });

            var allOutput = new List <object>();

            var durableTaskHandler = new DurableTaskHandler();

            durableTaskHandler.WaitAll(tasksToWaitFor, orchestrationContext, output => { allOutput.Add(output); });

            Assert.Equal(new[] { "Result1", "Result2", "Result3" }, allOutput);
            VerifyNoOrchestrationActionAdded(orchestrationContext);
        }
Example #25
0
        public void CurrentUtcDateTime_UpdatesToNextOrchestratorStartedTimestamp_IfAnyActivitiesCompleted_WhenWaitAnyIsCalled(bool anyCompleted)
        {
            var activityFunctions = new Dictionary <string, bool>();

            activityFunctions.Add("FunctionA", false);
            activityFunctions.Add("FunctionB", anyCompleted);
            activityFunctions.Add("FunctionC", false);
            var history = DurableTestUtilities.MergeHistories(
                CreateOrchestratorStartedHistory(startTime: _startTime, isProcessed: true),
                CreateNoWaitActivityHistory(scheduled: activityFunctions, restartTime: _restartTime, orchestratorStartedIsProcessed: false),
                CreateOrchestratorStartedHistory(startTime: _shouldNotHitTime, isProcessed: false)
                );
            OrchestrationContext context = new OrchestrationContext {
                History = history, CurrentUtcDateTime = _startTime
            };
            var tasksToWaitFor = new ReadOnlyCollection <ActivityInvocationTask>(
                new[] { "FunctionA", "FunctionB", "FunctionC" }.Select(name => new ActivityInvocationTask(name, FunctionInput)).ToArray());
            var durableTaskHandler = new DurableTaskHandler();
            var allOutput          = new List <object>();

            if (!anyCompleted)
            {
                DurableTestUtilities.EmulateStop(durableTaskHandler);
            }

            durableTaskHandler.WaitAny(tasksToWaitFor, context, output => allOutput.Add(output));

            if (anyCompleted)
            {
                Assert.Equal(_restartTime, context.CurrentUtcDateTime);
            }
            else
            {
                Assert.Equal(_startTime, context.CurrentUtcDateTime);
            }
        }