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())
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