Ejemplo n.º 1
0
    def test_is_cyclic(self):
        g = DAG([(2, 0), (2, 3), (0, 1), (0, 2)])
        self.assertTrue(g.is_cyclic())

        g = DAG([(2, 0), (2, 3), (0, 1), (1, 2)])
        self.assertTrue(g.is_cyclic())

        g = DAG([(2, 0), (2, 3), (0, 1), (3, 3)])
        self.assertTrue(g.is_cyclic())

        g = DAG([(2, 0), (2, 3), (0, 1), (4, 5), (5, 4)])
        self.assertTrue(g.is_cyclic())
Ejemplo n.º 2
0
    def __init__(self, dict_tree: t.Dict[ICommand, t.List[ICommand]],
                 stop_on_error: bool, stop_undo_on_error: bool = None,
                 id_=None, executor: concurrent.futures.Executor = None,
                 register: 'RegisterStepExecution' = None, var_context: Context = None):
        """

        Parameters
        ----------
        dict_tree:
            dict tree containing command nodes as keys and it's neighbours as a list of commands. See examples for more
            information
        undo_on_error:
            executes the undo process even if the command ended up with error
        stop_on_error:
            executes all the commands regardless if a command succeed or fail
        stop_undo_on_error:
            executes all the undo commands regardless if an undo command succeed or fail
        id_:
            command identifier
        executor:
            async call executor. defaults to concurrent.futures.process.ProcessPoolExecutor
        """
        self._id = id_
        self._dag = DAG().from_dict_of_lists(dict_tree)
        self.stop_on_error = stop_on_error
        self.stop_undo_on_error = stop_undo_on_error
        self.executor = executor or ThreadPoolExecutor(max_workers=4)
        self.register = register
        self.var_context = var_context
Ejemplo n.º 3
0
    def __init__(self,
                 name: str,
                 version: int,
                 description: t.Optional[str] = None,
                 steps: t.List[Step] = None,
                 stop_on_error: bool = True,
                 stop_undo_on_error: bool = True,
                 undo_on_error: bool = True,
                 dependencies: Tdependencies = None,
                 created_at=None,
                 **kwargs):
        super().__init__(**kwargs)

        self.name = name
        self.version = version
        self.description = '\n'.join(description) if is_iterable_not_string(
            description) else description
        self.steps = steps or []
        assert isinstance(stop_on_error, bool)
        self.stop_on_error = stop_on_error
        assert isinstance(stop_undo_on_error, bool)
        self.stop_undo_on_error = stop_undo_on_error
        assert isinstance(undo_on_error, bool)
        self.undo_on_error = undo_on_error
        self.created_at = created_at or get_now()

        if dependencies:
            self.set_dependencies(dependencies)
        else:
            self._graph = DAG()
Ejemplo n.º 4
0
 def test_to_dict_of_lists(self):
     g = DAG([(1, 2), (2, 3), (2, 4)])
     self.assertDictEqual(g.to_dict_of_lists(), {
         1: [2],
         2: [3, 4],
         3: [],
         4: []
     })
Ejemplo n.º 5
0
 def init_on_load(self):
     self._graph = DAG()
     for step in self.steps:
         if step.parents:
             for p in step.parents:
                 self._graph.add_edge(p, step)
         else:
             self._graph.add_node(step)
Ejemplo n.º 6
0
    def test_add_edges_from(self):
        class Foo():
            pass

        bar = Foo()
        g = DAG()
        g.add_edges_from([(3, bar), (2, 3), (2, 3)])

        self.assertDictEqual(g.succ, {2: [3], 3: [bar], bar: []})
Ejemplo n.º 7
0
    def test_level(self):
        g = DAG([(1, 2), (1, 7), (7, 2), (2, 4), (2, 3), (4, 5), (4, 6)])

        self.assertEqual(g.level(1), 1)
        self.assertEqual(g.level(2), 3)
        self.assertEqual(g.level(3), 4)
        self.assertEqual(g.level(4), 4)
        self.assertEqual(g.level(5), 5)
        self.assertEqual(g.level(6), 5)
        self.assertEqual(g.level(7), 2)
Ejemplo n.º 8
0
    def test_remove_edges_from(self):
        class Foo():
            pass

        bar = Foo()
        g = DAG()
        g.add_edges_from([(3, bar), (2, 3), (2, 3)])
        ebunch = [(1, 2), (2, 3)]
        g.remove_edges_from(ebunch)

        self.assertListEqual(g.succ[2], [])
Ejemplo n.º 9
0
    def test_add_edge(self):
        class Foo():
            pass

        g = DAG()
        g.add_edge(2, 3)
        bar = Foo()
        g.add_edge(3, bar)
        g.add_edge(3, bar)
        self.assertListEqual(g.nodes, [2, 3, bar])

        self.assertDictEqual(g.succ, {2: [3], 3: [bar], bar: []})
Ejemplo n.º 10
0
    def test_remove_nodes_from(self):
        class Foo():
            pass

        bar = Foo()
        g = DAG()
        g.add_edges_from([(3, bar), (2, 3), (2, 3)])

        g.remove_nodes_from([5, 2, bar])

        self.assertListEqual(g.nodes, [3])

        self.assertDictEqual(g.succ, {3: []})
        self.assertDictEqual(g.pred, {3: []})
Ejemplo n.º 11
0
    def test_add_node(self):
        g = DAG()
        g.add_node(1)
        self.assertListEqual(g.nodes, [1])

        class Foo():
            pass

        bar = Foo()
        g.add_node(bar)

        self.assertListEqual(g.nodes, [1, bar])

        g.add_node(bar)

        self.assertListEqual(g.nodes, [1, bar])
Ejemplo n.º 12
0
    def test_remove_node(self):
        class Foo():
            pass

        bar = Foo()
        g = DAG()
        g.add_edges_from([(3, bar), (2, 3), (2, 3)])

        with self.assertRaises(DAGError):
            g.remove_node(5)

        g.remove_node(3)

        self.assertListEqual(g.nodes, [bar, 2])

        self.assertDictEqual(g.succ, {2: [], bar: []})
        self.assertDictEqual(g.pred, {2: [], bar: []})
Ejemplo n.º 13
0
    def test_subtree(self):
        g = DAG([(1, 2), (1, 7), (7, 2), (2, 4), (2, 3), (4, 5), (4, 6)])

        self.assertDictEqual(g.subtree([2]), {
            2: [4, 3],
            3: [],
            4: [5, 6],
            5: [],
            6: []
        })
        self.assertDictEqual(g.subtree([2, 7]), {
            7: [2],
            2: [4, 3],
            3: [],
            4: [5, 6],
            5: [],
            6: []
        })
        self.assertDictEqual(g.subtree([5, 6]), {5: [], 6: []})
Ejemplo n.º 14
0
 def set_dependencies(self, dependencies: Tdependencies):
     edges = []
     find = lambda id_: next(
         (step for step in self.steps if step.id == id_))
     if isinstance(dependencies, t.Dict):
         for k, v in dependencies.items():
             try:
                 step_from = find(k)
             except StopIteration:
                 raise ValueError(f'id step {k} not found in steps list')
             for child_id in v:
                 try:
                     step_to = find(child_id)
                 except StopIteration:
                     raise ValueError(
                         f'id step {child_id} not found in steps list')
                 edges.append((step_from, step_to))
     elif isinstance(dependencies, t.Iterable):
         edges = dependencies
     else:
         raise ValueError(
             f'dependencies must be a dict like object or an iterable of tuples. '
             f'See the docs for more information')
     self._graph = DAG(edges)
Ejemplo n.º 15
0
    def test_pred(self):
        G = DAG()
        self.assertDictEqual(G.pred, {})

        G.add_node(1)
        self.assertDictEqual(G.pred, {1: []})
Ejemplo n.º 16
0
    def test_get_nodes_at_level(self):
        g = DAG([(1, 2), (1, 7), (7, 2), (2, 4), (2, 3), (4, 5), (4, 6)])

        self.assertListEqual([4, 3], g.get_nodes_at_level(4))
Ejemplo n.º 17
0
    def test_depth(self):
        g = DAG([(1, 2), (1, 7), (7, 2), (2, 4), (2, 3), (4, 5), (4, 6)])

        self.assertEqual(5, g.depth)
Ejemplo n.º 18
0
    def test_succ(self):
        G = DAG()
        self.assertDictEqual(G.succ, {})

        G.add_node(1)
        self.assertDictEqual(G.succ, {1: []})
Ejemplo n.º 19
0
    def test_nodes(self):
        G = DAG()
        self.assertListEqual(G.nodes, [])

        G.add_node(1)
        self.assertListEqual(G.nodes, [1])
Ejemplo n.º 20
0
def orchestrations_full():
    json_data = request.get_json()
    json_steps = json_data.pop('steps')
    generated_version = False
    if 'version' not in json_data:
        generated_version = True
        json_data['version'] = Orchestration.query.filter_by(
            name=json_data['name']).count() + 1
    o = Orchestration(**json_data)
    db.session.add(o)
    resp_data = {'id': o.id}
    if generated_version:
        resp_data.update(version=o.version)

    # reorder steps in order of dependency
    id2step = {s['id']: s for s in json_steps}

    dag = DAG()
    for s in json_steps:
        step_id = s['id']
        if s['undo'] and len(s.get('parent_step_ids', [])) == 0:
            raise errors.UndoStepWithoutParent(step_id)
        dag.add_node(step_id)
        for p_s_id in s.get('parent_step_ids', []):
            dag.add_edge(p_s_id, step_id)

    if dag.is_cyclic():
        raise errors.CycleError

    new_steps = []
    for step_id in dag.ordered_nodes:
        step = id2step[step_id]
        new_steps.append(step)
    # end reorder steps in order of dependency

    rid2step = OrderedDict()
    dependencies = {}
    for json_step in new_steps:
        rid = json_step.pop('id', None)
        json_step['rid'] = rid
        if rid is not None and rid in rid2step.keys():
            raise errors.DuplicatedId(rid)
        if 'action_template_id' in json_step:
            json_step['action_template'] = ActionTemplate.query.get_or_raise(
                json_step.pop('action_template_id'))
        elif 'action_type' in json_step:
            json_step['action_type'] = ActionType[json_step.pop('action_type')]
        dependencies[rid] = {
            'parent_step_ids':
            [p_id for p_id in json_step.pop('parent_step_ids', [])]
        }
        s = o.add_step(**json_step)
        db.session.add(s)
        if rid:
            rid2step[rid] = s

        continue

    # process dependencies
    for rid, dep in dependencies.items():
        step = rid2step[rid]
        parents = []
        for p_s_id in dep['parent_step_ids']:
            if p_s_id in rid2step:
                parents.append(rid2step[p_s_id])
        o.set_parents(step, parents)

    db.session.commit()

    # send new ids in order of appearance at beginning
    new_id_steps = []
    for rid in rid2step.keys():
        new_id_steps.append(rid2step[rid].id)
    resp_data.update({'step_ids': new_id_steps})
    return resp_data, 201
Ejemplo n.º 21
0
 def test_add_nodes_from(self):
     g = DAG()
     g.add_nodes_from(range(3))
     self.assertListEqual(g.nodes, [0, 1, 2])