public async Task TestActivity() { Func<int, int> pow = x => x*x; var activity = new ActivityBlock(pow); var workflow = new Workflow<int, int>("test", activity); var output = await WorkflowRunner.Run(workflow, 2); Assert.Equal(4, output); }
public async Task MethodWithReturnValue() { Func<int> func = () => 1; var workItem = new WorkItem {JobId = Helpers.Integer()}; var activity = new ActivityBlock(func); _workflowPathNavigator.Find(null).ReturnsForAnyArgs(activity); await _activityRunner.Run(workItem); _dataStore.Received(1).Add(workItem.JobId, 1, typeof (int)); }
public async Task CheckPostConditionWhenSuccess() { Action action = delegate { }; var workItem = new WorkItem(); var activity = new ActivityBlock(action); _workflowPathNavigator.Find(null).ReturnsForAnyArgs(activity); await _activityRunner.Run(workItem); Assert.Equal(WorkItemStatus.Completed, workItem.Status); _repository.Received().Update(Arg.Is<WorkItem>(_ => _.Status == WorkItemStatus.Completed)); }
public async Task IgnoringInput() { var invoked = false; Action action = delegate { invoked = true; }; var workItem = new WorkItem {InputId = Helpers.Integer()}; var activity = new ActivityBlock(action); _workflowPathNavigator.Find(null).ReturnsForAnyArgs(activity); await _activityRunner.Run(workItem); Assert.True(invoked); }
public async Task MethodWithNoArgumentAndReturnValue() { var invoked = false; Action action = delegate { invoked = true; }; var workItem = new WorkItem(); var activity = new ActivityBlock(action); _workflowPathNavigator.Find(null).ReturnsForAnyArgs(activity); await _activityRunner.Run(workItem); Assert.True(invoked); }
public async Task MethodWithSingleArgument() { Func<int, int> identity = i => i; var workItem = new WorkItem {JobId = Helpers.Integer(), InputId = Helpers.Integer()}; var activity = new ActivityBlock(identity); _workflowPathNavigator.Find(null).ReturnsForAnyArgs(activity); _dataStore.Get(workItem.InputId.Value).Returns(2); await _activityRunner.Run(workItem); _dataStore.Received(1).Add(workItem.JobId, 2, typeof (int)); }
public async Task TestFork() { Func<int, int> twice = x => 2*x; var activity = new ActivityBlock(twice); var fork = new ForkBlock(activity, 2); var workflow = new Workflow<int[], IEnumerable<int>>("test", fork); var output = await WorkflowRunner.Run(workflow, new[] {1, 2, 3}); //int[] would work but not recommended Assert.Equal(new[] {2, 4, 6}, output); }
public async Task TestSequence() { Func<int, int> increment = x => x + 1; var a1 = new ActivityBlock(increment); var a2 = new ActivityBlock(increment); var seq = new SequenceBlock(new[] {a1, a2}); var workflow = new Workflow<int, int>("test", seq); var output = await WorkflowRunner.Run(workflow, 0); Assert.Equal(2, output); }
public async Task TestAsync() { Func<int, Task<int>> identity = async x => { await Task.Delay(100); return x; }; var activity = new ActivityBlock(identity); var workflow = new Workflow<int, int>("test", activity); var output = await WorkflowRunner.Run(workflow, 1); Assert.Equal(1, output); }
public void ActivityConstruction() { Func<int, int, string> add = (x, y) => string.Format("{0} + {1} = {2}", x, y, x + y); var activity = new ActivityBlock(add); Assert.Equal(WorkflowType.Activity, activity.Type); Assert.Equal(new[] {typeof (int), typeof (int)}, activity.InputTypes); Assert.Equal(typeof (string), activity.OutputType); // test method with signature void(void) activity = new ActivityBlock(new Action(delegate { })); Assert.False(activity.InputTypes.Any()); Assert.Equal(typeof (void), activity.OutputType); }
public async Task TestExceptionPropagation() { Func<int, int> increment = x => x + 1; Func<int, int> divide = x => 1/x; var a1 = new ActivityBlock(increment); var a2 = new ActivityBlock(divide); var seq = new SequenceBlock(new[] {new SequenceBlock(new[] {a1, a2})}) { ExceptionHandler = (Func<Exception, int>) (_ => -1) }; var workflow = new Workflow<int, int>("test", seq); var output = await WorkflowRunner.Run(workflow, -1); Assert.Equal(-1, output); }
public async Task TestExceptionHandling() { Func<int, int> divide = x => 1/x; var activity = new ActivityBlock(divide); activity.ExceptionHandler = (Func<Exception, int>) (_ => -1); var workflow = new Workflow<int, int>("test", activity); var output = await WorkflowRunner.Run(workflow, 0); Assert.Equal(-1, output); }
public async Task TestAsyncMethod() { Func<Task<int>> oneInFuture = () => Task.FromResult(1); var workItem = new WorkItem(); var activity = new ActivityBlock(oneInFuture); _workflowPathNavigator.Find(null).ReturnsForAnyArgs(activity); await _activityRunner.Run(workItem); _dataStore.Received(1).Add(workItem.JobId, 1, typeof (int)); }
public async Task RecordsExceptionIfItHasNotDefinedHandler() { var divider = 0; Func<int> divide = () => 1/divider; var workItem = new WorkItem {JobId = Helpers.Integer()}; var activity = new ActivityBlock(divide); _workflowPathNavigator.Find(null).ReturnsForAnyArgs(activity); await _activityRunner.Run(workItem); Assert.Equal(WorkItemStatus.Failed, workItem.Status); _dataStore.Received(1).Add(workItem.JobId, Arg.Any<DivideByZeroException>(), typeof (DivideByZeroException)); _repository.Received().Update(Arg.Is<WorkItem>(_ => _.Status == WorkItemStatus.Failed)); }
public async Task TestExceptionHandling() { var divider = 0; Func<int> divide = () => 1/divider; var workItem = new WorkItem {JobId = Helpers.Integer()}; var activity = new ActivityBlock(divide); _workflowPathNavigator.Find(null).ReturnsForAnyArgs(activity); Exception exception = null; activity.ExceptionHandler = (Func<Exception, int>) (ex => { exception = ex; return -1; }); await _activityRunner.Run(workItem); Assert.True(exception is DivideByZeroException); _dataStore.Received(1).Add(workItem.JobId, -1, typeof (int)); Assert.Equal(WorkItemStatus.Completed, workItem.Status); _repository.Received().Update(Arg.Is<WorkItem>(_ => _.Status == WorkItemStatus.Completed)); }
public async Task MethodWithMultipleArguments() { Func<int, int, int> add = (x, y) => x + y; var workItem = new WorkItem {JobId = Helpers.Integer(), InputId = Helpers.Integer()}; var activity = new ActivityBlock(add); _workflowPathNavigator.Find(null).ReturnsForAnyArgs(activity); _dataStore.Get(workItem.InputId.Value).Returns(new object[] {1, 2}); await _activityRunner.Run(workItem); _dataStore.Received(1).Add(workItem.JobId, 3, typeof (int)); }
public async Task TestLargeChunckOfFork() { Func<int, int> identity = x => x; var activity = new ActivityBlock(identity); var fork = new ForkBlock(activity, 1); var workflow = new Workflow<IEnumerable<int>, IEnumerable<int>>("test", fork); var input = Enumerable.Repeat(1, 1000).ToArray(); var output = await WorkflowRunner.Run(workflow, input); //int[] would work but not recommended Assert.Equal(input, output); }
public async Task TestChainedFork() { Func<int, int> identity = x => x; var activity = new ActivityBlock(identity); var fork = new ForkBlock(new ForkBlock(new ForkBlock(activity, 1), 1), 1); var workflow = new Workflow<int[][][], IEnumerable<IEnumerable<IEnumerable<int>>>>("test", fork); var output = await WorkflowRunner.Run(workflow, new[] {new[] {new[] {1}}}); Assert.Equal(new[] {1}, output.SelectMany(_ => _).SelectMany(_ => _)); }
async Task RunCore(WorkItem workItem, ActivityBlock activityBlock) { workItem.Status = WorkItemStatus.Running; _repository.Update(workItem); object output; var inputTypes = activityBlock.InputTypes.ToArray(); if (inputTypes.Length == 0) { if (activityBlock.IsAsync) { var task = (Task) activityBlock.Method.DynamicInvoke(); await task; output = task.GetResult(); } else { output = activityBlock.Method.DynamicInvoke(); } } else if (inputTypes.Length == 1) { var arg = _dataStore.Get(workItem.InputId.Value); if (inputTypes[0].IsTuple() && arg is object[]) // If output is array from parallel and input of continuation is Tuple { var ctor = inputTypes[0].GetConstructors().Single(); arg = ctor.Invoke((object[]) arg); } if (activityBlock.IsAsync) { var task = (Task) activityBlock.Method.DynamicInvoke(arg); await task; output = task.GetResult(); } else { output = activityBlock.Method.DynamicInvoke(arg); } } else { var args = (object[]) _dataStore.Get(workItem.InputId.Value); if (activityBlock.IsAsync) { var task = (Task) activityBlock.Method.DynamicInvoke(args); await task; output = task.GetResult(); } else { output = activityBlock.Method.DynamicInvoke(args); } } if (output != null) { workItem.OutputId = _dataStore.Add(workItem.JobId, output, activityBlock.OutputType); } }
public async Task MethodWithTupleInputAndOutputFromPreviousStepIsArray() { Func<Tuple<int, string>, Tuple<int, string>> identity = _ => _; var workItem = new WorkItem {JobId = Helpers.Integer(), InputId = Helpers.Integer()}; var activity = new ActivityBlock(identity); _workflowPathNavigator.Find(null).ReturnsForAnyArgs(activity); _dataStore.Get(workItem.InputId.Value).Returns(new object[] {1, "a"}); await _activityRunner.Run(workItem); _dataStore.Received(1).Add(workItem.JobId, Tuple.Create(1, "a"), typeof (Tuple<int, string>)); }