From 2339bacaf7edd9a781267cf8ca38b8639f34137b Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Fri, 18 Jul 2014 12:49:39 -0700 Subject: [PATCH] Relax the linear flow symbol constraints In order to make it possible to have a symbol tree we need to relax and remove the constraints that are being imposed by the linear constraints and later move those constraint checks and validations into the engines compilation stage. Part of blueprint taskflow-improved-scoping Change-Id: I6efdc821ff991e83572d89f56be5c678d007f9f8 --- taskflow/patterns/linear_flow.py | 33 ++---------------- .../tests/unit/patterns/test_linear_flow.py | 19 ----------- taskflow/tests/unit/test_flow_dependencies.py | 34 ------------------- 3 files changed, 2 insertions(+), 84 deletions(-) diff --git a/taskflow/patterns/linear_flow.py b/taskflow/patterns/linear_flow.py index 14799b82..77559231 100644 --- a/taskflow/patterns/linear_flow.py +++ b/taskflow/patterns/linear_flow.py @@ -14,7 +14,6 @@ # License for the specific language governing permissions and limitations # under the License. -from taskflow import exceptions from taskflow import flow @@ -22,14 +21,11 @@ _LINK_METADATA = {'invariant': True} class Flow(flow.Flow): - """Linear Flow pattern. + """Linear flow pattern. A linear (potentially nested) flow of *tasks/flows* that can be applied in order as one unit and rolled back as one unit using the reverse order that the *tasks/flows* have been applied in. - - NOTE(imelnikov): Tasks/flows contained in this linear flow must not - depend on outputs (provided names/values) of tasks/flows that follow it. """ def __init__(self, name, retry=None): @@ -38,32 +34,7 @@ class Flow(flow.Flow): def add(self, *items): """Adds a given task/tasks/flow/flows to this flow.""" - if not items: - return self - - # NOTE(imelnikov): we add item to the end of flow, so it should - # not provide anything previous items of the flow require. - requires = self.requires - provides = self.provides - for item in items: - requires |= item.requires - out_of_order = requires & item.provides - if out_of_order: - raise exceptions.DependencyFailure( - "%(item)s provides %(oo)s that are required " - "by previous item(s) of linear flow %(flow)s" - % dict(item=item.name, flow=self.name, - oo=sorted(out_of_order))) - same_provides = provides & item.provides - if same_provides: - raise exceptions.DependencyFailure( - "%(item)s provides %(value)s but is already being" - " provided by %(flow)s and duplicate producers" - " are disallowed" - % dict(item=item.name, flow=self.name, - value=sorted(same_provides))) - provides |= item.provides - + items = [i for i in items if i not in self._children] self._children.extend(items) return self diff --git a/taskflow/tests/unit/patterns/test_linear_flow.py b/taskflow/tests/unit/patterns/test_linear_flow.py index a0dbd0d7..23f891a8 100644 --- a/taskflow/tests/unit/patterns/test_linear_flow.py +++ b/taskflow/tests/unit/patterns/test_linear_flow.py @@ -14,7 +14,6 @@ # License for the specific language governing permissions and limitations # under the License. -from taskflow import exceptions as exc from taskflow.patterns import linear_flow as lf from taskflow import retry from taskflow import test @@ -95,24 +94,6 @@ class LinearFlowTest(test.TestCase): (task1, task2, {'invariant': True}) ]) - def test_linear_flow_two_dependent_tasks_reverse_order(self): - task1 = _task(name='task1', provides=['a']) - task2 = _task(name='task2', requires=['a']) - f = lf.Flow('test') - self.assertRaises(exc.DependencyFailure, f.add, task2, task1) - - def test_linear_flow_two_dependent_tasks_reverse_order2(self): - task1 = _task(name='task1', provides=['a']) - task2 = _task(name='task2', requires=['a']) - f = lf.Flow('test').add(task2) - self.assertRaises(exc.DependencyFailure, f.add, task1) - - def test_linear_flow_two_task_same_provide(self): - task1 = _task(name='task1', provides=['a', 'b']) - task2 = _task(name='task2', provides=['a', 'c']) - f = lf.Flow('test') - self.assertRaises(exc.DependencyFailure, f.add, task2, task1) - def test_linear_flow_three_tasks(self): task1 = _task(name='task1') task2 = _task(name='task2') diff --git a/taskflow/tests/unit/test_flow_dependencies.py b/taskflow/tests/unit/test_flow_dependencies.py index 3ddb95d9..3f8e7509 100644 --- a/taskflow/tests/unit/test_flow_dependencies.py +++ b/taskflow/tests/unit/test_flow_dependencies.py @@ -186,13 +186,6 @@ class FlowDependenciesTest(test.TestCase): self.assertEqual(flow.requires, set(['a', 'b', 'c'])) self.assertEqual(flow.provides, set(['x', 'y', 'z', 'q'])) - def test_nested_flows_provides_same_values(self): - flow = lf.Flow('lf').add( - uf.Flow('uf').add(utils.TaskOneReturn(provides='x'))) - self.assertRaises(exceptions.DependencyFailure, - flow.add, - gf.Flow('gf').add(utils.TaskOneReturn(provides='x'))) - def test_graph_flow_requires_values(self): flow = gf.Flow('gf').add( utils.TaskOneArg('task1'), @@ -336,18 +329,6 @@ class FlowDependenciesTest(test.TestCase): self.assertEqual(flow.requires, set(['x', 'y', 'c'])) self.assertEqual(flow.provides, set(['a', 'b', 'z'])) - def test_linear_flow_retry_and_task_dependency_conflict(self): - flow = lf.Flow('lf', retry.AlwaysRevert('rt', requires=['x'])) - self.assertRaises(exceptions.DependencyFailure, - flow.add, - utils.TaskOneReturn(provides=['x'])) - - def test_linear_flow_retry_and_task_provide_same_value(self): - flow = lf.Flow('lf', retry.AlwaysRevert('rt', provides=['x'])) - self.assertRaises(exceptions.DependencyFailure, - flow.add, - utils.TaskOneReturn('t1', provides=['x'])) - def test_unordered_flow_retry_and_task(self): flow = uf.Flow('uf', retry.AlwaysRevert('rt', requires=['x', 'y'], @@ -399,21 +380,6 @@ class FlowDependenciesTest(test.TestCase): flow.add, utils.TaskOneReturn('t1', provides=['x'])) - def test_two_retries_provide_same_values_in_nested_flows(self): - flow = lf.Flow('lf', retry.AlwaysRevert('rt1', provides=['x'])) - self.assertRaises(exceptions.DependencyFailure, - flow.add, - lf.Flow('lf1', retry.AlwaysRevert('rt2', - provides=['x']))) - - def test_two_retries_provide_same_values(self): - flow = lf.Flow('lf').add( - lf.Flow('lf1', retry.AlwaysRevert('rt1', provides=['x']))) - self.assertRaises(exceptions.DependencyFailure, - flow.add, - lf.Flow('lf2', retry.AlwaysRevert('rt2', - provides=['x']))) - def test_builtin_retry_args(self): class FullArgsRetry(retry.AlwaysRevert):