Skip to content
Snippets Groups Projects
Select Git revision
  • 522ec28e55b390dbdbbebbb1dd139949638571da
  • main default protected
  • f-yaml-parser-enums
  • dev protected
  • f-fix-paths
  • f-fix-validate-to-dict
  • f-labfolder-converter
  • f-state-machine-script
  • f-xlsx-converter-warnings-errors
  • f-rename
  • f-extra-deps
  • f-more-jsonschema-export
  • f-henrik
  • f-fix-89
  • f-trigger-advanced-user-tools
  • f-real-rename-test
  • f-linkahead-rename
  • f-register-integrationtests
  • f-fix-id
  • f-h5-files
  • f-json-schema
  • v0.14.0
  • v0.13.0
  • v0.12.0
  • v0.11.0
  • v0.10.0-numpy2
  • v0.10.0
  • v0.9.0
  • v0.8.0
  • v0.7.0
  • v0.6.1
  • v0.6.0
  • v0.5.0
  • v0.4.1
  • v0.4.0
  • v0.3.1
  • v0.3.0
37 results

test_json_schema_model_parser.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    test_error_stuff.py 12.19 KiB
    # encoding: utf-8
    #
    # ** header v3.0
    # This file is a part of the CaosDB Project.
    #
    # Copyright (C) 2018 Research Group Biomedical Physics,
    # Max-Planck-Institute for Dynamics and Self-Organization Göttingen
    # Copyright (C) 2020 Indiscale GmbH <info@indiscale.com>
    # Copyright (C) 2020 Florian Spreckelsen <f.spreckelsen@indiscale.com>
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU Affero General Public License as
    # published by the Free Software Foundation, either version 3 of the
    # License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU Affero General Public License for more details.
    #
    # You should have received a copy of the GNU Affero General Public License
    # along with this program. If not, see <https://www.gnu.org/licenses/>.
    #
    # ** end header
    #
    """Test different entity errors.
    
    Created on 19.02.2015.
    
    @author: tf
    
    """
    import linkahead as db
    from caosdb.exceptions import (AmbiguousEntityError,
                                   EntityDoesNotExistError, EntityError,
                                   EntityHasNoDatatypeError,
                                   TransactionError, UniqueNamesError,
                                   UnqualifiedParentsError,
                                   UnqualifiedPropertiesError)
    import pytest
    
    
    def setup_function(function):
        try:
            db.execute_query("FIND ENTITY").delete()
        except BaseException:
            pass
    
    
    def teardown_function(function):
        """Delete everything."""
        setup_function(function)
    
    
    def test_retrieval_no_exception_raised():
        """Test whether retrieval fails but error is suppressed."""
        p = db.Property(name="TestNon-ExsistentProperty").retrieve(
            unique=True, raise_exception_on_error=False)
        assert not p.is_valid()
        assert (p.id is None or p.id < 0)
    
    
    def test_retrieval_exception_raised():
        """Test if a TransactionError with the correct child is raised, and if
        the child has the correct super classes.
    
        """
        propname = "TestNon-ExistentProperty"
        with pytest.raises(TransactionError) as te:
            db.Property(name="TestNon-ExistentProperty").retrieve(unique=True,
                                                                  raise_exception_on_error=True)
        assert len(te.value.errors) == 1
        ee = te.value.errors[0]
        # Check for type incl. inheritance
        assert isinstance(ee, EntityDoesNotExistError)
        assert isinstance(ee, EntityError)
        assert isinstance(ee, TransactionError)
        # Correct entity causing the error:
        assert ee.entity is not None
        assert ee.entity.name == propname
        assert not ee.entity.is_valid()
        assert ee.entity.has_errors()
    
    
    @pytest.mark.xfail(reason=("Error treatment on server-side"
                               "has to be implemented first."))
    def test_ambiguous_retrieval():
        """Test if a TransactionError containing an AmbiguousEntityError is
        raised correctly if there are two possible candidates.
    
        """
        db.RecordType(name="TestType").insert()
        db.Record(name="TestRec").add_parent(name="TestType").insert()
        # Insert twice, so unique=False
        db.Record(name="TestRec").add_parent(name="TestType").insert(unique=False)
        with pytest.raises(TransactionError) as te:
            db.Record(name="TestRec").retrieve()
        assert te.value.has_error(AmbiguousEntityError)
        assert te.value.errors[0].entity.name == "TestRec"
    
    
    def test_insertion_no_exception_raised():
        """Test whether insertion fails but no error is raised."""
        p = db.Property(name="TestNoTypeProperty").insert(
            raise_exception_on_error=False)
        assert not p.is_valid()
        assert (p.id is None or p.id < 0)
    
    
    def test_insertion_exception_raised():
        """Test insertion of a property with missing datatype."""
        p = db.Property(name="TestNoTypeProperty")
        with pytest.raises(TransactionError) as te:
            p.insert(raise_exception_on_error=True)
        assert te.value.has_error(EntityHasNoDatatypeError)
    
    
    def test_insertion_with_invalid_parents():
        with pytest.raises(TransactionError) as te:
            p = db.Property(
                name="TestNoTypeProperty",
                datatype="Text").add_parent(
                id=-1)
            p.insert(raise_exception_on_error=True)
        upe = te.value.errors[0]
        print(upe)
        assert isinstance(upe, UnqualifiedParentsError)
        assert upe.entity is not None
        assert upe.entity.name == p.name
        assert upe.entity.id == p.id
        assert upe.entity.has_errors()
        assert not p.is_valid()
        assert not upe.entity.is_valid()
        assert upe.entities is not None
    
    
    def test_insertion_with_invalid_properties():
        with pytest.raises(TransactionError) as te:
            p = db.Property(
                name="TestNoTypeProperty",
                datatype="Text").add_property(
                id=-1)
            p.insert(raise_exception_on_error=True)
        upe = te.value.errors[0]
        assert isinstance(upe, UnqualifiedPropertiesError)
        assert upe.entity is not None
        assert upe.entity.name == p.name
        assert upe.entity.has_errors()
        assert p.has_errors()
        assert not p.is_valid()
        assert not upe.entity.is_valid()
    
    
    def test_entity_does_not_exist():
        """When retrieving a container with existing and non-existing
        entities, only those that don't exist should cause
        EntityDoesNotExistErrors.
    
        """
        p1 = db.Property(name="TestNon-ExistentProperty1").retrieve(
            raise_exception_on_error=False)
        p2 = db.Property(name="TestNon-ExistentProperty2").retrieve(
            raise_exception_on_error=False)
        p3 = db.Property(name="TestNon-ExistentProperty3").retrieve(
            raise_exception_on_error=False)
        # None of them should exist
        assert not p1.is_valid()
        assert (p1.id is None or p1.id < 0)
        assert not p2.is_valid()
        assert (p2.id is None or p2.id < 0)
        assert not p3.is_valid()
        assert (p3.id is None or p3.id < 0)
    
        pe = db.Property(name="TestExistentProperty", datatype="text").insert()
    
        c = db.Container().extend(
            [
                db.Property(
                    name="TestNon-ExistentProperty1"),
                db.Property(
                    name="TestNon-ExistentProperty2"),
                db.Property(
                    name="TestNon-ExistentProperty3"),
                db.Property(
                    name="TestExistentProperty")])
    
        with pytest.raises(TransactionError) as te:
            c.retrieve()
        te = te.value
        assert te.has_error(EntityDoesNotExistError)
        # Only non-existing entities caused the container error
        assert not pe.name in [x.name for x in te.all_entities]
        for p in (p1, p2, p3):
            assert p.name in [x.name for x in te.all_entities]
    
    
    def test_insert_existent_entity():
        """Insertion of an already existing entity should cause a
        UniqueNamesError.
    
        """
        p1 = db.Property(name="TestNon-ExistentProperty1").retrieve(
            raise_exception_on_error=False)
        p2 = db.Property(name="TestNon-ExistentProperty2").retrieve(
            raise_exception_on_error=False)
        p3 = db.Property(name="TestNon-ExistentProperty3").retrieve(
            raise_exception_on_error=False)
        # None of them should exist
        assert not p1.is_valid()
        assert (p1.id is None or p1.id < 0)
        assert not p2.is_valid()
        assert (p2.id is None or p2.id < 0)
        assert not p3.is_valid()
        assert (p3.id is None or p3.id < 0)
    
        pe = db.Property(name="TestExistentProperty", datatype="text").insert()
        assert pe.is_valid()
    
        c = db.Container().extend(
            [
                db.Property(
                    name="TestNon-ExistentProperty1",
                    datatype="text"),
                db.Property(
                    name="TestNon-ExistentProperty2",
                    datatype="text"),
                db.Property(
                    name="TestNon-ExistentProperty3",
                    datatype="text"),
                db.Property(
                    name="TestExistentProperty",
                    datatype="text")])
    
        with pytest.raises(TransactionError) as te:
            c.insert(unique=True)
        te = te.value
        assert te.has_error(UniqueNamesError)
        une = te.errors[0]
        assert une.entity is not None
        assert pe.name == une.entity.name
        for p in (p1, p2, p3):
            assert p not in te.all_entities
    
    
    def test_double_insertion():
        c1 = db.Container()
    
        c1.append(
            db.Property(
                name="TestSimpleTextProperty",
                description="simple text property (from test_error_stuff.py)",
                datatype='text'))
        c1.append(
            db.Property(
                name="TestSimpleDoubleProperty",
                description="simple double property (from test_error_stuff.py)",
                datatype='double'))
        c1.append(
            db.Property(
                name="TestSimpleIntegerProperty",
                description="simple integer property (from test_error_stuff.py)",
                datatype='integer'))
        c1.append(
            db.Property(
                name="TestSimpleDatetimeProperty",
                description="simple datetime property (from test_error_stuff.py)",
                datatype='datetime'))
    
        c1.append(
            db.RecordType(
                name="TestSimpleRecordType",
                description="simple recordType (from test_error_stuff.py)").add_property(
                    name='TestSimpleTextProperty').add_property(
                        name='TestSimpleDoubleProperty').add_property(
                            name='TestSimpleIntegerProperty').add_property(
                                name='TestSimpleDatetimeProperty'))
    
        c1.insert()
    
        c2 = db.Container()
        c2.append(
            db.Property(
                name="TestSimpleTextProperty",
                description="simple text property (from test_error_stuff.py)",
                datatype='text'))
        c2.append(
            db.Property(
                name="TestSimpleDoubleProperty",
                description="simple double property (from test_error_stuff.py)",
                datatype='double'))
        c2.append(
            db.Property(
                name="TestSimpleIntegerProperty",
                description="simple integer property (from test_error_stuff.py)",
                datatype='integer'))
        c2.append(
            db.Property(
                name="TestSimpleDatetimeProperty",
                description="simple datetime property (from test_error_stuff.py)",
                datatype='datetime'))
    
        c2.append(
            db.RecordType(
                name="TestSimpleRecordType",
                description="simple recordType (from test_error_stuff.py)").add_property(
                    name='TestSimpleTextProperty').add_property(
                        name='TestSimpleDoubleProperty').add_property(
                            name='TestSimpleIntegerProperty').add_property(
                                name='TestSimpleDatetimeProperty'))
        with pytest.raises(TransactionError) as te:
            c2.insert()
        te = te.value
        assert te.has_error(UniqueNamesError)
        # c2 caused the ContainerError
        assert te.container == c2
        # exactly 5 faulty entities in c2
        assert len(te.entities) == 5
    
    
    def test_update_acl_errors():
        """Test the special cases of entity errors when using
        `Entity.update_acl`
    
        """
        rec_ne = db.Record("TestRecordNonExisting")
    
        with pytest.raises(TransactionError) as te:
    
            rec_ne.update_acl()
    
        assert te.value.has_error(EntityDoesNotExistError)
        assert te.value.errors[0].entity.name == rec_ne.name
    
        rt = db.RecordType(name="TestType").insert()
        rec = db.Record(name="TestRecord").add_parent(rt).insert()
        db.Record(name=rec.name).add_parent(rt).insert(unique=False)
    
        with pytest.raises(TransactionError) as te:
    
            db.Record(name=rec.name).update_acl()
    
        assert te.value.has_error(AmbiguousEntityError)
    
    
    def test_URI_too_long():
        """Some tests for variours URI too long commands.
    
        See for example https://gitlab.indiscale.com/caosdb/src/caosdb-pylib/-/issues/180
    
        """
    
        short = 100
        uri_long = 819
        header_long = 815
    
        with pytest.raises(db.TransactionError) as excinfo:
            db.execute_query("0123456789" * short)
        assert "Parsing" in excinfo.value.msg
    
        with pytest.raises(db.HTTPURITooLongError) as excinfo:
            db.execute_query("0123456789" * uri_long)
        assert "414" in excinfo.value.msg
    
        with pytest.raises(db.HTTPURITooLongError) as excinfo:
            db.execute_query("0123456789" * header_long)
        assert "431" in excinfo.value.msg