Пример #1
0
    def fill_repo(self):
        """Utility function to create repository nodes"""
        from aiida.orm import CalcJobNode, Data, Dict

        extra_name = self.__class__.__name__ + '/test_with_subclasses'
        resources = {'num_machines': 1, 'num_mpiprocs_per_machine': 1}

        a1 = CalcJobNode(computer=self.computer)
        a1.set_option('resources', resources)
        a1.store()
        # To query only these nodes later
        a1.set_extra(extra_name, True)
        a3 = Data().store()
        a3.set_extra(extra_name, True)
        a4 = Dict(dict={'a': 'b'}).store()
        a4.set_extra(extra_name, True)
        a5 = Data().store()
        a5.set_extra(extra_name, True)
        # I don't set the extras, just to be sure that the filtering works
        # The filtering is needed because other tests will put stuff int he DB
        a6 = CalcJobNode(computer=self.computer)
        a6.set_option('resources', resources)
        a6.store()
        a7 = Data()
        a7.store()
Пример #2
0
    def test_ordering_limits_offsets_sqla(self):
        """Test ordering limits offsets of SQLA query results."""
        # Creating 10 nodes with an attribute that can be ordered
        for i in range(10):
            node = Data()
            node.set_attribute('foo', i)
            node.store()
        q_b = QueryBuilder().append(Node, project='attributes.foo').order_by(
            {Node: {
                'attributes.foo': {
                    'cast': 'i'
                }
            }})
        res = next(zip(*q_b.all()))
        self.assertEqual(res, tuple(range(10)))

        # Now applying an offset:
        q_b.offset(5)
        res = next(zip(*q_b.all()))
        self.assertEqual(res, tuple(range(5, 10)))

        # Now also applying a limit:
        q_b.limit(3)
        res = next(zip(*q_b.all()))
        self.assertEqual(res, tuple(range(5, 8)))
Пример #3
0
    def test_ordering_limits_offsets_of_results_for_SQLA(self):
        from aiida.orm import Node, Data
        from aiida.orm.querybuilder import QueryBuilder
        # Creating 10 nodes with an attribute that can be ordered
        for i in range(10):
            n = Data()
            n.set_attribute('foo', i)
            n.store()
        qb = QueryBuilder().append(
            Node, project='attributes.foo'
        ).order_by(
            {Node: {'attributes.foo': {'cast': 'i'}}}
        )
        res = next(zip(*qb.all()))
        self.assertEqual(res, tuple(range(10)))

        # Now applying an offset:
        qb.offset(5)
        res = next(zip(*qb.all()))
        self.assertEqual(res, tuple(range(5, 10)))

        # Now also applying a limit:
        qb.limit(3)
        res = next(zip(*qb.all()))
        self.assertEqual(res, tuple(range(5, 8)))
Пример #4
0
    def test_node_outdegree_unique_triple(self):
        """Test that the validation of links with outdegree `unique_triple` works correctly

        The example here is a `CalculationNode` that has two outgoing CREATE links with the same label, but to different
        target nodes. This is legal and should pass validation.
        """
        creator = CalculationNode().store()
        data_one = Data()
        data_two = Data()

        # Verify that adding two create links with the same link label but to different target is allowed from the
        # perspective of the source node (the CalculationNode in this case)
        data_one.add_incoming(creator,
                              link_type=LinkType.CREATE,
                              link_label='create')
        data_two.add_incoming(creator,
                              link_type=LinkType.CREATE,
                              link_label='create')
        data_one.store()
        data_two.store()

        uuids_outgoing = set(node.uuid
                             for node in creator.get_outgoing().all_nodes())
        uuids_expected = set([data_one.uuid, data_two.uuid])
        self.assertEqual(uuids_outgoing, uuids_expected)
Пример #5
0
def get_data_node(store=True):
    """A function to create a simple data node."""
    data = Data()
    data.set_attribute_many({str(i): i for i in range(10)})
    if store:
        data.store()
    return (), {'node': data}
Пример #6
0
def get_data_node_and_object(store=True):
    """A function to create a simple data node, with an object."""
    data = Data()
    data.set_attribute_many({str(i): i for i in range(10)})
    data.put_object_from_filelike(StringIO('a' * 10000), 'key')
    if store:
        data.store()
    return (), {'node': data}
Пример #7
0
    def test_delete_collection_outgoing_link(self):
        """Test deletion through objects collection raises when there are outgoing links."""
        calculation = CalculationNode().store()
        data = Data()
        data.add_incoming(calculation, LinkType.CREATE, 'output')
        data.store()

        with pytest.raises(exceptions.InvalidOperation):
            Node.objects.delete(calculation.pk)
Пример #8
0
    def test_load_nodes(self):
        """
        Test for load_node() function.
        """
        from aiida.orm import load_node
        from aiida.backends.sqlalchemy import get_scoped_session

        a = Data()
        a.store()

        self.assertEquals(a.pk, load_node(identifier=a.pk).pk)
        self.assertEquals(a.pk, load_node(identifier=a.uuid).pk)
        self.assertEquals(a.pk, load_node(pk=a.pk).pk)
        self.assertEquals(a.pk, load_node(uuid=a.uuid).pk)

        session = get_scoped_session()

        try:
            session.begin_nested()
            with self.assertRaises(ValueError):
                load_node(identifier=a.pk, pk=a.pk)
        finally:
            session.rollback()

        try:
            session.begin_nested()
            with self.assertRaises(ValueError):
                load_node(pk=a.pk, uuid=a.uuid)
        finally:
            session.rollback()

        try:
            session.begin_nested()
            with self.assertRaises(TypeError):
                load_node(pk=a.uuid)
        finally:
            session.rollback()

        try:
            session.begin_nested()
            with self.assertRaises(TypeError):
                load_node(uuid=a.pk)
        finally:
            session.rollback()

        try:
            session.begin_nested()
            with self.assertRaises(ValueError):
                load_node()
        finally:
            session.rollback()
Пример #9
0
    def test_erase_stored_raise(self):
        """
        Test that trying to erase the repository content of a stored
        Data node without the force flag raises.
        """
        node = Data()
        node.put_object_from_tree(self.tempdir, '')
        node.store()

        self.assertEqual(sorted(node.list_object_names()), ['c.txt', 'subdir'])
        self.assertEqual(sorted(node.list_object_names('subdir')),
                         ['a.txt', 'b.txt', 'nested'])

        self.assertRaises(ModificationNotAllowed, node._repository.erase)  # pylint: disable=protected-access
Пример #10
0
    def test_detect_invalid_nodes_unknown_node_type(self):
        """Test `verdi database integrity detect-invalid-nodes` when node type is invalid."""
        result = self.cli_runner.invoke(cmd_database.detect_invalid_nodes, [])
        self.assertEqual(result.exit_code, 0)
        self.assertClickResultNoException(result)

        # Create a node with invalid type: since there are a lot of validation rules that prevent us from creating an
        # invalid node type normally, we have to do it manually on the database model instance before storing
        node = Data()
        node.backend_entity.dbmodel.node_type = '__main__.SubClass.'
        node.store()

        result = self.cli_runner.invoke(cmd_database.detect_invalid_nodes, [])
        self.assertNotEqual(result.exit_code, 0)
        self.assertIsNotNone(result.exception)
Пример #11
0
    def test_erase_stored_force(self):
        """
        Test that _repository.erase removes the content of an stored
        Data node when passing force=True.
        """
        node = Data()
        node.put_object_from_tree(self.tempdir, '')
        node.store()

        self.assertEqual(sorted(node.list_object_names()), ['c.txt', 'subdir'])
        self.assertEqual(sorted(node.list_object_names('subdir')),
                         ['a.txt', 'b.txt', 'nested'])

        node._repository.erase(force=True)  # pylint: disable=protected-access
        self.assertEqual(node.list_object_names(), [])
Пример #12
0
def test_store_from_cache():
    """Regression test for storing a Node with (nested) repository content with caching."""
    data = Data()
    with tempfile.TemporaryDirectory() as tmpdir:
        dir_path = os.path.join(tmpdir, 'directory')
        os.makedirs(dir_path)
        with open(os.path.join(dir_path, 'file'), 'w') as file:
            file.write('content')
        data.put_object_from_tree(tmpdir)

    data.store()

    clone = data.clone()
    clone._store_from_cache(data, with_transaction=True)  # pylint: disable=protected-access

    assert clone.is_stored
    assert clone.get_cache_source() == data.uuid
    assert data.get_hash() == clone.get_hash()
Пример #13
0
    def test_subclassing(self):
        from aiida.orm.data.structure import StructureData
        from aiida.orm.data.parameter import ParameterData
        from aiida.orm import Node, Data
        from aiida.orm.querybuilder import QueryBuilder
        s = StructureData()
        s._set_attr('cat', 'miau')
        s.store()

        d = Data()
        d._set_attr('cat', 'miau')
        d.store()

        p = ParameterData(dict=dict(cat='miau'))
        p.store()

        n = Node()
        n._set_attr('cat', 'miau')
        n.store()

        # Now when asking for a node with attr.cat==miau, I want 4 esults:
        qb = QueryBuilder().append(Node, filters={'attributes.cat': 'miau'})
        self.assertEqual(qb.count(), 4)

        qb = QueryBuilder().append(Data, filters={'attributes.cat': 'miau'})
        self.assertEqual(qb.count(), 3)

        # If I'm asking for the specific lowest subclass, I want one result
        for cls in (StructureData, ParameterData):
            qb = QueryBuilder().append(cls, filters={'attributes.cat': 'miau'})
            self.assertEqual(qb.count(), 1)

        # Now I am not allow the subclassing, which should give 1 result for each
        for cls in (StructureData, ParameterData, Node, Data):
            qb = QueryBuilder().append(cls,
                                       filters={'attributes.cat': 'miau'},
                                       subclassing=False)
            self.assertEqual(qb.count(), 1)
Пример #14
0
    def test_simple_query_django_1(self):
        """
        Testing a simple query
        """
        from aiida.orm.querybuilder import QueryBuilder
        from aiida.orm.calculation.job import JobCalculation
        from aiida.orm import Node, Data, Calculation
        from datetime import datetime
        from aiida.common.links import LinkType

        n1 = Data()
        n1.label = 'node1'
        n1._set_attr('foo', ['hello', 'goodbye'])
        n1.store()

        n2 = Calculation()
        n2.label = 'node2'
        n2._set_attr('foo', 1)
        n2.store()

        n3 = Data()
        n3.label = 'node3'
        n3._set_attr('foo', 1.0000)  # Stored as fval
        n3.store()

        n4 = Calculation()
        n4.label = 'node4'
        n4._set_attr('foo', 'bar')
        n4.store()

        n5 = Data()
        n5.label = 'node5'
        n5._set_attr('foo', None)
        n5.store()

        n2.add_link_from(n1, link_type=LinkType.INPUT)
        n3.add_link_from(n2, link_type=LinkType.CREATE)

        n4.add_link_from(n3, link_type=LinkType.INPUT)
        n5.add_link_from(n4, link_type=LinkType.CREATE)

        qb1 = QueryBuilder()
        qb1.append(Node, filters={'attributes.foo': 1.000})

        self.assertEqual(len(qb1.all()), 2)

        qb2 = QueryBuilder()
        qb2.append(Data)
        self.assertEqual(qb2.count(), 3)

        qb2 = QueryBuilder()
        qb2.append(type='data.Data.')
        self.assertEqual(qb2.count(), 3)

        qb3 = QueryBuilder()
        qb3.append(Node, project='label', tag='node1')
        qb3.append(Node, project='label', tag='node2')
        self.assertEqual(qb3.count(), 4)

        qb4 = QueryBuilder()
        qb4.append(Calculation, tag='node1')
        qb4.append(Data, tag='node2')
        self.assertEqual(qb4.count(), 2)

        qb5 = QueryBuilder()
        qb5.append(Data, tag='node1')
        qb5.append(Calculation, tag='node2')
        self.assertEqual(qb5.count(), 2)

        qb6 = QueryBuilder()
        qb6.append(Data, tag='node1')
        qb6.append(Data, tag='node2')
        self.assertEqual(qb6.count(), 0)
Пример #15
0
class TestNodeAttributesExtras(AiidaTestCase):
    """Test for node attributes and extras."""

    def setUp(self):
        super(TestNodeAttributesExtras, self).setUp()
        self.node = Data()

    def test_attributes(self):
        """Test the `Node.attributes` property."""
        original_attribute = {'nested': {'a': 1}}

        self.node.set_attribute('key', original_attribute)
        node_attributes = self.node.attributes
        self.assertEqual(node_attributes['key'], original_attribute)
        node_attributes['key']['nested']['a'] = 2

        self.assertEqual(original_attribute['nested']['a'], 2)

        # Now store the node and verify that `attributes` then returns a deep copy
        self.node.store()
        node_attributes = self.node.attributes

        # We change the returned node attributes but the original attribute should remain unchanged
        node_attributes['key']['nested']['a'] = 3
        self.assertEqual(original_attribute['nested']['a'], 2)

    def test_get_attribute(self):
        """Test the `Node.get_attribute` method."""
        original_attribute = {'nested': {'a': 1}}

        self.node.set_attribute('key', original_attribute)
        node_attribute = self.node.get_attribute('key')
        self.assertEqual(node_attribute, original_attribute)
        node_attribute['nested']['a'] = 2

        self.assertEqual(original_attribute['nested']['a'], 2)

        default = 'default'
        self.assertEqual(self.node.get_attribute('not_existing', default=default), default)
        with self.assertRaises(AttributeError):
            self.node.get_attribute('not_existing')

        # Now store the node and verify that `get_attribute` then returns a deep copy
        self.node.store()
        node_attribute = self.node.get_attribute('key')

        # We change the returned node attributes but the original attribute should remain unchanged
        node_attribute['nested']['a'] = 3
        self.assertEqual(original_attribute['nested']['a'], 2)

        default = 'default'
        self.assertEqual(self.node.get_attribute('not_existing', default=default), default)
        with self.assertRaises(AttributeError):
            self.node.get_attribute('not_existing')

    def test_get_attribute_many(self):
        """Test the `Node.get_attribute_many` method."""
        original_attribute = {'nested': {'a': 1}}

        self.node.set_attribute('key', original_attribute)
        node_attribute = self.node.get_attribute_many(['key'])[0]
        self.assertEqual(node_attribute, original_attribute)
        node_attribute['nested']['a'] = 2

        self.assertEqual(original_attribute['nested']['a'], 2)

        # Now store the node and verify that `get_attribute` then returns a deep copy
        self.node.store()
        node_attribute = self.node.get_attribute_many(['key'])[0]

        # We change the returned node attributes but the original attribute should remain unchanged
        node_attribute['nested']['a'] = 3
        self.assertEqual(original_attribute['nested']['a'], 2)

    def test_set_attribute(self):
        """Test the `Node.set_attribute` method."""
        with self.assertRaises(exceptions.ValidationError):
            self.node.set_attribute('illegal.key', 'value')

        self.node.set_attribute('valid_key', 'value')
        self.node.store()

        with self.assertRaises(exceptions.ModificationNotAllowed):
            self.node.set_attribute('valid_key', 'value')

    def test_set_attribute_many(self):
        """Test the `Node.set_attribute` method."""
        with self.assertRaises(exceptions.ValidationError):
            self.node.set_attribute_many({'illegal.key': 'value', 'valid_key': 'value'})

        self.node.set_attribute_many({'valid_key': 'value'})
        self.node.store()

        with self.assertRaises(exceptions.ModificationNotAllowed):
            self.node.set_attribute_many({'valid_key': 'value'})

    def test_reset_attribute(self):
        """Test the `Node.reset_attribute` method."""
        attributes_before = {'attribute_one': 'value', 'attribute_two': 'value'}
        attributes_after = {'attribute_three': 'value', 'attribute_four': 'value'}
        attributes_illegal = {'attribute.illegal': 'value', 'attribute_four': 'value'}

        self.node.set_attribute_many(attributes_before)
        self.assertEqual(self.node.attributes, attributes_before)
        self.node.reset_attributes(attributes_after)
        self.assertEqual(self.node.attributes, attributes_after)

        with self.assertRaises(exceptions.ValidationError):
            self.node.reset_attributes(attributes_illegal)

        self.node.store()

        with self.assertRaises(exceptions.ModificationNotAllowed):
            self.node.reset_attributes(attributes_after)

    def test_delete_attribute(self):
        """Test the `Node.delete_attribute` method."""
        self.node.set_attribute('valid_key', 'value')
        self.assertEqual(self.node.get_attribute('valid_key'), 'value')
        self.node.delete_attribute('valid_key')

        with self.assertRaises(AttributeError):
            self.node.delete_attribute('valid_key')

        # Repeat with stored node
        self.node.set_attribute('valid_key', 'value')
        self.node.store()

        with self.assertRaises(exceptions.ModificationNotAllowed):
            self.node.delete_attribute('valid_key')

    def test_delete_attribute_many(self):
        """Test the `Node.delete_attribute_many` method."""

    def test_clear_attributes(self):
        """Test the `Node.clear_attributes` method."""
        attributes = {'attribute_one': 'value', 'attribute_two': 'value'}
        self.node.set_attribute_many(attributes)
        self.assertEqual(self.node.attributes, attributes)

        self.node.clear_attributes()
        self.assertEqual(self.node.attributes, {})

        # Repeat for stored node
        self.node.store()

        with self.assertRaises(exceptions.ModificationNotAllowed):
            self.node.clear_attributes()

    def test_attributes_items(self):
        """Test the `Node.attributes_items` generator."""
        attributes = {'attribute_one': 'value', 'attribute_two': 'value'}
        self.node.set_attribute_many(attributes)
        self.assertEqual(dict(self.node.attributes_items()), attributes)

    def test_attributes_keys(self):
        """Test the `Node.attributes_keys` generator."""
        attributes = {'attribute_one': 'value', 'attribute_two': 'value'}
        self.node.set_attribute_many(attributes)
        self.assertEqual(set(self.node.attributes_keys()), set(attributes))

    def test_extras(self):
        """Test the `Node.extras` property."""
        original_extra = {'nested': {'a': 1}}

        self.node.set_extra('key', original_extra)
        node_extras = self.node.extras
        self.assertEqual(node_extras['key'], original_extra)
        node_extras['key']['nested']['a'] = 2

        self.assertEqual(original_extra['nested']['a'], 2)

        # Now store the node and verify that `extras` then returns a deep copy
        self.node.store()
        node_extras = self.node.extras

        # We change the returned node extras but the original extra should remain unchanged
        node_extras['key']['nested']['a'] = 3
        self.assertEqual(original_extra['nested']['a'], 2)

    def test_get_extra(self):
        """Test the `Node.get_extra` method."""
        original_extra = {'nested': {'a': 1}}

        self.node.set_extra('key', original_extra)
        node_extra = self.node.get_extra('key')
        self.assertEqual(node_extra, original_extra)
        node_extra['nested']['a'] = 2

        self.assertEqual(original_extra['nested']['a'], 2)

        default = 'default'
        self.assertEqual(self.node.get_extra('not_existing', default=default), default)
        with self.assertRaises(AttributeError):
            self.node.get_extra('not_existing')

        # Now store the node and verify that `get_extra` then returns a deep copy
        self.node.store()
        node_extra = self.node.get_extra('key')

        # We change the returned node extras but the original extra should remain unchanged
        node_extra['nested']['a'] = 3
        self.assertEqual(original_extra['nested']['a'], 2)

        default = 'default'
        self.assertEqual(self.node.get_extra('not_existing', default=default), default)
        with self.assertRaises(AttributeError):
            self.node.get_extra('not_existing')

    def test_get_extra_many(self):
        """Test the `Node.get_extra_many` method."""
        original_extra = {'nested': {'a': 1}}

        self.node.set_extra('key', original_extra)
        node_extra = self.node.get_extra_many(['key'])[0]
        self.assertEqual(node_extra, original_extra)
        node_extra['nested']['a'] = 2

        self.assertEqual(original_extra['nested']['a'], 2)

        # Now store the node and verify that `get_extra` then returns a deep copy
        self.node.store()
        node_extra = self.node.get_extra_many(['key'])[0]

        # We change the returned node extras but the original extra should remain unchanged
        node_extra['nested']['a'] = 3
        self.assertEqual(original_extra['nested']['a'], 2)

    def test_set_extra(self):
        """Test the `Node.set_extra` method."""
        with self.assertRaises(exceptions.ValidationError):
            self.node.set_extra('illegal.key', 'value')

        self.node.set_extra('valid_key', 'value')
        self.node.store()

        self.node.set_extra('valid_key', 'changed')
        self.assertEqual(load_node(self.node.pk).get_extra('valid_key'), 'changed')

    def test_set_extra_many(self):
        """Test the `Node.set_extra` method."""
        with self.assertRaises(exceptions.ValidationError):
            self.node.set_extra_many({'illegal.key': 'value', 'valid_key': 'value'})

        self.node.set_extra_many({'valid_key': 'value'})
        self.node.store()

        self.node.set_extra_many({'valid_key': 'changed'})
        self.assertEqual(load_node(self.node.pk).get_extra('valid_key'), 'changed')

    def test_reset_extra(self):
        """Test the `Node.reset_extra` method."""
        extras_before = {'extra_one': 'value', 'extra_two': 'value'}
        extras_after = {'extra_three': 'value', 'extra_four': 'value'}
        extras_illegal = {'extra.illegal': 'value', 'extra_four': 'value'}

        self.node.set_extra_many(extras_before)
        self.assertEqual(self.node.extras, extras_before)
        self.node.reset_extras(extras_after)
        self.assertEqual(self.node.extras, extras_after)

        with self.assertRaises(exceptions.ValidationError):
            self.node.reset_extras(extras_illegal)

        self.node.store()

        self.node.reset_extras(extras_after)
        self.assertEqual(load_node(self.node.pk).extras, extras_after)

    def test_delete_extra(self):
        """Test the `Node.delete_extra` method."""
        self.node.set_extra('valid_key', 'value')
        self.assertEqual(self.node.get_extra('valid_key'), 'value')
        self.node.delete_extra('valid_key')

        with self.assertRaises(AttributeError):
            self.node.delete_extra('valid_key')

        # Repeat with stored node
        self.node.set_extra('valid_key', 'value')
        self.node.store()

        self.node.delete_extra('valid_key')
        with self.assertRaises(AttributeError):
            load_node(self.node.pk).get_extra('valid_key')

    def test_delete_extra_many(self):
        """Test the `Node.delete_extra_many` method."""

    def test_clear_extras(self):
        """Test the `Node.clear_extras` method."""
        extras = {'extra_one': 'value', 'extra_two': 'value'}
        self.node.set_extra_many(extras)
        self.assertEqual(self.node.extras, extras)

        self.node.clear_extras()
        self.assertEqual(self.node.extras, {})

        # Repeat for stored node
        self.node.store()

        self.node.clear_extras()
        self.assertEqual(load_node(self.node.pk).extras, {})

    def test_extras_items(self):
        """Test the `Node.extras_items` generator."""
        extras = {'extra_one': 'value', 'extra_two': 'value'}
        self.node.set_extra_many(extras)
        self.assertEqual(dict(self.node.extras_items()), extras)

    def test_extras_keys(self):
        """Test the `Node.extras_keys` generator."""
        extras = {'extra_one': 'value', 'extra_two': 'value'}
        self.node.set_extra_many(extras)
        self.assertEqual(set(self.node.extras_keys()), set(extras))