Select Git revision
import_from_xml.py
-
Timm Fitschen authoredTimm Fitschen authored
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