def test_inputs_parents_relationship(self): """ This test checks that the inputs_q, parents_q relationship and the corresponding properties work as expected. """ n1 = Node().store() n2 = Node().store() n3 = Node().store() # Create a link between these 2 nodes n2.add_link_from(n1, "N1") n3.add_link_from(n2, "N2") # Check that the result of outputs is a list self.assertIsInstance(n1.dbnode.inputs, list, "This is expected to be a list") # Check that the result of outputs_q is a query from sqlalchemy.orm.dynamic import AppenderQuery self.assertIsInstance(n1.dbnode.inputs_q, AppenderQuery, "This is expected to be an AppenderQuery") # Check that the result of inputs is correct out = set([_.pk for _ in n3.dbnode.inputs]) self.assertEqual(out, set([n2.pk]))
def test_get_inputs_and_outputs(self): a1 = Node().store() a2 = Node().store() a3 = Node().store() a4 = Node().store() a2.add_link_from(a1) a3.add_link_from(a2) a4.add_link_from(a2) a4.add_link_from(a3) # I check that I get the correct links self.assertEquals(set([n.uuid for n in a1.get_inputs()]), set([])) self.assertEquals(set([n.uuid for n in a1.get_outputs()]), set([a2.uuid])) self.assertEquals(set([n.uuid for n in a2.get_inputs()]), set([a1.uuid])) self.assertEquals(set([n.uuid for n in a2.get_outputs()]), set([a3.uuid, a4.uuid])) self.assertEquals(set([n.uuid for n in a3.get_inputs()]), set([a2.uuid])) self.assertEquals(set([n.uuid for n in a3.get_outputs()]), set([a4.uuid])) self.assertEquals(set([n.uuid for n in a4.get_inputs()]), set([a2.uuid, a3.uuid])) self.assertEquals(set([n.uuid for n in a4.get_outputs()]), set([]))
def test_loop_not_allowed(self): """ Test that no loop can be formed when inserting link """ n1 = Node().store() n2 = Node().store() n3 = Node().store() n4 = Node().store() n2.add_link_from(n1) n3.add_link_from(n2) n4.add_link_from(n3) with self.assertRaises(ValueError): # This would generate a loop n1.add_link_from(n4)
def test_creation_and_deletion(self): from aiida.backends.djsite.db.models import DbLink # Direct links from aiida.orm.querybuilder import QueryBuilder from aiida.common.links import LinkType n1 = Node().store() n2 = Node().store() n3 = Node().store() n4 = Node().store() n5 = Node().store() n6 = Node().store() n7 = Node().store() n8 = Node().store() n9 = Node().store() # I create a strange graph, inserting links in a order # such that I often have to create the transitive closure # between two graphs n3.add_link_from(n2, link_type=LinkType.CREATE) n2.add_link_from(n1, link_type=LinkType.CREATE) n5.add_link_from(n3, link_type=LinkType.CREATE) n5.add_link_from(n4, link_type=LinkType.CREATE) n4.add_link_from(n2, link_type=LinkType.CREATE) n7.add_link_from(n6, link_type=LinkType.CREATE) n8.add_link_from(n7, link_type=LinkType.CREATE) # Yet, no links from 1 to 8 self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 0) n6.add_link_from(n5, link_type=LinkType.INPUT) # Yet, now 2 links from 1 to 8 self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 2) n7.add_link_from(n9, link_type=LinkType.INPUT) # Still two links... self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 2) n9.add_link_from(n6, link_type=LinkType.INPUT) # And now there should be 4 nodes self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 4) ### I start deleting now # I cut one branch below: I should loose 2 links DbLink.objects.filter(input=n6, output=n9).delete() self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 2) DbLink.objects.filter(input=n2, output=n4).delete() self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 1) #~ self.assertEquals( #~ len(DbPath.objects.filter(parent=n1, child=n8).distinct()), 1) # Another cut should delete all links DbLink.objects.filter(input=n3, output=n5).delete() self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 0) #~ self.assertEquals( #~ len(DbPath.objects.filter(parent=n1, child=n8).distinct()), 0) # But I did not delete everything! For instance, I can check # the following links self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n4.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 1) self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n5.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n7.pk }).count(), 1) #~ self.assertEquals( #~ len(DbPath.objects.filter(parent=n4, child=n8).distinct()), 1) #~ self.assertEquals( #~ len(DbPath.objects.filter(parent=n5, child=n7).distinct()), 1) # Finally, I reconnect in a different way the two graphs and # check that 1 and 8 are again connected n4.add_link_from(n3, link_type=LinkType.INPUT) self.assertEquals( QueryBuilder().append(Node, filters={ 'id': n1.pk }, tag='anc').append(Node, descendant_of='anc', filters={ 'id': n8.pk }).count(), 1)
def test_links_and_queries(self): from aiida.backends.djsite.db.models import DbNode, DbLink a = Node() a._set_attr('myvalue', 123) a.store() a2 = Node().store() a3 = Node() a3._set_attr('myvalue', 145) a3.store() a4 = Node().store() a2.add_link_from(a) a3.add_link_from(a2) a4.add_link_from(a2) a4.add_link_from(a3) b = Node.query(pk=a2) self.assertEquals(len(b), 1) # It is a aiida.orm.Node instance self.assertTrue(isinstance(b[0], Node)) self.assertEquals(b[0].uuid, a2.uuid) going_out_from_a2 = Node.query(inputs__in=b) # Two nodes going out from a2 self.assertEquals(len(going_out_from_a2), 2) self.assertTrue(isinstance(going_out_from_a2[0], Node)) self.assertTrue(isinstance(going_out_from_a2[1], Node)) uuid_set = set([going_out_from_a2[0].uuid, going_out_from_a2[1].uuid]) # I check that I can query also directly the django DbNode # class passing a aiida.orm.Node entity going_out_from_a2_db = DbNode.objects.filter(inputs__in=b) self.assertEquals(len(going_out_from_a2_db), 2) self.assertTrue(isinstance(going_out_from_a2_db[0], DbNode)) self.assertTrue(isinstance(going_out_from_a2_db[1], DbNode)) uuid_set_db = set( [going_out_from_a2_db[0].uuid, going_out_from_a2_db[1].uuid]) # I check that doing the query with a Node or DbNode instance, # I get the same nodes self.assertEquals(uuid_set, uuid_set_db) # This time I don't use the __in filter, but I still pass a Node instance going_out_from_a2_bis = Node.query(inputs=b[0]) self.assertEquals(len(going_out_from_a2_bis), 2) self.assertTrue(isinstance(going_out_from_a2_bis[0], Node)) self.assertTrue(isinstance(going_out_from_a2_bis[1], Node)) # Query for links starting from b[0]==a2 using again the Node class output_links_b = DbLink.objects.filter(input=b[0]) self.assertEquals(len(output_links_b), 2) self.assertTrue(isinstance(output_links_b[0], DbLink)) self.assertTrue(isinstance(output_links_b[1], DbLink)) uuid_set_db_link = set( [output_links_b[0].output.uuid, output_links_b[1].output.uuid]) self.assertEquals(uuid_set, uuid_set_db_link) # Query for related fields using django syntax # Note that being myvalue an attribute, it is internally stored starting # with an underscore nodes_with_given_attribute = Node.query(dbattributes__key='myvalue', dbattributes__ival=145) # should be entry a3 self.assertEquals(len(nodes_with_given_attribute), 1) self.assertTrue(isinstance(nodes_with_given_attribute[0], Node)) self.assertEquals(nodes_with_given_attribute[0].uuid, a3.uuid)
def test_creation_and_deletion(self): from aiida.backends.sqlalchemy.models.node import DbLink # Direct links from aiida.backends.sqlalchemy.models.node import DbPath # The transitive closure table from aiida.orm.node import Node n1 = Node().store() n2 = Node().store() n3 = Node().store() n4 = Node().store() n5 = Node().store() n6 = Node().store() n7 = Node().store() n8 = Node().store() n9 = Node().store() # I create a strange graph, inserting links in a order # such that I often have to create the transitive closure # between two graphs n3.add_link_from(n2) n2.add_link_from(n1) n5.add_link_from(n3) n5.add_link_from(n4) n4.add_link_from(n2) n7.add_link_from(n6) n8.add_link_from(n7) # Yet, no links from 1 to 8 self.assertEquals( DbPath.query.filter(DbPath.parent == n1.dbnode, DbPath.child == n8.dbnode).distinct().count(), 0) n6.add_link_from(n5) # Yet, now 2 links from 1 to 8 self.assertEquals( DbPath.query.filter(DbPath.parent == n1.dbnode, DbPath.child == n8.dbnode).distinct().count(), 2) n7.add_link_from(n9) # Still two links... self.assertEquals( DbPath.query.filter(DbPath.parent == n1.dbnode, DbPath.child == n8.dbnode).distinct().count(), 2) n9.add_link_from(n6) # And now there should be 4 nodes self.assertEquals( DbPath.query.filter(DbPath.parent == n1.dbnode, DbPath.child == n8.dbnode).distinct().count(), 4) ### I start deleting now # I cut one branch below: I should loose 2 links DbLink.query.filter(DbLink.input == n6.dbnode, DbLink.output == n9.dbnode).delete() self.assertEquals( DbPath.query.filter(DbPath.parent == n1.dbnode, DbPath.child == n8.dbnode).distinct().count(), 2) # I cut another branch above: I should loose one more link DbLink.query.filter(DbLink.input == n2.dbnode, DbLink.output == n4.dbnode).delete() self.assertEquals( DbPath.query.filter(DbPath.parent == n1.dbnode, DbPath.child == n8.dbnode).distinct().count(), 1) # Another cut should delete all links DbLink.query.filter(DbLink.input == n3.dbnode, DbLink.output == n5.dbnode).delete() self.assertEquals( DbPath.query.filter(DbPath.parent == n1.dbnode, DbPath.child == n8.dbnode).distinct().count(), 0) # But I did not delete everything! For instance, I can check # the following links self.assertEquals( DbPath.query.filter(DbPath.parent == n4.dbnode, DbPath.child == n8.dbnode).distinct().count(), 1) self.assertEquals( DbPath.query.filter(DbPath.parent == n5.dbnode, DbPath.child == n7.dbnode).distinct().count(), 1) # Finally, I reconnect in a different way the two graphs and # check that 1 and 8 are again connected n4.add_link_from(n3) self.assertEquals( DbPath.query.filter(DbPath.parent == n1.dbnode, DbPath.child == n8.dbnode).distinct().count(), 1)
def test_creation_and_deletion(self): """ Test the creation and deletion of the transitive closure table """ n1 = Node().store() n2 = Node().store() n3 = Node().store() n4 = Node().store() n5 = Node().store() n6 = Node().store() n7 = Node().store() n8 = Node().store() n9 = Node().store() # I create a strange graph, inserting links in a order # such that I often have to create the transitive closure # between two graphs n3.add_link_from(n2) n2.add_link_from(n1) n5.add_link_from(n3) n5.add_link_from(n4) n4.add_link_from(n2) n7.add_link_from(n6) n8.add_link_from(n7) # Yet, no links from 1 to 8 self.assertEquals( DbPath.query.filter_by(parent_id=n1.dbnode.id, child_id=n8.dbnode.id).count(), 0) n6.add_link_from(n5) # Yet, now 2 links from 1 to 8 self.assertEquals( DbPath.query.filter_by(parent_id=n1.dbnode.id, child_id=n8.dbnode.id).count(), 2) n7.add_link_from(n9) # Still two links... self.assertEquals( DbPath.query.filter_by(parent_id=n1.dbnode.id, child_id=n8.dbnode.id).count(), 2) n9.add_link_from(n6) # And now there should be 4 nodes self.assertEquals( DbPath.query.filter_by(parent_id=n1.dbnode.id, child_id=n8.dbnode.id).count(), 4) ### I start deleting now # I cut one branch below: I should loose 2 links self.session.delete( DbLink.query.filter_by(input_id=n6.dbnode.id, output_id=n9.dbnode.id).first()) self.assertEquals( DbPath.query.filter_by(parent_id=n1.dbnode.id, child_id=n8.dbnode.id).count(), 2) # I cut another branch above: I should loose one more link self.session.delete( DbLink.query.filter_by(input_id=n2.dbnode.id, output_id=n4.dbnode.id).first()) self.assertEquals( DbPath.query.filter_by(parent_id=n1.dbnode.id, child_id=n8.dbnode.id).count(), 1) # Another cut should delete all links self.session.delete( DbLink.query.filter_by(input_id=n3.dbnode.id, output_id=n5.dbnode.id).first()) self.assertEquals( DbPath.query.filter_by(parent_id=n1.dbnode.id, child_id=n8.dbnode.id).count(), 0) # But I did not delete everything! For instance, I can check # the following links self.assertEquals( DbPath.query.filter_by(parent_id=n4.dbnode.id, child_id=n8.dbnode.id).count(), 1) self.assertEquals( DbPath.query.filter_by(parent_id=n5.dbnode.id, child_id=n8.dbnode.id).count(), 1) # Finally, I reconnect in a different way the two graphs and # check that 1 and 8 are again connected n4.add_link_from(n3) self.assertEquals( DbPath.query.filter_by(parent_id=n1.dbnode.id, child_id=n8.dbnode.id).count(), 1)
def test_links_and_queries(self): a = Node() a._set_attr('myvalue', 123) a.store() a2 = Node().store() a3 = Node() a3._set_attr('myvalue', 145) a3.store() a4 = Node().store() a2.add_link_from(a) a3.add_link_from(a2) a4.add_link_from(a2) a4.add_link_from(a3) b = Node.query(id=a2.id).all() self.assertEquals(len(b), 1) # It is a aiida.orm.Node instance self.assertTrue(isinstance(b[0], Node)) self.assertEquals(b[0].uuid, a2.uuid) going_out_from_a2 = Node.query(inputs__id__in=[_.id for _ in b]).all() # Two nodes going out from a2 self.assertEquals(len(going_out_from_a2), 2) self.assertTrue(isinstance(going_out_from_a2[0], Node)) self.assertTrue(isinstance(going_out_from_a2[1], Node)) uuid_set = set([going_out_from_a2[0].uuid, going_out_from_a2[1].uuid]) # I check that I can query also directly the django DbNode # class passing a aiida.orm.Node entity # # XXX SP: we can't do this using SqlAlchemy => pass a Node instance and # # expect a filter on the DbNode id # going_out_from_a2_db = DbNode.query.filter(DbNode.inputs.in_(b)).all() # self.assertEquals(len(going_out_from_a2_db), 2) # self.assertTrue(isinstance(going_out_from_a2_db[0], DbNode)) # self.assertTrue(isinstance(going_out_from_a2_db[1], DbNode)) # uuid_set_db = set([going_out_from_a2_db[0].uuid, # going_out_from_a2_db[1].uuid]) # # # I check that doing the query with a Node or DbNode instance, # # I get the same nodes # self.assertEquals(uuid_set, uuid_set_db) # # # This time I don't use the __in filter, but I still pass a Node instance # going_out_from_a2_bis = Node.query(inputs=b[0]).all() # self.assertEquals(len(going_out_from_a2_bis), 2) # self.assertTrue(isinstance(going_out_from_a2_bis[0], Node)) # self.assertTrue(isinstance(going_out_from_a2_bis[1], Node)) # # # Query for links starting from b[0]==a2 using again the Node class # output_links_b = DbLink.query.filter_by(input=b[0]) # self.assertEquals(len(output_links_b), 2) # self.assertTrue(isinstance(output_links_b[0], DbLink)) # self.assertTrue(isinstance(output_links_b[1], DbLink)) # uuid_set_db_link = set([output_links_b[0].output.uuid, # output_links_b[1].output.uuid]) # self.assertEquals(uuid_set, uuid_set_db_link) # Query for related fields using django syntax # Note that being myvalue an attribute, it is internally stored starting # with an underscore nodes_with_given_attribute = Node.query(dbattributes__key='myvalue', dbattributes__ival=145).all() # should be entry a3 self.assertEquals(len(nodes_with_given_attribute), 1) self.assertTrue(isinstance(nodes_with_given_attribute[0], Node)) self.assertEquals(nodes_with_given_attribute[0].uuid, a3.uuid)
def test_creation_and_deletion(self): from aiida.backends.djsite.db.models import DbLink # Direct links from aiida.backends.djsite.db.models import DbPath # The transitive closure table n1 = Node().store() n2 = Node().store() n3 = Node().store() n4 = Node().store() n5 = Node().store() n6 = Node().store() n7 = Node().store() n8 = Node().store() n9 = Node().store() # I create a strange graph, inserting links in a order # such that I often have to create the transitive closure # between two graphs n3.add_link_from(n2) n2.add_link_from(n1) n5.add_link_from(n3) n5.add_link_from(n4) n4.add_link_from(n2) n7.add_link_from(n6) n8.add_link_from(n7) # Yet, no links from 1 to 8 self.assertEquals( len(DbPath.objects.filter(parent=n1, child=n8).distinct()), 0) n6.add_link_from(n5) # Yet, now 2 links from 1 to 8 self.assertEquals( len(DbPath.objects.filter(parent=n1, child=n8).distinct()), 2) n7.add_link_from(n9) # Still two links... self.assertEquals( len(DbPath.objects.filter(parent=n1, child=n8).distinct()), 2) n9.add_link_from(n6) # And now there should be 4 nodes self.assertEquals( len(DbPath.objects.filter(parent=n1, child=n8).distinct()), 4) ### I start deleting now # I cut one branch below: I should loose 2 links DbLink.objects.filter(input=n6, output=n9).delete() self.assertEquals( len(DbPath.objects.filter(parent=n1, child=n8).distinct()), 2) # print "\n".join([str((i.pk, i.input.pk, i.output.pk)) # for i in DbLink.objects.filter()]) # print "\n".join([str((i.pk, i.parent.pk, i.child.pk, i.depth, # i.entry_edge_id, i.direct_edge_id, # i.exit_edge_id)) for i in DbPath.objects.filter()]) # I cut another branch above: I should loose one more link DbLink.objects.filter(input=n2, output=n4).delete() # print "\n".join([str((i.pk, i.input.pk, i.output.pk)) # for i in DbLink.objects.filter()]) # print "\n".join([str((i.pk, i.parent.pk, i.child.pk, i.depth, # i.entry_edge_id, i.direct_edge_id, # i.exit_edge_id)) for i in DbPath.objects.filter()]) self.assertEquals( len(DbPath.objects.filter(parent=n1, child=n8).distinct()), 1) # Another cut should delete all links DbLink.objects.filter(input=n3, output=n5).delete() self.assertEquals( len(DbPath.objects.filter(parent=n1, child=n8).distinct()), 0) # But I did not delete everything! For instance, I can check # the following links self.assertEquals( len(DbPath.objects.filter(parent=n4, child=n8).distinct()), 1) self.assertEquals( len(DbPath.objects.filter(parent=n5, child=n7).distinct()), 1) # Finally, I reconnect in a different way the two graphs and # check that 1 and 8 are again connected n4.add_link_from(n3) self.assertEquals( len(DbPath.objects.filter(parent=n1, child=n8).distinct()), 1)