diff --git a/tests/test_issues_pylib.py b/tests/test_issues_pylib.py new file mode 100644 index 0000000000000000000000000000000000000000..56009a824f9b3a3608f444c2206237c668f394eb --- /dev/null +++ b/tests/test_issues_pylib.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +# This file is a part of the LinkAhead Project. +# +# Copyright (c) 2023 IndiScale GmbH <info@indiscale.com> +# Copyright (c) 2023 Daniel Hornung <d.hornung@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/>. + +"""Tests for issues on gitlab.com, project linkahead-pylib. + +Tests should be named: + + ``test_gitlab_com_{issue_id}`` +""" + +import math +import os +import tempfile +import time + +import linkahead as db +import pytest + +from linkahead import administration as admin +from linkahead.exceptions import (TransactionError, HTTPClientError) + +CURATOR_ROLE = "curator" + + +def setup_module(): + db.configure_connection() + try: + db.execute_query("FIND ENTITY WITH ID > 99").delete() + except Exception as delete_exc: + print(delete_exc) + try: + admin._delete_user("TestUser") + except Exception as delete_exc: + print(delete_exc) + try: + admin._delete_role(CURATOR_ROLE) + except Exception as delete_exc: + print(delete_exc) + + +def setup_function(function): + """No setup required.""" + setup_module() + + +def teardown_function(function): + """Deleting entities again.""" + setup_module() + +# ########################### Issue tests start here ##################### + + +# @pytest.mark.xfail(reason="Entities with many, long, properties: " +# "https://gitlab.com/linkahead/linkahead-pylib/-/issues/108") +def test_gitlab_com_108(): + """Create RT and a list of properties, then insert and retrieve. + + This is another instance of bugs caused by caosdb/src/caosdb-mysqlbackend#48, but was originally + reported as https://gitlab.com/linkahead/linkahead-pylib/-/issues/108 + """ + cont = db.Container() + long = "Long" * 50 + first_RT = db.RecordType(name="TestRecord_first") + for index in range(20): + this_RT = db.RecordType(name=f"TestRecord_{long}_{index:02d}") + first_RT.add_property(this_RT) + cont.append(this_RT) + cont.append(first_RT) + cont.insert() + cont.retrieve() + print("retrieved") + + # Incidentally, the following lines seem to trigger another, unrelated problem + tests = db.execute_query("FIND ENTITY test*", cache=False) + tests.delete() + print("deleted") diff --git a/tests/test_issues_server.py b/tests/test_issues_server.py index f35e85d4b0efe82898f7f11c090045a534aa7b39..932aa2a7d3178323c019aa297ec0369300a692b7 100644 --- a/tests/test_issues_server.py +++ b/tests/test_issues_server.py @@ -101,12 +101,14 @@ def test_issue_62(): # renaming has to be reflected in Test_Record and Test_Prop rec = db.execute_query("FIND Record Test_Record", unique=True) assert rec.parents[0].name == rtb.name + assert rec.get_property("Test_Prop").datatype == rtb.name prop = db.execute_query("FIND Property Test_Prop", unique=True) assert prop.datatype == rtb.name # fails; datatype not updated # Can't use Test_RTA as datatype anymore prop2 = db.Property(name="Test_Prop2", datatype="Test_RTA") - with pytest.raises(TransactionError): + with pytest.raises(TransactionError) as exc: prop2.insert() + assert "Unknown data type." in str(exc.value) def test_issue_85_a(): @@ -178,7 +180,7 @@ def test_issue_99(): dbfile = cont[0] # Checksum should exist after a short time - time.sleep(0.1) + time.sleep(1) dbfile.retrieve() assert dbfile.checksum is not None diff --git a/tests/test_misc.py b/tests/test_misc.py index cdc442cc0bf922444e133360edf2d2e3ca692965..8ffa14310703f34758dd0eec5b987ca27e1c342d 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -33,6 +33,12 @@ from pytest import raises, mark, fixture set_test_key("_CAOSDB_PYINTTEST_SUITE") +def setup_function(function): + d = db.execute_query("SELECT id FROM ENTITY") + if len(d) > 0: + d.delete() + + def teardown_function(function): assert len(db.execute_query("FIND Entity")) == 0 @@ -366,51 +372,62 @@ def test_overrides_in_subdomains(clear_database): pov1 = Property( id=p1.id, + value="pov1", name="TestPropertyov1", description="desc1ov1") pov2 = Property( id=p2.id, + value="pov2", name="TestPropertyov2", - description="desc1ov2") + description="desc2ov2") pov3 = Property( id=p3.id, + value="pov3", name="TestPropertyov3", - description="desc1ov3") + description="desc3ov3") pov21 = Property( id=p1.id, + value="pov21", name="TestPropertyov21", description="desc1ov21") pov22 = Property( id=p2.id, + value="pov22", name="TestPropertyov22", - description="desc1ov22") + description="desc2ov22") pov31 = Property( id=p1.id, + value="pov31", name="TestPropertyov31", description="desc1ov31") pov32 = Property( id=p2.id, + value="pov32", name="TestPropertyov32", - description="desc1ov32") + description="desc2ov32") pov33 = Property( id=p3.id, + value="pov33", name="TestPropertyov33", - description="desc1ov33") + description="desc3ov33") pov321 = Property( id=p1.id, + value="pov321", name="TestPropertyov321", description="desc1ov321") pov322 = Property( id=p2.id, + value="pov322", name="TestPropertyov322", - description="desc1ov322") + description="desc2ov322") pov323 = Property( id=p3.id, + value="pov323", name="TestPropertyov323", - description="desc1ov323") + description="desc3ov323") pov32.add_property(pov321).add_property( pov322).add_property(pov323) @@ -418,8 +435,54 @@ def test_overrides_in_subdomains(clear_database): pov2.add_property(pov21).add_property(pov22) rt1 = RecordType(name="TestRT1").add_property( - pov1).add_property(pov2).add_property(pov3).insert() + pov1).add_property(pov2).add_property(pov3) + + rt1.insert() assert rt1.is_valid() is True + rt1 = db.execute_query(f"FIND ENTITY WITH id={rt1.id}", unique=True) + + assert len(rt1.get_properties()) == 3 + assert rt1.get_property("TestPropertyov1").description == "desc1ov1" + assert rt1.get_property("TestPropertyov1").value == "pov1" + assert rt1.get_property("TestPropertyov2").description == "desc2ov2" + assert rt1.get_property("TestPropertyov2").value == "pov2" + assert rt1.get_property("TestPropertyov3").description == "desc3ov3" + assert rt1.get_property("TestPropertyov3").value == "pov3" + + p1o = rt1.get_property("TestPropertyov1") + assert len(p1o.get_properties()) == 0 + + p2o = rt1.get_property("TestPropertyov2") + assert len(p2o.get_properties()) == 2 + assert p2o.get_property("TestPropertyov21").description == "desc1ov21" + assert p2o.get_property("TestPropertyov21").value == "pov21" + assert p2o.get_property("TestPropertyov22").description == "desc2ov22" + assert p2o.get_property("TestPropertyov22").value == "pov22" + assert len(p2o.get_property("TestPropertyov21").get_properties()) == 0 + assert len(p2o.get_property("TestPropertyov22").get_properties()) == 0 + + p3o = rt1.get_property("TestPropertyov3") + assert len(p3o.get_properties()) == 3 + assert p3o.get_property("TestPropertyov31").description == "desc1ov31" + assert p3o.get_property("TestPropertyov31").value == "pov31" + assert p3o.get_property("TestPropertyov32").description == "desc2ov32" + assert p3o.get_property("TestPropertyov32").value == "pov32" + assert p3o.get_property("TestPropertyov33").description == "desc3ov33" + assert p3o.get_property("TestPropertyov33").value == "pov33" + assert len(p3o.get_property("TestPropertyov31").get_properties()) == 0 + assert len(p3o.get_property("TestPropertyov32").get_properties()) == 3 + assert len(p3o.get_property("TestPropertyov33").get_properties()) == 0 + + p32o = p3o.get_property("TestPropertyov32") + assert p32o.get_property("TestPropertyov321").description == "desc1ov321" + assert p32o.get_property("TestPropertyov321").value == "pov321" + assert p32o.get_property("TestPropertyov322").description == "desc2ov322" + assert p32o.get_property("TestPropertyov322").value == "pov322" + assert p32o.get_property("TestPropertyov323").description == "desc3ov323" + assert p32o.get_property("TestPropertyov323").value == "pov323" + assert len(p32o.get_property("TestPropertyov321").get_properties()) == 0 + assert len(p32o.get_property("TestPropertyov322").get_properties()) == 0 + assert len(p32o.get_property("TestPropertyov323").get_properties()) == 0 def test_role_after_retrieve(clear_database): diff --git a/tests/test_query.py b/tests/test_query.py index dc73ab9348065d598a72ac5ce9f5c2bf85f25932..e864bd101e7441c560ff6fa29b2cec6c2730a558 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -29,13 +29,13 @@ import os import random -import caosdb as db -from pytest import mark, raises +import caosdb as db from caosdb.connection.connection import get_connection from caosdb.exceptions import EmptyUniqueQueryError, TransactionError from caosdb.common.models import is_temporary_id from lxml import etree +from pytest import mark, raises def setup_module(): @@ -94,6 +94,8 @@ def test_query_with_reference_by_parent(): unique=True).id assert exp_rec.id == db.execute_query( "FIND TestExperiment .-> " + str(sp_rec.id), unique=True).id + assert exp_rec.id == db.execute_query("FIND ENTITY " + str(exp_rec.id), unique=True).id + assert exp_rec.id == db.execute_query("FIND RECORD " + str(exp_rec.id), unique=True).id assert exp_rec.id == db.execute_query( "FIND TestExperiment .-> TestSpecialProtocolLog1", unique=True).id assert exp_rec.id == db.execute_query( @@ -1453,3 +1455,18 @@ def test_greatest_smallest_id_over_roles(): assert db.execute_query("FIND ENTITY WITH THE SMALLEST ID", unique=True).id == rt1.id assert db.execute_query("FIND ENTITY WITH THE GREATEST ID", unique=True).id == p2.id + + +def test_find_id(): + """See also: https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/323""" + rt1 = db.RecordType("TestRT1").insert() + rt2 = db.RecordType("TestRT2").insert() + rt3 = db.RecordType("TestRT3").add_parent("TestRT2").add_property("TestRT1").insert() + + assert db.execute_query("FIND TestRT1", unique=True).id == rt1.id + assert db.execute_query(f"FIND {rt1.id}", unique=True).id == rt1.id + assert set([e.id for e in db.execute_query("FIND TestRT2")]) == set([rt2.id, rt3.id]) + assert db.execute_query("FIND TestRT2 WITH TestRT1", unique=True).id == rt3.id + assert db.execute_query("FIND TestRT3 WITH TestRT1", unique=True).id == rt3.id + assert db.execute_query(f"FIND {rt2.id} WITH TestRT1", unique=True).id == rt3.id + assert db.execute_query(f"FIND {rt3.id} WITH TestRT1", unique=True).id == rt3.id