Skip to content
Snippets Groups Projects
Select Git revision
1 result Searching

constants.h.in

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    test_issues_server.py 8.37 KiB
    # -*- coding: utf-8 -*-
    #
    # ** header v3.0
    # This file is a part of the CaosDB Project.
    #
    # Copyright (c) 2020 IndiScale GmbH <info@indiscale.com>
    # Copyright (c) 2020 Daniel Hornung <d.hornung@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
    
    """Tests for issues on gitlab.com, project caosdb-server."""
    
    import os
    import tempfile
    import time
    
    import caosdb as db
    import pytest
    from caosdb.exceptions import TransactionError
    
    
    def setup_module():
        try:
            db.execute_query("FIND ENTITY WITH ID > 99").delete()
        except Exception as delete_exc:
            print(delete_exc)
    
    
    def setup():
        """No setup required."""
        setup_module()
    
    
    def teardown():
        """Deleting entities again."""
        setup_module()
    
    
    # ########################### Issue tests start here #####################
    
    
    def test_issue_39():
        """Query Language Bug - quotes around year
    
        Test for https://gitlab.com/caosdb/caosdb-server/-/issues/39
        """
        date_str = "2020-01-01"
        prop_name = "Test_Date"
        db.Property(name=prop_name, datatype=db.DATETIME).insert()
        db.RecordType(name="Test_Type").add_property(name=prop_name).insert()
        db.Record(name="Test_Record").add_parent(name="Test_Type").add_property(
            name=prop_name, value=date_str).insert()
        # Quotes around years should work in the query
        ent = db.execute_query("FIND entity WITH A Test_Date IN \"2020\"",
                               unique=True)
        assert ent.get_property(prop_name).value == date_str
        # This should raise a transaction error
        with pytest.raises(TransactionError):
            db.execute_query("FIND entity WITH A Test_Date IN \"abcd\"")
    
    
    @pytest.mark.xfail(reason="to be fixed in server repo")
    def test_issue_62():
        """datatype is not changed when recordtype name changes
    
        Tests for https://gitlab.com/caosdb/caosdb-server/-/issues/62
        """
        db.RecordType(name="Test_RTA").insert()
        db.Property(name="Test_Prop", datatype="Test_RTA").insert()
        db.Record(name="Test_Record").add_parent(
            name="Test_RTA").add_property(name="Test_Prop").insert()
        # rename Test_RTA to Test_RTB
        rtb = db.execute_query("FIND RecordType Test_RTA", unique=True)
        rtb.name = "Test_RTB"
        rtb.update()
        # 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
        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):
            prop2.insert()
    
    
    def test_issue_85_a():
        """SQLIntegrityConstraintViolationException for special inheritance patterns.
    
        Tests for https://gitlab.com/caosdb/caosdb-server/-/issues/85
        """
        A = db.RecordType(name="A")
        B = db.RecordType(name="B")
        C = db.RecordType(name="C")
    
        B.add_parent(A)
    
        # This order is important for the test to fail.
        C.add_parent(B)
        C.add_parent(C)
        C.add_parent(A)
    
        c = db.Container()
        # c.extend([C, B, A])  # worked before #86 was fixed
        # c.extend([C, A, B])  # worked before #86 was fixed
        c.extend([B, C, A])    # insert() failed before #86 was fixed
        c.insert()  # Raised java.sql.SQLIntegrityConstraintViolationException:
        #           # Duplicate entry '12345-12346-12345' for key 'PRIMARY'
    
    
    def test_issue_85_b():
        """SQLIntegrityConstraintViolationException for special inheritance patterns.
    
        Tests for https://gitlab.com/caosdb/caosdb-server/-/issues/85
        """
        A = db.RecordType(name="A")
        B = db.RecordType(name="B")
        C = db.RecordType(name="C")
        A.insert()
        B.insert()
        C.insert()
        B.add_parent(A)
        B.update()
        C.add_parent(B)
        C.update()
        C.add_parent(C)
        C.update()
        C.add_parent(A)
        C.update()  # Failed at this step
    
    
    @pytest.mark.local_server
    def test_issue_99():
        """Checksum updating failed with versioning enabled.
        """
    
        # Using files in extroot, because this allows us to update the file
        # content from the outside.
        local_dir = os.path.join(db.get_config().get("IntegrationTests",
                                                     "test_files.test_insert_files_in_dir.local"),
                                 "test_issue_99")
        docker_dir = os.path.join(db.get_config().get("IntegrationTests",
                                                      "test_files.test_insert_files_in_dir.server"),
                                  "test_issue_99")
        os.makedirs(local_dir, exist_ok=True)
        with tempfile.NamedTemporaryFile(dir=local_dir) as file_99:
            # Create File entity in CaosDB
            file_99.write("test 99\n".encode())
            os.fchmod(file_99.fileno(), 0o744)  # make the file world readable
            cont = db.Container()
            cont.insert(unique=False, raise_exception_on_error=False,
                        flags={"InsertFilesInDir": docker_dir})
            dbfile = cont[0]
    
            # Checksum should exist after a short time
            time.sleep(0.1)
            dbfile.retrieve()
            assert dbfile.checksum is not None
    
    
    def test_issue_110():
        """query ignores ID: FIND MusicalInstrument which is referenced by Analysis with ID=124 """
        cont = db.Container()
        A = db.RecordType(name="TypeA")
        B = db.RecordType(name="TypeB")
        prop = db.Property(name="prop_ba", datatype=db.REFERENCE)
    
        # Referenced Records
        a1 = db.Record().add_parent(A)
        a2 = db.Record().add_parent(A)
    
        # Referencing Records
        b1 = db.Record().add_parent(B).add_property(prop, value=a1)
        b2 = db.Record().add_parent(B).add_property(prop, value=a2)
    
        cont.extend([A, B, prop, a1, a2, b1, b2])
        cont.insert()
    
        id_b1 = b1.id
        query = "FIND TypeA WHICH IS REFERENCED BY TypeB WITH ID={}".format(id_b1)
        print(query)
        result = db.execute_query(query)
        print(result)
        assert len(result) == 1
        print(result[0])
        print(a1)
        assert result[0].id == a1.id
    
    
    def test_issue_120():
        """Editing entities that were created with a no longer existing user leads
        to a server error.
    
        The server should throw an error when CHECK_ENTITY_ACL_ROLES_MODE=MUST,
        otherwise a warning.
        """
        # insert an entity
        entity = db.RecordType("TestRT").insert(flags={"ACL": None})
    
        db.administration.set_server_property("CHECK_ENTITY_ACL_ROLES_MODE",
                                              "SHOULD")
        # update with non-existing user, realm and role
        entity.deny(
            realm="CaosDB",
            username="NON_EXISTING_USER",
            permission="USE:AS_REFERENCE")
        entity.update(flags={"ACL": None})
        assert entity.messages["Warning", 1104][0] == "User Role does not exist."
    
        entity.deny(
            realm="NON_EXISTING_REALM",
            username="NON_EXISTING_USER",
            permission="USE:AS_REFERENCE")
        entity.update(flags={"ACL": None})
        assert entity.messages["Warning", 1104][0] == "User Role does not exist."
    
        entity.deny(
            role="ALSO_NON_EXISTING_ROLE",
            permission="USE:AS_REFERENCE")
        entity.update(flags={"ACL": None})
        assert entity.messages["Warning", 1104][0] == "User Role does not exist."
    
    
    def test_issue_134():
        """multiple white space characters after `FROM`"""
        db.execute_query("SELECT pname FROM  ename")
    
    
    def test_issue_131():
        """white space befor unit with strange character"""
        rt = db.RecordType(name="TestType").insert()
        prop = db.Property(name="TestProp", datatype=db.INTEGER, unit="").insert()
        rec = db.Record(name="TestRecord").add_property(
            name=prop.name, value=101, unit="")
        rec.add_parent(rt)
        rec.insert()
        result_ids = [ent.id for ent in db.execute_query(
            "FIND Entity WITH {} > 100 €".format(prop.name))]
    
        assert rec.id in result_ids