ariatosca-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r..@apache.org
Subject incubator-ariatosca git commit: fixed test_task_graph
Date Mon, 07 Nov 2016 14:03:54 GMT
Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-3-api-for-creating-workflows ade7597c0 -> a62dd5fc0


fixed test_task_graph


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/a62dd5fc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/a62dd5fc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/a62dd5fc

Branch: refs/heads/ARIA-3-api-for-creating-workflows
Commit: a62dd5fc02d7484d04ba47289fe8916da8fc2901
Parents: ade7597
Author: Ran Ziv <ran@gigaspaces.com>
Authored: Mon Nov 7 16:03:39 2016 +0200
Committer: Ran Ziv <ran@gigaspaces.com>
Committed: Mon Nov 7 16:03:39 2016 +0200

----------------------------------------------------------------------
 aria/workflows/api/task_graph.py       |  12 +-
 tests/workflows/api/test_task_graph.py | 719 ++++++++++++++--------------
 2 files changed, 374 insertions(+), 357 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a62dd5fc/aria/workflows/api/task_graph.py
----------------------------------------------------------------------
diff --git a/aria/workflows/api/task_graph.py b/aria/workflows/api/task_graph.py
index 634a6e2..67b3dc4 100644
--- a/aria/workflows/api/task_graph.py
+++ b/aria/workflows/api/task_graph.py
@@ -153,12 +153,12 @@ class TaskGraph(object):
         """
         return_tasks = []
 
-        if len(tasks) > 1:
-            for sub_task in tasks:
-                return_tasks += self.remove_tasks(*sub_task)
-        elif self.has_tasks(tasks[0]):
-            self._graph.remove_node(tasks[0].id)
-            return_tasks.append(tasks[0])
+        for task in tasks:
+            if isinstance(task, Iterable):
+                return_tasks += self.remove_tasks(*task)
+            elif self.has_tasks(task):
+                self._graph.remove_node(task.id)
+                return_tasks.append(task)
 
         return return_tasks
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/a62dd5fc/tests/workflows/api/test_task_graph.py
----------------------------------------------------------------------
diff --git a/tests/workflows/api/test_task_graph.py b/tests/workflows/api/test_task_graph.py
index bfebd6c..3ff60a4 100644
--- a/tests/workflows/api/test_task_graph.py
+++ b/tests/workflows/api/test_task_graph.py
@@ -38,6 +38,28 @@ class TestTaskGraphTasks(object):
         assert len(tasks) == 1
         assert tasks[0] == task
 
+    def test_add_empty_group(self, graph):
+        result = graph.add_tasks([])
+        assert result == []
+
+    def test_add_group(self, graph):
+        tasks = [MockTask(), MockTask(), MockTask()]
+        added_tasks = graph.add_tasks(*tasks)
+        assert added_tasks == tasks
+
+    def test_add_partially_existing_group(self, graph):
+        task = MockTask()
+        graph.add_tasks(task)
+        tasks = [MockTask(), task, MockTask()]
+        added_tasks = graph.add_tasks(*tasks)
+        assert added_tasks == [tasks[0], tasks[2]]
+
+    def test_add_recursively_group(self, graph):
+        recursive_group = [MockTask(), MockTask()]
+        tasks = [MockTask(), recursive_group, MockTask()]
+        added_tasks = graph.add_tasks(tasks)
+        assert added_tasks == [tasks[0], recursive_group[0], recursive_group[1], tasks[2]]
+
     def test_add_existing_task(self, graph):
         task = MockTask()
         graph.add_tasks(task)
@@ -72,6 +94,30 @@ class TestTaskGraphTasks(object):
         # asserting no dependencies are left for the dependent task
         assert len(list(graph.get_dependencies(task))) == 0
 
+    def test_remove_empty_group(self, graph):
+        result = graph.remove_tasks([])
+        assert result == []
+
+    def test_remove_group(self, graph):
+        tasks = [MockTask(), MockTask(), MockTask()]
+        graph.add_tasks(*tasks)
+        removed_tasks = graph.remove_tasks(*tasks)
+        assert removed_tasks == tasks
+
+    def test_remove_partially_existing_group(self, graph):
+        task = MockTask()
+        graph.add_tasks(task)
+        tasks = [MockTask(), task, MockTask()]
+        removed_tasks = graph.remove_tasks(*tasks)
+        assert removed_tasks == [task]
+
+    def test_remove_recursively_group(self, graph):
+        recursive_group = [MockTask(), MockTask()]
+        tasks = [MockTask(), recursive_group, MockTask()]
+        graph.add_tasks(tasks)
+        removed_tasks = graph.remove_tasks(tasks)
+        assert removed_tasks == [tasks[0], recursive_group[0], recursive_group[1], tasks[2]]
+
     def test_remove_nonexistent_task(self, graph):
         task = MockTask()
         task_not_in_graph = MockTask()
@@ -94,6 +140,27 @@ class TestTaskGraphTasks(object):
         graph.add_tasks(task)
         assert graph.has_tasks(task_not_in_graph) is False
 
+    def test_has_empty_group(self, graph):
+        # the "empty task" is in the graph
+        assert graph.has_tasks([]) is True
+
+    def test_has_group(self, graph):
+        tasks = [MockTask(), MockTask(), MockTask()]
+        graph.add_tasks(*tasks)
+        assert graph.has_tasks(*tasks) is True
+
+    def test_has_partially_existing_group(self, graph):
+        task = MockTask()
+        graph.add_tasks(task)
+        tasks = [MockTask(), task, MockTask()]
+        assert graph.has_tasks(tasks) is False
+
+    def test_has_recursively_group(self, graph):
+        recursive_group = [MockTask(), MockTask()]
+        tasks = [MockTask(), recursive_group, MockTask()]
+        graph.add_tasks(tasks)
+        assert graph.has_tasks(tasks) is True
+
     def test_get_task(self, graph):
         task = MockTask()
         graph.add_tasks(task)
@@ -228,6 +295,77 @@ class TestTaskGraphDependencies(object):
         with pytest.raises(task_graph.TaskNotInGraphError):
             graph.add_dependency(task, task_not_in_graph)
 
+    def test_add_dependency_empty_dependent(self, graph):
+        task = MockTask()
+        graph.add_tasks(task)
+        # expecting add_dependency result to be False - no dependency has been created
+        assert graph.add_dependency([], task) is False
+
+    def test_add_dependency_empty_dependency(self, graph):
+        task = MockTask()
+        graph.add_tasks(task)
+        # expecting add_dependency result to be False - no dependency has been created
+        assert graph.add_dependency(task, []) is False
+
+    def test_add_dependency_dependent_group(self, graph):
+        task = MockTask()
+        group_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(task)
+        graph.add_tasks(*group_tasks)
+        graph.add_dependency(group_tasks, task)
+        assert graph.has_dependency(group_tasks[0], task) is True
+        assert graph.has_dependency(group_tasks[1], task) is True
+        assert graph.has_dependency(group_tasks[2], task) is True
+
+    def test_add_dependency_dependency_group(self, graph):
+        task = MockTask()
+        group_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(task)
+        graph.add_tasks(*group_tasks)
+        graph.add_dependency(task, group_tasks)
+        assert graph.has_dependency(task, group_tasks[0]) is True
+        assert graph.has_dependency(task, group_tasks[1]) is True
+        assert graph.has_dependency(task, group_tasks[2]) is True
+
+    def test_add_dependency_between_groups(self, graph):
+        group_1_tasks = [MockTask() for _ in xrange(3)]
+        group_2_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(*group_1_tasks)
+        graph.add_tasks(*group_2_tasks)
+        graph.add_dependency(group_1_tasks, group_2_tasks)
+        for group_2_task in group_2_tasks:
+            assert graph.has_dependency(group_1_tasks[0], group_2_task) is True
+            assert graph.has_dependency(group_1_tasks[1], group_2_task) is True
+            assert graph.has_dependency(group_1_tasks[2], group_2_task) is True
+
+    def test_add_dependency_dependency_group_with_some_existing_dependencies(self, graph):
+        task = MockTask()
+        group_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(task)
+        graph.add_tasks(*group_tasks)
+        # adding a dependency on a specific task manually,
+        # before adding a dependency on the whole parallel
+        graph.add_dependency(task, group_tasks[1])
+        graph.add_dependency(task, group_tasks)
+        assert graph.has_dependency(task, group_tasks[0]) is True
+        assert graph.has_dependency(task, group_tasks[1]) is True
+        assert graph.has_dependency(task, group_tasks[2]) is True
+
+    def test_add_existing_dependency_between_groups(self, graph):
+        group_1_tasks = [MockTask() for _ in xrange(3)]
+        group_2_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(*group_1_tasks)
+        graph.add_tasks(*group_2_tasks)
+        add_result = graph.add_dependency(group_1_tasks, group_2_tasks)
+        assert add_result is True
+        # adding a dependency already in graph - should have no effect, and return False
+        add_result = graph.add_dependency(group_1_tasks, group_2_tasks)
+        assert add_result is False
+        for group_2_task in group_2_tasks:
+            assert graph.has_dependency(group_1_tasks[0], group_2_task) is True
+            assert graph.has_dependency(group_1_tasks[1], group_2_task) is True
+            assert graph.has_dependency(group_1_tasks[2], group_2_task) is True
+
     def test_has_dependency(self, graph):
         task = MockTask()
         dependency_task = MockTask()
@@ -257,6 +395,61 @@ class TestTaskGraphDependencies(object):
         with pytest.raises(task_graph.TaskNotInGraphError):
             graph.has_dependency(task, task_not_in_graph)
 
+    def test_has_dependency_empty_dependent(self, graph):
+        task = MockTask()
+        graph.add_tasks(task)
+        # expecting has_dependency result to be False - dependency in an empty form
+        assert graph.has_dependency([], task) is True
+
+    def test_has_dependency_empty_dependency(self, graph):
+        task = MockTask()
+        graph.add_tasks(task)
+        # expecting has_dependency result to be True - dependency in an empty form
+        assert graph.has_dependency(task, []) is True
+
+    def test_has_dependency_dependent_group(self, graph):
+        task = MockTask()
+        group_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(task)
+        graph.add_tasks(*group_tasks)
+        assert graph.has_dependency(group_tasks, task) is False
+        graph.add_dependency(group_tasks, task)
+        assert graph.has_dependency(group_tasks, task) is True
+
+    def test_has_dependency_dependency_parallel(self, graph):
+        task = MockTask()
+        group_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(task)
+        graph.add_tasks(*group_tasks)
+        assert graph.has_dependency(task, group_tasks) is False
+        graph.add_dependency(task, group_tasks)
+        assert graph.has_dependency(task, group_tasks) is True
+
+    def test_has_dependency_between_groups(self, graph):
+        group_1_tasks = [MockTask() for _ in xrange(3)]
+        group_2_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(*group_1_tasks)
+        graph.add_tasks(*group_2_tasks)
+        assert graph.has_dependency(group_2_tasks, group_1_tasks) is False
+        graph.add_dependency(group_2_tasks, group_1_tasks)
+        assert graph.has_dependency(group_2_tasks, group_1_tasks) is True
+
+    def test_has_dependency_dependency_parallel_with_some_existing_dependencies(self, graph):
+        task = MockTask()
+        parallel_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(task)
+        parallel = graph.add_tasks(*parallel_tasks)
+        graph.add_dependency(task, parallel_tasks[1])
+        # only a partial dependency exists - has_dependency is expected to return False
+        assert graph.has_dependency(task, parallel) is False
+
+    def test_has_nonexistent_dependency_between_groups(self, graph):
+        group_1_tasks = [MockTask() for _ in xrange(3)]
+        group_2_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(*group_1_tasks)
+        graph.add_tasks(*group_2_tasks)
+        assert graph.has_dependency(group_1_tasks, group_2_tasks) is False
+
     def test_remove_dependency(self, graph):
         task = MockTask()
         dependency_task = MockTask()
@@ -298,8 +491,139 @@ class TestTaskGraphDependencies(object):
         with pytest.raises(task_graph.TaskNotInGraphError):
             graph.remove_dependency(task, task_not_in_graph)
 
+    def test_remove_dependency_empty_dependent(self, graph):
+        task = MockTask()
+        graph.add_tasks(task)
+        # expecting remove_dependency result to be False - no dependency has been created
+        assert graph.remove_dependency([], task) is False
+
+    def test_remove_dependency_empty_dependency(self, graph):
+        task = MockTask()
+        graph.add_tasks(task)
+        # expecting remove_dependency result to be False - no dependency has been created
+        assert graph.remove_dependency(task, []) is False
+
+    def test_remove_dependency_dependent_group(self, graph):
+        task = MockTask()
+        group_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(task)
+        graph.add_tasks(*group_tasks)
+        graph.add_dependency(group_tasks, task)
+        remove_result = graph.remove_dependency(group_tasks, task)
+        assert remove_result is True
+        assert graph.has_dependency(group_tasks[0], task) is False
+        assert graph.has_dependency(group_tasks[1], task) is False
+        assert graph.has_dependency(group_tasks[2], task) is False
+
+    def test_remove_dependency_dependency_group(self, graph):
+        task = MockTask()
+        group_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(task)
+        graph.add_tasks(*group_tasks)
+        graph.add_dependency(task, group_tasks)
+        remove_result = graph.remove_dependency(task, group_tasks)
+        assert remove_result is True
+        assert graph.has_dependency(task, group_tasks[0]) is False
+        assert graph.has_dependency(task, group_tasks[1]) is False
+        assert graph.has_dependency(task, group_tasks[2]) is False
+
+    def test_remove_dependency_between_groups(self, graph):
+        group_1_tasks = [MockTask() for _ in xrange(3)]
+        group_2_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(*group_1_tasks)
+        graph.add_tasks(*group_2_tasks)
+        graph.add_dependency(group_2_tasks, group_1_tasks)
+        remove_result = graph.remove_dependency(group_2_tasks, group_1_tasks)
+        assert remove_result is True
+        for group_2_task in group_2_tasks:
+            assert graph.has_dependency(group_2_task, group_1_tasks[0]) is False
+            assert graph.has_dependency(group_2_task, group_1_tasks[1]) is False
+            assert graph.has_dependency(group_2_task, group_1_tasks[2]) is False
+
+    def test_remove_dependency_dependency_group_with_some_existing_dependencies(self, graph):
+        task = MockTask()
+        group_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(task)
+        graph.add_tasks(*group_tasks)
+        graph.add_dependency(task, group_tasks[1])
+        remove_result = graph.remove_dependency(task, group_tasks)
+        # only a partial dependency exists - remove_dependency is expected to return False
+        assert remove_result is False
+        # no dependencies are expected to have changed
+        assert graph.has_dependency(task, group_tasks[0]) is False
+        assert graph.has_dependency(task, group_tasks[1]) is True
+        assert graph.has_dependency(task, group_tasks[2]) is False
+
+    def test_remove_nonexistent_dependency_between_groups(self, graph):
+        group_1_tasks = [MockTask() for _ in xrange(3)]
+        group_2_tasks = [MockTask() for _ in xrange(3)]
+        graph.add_tasks(*group_1_tasks)
+        graph.add_tasks(*group_2_tasks)
+        # removing a dependency not in graph - should have no effect, and return False
+        remove_result = graph.remove_dependency(group_2_tasks, group_1_tasks)
+        assert remove_result is False
+
+    # nested tests
+
+    def test_group_with_nested_sequence(self, graph):
+        all_tasks = [MockTask() for _ in xrange(5)]
+        graph.add_tasks(all_tasks[0],
+                        graph.sequence(all_tasks[1], all_tasks[2], all_tasks[3]),
+                        all_tasks[4])
+        assert set(graph.tasks) == set(all_tasks)
+
+        # tasks[2] and tasks[3] should each have a single dependency; the rest should have
none
+        assert len(list(graph.get_dependencies(all_tasks[0]))) == 0
+        assert len(list(graph.get_dependencies(all_tasks[1]))) == 0
+        assert set(graph.get_dependencies(all_tasks[2])) == set([all_tasks[1]])
+        assert set(graph.get_dependencies(all_tasks[3])) == set([all_tasks[2]])
+        assert len(list(graph.get_dependencies(all_tasks[4]))) == 0
+
+    def test_group_with_nested_group(self, graph):
+        tasks = [MockTask() for _ in xrange(5)]
+        graph.add_tasks(tasks[0], (tasks[1], tasks[2], tasks[3]), tasks[4])
+        graph_tasks = [t for t in graph.tasks]
+        assert set(graph_tasks) == set(tasks)
+        # none of the tasks should have any dependencies
+        for i in xrange(len(tasks)):
+            assert len(list(graph.get_dependencies(tasks[i]))) == 0
+
+    def test_group_with_recursively_nested_group(self, graph):
+        recursively_nested_tasks = [MockTask(), MockTask(), MockTask()]
+        nested_tasks = [MockTask(), MockTask(), MockTask(), recursively_nested_tasks]
+        tasks = [MockTask(), MockTask(), MockTask(), nested_tasks]
+        graph.add_tasks(*tasks)
+
+        assert set(graph.tasks) == set(tasks[:3] + nested_tasks[:3] + recursively_nested_tasks)
+        for tasks_list in [tasks, nested_tasks, recursively_nested_tasks]:
+            for i in xrange(len(tasks_list[:3])):
+                assert len(list(graph.get_dependencies(tasks_list[i]))) == 0
+
+    def test_group_with_recursively_nested_group_and_interdependencies(self, graph):
+        recursively_nested_tasks = [MockTask(), MockTask(), MockTask()]
+        nested_tasks = [MockTask(), MockTask(), MockTask(), recursively_nested_tasks]
+        tasks = [MockTask(), MockTask(), MockTask(), nested_tasks]
+        graph.add_tasks(*tasks)
+
+        graph.add_dependency(tasks[2], nested_tasks[2])
+        graph.add_dependency(nested_tasks[1], recursively_nested_tasks[0])
+        graph.add_dependency(recursively_nested_tasks[1], tasks[0])
+
+        assert set(graph.tasks) == set(tasks[:3] + nested_tasks[:3] + recursively_nested_tasks)
+        assert set(graph.get_dependencies(tasks[0])) == set()
+        assert set(graph.get_dependencies(tasks[1])) == set()
+        assert set(graph.get_dependencies(tasks[2])) == set([nested_tasks[2]])
+
+        assert set(graph.get_dependencies(nested_tasks[0])) == set()
+        assert set(graph.get_dependencies(nested_tasks[1])) == set([recursively_nested_tasks[0]])
+        assert set(graph.get_dependencies(nested_tasks[2])) == set()
+
+        assert set(graph.get_dependencies(recursively_nested_tasks[0])) == set()
+        assert set(graph.get_dependencies(recursively_nested_tasks[1])) == set([tasks[0]])
+        assert set(graph.get_dependencies(recursively_nested_tasks[2])) == set()
 
-class TestTaskGraphArrangements(object):
+
+class TestTaskGraphSequence(object):
 
     def test_sequence(self, graph):
         tasks = [MockTask(), MockTask(), MockTask()]
@@ -311,6 +635,8 @@ class TestTaskGraphArrangements(object):
         assert set(graph.get_dependencies(tasks[2])) == set([tasks[1]])
 
     def test_sequence_with_some_tasks_and_dependencies_already_in_graph(self, graph):
+        # tests both that tasks which werent previously in graph get inserted, and that existing
tasks don't get
+        # re-added to graph
         tasks = [MockTask(), MockTask(), MockTask()]
         # insert some tasks and dependencies to the graph
         graph.add_tasks(tasks[1])
@@ -336,7 +662,7 @@ class TestTaskGraphArrangements(object):
         assert len(list(graph.get_dependencies(tasks[3]))) == 2
         assert len(list(graph.get_dependencies(tasks[4]))) == 3
 
-    def test_sequence_with_nested_parallel(self, graph):
+    def test_sequence_with_nested_group(self, graph):
         tasks = [MockTask() for _ in xrange(5)]
         graph.sequence(tasks[0], (tasks[1], tasks[2], tasks[3]), tasks[4])
         graph_tasks = [t for t in graph.tasks]
@@ -349,364 +675,55 @@ class TestTaskGraphArrangements(object):
         # last task should have have a dependency on all tasks except for the first one
         assert set(graph.get_dependencies(tasks[4])) == set([tasks[1], tasks[2], tasks[3]])
 
-    def test_parallel(self, graph):
-        tasks = [MockTask(), MockTask(), MockTask()]
-        graph.add_tasks(tasks)
-        graph_tasks = [t for t in graph.tasks]
-        assert set(graph_tasks) == set(tasks)
-        for i in xrange(len(tasks)):
-            assert len(list(graph.get_dependencies(tasks[i]))) == 0
-
-    def test_parallel_with_some_tasks_and_dependencies_already_in_graph(self, graph):
-        tasks = [MockTask(), MockTask(), MockTask()]
-
-        # insert some tasks and dependencies to the graph
-        graph.add_tasks(tasks[1])
-        graph.add_tasks(tasks[2])
-        graph.add_tasks(*tasks)
+    def test_sequence_with_recursively_nested_group(self, graph):
+        recursively_nested_group = [MockTask(), MockTask()]
+        nested_group = [MockTask(), recursively_nested_group, MockTask()]
+        sequence_tasks = [MockTask(), nested_group, MockTask()]
 
-        assert set(graph.tasks) == set(tasks)
-        for i in xrange(len(tasks)):
-            assert len(list(graph.get_dependencies(tasks[i]))) == 0
-
-    def test_parallel_with_nested_sequence(self, graph):
-        all_tasks = [MockTask() for _ in xrange(5)]
-        graph.add_tasks(all_tasks[0],
-                        graph.sequence(all_tasks[1], all_tasks[2], all_tasks[3]),
-                        all_tasks[4])
-        assert set(graph.tasks) == set(all_tasks)
-
-        # tasks[2] and tasks[3] should each have a single dependency; the rest should have
none
-        assert len(list(graph.get_dependencies(all_tasks[0]))) == 0
-        assert len(list(graph.get_dependencies(all_tasks[1]))) == 0
-        assert set(graph.get_dependencies(all_tasks[2])) == set([all_tasks[1]])
-        assert set(graph.get_dependencies(all_tasks[3])) == set([all_tasks[2]])
-        assert len(list(graph.get_dependencies(all_tasks[4]))) == 0
-
-    def test_parallel_with_nested_parallel(self, graph):
-        tasks = [MockTask() for _ in xrange(5)]
-        graph.add_tasks(tasks[0], (tasks[1], tasks[2], tasks[3]), tasks[4])
+        graph.sequence(*sequence_tasks)
         graph_tasks = [t for t in graph.tasks]
-        assert set(graph_tasks) == set(tasks)
-        # none of the tasks should have any dependencies
-        for i in xrange(len(tasks)):
-            assert len(list(graph.get_dependencies(tasks[i]))) == 0
-
-    def test_group_with_twice_nested_group(self, graph):
-        twice_nested_tasks = [MockTask(), MockTask(), MockTask()]
-        once_nested_tasks = [MockTask(), MockTask(), MockTask(), twice_nested_tasks]
-        tasks = [MockTask(), MockTask(), MockTask(), once_nested_tasks]
-        graph.add_tasks(*tasks)
-
-        assert set(graph.tasks) == set(tasks[:3] + once_nested_tasks[:3] + twice_nested_tasks)
-        for tasks_list in [tasks, once_nested_tasks, twice_nested_tasks]:
-            for i in xrange(len(tasks_list[:3])):
-                assert len(list(graph.get_dependencies(tasks_list[i]))) == 0
-
-
-class TestTaskGraphDependenciesWithArrangements(object):
-
-    def test_add_dependency_dependent_sequence(self, graph):
-        task = MockTask()
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        sequence = graph.sequence(*sequence_tasks)
-        graph.add_dependency(sequence, task)
-        assert graph.has_dependency(sequence_tasks[0], task) is True
-        assert graph.has_dependency(sequence_tasks[1], task) is True
-        assert graph.has_dependency(sequence_tasks[2], task) is True
-
-    def test_add_dependency_dependency_sequence(self, graph):
-        task = MockTask()
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        sequence = graph.sequence(*sequence_tasks)
-        graph.add_dependency(task, sequence)
-        assert graph.has_dependency(task, sequence_tasks[0]) is True
-        assert graph.has_dependency(task, sequence_tasks[1]) is True
-        assert graph.has_dependency(task, sequence_tasks[2]) is True
-
-    def test_add_dependency_dependent_parallel(self, graph):
-        task = MockTask()
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        parallel = graph.add_tasks(*parallel_tasks)
-        graph.add_dependency(parallel, task)
-        assert graph.has_dependency(parallel_tasks[0], task) is True
-        assert graph.has_dependency(parallel_tasks[1], task) is True
-        assert graph.has_dependency(parallel_tasks[2], task) is True
-
-    def test_add_dependency_dependency_parallel(self, graph):
-        task = MockTask()
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        parallel = graph.add_tasks(*parallel_tasks)
-        graph.add_dependency(task, parallel)
-        assert graph.has_dependency(task, parallel_tasks[0]) is True
-        assert graph.has_dependency(task, parallel_tasks[1]) is True
-        assert graph.has_dependency(task, parallel_tasks[2]) is True
-
-    def test_add_dependency_between_sequence_and_parallel(self, graph):
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        sequence = graph.sequence(*sequence_tasks)
-        parallel = graph.add_tasks(*parallel_tasks)
-        graph.add_dependency(sequence, parallel)
-        for parallel_task in parallel_tasks:
-            assert graph.has_dependency(sequence_tasks[0], parallel_task) is True
-            assert graph.has_dependency(sequence_tasks[1], parallel_task) is True
-            assert graph.has_dependency(sequence_tasks[2], parallel_task) is True
-
-    def test_add_dependency_between_parallel_and_sequence(self, graph):
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        sequence = graph.sequence(*sequence_tasks)
-        parallel = graph.add_tasks(*parallel_tasks)
-        graph.add_dependency(parallel, sequence)
-        for parallel_task in parallel_tasks:
-            assert graph.has_dependency(parallel_task, sequence_tasks[0]) is True
-            assert graph.has_dependency(parallel_task, sequence_tasks[1]) is True
-            assert graph.has_dependency(parallel_task, sequence_tasks[2]) is True
-
-    def test_add_dependency_dependency_parallel_with_some_existing_dependencies(self, graph):
-        task = MockTask()
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        parallel = graph.add_tasks(*parallel_tasks)
-        # adding a dependency on a specific task manually,
-        # before adding a dependency on the whole parallel
-        graph.add_dependency(task, parallel_tasks[1])
-        graph.add_dependency(task, parallel)
-        assert graph.has_dependency(task, parallel_tasks[0]) is True
-        assert graph.has_dependency(task, parallel_tasks[1]) is True
-        assert graph.has_dependency(task, parallel_tasks[2]) is True
-
-    def test_add_existing_dependency_between_sequence_and_parallel(self, graph):
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        sequence = graph.sequence(*sequence_tasks)
-        parallel = graph.add_tasks(*parallel_tasks)
-        add_result = graph.add_dependency(sequence, parallel)
-        assert add_result is True
-        # adding a dependency already in graph - should have no effect, and return False
-        add_result = graph.add_dependency(sequence, parallel)
-        assert add_result is False
-        for parallel_task in parallel_tasks:
-            assert graph.has_dependency(sequence_tasks[0], parallel_task) is True
-            assert graph.has_dependency(sequence_tasks[1], parallel_task) is True
-            assert graph.has_dependency(sequence_tasks[2], parallel_task) is True
-
-    def test_has_dependency_dependent_sequence(self, graph):
-        task = MockTask()
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        sequence = graph.sequence(*sequence_tasks)
-        assert graph.has_dependency(sequence, task) is False
-        graph.add_dependency(sequence, task)
-        assert graph.has_dependency(sequence, task) is True
-
-    def test_has_dependency_dependency_sequence(self, graph):
-        task = MockTask()
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        sequence = graph.sequence(*sequence_tasks)
-        assert graph.has_dependency(task, sequence) is False
-        graph.add_dependency(task, sequence)
-        assert graph.has_dependency(task, sequence) is True
-
-    def test_has_dependency_dependent_parallel(self, graph):
-        task = MockTask()
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        parallel = graph.add_tasks(*parallel_tasks)
-        assert graph.has_dependency(parallel, task) is False
-        graph.add_dependency(parallel, task)
-        assert graph.has_dependency(parallel, task) is True
-
-    def test_has_dependency_dependency_parallel(self, graph):
-        task = MockTask()
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        parallel = graph.add_tasks(*parallel_tasks)
-        assert graph.has_dependency(task, parallel) is False
-        graph.add_dependency(task, parallel)
-        assert graph.has_dependency(task, parallel) is True
-
-    def test_has_dependency_between_sequence_and_parallel(self, graph):
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        sequence = graph.sequence(*sequence_tasks)
-        parallel = graph.add_tasks(*parallel_tasks)
-        assert graph.has_dependency(sequence, parallel) is False
-        graph.add_dependency(sequence, parallel)
-        assert graph.has_dependency(sequence, parallel) is True
-
-    def test_has_dependency_between_parallel_and_sequence(self, graph):
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        sequence = graph.sequence(*sequence_tasks)
-        parallel = graph.add_tasks(*parallel_tasks)
-        assert graph.has_dependency(parallel, sequence) is False
-        graph.add_dependency(parallel, sequence)
-        assert graph.has_dependency(parallel, sequence) is True
-
-    def test_has_dependency_dependency_parallel_with_some_existing_dependencies(self, graph):
-        task = MockTask()
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        parallel = graph.add_tasks(*parallel_tasks)
-        graph.add_dependency(task, parallel_tasks[1])
-        # only a partial dependency exists - has_dependency is expected to return False
-        assert graph.has_dependency(task, parallel) is False
-
-    def test_has_nonexistent_dependency_between_sequence_and_parallel(self, graph):
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        sequence = graph.sequence(*sequence_tasks)
-        parallel = graph.add_tasks(*parallel_tasks)
-        assert graph.has_dependency(sequence, parallel) is False
-
-    def test_remove_dependency_dependent_sequence(self, graph):
-        task = MockTask()
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        sequence = graph.sequence(*sequence_tasks)
-        graph.add_dependency(sequence, task)
-        remove_result = graph.remove_dependency(sequence, task)
-        assert remove_result is True
-        assert graph.has_dependency(sequence_tasks[0], task) is False
-        assert graph.has_dependency(sequence_tasks[1], task) is False
-        assert graph.has_dependency(sequence_tasks[2], task) is False
-
-    def test_remove_dependency_dependency_sequence(self, graph):
-        task = MockTask()
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        sequence = graph.sequence(*sequence_tasks)
-        graph.add_dependency(task, sequence)
-        remove_result = graph.remove_dependency(task, sequence)
-        assert remove_result is True
-        assert graph.has_dependency(task, sequence_tasks[0]) is False
-        assert graph.has_dependency(task, sequence_tasks[1]) is False
-        assert graph.has_dependency(task, sequence_tasks[2]) is False
-
-    def test_remove_dependency_dependent_parallel(self, graph):
-        task = MockTask()
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        parallel = graph.add_tasks(*parallel_tasks)
-        graph.add_dependency(parallel, task)
-        remove_result = graph.remove_dependency(parallel, task)
-        assert remove_result is True
-        assert graph.has_dependency(parallel_tasks[0], task) is False
-        assert graph.has_dependency(parallel_tasks[1], task) is False
-        assert graph.has_dependency(parallel_tasks[2], task) is False
-
-    def test_remove_dependency_dependency_parallel(self, graph):
-        task = MockTask()
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        parallel = graph.add_tasks(*parallel_tasks)
-        graph.add_dependency(task, parallel)
-        remove_result = graph.remove_dependency(task, parallel)
-        assert remove_result is True
-        assert graph.has_dependency(task, parallel_tasks[0]) is False
-        assert graph.has_dependency(task, parallel_tasks[1]) is False
-        assert graph.has_dependency(task, parallel_tasks[2]) is False
-
-    def test_remove_dependency_between_sequence_and_parallel(self, graph):
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        sequence = graph.sequence(*sequence_tasks)
-        parallel = graph.add_tasks(*parallel_tasks)
-        graph.add_dependency(sequence, parallel)
-        remove_result = graph.remove_dependency(sequence, parallel)
-        assert remove_result is True
-        for parallel_task in parallel_tasks:
-            assert graph.has_dependency(sequence_tasks[0], parallel_task) is False
-            assert graph.has_dependency(sequence_tasks[1], parallel_task) is False
-            assert graph.has_dependency(sequence_tasks[2], parallel_task) is False
+        assert set(graph_tasks) == set([sequence_tasks[0], nested_group[0], recursively_nested_group[0],
+                                       recursively_nested_group[1], nested_group[2], sequence_tasks[2]])
 
-    def test_remove_dependency_between_parallel_and_sequence(self, graph):
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        sequence = graph.sequence(*sequence_tasks)
-        parallel = graph.add_tasks(*parallel_tasks)
-        graph.add_dependency(parallel, sequence)
-        remove_result = graph.remove_dependency(parallel, sequence)
-        assert remove_result is True
-        for parallel_task in parallel_tasks:
-            assert graph.has_dependency(parallel_task, sequence_tasks[0]) is False
-            assert graph.has_dependency(parallel_task, sequence_tasks[1]) is False
-            assert graph.has_dependency(parallel_task, sequence_tasks[2]) is False
-
-    def test_remove_dependency_dependency_parallel_with_some_existing_dependencies(self,
graph):
-        task = MockTask()
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        graph.add_tasks(task)
-        parallel = graph.add_tasks(*parallel_tasks)
-        graph.add_dependency(task, parallel_tasks[1])
-        remove_result = graph.remove_dependency(task, parallel)
-        # only a partial dependency exists - remove_dependency is expected to return False
-        assert remove_result is False
-        # no dependencies are expected to have changed
-        assert graph.has_dependency(task, parallel_tasks[0]) is False
-        assert graph.has_dependency(task, parallel_tasks[1]) is True
-        assert graph.has_dependency(task, parallel_tasks[2]) is False
+        assert list(graph.get_dependencies(nested_group[0])) == [sequence_tasks[0]]
+        assert list(graph.get_dependencies(recursively_nested_group[0])) == [sequence_tasks[0]]
+        assert list(graph.get_dependencies(recursively_nested_group[1])) == [sequence_tasks[0]]
+        assert list(graph.get_dependencies(nested_group[2])) == [sequence_tasks[0]]
 
-    def test_remove_nonexistent_dependency_between_sequence_and_parallel(self, graph):
-        sequence_tasks = [MockTask() for _ in xrange(3)]
-        parallel_tasks = [MockTask() for _ in xrange(3)]
-        sequence = graph.sequence(*sequence_tasks)
-        parallel = graph.add_tasks(*parallel_tasks)
-        # removing a dependency not in graph - should have no effect, and return False
-        remove_result = graph.remove_dependency(sequence, parallel)
-        assert remove_result is False
+        assert list(graph.get_dependents(nested_group[0])) == [sequence_tasks[2]]
+        assert list(graph.get_dependents(recursively_nested_group[0])) == [sequence_tasks[2]]
+        assert list(graph.get_dependents(recursively_nested_group[1])) == [sequence_tasks[2]]
+        assert list(graph.get_dependents(nested_group[2])) == [sequence_tasks[2]]
 
-    def test_sequence_with_twice_nested_sequence_and_interdependencies(self, graph):
-        twice_nested_tasks = list(graph.sequence(MockTask(), MockTask(), MockTask()))
-        once_nested_tasks = list(graph.sequence(MockTask(),
-                                                MockTask(),
-                                                MockTask(),
-                                                twice_nested_tasks))
-        tasks = [MockTask(), MockTask(), MockTask(), once_nested_tasks]
+    def test_sequence_with_empty_group(self, graph):
+        tasks = [MockTask(), [], MockTask()]
+        graph.sequence(*tasks)
+        graph_tasks = [t for t in graph.tasks]
+        assert graph_tasks == [tasks[0], tasks[2]]
+        assert list(graph.get_dependents(tasks[0])) == [tasks[2]]
+        assert list(graph.get_dependencies(tasks[2])) == [tasks[0]]
+
+    def test_sequence_with_recursively_nested_sequence_and_interdependencies(self, graph):
+        recursively_nested_tasks = list(graph.sequence(MockTask(), MockTask(), MockTask()))
+        nested_tasks = list(graph.sequence(MockTask(),
+                                           MockTask(),
+                                           MockTask(),
+                                           recursively_nested_tasks))
+        tasks = [MockTask(), MockTask(), MockTask(), nested_tasks]
         graph.sequence(*tasks)
 
-        assert set(graph.tasks) == set(tasks[:3] + once_nested_tasks[:3] + twice_nested_tasks)
+        assert set(graph.tasks) == set(tasks[:3] + nested_tasks[:3] + recursively_nested_tasks)
         assert set(graph.get_dependencies(tasks[0])) == set()
         for i in xrange(1, len(tasks[:-1])):
             assert set(graph.get_dependencies(tasks[i])) == set([tasks[i - 1]])
 
-        assert set(graph.get_dependencies(once_nested_tasks[0])) == set([tasks[2]])
-        for i in xrange(1, len(once_nested_tasks[:-1])):
-            assert set(graph.get_dependencies(once_nested_tasks[i])) == \
-                   set([tasks[2], once_nested_tasks[i-1]])
-
-        assert set(graph.get_dependencies(twice_nested_tasks[0])) == \
-               set([tasks[2], once_nested_tasks[2]])
-        for i in xrange(1, len(twice_nested_tasks[:-1])):
-            assert set(graph.get_dependencies(twice_nested_tasks[i])) == \
-                   set([tasks[2], once_nested_tasks[2], twice_nested_tasks[i-1]])
-
-    def test_group_with_twice_nested_group_and_interdependencies(self, graph):
-        twice_nested_tasks = [MockTask(), MockTask(), MockTask()]
-        once_nested_tasks = [MockTask(), MockTask(), MockTask(), twice_nested_tasks]
-        tasks = [MockTask(), MockTask(), MockTask(), once_nested_tasks]
-        graph.add_tasks(*tasks)
-
-        graph.add_dependency(tasks[2], once_nested_tasks[2])
-        graph.add_dependency(once_nested_tasks[1], twice_nested_tasks[0])
-        graph.add_dependency(twice_nested_tasks[1], tasks[0])
-
-        assert set(graph.tasks) == set(tasks[:3] + once_nested_tasks[:3] + twice_nested_tasks)
-        assert set(graph.get_dependencies(tasks[0])) == set()
-        assert set(graph.get_dependencies(tasks[1])) == set()
-        assert set(graph.get_dependencies(tasks[2])) == set([once_nested_tasks[2]])
-
-        assert set((graph.get_dependencies(once_nested_tasks[0]))) == set()
-        assert set(graph.get_dependencies(once_nested_tasks[1])) == set([twice_nested_tasks[0]])
-        assert set(graph.get_dependencies(once_nested_tasks[2])) == set()
+        assert set(graph.get_dependencies(nested_tasks[0])) == set([tasks[2]])
+        for i in xrange(1, len(nested_tasks[:-1])):
+            assert set(graph.get_dependencies(nested_tasks[i])) == \
+                   set([tasks[2], nested_tasks[i-1]])
 
-        assert set((graph.get_dependencies(twice_nested_tasks[0]))) == set()
-        assert set(graph.get_dependencies(twice_nested_tasks[1])) == set([tasks[0]])
-        assert set(graph.get_dependencies(twice_nested_tasks[2])) == set()
+        assert set(graph.get_dependencies(recursively_nested_tasks[0])) == \
+               set([tasks[2], nested_tasks[2]])
+        for i in xrange(1, len(recursively_nested_tasks[:-1])):
+            assert set(graph.get_dependencies(recursively_nested_tasks[i])) == \
+                   set([tasks[2], nested_tasks[2], recursively_nested_tasks[i-1]])



Mime
View raw message