Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
test_issues_server.py 5.73 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
from caosdb.exceptions import EntityError, TransactionError
import pytest


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(EntityError):
        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


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