public void CanSubmitAndRunAWorkflowWithTypedTasks()
        {
            var db = _mux.GetDatabase();

            db.ScriptEvaluate("print(\"CanSubmitAndRunAWorkflow\")");
            db.ScriptEvaluate("redis.call(\"flushdb\")");

            var th = new TestTaskHandler();

            var complete = new ManualResetEvent(false);

            var events = new List <string>();

            var wh = new WorkflowHandler();

            wh.WorkflowComplete += (s, w) => { events.Add("complete"); complete.Set(); };

            var type1 = new TaskType("testTaskType");
            var type2 = new TaskType("testTaskType2");

            using (var wm = new WorkflowManagement(_mux, th, wh, new WorkflowManagementId("test"), new[] { type1 }, new Lua()))
                using (var wm2 = new WorkflowManagement(_mux, th, wh, new WorkflowManagementId("test2"), new[] { type2 }, new Lua()))
                {
                    var t1 = new TaskName("TestNode1");
                    var t2 = new TaskName("TestNode2");
                    var t3 = new TaskName("TestNode3");
                    var t4 = new TaskName("TestNode4");
                    var t5 = new TaskName("TestNode5");
                    var t6 = new TaskName("TestNode6");

                    var workflow = new Workflow(new WorkflowName("TestWorkflow"));
                    workflow.AddTask(t1, new Payload("Node1"), type1, SimplePriority, EmptyTaskList, new[] { t2 });
                    workflow.AddTask(t2, new Payload("Node2"), type1, SimplePriority, new[] { t1 }, new[] { t3, t4, t5, t6 });
                    workflow.AddTask(t3, new Payload("Node3"), type2, SimplePriority, new[] { t2 }, EmptyTaskList);
                    workflow.AddTask(t4, new Payload("Node4"), type1, SimplePriority, new[] { t2 }, EmptyTaskList);
                    workflow.AddTask(t5, new Payload("Node5"), type2, SimplePriority, new[] { t2 }, EmptyTaskList);
                    workflow.AddTask(t6, new Payload("Node6"), type1, SimplePriority, new[] { t2 }, EmptyTaskList);

                    wm.PushWorkflow(workflow);

                    var workflowWasCompleted = complete.WaitOne(2000);

                    Assert.IsTrue(workflowWasCompleted);

                    Console.WriteLine("WM events"); foreach (var ev in events)
                    {
                        Console.WriteLine("Event: " + ev);
                    }

                    Assert.AreEqual(6, th.TaskRunCount);
                }
        }
        public void RunsTasksInPriorityOrder()
        {
            var db = _mux.GetDatabase();

            db.ScriptEvaluate("print(\"CanSubmitAndRunAWorkflow\")");
            db.ScriptEvaluate("redis.call(\"flushdb\")");

            var th = new TestTaskHandler();

            var complete = new ManualResetEvent(false);

            var events = new List <string>();

            var wh = new WorkflowHandler();

            wh.WorkflowComplete += (s, w) => { events.Add("complete"); complete.Set(); };

            using (var wm = new WorkflowManagement(_mux, th, wh, new WorkflowManagementId("test"), null, new Lua()))
            {
                var workflow = new Workflow(new WorkflowName("TestWorkflow"));
                workflow.AddTask(new TaskName("TestNode1"), new Payload("Node1"), NoType, new TaskPriority(3), EmptyTaskList, EmptyTaskList);
                workflow.AddTask(new TaskName("TestNode2"), new Payload("Node2"), NoType, new TaskPriority(2), EmptyTaskList, EmptyTaskList);
                workflow.AddTask(new TaskName("TestNode3"), new Payload("Node3"), NoType, new TaskPriority(1), EmptyTaskList, EmptyTaskList);
                workflow.AddTask(new TaskName("TestNode4"), new Payload("Node4"), NoType, new TaskPriority(4), EmptyTaskList, EmptyTaskList);
                workflow.AddTask(new TaskName("TestNode5"), new Payload("Node5"), NoType, new TaskPriority(6), EmptyTaskList, EmptyTaskList);
                workflow.AddTask(new TaskName("TestNode6"), new Payload("Node6"), NoType, new TaskPriority(5), EmptyTaskList, EmptyTaskList);

                wm.PushWorkflow(workflow);

                var workflowWasCompleted = complete.WaitOne(2000);

                Assert.IsTrue(workflowWasCompleted);

                Console.WriteLine("WM events"); foreach (var ev in events)
                {
                    Console.WriteLine("Event: " + ev);
                }

                Assert.AreEqual(6, th.TaskRunCount);
                Assert.AreEqual("Node3", th.Payloads[0]);
                Assert.AreEqual("Node2", th.Payloads[1]);
                Assert.AreEqual("Node1", th.Payloads[2]);
                Assert.AreEqual("Node4", th.Payloads[3]);
                Assert.AreEqual("Node6", th.Payloads[4]);
                Assert.AreEqual("Node5", th.Payloads[5]);
            }
        }
        public void HandlesExceptionsFromBadLuaInASucceedingWorkflow()
        {
            var cases = new[] { TestCase.PopTask, TestCase.CompleteTask, TestCase.PopCompleteWorkflow };

            foreach (var testCase in cases)
            {
                var lua = new BadLua(testCase);

                var message = "HandlesExceptionsFromBadLuaInASucceedingWorkflow:" + testCase;

                var db = _mux.GetDatabase();
                db.ScriptEvaluate("print(\"" + message + "\")");
                db.ScriptEvaluate("redis.call(\"flushdb\")");

                var th = new TestTaskHandler();

                var complete  = new ManualResetEvent(false);
                var failed    = new ManualResetEvent(false);
                var exception = new ManualResetEvent(false);

                var events = new List <string>();

                var wh = new WorkflowHandler();
                wh.WorkflowComplete += (s, w) => { events.Add("complete"); complete.Set(); };
                wh.WorkflowFailed   += (s, w) => { events.Add("failed"); failed.Set(); };

                EventHandler <Exception> eh = (s, e) => { events.Add(e.Message); exception.Set(); };

                using (var wm = new WorkflowManagement(_mux, th, wh, new WorkflowManagementId("test"), null, lua, eh, Behaviours.Processor | Behaviours.Submitter))
                {
                    var workflow = new Workflow(new WorkflowName("TestWorkflow"));
                    workflow.AddTask(new TaskName("TestNode1"), new Payload("Node1"), new TaskType(""), new TaskPriority(1), new TaskName[0], new TaskName[0]);

                    wm.PushWorkflow(workflow);

                    var waitResult = WaitHandle.WaitAny(new[] { exception, failed, complete }, 2000);

                    Assert.AreEqual(0, waitResult);
                }
            }
        }
        public void CanCleanUpAfterAWorkflow()
        {
            var db = _mux.GetDatabase();
            db.ScriptEvaluate("print(\"CanCleanUpAfterAWorkflow\")");
            db.ScriptEvaluate("redis.call(\"flushdb\")");

            var th = new TestTaskHandler();

            var complete = new ManualResetEvent(false);

            var wh = new WorkflowHandler();
            wh.WorkflowComplete += (s, w) => { complete.Set(); };

            using (var wm = new WorkflowManagement(_mux, th, wh, new WorkflowManagementId("test"), null, new Lua()))
            {
                var t1 = new TaskName("TestNode1");
                var t2 = new TaskName("TestNode2");
                var t3 = new TaskName("TestNode3");
                var t4 = new TaskName("TestNode4");
                var t5 = new TaskName("TestNode5");
                var t6 = new TaskName("TestNode6");

                var workflow = new Workflow(new WorkflowName("TestWorkflow"));
                workflow.AddTask(t1, new Payload("Node1"), NoType, SimplePriority, EmptyTaskList, new[] { t2 });
                workflow.AddTask(t2, new Payload("Node2"), NoType, SimplePriority, new[] { t1 }, new[] { t3, t4, t5, t6 });
                workflow.AddTask(t3, new Payload("Node3"), NoType, SimplePriority, new[] { t2 }, EmptyTaskList);
                workflow.AddTask(t4, new Payload("Node4"), NoType, SimplePriority, new[] { t2 }, EmptyTaskList);
                workflow.AddTask(t5, new Payload("Node5"), NoType, SimplePriority, new[] { t2 }, EmptyTaskList);
                workflow.AddTask(t6, new Payload("Node6"), NoType, SimplePriority, new[] { t2 }, EmptyTaskList);

                var workflowId = wm.PushWorkflow(workflow);

                var workflowCompleted = complete.WaitOne(2000); // machine-performance dependent, but 2 seconds is a long time

                Assert.IsTrue(workflowCompleted);

                var info = wm.FetchWorkflowInformation(workflowId.ToString());

                Assert.AreEqual("1", info.Id);
                Assert.AreEqual(6, info.Tasks.Count);

                wm.CleanUp(workflowId.ToString());

                db = _mux.GetDatabase();
                for (var t = 0; t < 6; t++)
                {
                    Assert.IsFalse(db.KeyExists("task:" + t));
                    Assert.IsFalse(db.KeyExists("parents-" + t));
                    Assert.IsFalse(db.KeyExists("children-" + t));
                    Assert.IsFalse(db.SetContains("tasks", t));
                    Assert.IsFalse(db.SetContains("submitted", t));
                    Assert.IsFalse(db.SetContains("complete", t));
                    Assert.IsFalse(db.SetContains("failed", t));
                    Assert.IsFalse(db.SetContains("abandoned", t));
                    Assert.AreEqual(0, db.ListRemove("running", t));
                }
                Assert.AreEqual(0, db.ListRemove("workflowComplete", "1"));
                Assert.AreEqual(0, db.ListRemove("workflowFailed", "1"));
                Assert.IsFalse(db.KeyExists("workflow-tasks-1"));
                Assert.IsFalse(db.KeyExists("workflow-remaining-1"));
                Assert.IsFalse(db.SetContains("workflows", "1"));
                Assert.IsFalse(db.KeyExists("submitted:1"));
                Assert.IsFalse(db.KeyExists("running:1"));
            }
        }
        public void CanSubmitAndRunAWorkflowWithTypedTasks()
        {
            var db = _mux.GetDatabase();
            db.ScriptEvaluate("print(\"CanSubmitAndRunAWorkflow\")");
            db.ScriptEvaluate("redis.call(\"flushdb\")");

            var th = new TestTaskHandler();

            var complete = new ManualResetEvent(false);

            var events = new List<string>();

            var wh = new WorkflowHandler();
            wh.WorkflowComplete += (s, w) => { events.Add("complete"); complete.Set(); };

            var type1 = new TaskType("testTaskType");
            var type2 = new TaskType("testTaskType2");

            using (var wm = new WorkflowManagement(_mux, th, wh, new WorkflowManagementId("test"), new[] { type1 }, new Lua()))
            using (var wm2 = new WorkflowManagement(_mux, th, wh, new WorkflowManagementId("test2"), new[] { type2 }, new Lua()))
            {
                var t1 = new TaskName("TestNode1");
                var t2 = new TaskName("TestNode2");
                var t3 = new TaskName("TestNode3");
                var t4 = new TaskName("TestNode4");
                var t5 = new TaskName("TestNode5");
                var t6 = new TaskName("TestNode6");
                
                var workflow = new Workflow(new WorkflowName("TestWorkflow"));
                workflow.AddTask(t1, new Payload("Node1"), type1, SimplePriority, EmptyTaskList, new[] { t2 });
                workflow.AddTask(t2, new Payload("Node2"), type1, SimplePriority, new[] { t1 }, new[] { t3, t4, t5, t6 });
                workflow.AddTask(t3, new Payload("Node3"), type2, SimplePriority, new[] { t2 }, EmptyTaskList);
                workflow.AddTask(t4, new Payload("Node4"), type1, SimplePriority, new[] { t2 }, EmptyTaskList);
                workflow.AddTask(t5, new Payload("Node5"), type2, SimplePriority, new[] { t2 }, EmptyTaskList);
                workflow.AddTask(t6, new Payload("Node6"), type1, SimplePriority, new[] { t2 }, EmptyTaskList);

                wm.PushWorkflow(workflow);

                var workflowWasCompleted = complete.WaitOne(2000);

                Assert.IsTrue(workflowWasCompleted);

                Console.WriteLine("WM events"); foreach (var ev in events) Console.WriteLine("Event: " + ev);

                Assert.AreEqual(6, th.TaskRunCount);
            }
        }
        public void RunsTasksInPriorityOrder()
        {
            var db = _mux.GetDatabase();
            db.ScriptEvaluate("print(\"CanSubmitAndRunAWorkflow\")");
            db.ScriptEvaluate("redis.call(\"flushdb\")");

            var th = new TestTaskHandler();

            var complete = new ManualResetEvent(false);

            var events = new List<string>();

            var wh = new WorkflowHandler();
            wh.WorkflowComplete += (s, w) => { events.Add("complete"); complete.Set(); };

            using (var wm = new WorkflowManagement(_mux, th, wh, new WorkflowManagementId("test"), null, new Lua()))
            {
                var workflow = new Workflow(new WorkflowName("TestWorkflow"));
                workflow.AddTask(new TaskName("TestNode1"), new Payload("Node1"), NoType, new TaskPriority(3), EmptyTaskList, EmptyTaskList);
                workflow.AddTask(new TaskName("TestNode2"), new Payload("Node2"), NoType, new TaskPriority(2), EmptyTaskList, EmptyTaskList);
                workflow.AddTask(new TaskName("TestNode3"), new Payload("Node3"), NoType, new TaskPriority(1), EmptyTaskList, EmptyTaskList);
                workflow.AddTask(new TaskName("TestNode4"), new Payload("Node4"), NoType, new TaskPriority(4), EmptyTaskList, EmptyTaskList);
                workflow.AddTask(new TaskName("TestNode5"), new Payload("Node5"), NoType, new TaskPriority(6), EmptyTaskList, EmptyTaskList);
                workflow.AddTask(new TaskName("TestNode6"), new Payload("Node6"), NoType, new TaskPriority(5), EmptyTaskList, EmptyTaskList);

                wm.PushWorkflow(workflow);

                var workflowWasCompleted = complete.WaitOne(2000);

                Assert.IsTrue(workflowWasCompleted);

                Console.WriteLine("WM events"); foreach (var ev in events) Console.WriteLine("Event: " + ev);

                Assert.AreEqual(6, th.TaskRunCount);
                Assert.AreEqual("Node3", th.Payloads[0]);
                Assert.AreEqual("Node2", th.Payloads[1]);
                Assert.AreEqual("Node1", th.Payloads[2]);
                Assert.AreEqual("Node4", th.Payloads[3]);
                Assert.AreEqual("Node6", th.Payloads[4]);
                Assert.AreEqual("Node5", th.Payloads[5]);
            }
        }
        public void HandlesExceptionsFromBadLuaInASucceedingWorkflow()
        {
            var cases = new[] { TestCase.PopTask, TestCase.CompleteTask, TestCase.PopCompleteWorkflow };

            foreach (var testCase in cases)
            {
                var lua = new BadLua(testCase);

                var message = "HandlesExceptionsFromBadLuaInASucceedingWorkflow:" + testCase;

                var db = _mux.GetDatabase();
                db.ScriptEvaluate("print(\"" + message + "\")");
                db.ScriptEvaluate("redis.call(\"flushdb\")");

                var th = new TestTaskHandler();

                var complete = new ManualResetEvent(false);
                var failed = new ManualResetEvent(false);
                var exception = new ManualResetEvent(false);

                var events = new List<string>();

                var wh = new WorkflowHandler();
                wh.WorkflowComplete += (s, w) => { events.Add("complete"); complete.Set(); };
                wh.WorkflowFailed += (s, w) => { events.Add("failed"); failed.Set(); };

                EventHandler<Exception> eh = (s, e) => { events.Add(e.Message); exception.Set(); };

                using (var wm = new WorkflowManagement(_mux, th, wh, new WorkflowManagementId("test"), null, lua, eh, Behaviours.Processor | Behaviours.Submitter))
                {
                    var workflow = new Workflow(new WorkflowName("TestWorkflow"));
                    workflow.AddTask(new TaskName("TestNode1"), new Payload("Node1"), new TaskType(""), new TaskPriority(1), new TaskName[0], new TaskName[0]);

                    wm.PushWorkflow(workflow);

                    var waitResult = WaitHandle.WaitAny(new[] { exception, failed, complete }, 2000);

                    Assert.AreEqual(0, waitResult);
                }
            }
        }
Пример #8
0
        public void CanCleanUpAfterAWorkflow()
        {
            var db = _mux.GetDatabase();
            db.ScriptEvaluate("print(\"CanCleanUpAfterAWorkflow\")");
            db.ScriptEvaluate("redis.call(\"flushdb\")");

            var th = new TestTaskHandler();

            var complete = new ManualResetEvent(false);

            var wh = new WorkflowHandler();
            wh.WorkflowComplete += (s, w) => { complete.Set(); };

            using (var wm = new WorkflowManagement(_mux, th, wh, "test", null, new Lua()))
            {
                var workflowName = "TestWorkflow";

                var tasks = new List<Task>();
                tasks.Add(new Task { Type = "", Name = "TestNode1", Payload = "Node1", Parents = new string[] { }, Children = new string[] { "TestNode2" }, Workflow = workflowName });
                tasks.Add(new Task { Type = "", Name = "TestNode2", Payload = "Node2", Parents = new string[] { "TestNode1" }, Children = new string[] { "TestNode3", "TestNode4", "TestNode5", "TestNode6" }, Workflow = workflowName });
                tasks.Add(new Task { Type = "", Name = "TestNode3", Payload = "Node3", Parents = new string[] { "TestNode2" }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Type = "", Name = "TestNode4", Payload = "Node4", Parents = new string[] { "TestNode2" }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Type = "", Name = "TestNode5", Payload = "Node5", Parents = new string[] { "TestNode2" }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Type = "", Name = "TestNode6", Payload = "Node6", Parents = new string[] { "TestNode2" }, Children = new string[] { }, Workflow = workflowName });

                var workflow = new Workflow { Name = workflowName, Tasks = tasks };

                var workflowId = wm.PushWorkflow(workflow);

                var workflowCompleted = complete.WaitOne(2000); // machine-performance dependent, but 2 seconds is a long time

                Assert.IsTrue(workflowCompleted);

                var info = wm.FetchWorkflowInformation(workflowId.ToString());

                Assert.AreEqual("1", info.Id);
                Assert.AreEqual(6, info.Tasks.Count);

                wm.CleanUp(workflowId.ToString());

                db = _mux.GetDatabase();
                for (var t = 0; t < 6; t++)
                {
                    Assert.IsFalse(db.KeyExists("task:" + t));
                    Assert.IsFalse(db.KeyExists("parents-" + t));
                    Assert.IsFalse(db.KeyExists("children-" + t));
                    Assert.IsFalse(db.SetContains("tasks", t));
                    Assert.IsFalse(db.SetContains("submitted", t));
                    Assert.IsFalse(db.SetContains("complete", t));
                    Assert.IsFalse(db.SetContains("failed", t));
                    Assert.IsFalse(db.SetContains("abandoned", t));
                    Assert.AreEqual(0, db.ListRemove("running", t));
                }
                Assert.AreEqual(0, db.ListRemove("workflowComplete", "1"));
                Assert.AreEqual(0, db.ListRemove("workflowFailed", "1"));
                Assert.IsFalse(db.KeyExists("workflow-tasks-1"));
                Assert.IsFalse(db.KeyExists("workflow-remaining-1"));
                Assert.IsFalse(db.SetContains("workflows", "1"));
                Assert.IsFalse(db.KeyExists("submitted:1"));
                Assert.IsFalse(db.KeyExists("running:1"));
            }
        }
Пример #9
0
        public void CanSubmitAndRunAWorkflowWithTypedTasks()
        {
            var db = _mux.GetDatabase();
            db.ScriptEvaluate("print(\"CanSubmitAndRunAWorkflow\")");
            db.ScriptEvaluate("redis.call(\"flushdb\")");

            var th = new TestTaskHandler();

            var complete = new ManualResetEvent(false);

            var events = new List<string>();

            var wh = new WorkflowHandler();
            wh.WorkflowComplete += (s, w) => { events.Add("complete"); complete.Set(); };

            using (var wm = new WorkflowManagement(_mux, th, wh, "test", new[] { "testTaskType" }, new Lua()))
            using (var wm2 = new WorkflowManagement(_mux, th, wh, "test2", new[] { "testTaskType2" }, new Lua()))
            {
                var workflowName = "TestWorkflow";

                var tasks = new List<Task>();
                tasks.Add(new Task { Type = "testTaskType", Name = "TestNode1", Payload = "Node1", Parents = new string[] { }, Children = new string[] { "TestNode2" }, Workflow = workflowName });
                tasks.Add(new Task { Type = "testTaskType", Name = "TestNode2", Payload = "Node2", Parents = new string[] { "TestNode1" }, Children = new string[] { "TestNode3", "TestNode4", "TestNode5", "TestNode6" }, Workflow = workflowName });
                tasks.Add(new Task { Type = "testTaskType2", Name = "TestNode3", Payload = "Node3", Parents = new string[] { "TestNode2" }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Type = "testTaskType", Name = "TestNode4", Payload = "Node4", Parents = new string[] { "TestNode2" }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Type = "testTaskType2", Name = "TestNode5", Payload = "Node5", Parents = new string[] { "TestNode2" }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Type = "testTaskType", Name = "TestNode6", Payload = "Node6", Parents = new string[] { "TestNode2" }, Children = new string[] { }, Workflow = workflowName });

                var workflow = new Workflow { Name = workflowName, Tasks = tasks };

                wm.PushWorkflow(workflow);

                var workflowWasCompleted = complete.WaitOne(2000);

                Assert.IsTrue(workflowWasCompleted);

                Console.WriteLine("WM events"); foreach (var ev in events) Console.WriteLine("Event: " + ev);

                Assert.AreEqual(6, th.TaskRunCount);
            }
        }
Пример #10
0
        public void RunsTasksInPriorityOrder()
        {
            var db = _mux.GetDatabase();
            db.ScriptEvaluate("print(\"CanSubmitAndRunAWorkflow\")");
            db.ScriptEvaluate("redis.call(\"flushdb\")");

            var th = new TestTaskHandler();

            var complete = new ManualResetEvent(false);

            var events = new List<string>();

            var wh = new WorkflowHandler();
            wh.WorkflowComplete += (s, w) => { events.Add("complete"); complete.Set(); };

            using (var wm = new WorkflowManagement(_mux, th, wh, "test", null, new Lua()))
            {
                var workflowName = "TestWorkflow";

                // 6 independent tasks in this workflow
                var tasks = new List<Task>();
                tasks.Add(new Task { Priority = 3, Type = "", Name = "TestNode1", Payload = "Node1", Parents = new string[] { }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Priority = 2, Type = "", Name = "TestNode2", Payload = "Node2", Parents = new string[] { }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Priority = 1, Type = "", Name = "TestNode3", Payload = "Node3", Parents = new string[] { }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Priority = 4, Type = "", Name = "TestNode4", Payload = "Node4", Parents = new string[] { }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Priority = 6, Type = "", Name = "TestNode5", Payload = "Node5", Parents = new string[] { }, Children = new string[] { }, Workflow = workflowName });
                tasks.Add(new Task { Priority = 5, Type = "", Name = "TestNode6", Payload = "Node6", Parents = new string[] { }, Children = new string[] { }, Workflow = workflowName });

                var workflow = new Workflow { Name = workflowName, Tasks = tasks };

                wm.PushWorkflow(workflow);

                var workflowWasCompleted = complete.WaitOne(2000);

                Assert.IsTrue(workflowWasCompleted);

                Console.WriteLine("WM events"); foreach (var ev in events) Console.WriteLine("Event: " + ev);

                Assert.AreEqual(6, th.TaskRunCount);
                Assert.AreEqual("Node3", th.Payloads[0]);
                Assert.AreEqual("Node2", th.Payloads[1]);
                Assert.AreEqual("Node1", th.Payloads[2]);
                Assert.AreEqual("Node4", th.Payloads[3]);
                Assert.AreEqual("Node6", th.Payloads[4]);
                Assert.AreEqual("Node5", th.Payloads[5]);
            }
        }
Пример #11
0
        public void HandlesExceptionsFromBadLuaInASucceedingWorkflow()
        {
            var cases = new[] { TestCase.PopTask, TestCase.CompleteTask, TestCase.PopCompleteWorkflow };

            foreach (var testCase in cases)
            {
                var lua = new BadLua(testCase);

                var message = "HandlesExceptionsFromBadLuaInASucceedingWorkflow:" + testCase;

                var db = _mux.GetDatabase();
                db.ScriptEvaluate("print(\"" + message + "\")");
                db.ScriptEvaluate("redis.call(\"flushdb\")");

                var th = new TestTaskHandler();

                var complete = new ManualResetEvent(false);
                var failed = new ManualResetEvent(false);
                var exception = new ManualResetEvent(false);

                var events = new List<string>();

                var wh = new WorkflowHandler();
                wh.WorkflowComplete += (s, w) => { events.Add("complete"); complete.Set(); };
                wh.WorkflowFailed += (s, w) => { events.Add("failed"); failed.Set(); };

                EventHandler<Exception> eh = (s, e) => { events.Add(e.Message); exception.Set(); };

                using (var wm = new WorkflowManagement(_mux, th, wh, "test", null, lua, eh, Behaviours.Processor | Behaviours.Submitter))
                {
                    var workflowName = "TestWorkflow";

                    var tasks = new List<Task>();
                    tasks.Add(new Task { Type = "", Name = "TestNode1", Payload = "Node1", Parents = new string[] { }, Children = new string[] { }, Workflow = workflowName }); // TODO what happens if we reference children that don't exist?

                    var workflow = new Workflow { Name = workflowName, Tasks = tasks };

                    wm.PushWorkflow(workflow);

                    var waitResult = WaitHandle.WaitAny(new[] { exception, failed, complete }, 2000);

                    Assert.AreEqual(0, waitResult);
                }
            }
        }
        public void CanCleanUpAfterAWorkflow()
        {
            var db = _mux.GetDatabase();

            db.ScriptEvaluate("print(\"CanCleanUpAfterAWorkflow\")");
            db.ScriptEvaluate("redis.call(\"flushdb\")");

            var th = new TestTaskHandler();

            var complete = new ManualResetEvent(false);

            var wh = new WorkflowHandler();

            wh.WorkflowComplete += (s, w) => { complete.Set(); };

            using (var wm = new WorkflowManagement(_mux, th, wh, new WorkflowManagementId("test"), null, new Lua()))
            {
                var t1 = new TaskName("TestNode1");
                var t2 = new TaskName("TestNode2");
                var t3 = new TaskName("TestNode3");
                var t4 = new TaskName("TestNode4");
                var t5 = new TaskName("TestNode5");
                var t6 = new TaskName("TestNode6");

                var workflow = new Workflow(new WorkflowName("TestWorkflow"));
                workflow.AddTask(t1, new Payload("Node1"), NoType, SimplePriority, EmptyTaskList, new[] { t2 });
                workflow.AddTask(t2, new Payload("Node2"), NoType, SimplePriority, new[] { t1 }, new[] { t3, t4, t5, t6 });
                workflow.AddTask(t3, new Payload("Node3"), NoType, SimplePriority, new[] { t2 }, EmptyTaskList);
                workflow.AddTask(t4, new Payload("Node4"), NoType, SimplePriority, new[] { t2 }, EmptyTaskList);
                workflow.AddTask(t5, new Payload("Node5"), NoType, SimplePriority, new[] { t2 }, EmptyTaskList);
                workflow.AddTask(t6, new Payload("Node6"), NoType, SimplePriority, new[] { t2 }, EmptyTaskList);

                var workflowId = wm.PushWorkflow(workflow);

                var workflowCompleted = complete.WaitOne(2000); // machine-performance dependent, but 2 seconds is a long time

                Assert.IsTrue(workflowCompleted);

                var info = wm.FetchWorkflowInformation(workflowId.ToString());

                Assert.AreEqual("1", info.Id);
                Assert.AreEqual(6, info.Tasks.Count);

                wm.CleanUp(workflowId.ToString());

                db = _mux.GetDatabase();
                for (var t = 0; t < 6; t++)
                {
                    Assert.IsFalse(db.KeyExists("task:" + t));
                    Assert.IsFalse(db.KeyExists("parents-" + t));
                    Assert.IsFalse(db.KeyExists("children-" + t));
                    Assert.IsFalse(db.SetContains("tasks", t));
                    Assert.IsFalse(db.SetContains("submitted", t));
                    Assert.IsFalse(db.SetContains("complete", t));
                    Assert.IsFalse(db.SetContains("failed", t));
                    Assert.IsFalse(db.SetContains("abandoned", t));
                    Assert.AreEqual(0, db.ListRemove("running", t));
                }
                Assert.AreEqual(0, db.ListRemove("workflowComplete", "1"));
                Assert.AreEqual(0, db.ListRemove("workflowFailed", "1"));
                Assert.IsFalse(db.KeyExists("workflow-tasks-1"));
                Assert.IsFalse(db.KeyExists("workflow-remaining-1"));
                Assert.IsFalse(db.SetContains("workflows", "1"));
                Assert.IsFalse(db.KeyExists("submitted:1"));
                Assert.IsFalse(db.KeyExists("running:1"));
            }
        }