コード例 #1
0
        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);
        }
コード例 #2
0
        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));
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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));
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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));
        }
コード例 #14
0
        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));
        }
コード例 #15
0
        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));
        }
コード例 #16
0
        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));
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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(_ => _));
        }
コード例 #19
0
        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);
            }
        }
コード例 #20
0
        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>));
        }