Commit 26ecbf90 authored by Henrik tom Wörden's avatar Henrik tom Wörden
Browse files

Merge branch 'dev' into ubuntu-based

parents 1b90b66f ae4f5662
......@@ -84,17 +84,31 @@ test:
variables:
DOCKER_HOST: tcp://docker:2375
script:
- echo $F_BRANCH
- echo $CAOSDB_TAG
- echo $CI_COMMIT_REF_NAME
- F_BRANCH=${F_BRANCH:-$CI_COMMIT_REF_NAME}
- echo $F_BRANCH
- echo $CAOSDB_TAG
- echo $CI_COMMIT_REF_NAME
- if ! echo "$F_BRANCH" | grep -c "^f-" ; then
F_BRANCH=dev;
fi
- if [[ "$CAOSDB_TAG" == "" ]]; then
if echo "$F_BRANCH" | grep -c "^f-" ; then
CAOSDB_TAG=f-feature-branch-pipeline_F_${F_BRANCH}-latest;
else
CAOSDB_TAG=dev-latest;
fi;
fi
# TODO default $CAOSDB_TAG to dev_F_$F_BRANCH-latest
- echo $F_BRANCH
- echo $CAOSDB_TAG
#- KNOWN_TAGS=$(curl -u gitlab+deploy-token-ci-pull:$TOKEN_CI_PULL -X GET https://$CI_REGISTRY_INDISCALE/v2/caosdb/src/caosdb-deploy/tags/list)
# - echo $KNOWN_TAGS
# test if the caosdb registry knows our current tag
# - echo $KNOWN_TAGS | grep "$CAOSDB_TAG"
- time docker load < /image-cache/caosdb-pyint-testenv.tar || true
- time docker load < /image-cache/mariadb.tar || true
- time docker load < /image-cache/caosdb.tar || true
- echo $CI_COMMIT_REF_NAME
- time docker load < /image-cache/caosdb-pyint-testenv-${CI_COMMIT_REF_NAME}.tar || true
- time docker load < /image-cache/mariadb-${F_BRANCH}.tar || true
- time docker load < /image-cache/caosdb-${F_BRANCH}.tar || true
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker login -u gitlab+deploy-token-ci-pull -p $TOKEN_CI_PULL $CI_REGISTRY_INDISCALE
- docker pull $CI_REGISTRY_IMAGE
......@@ -124,6 +138,18 @@ build-testenv:
stage: setup
script:
- df -h
- command -v wget
- if [ -z "$PYLIB" ]; then
if echo "$CI_COMMIT_REF_NAME" | grep -c "^f-" ; then
echo "Check if pylib has branch $CI_COMMIT_REF_NAME" ;
if wget https://gitlab.com/api/v4/projects/13656973/repository/branches/${CI_COMMIT_REF_NAME} ; then
PYLIB=$CI_COMMIT_REF_NAME ;
fi;
fi;
fi;
- PYLIB=${PYLIB:-dev}
- echo $PYLIB
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
# use here general latest or specific branch latest...
- docker build
......@@ -131,7 +157,7 @@ build-testenv:
--file .docker/Dockerfile
-t $CI_REGISTRY_IMAGE .
- docker push $CI_REGISTRY_IMAGE
- docker save $CI_REGISTRY_IMAGE > /image-cache/caosdb-pyint-testenv.tar
- docker save $CI_REGISTRY_IMAGE > /image-cache/caosdb-pyint-testenv-${CI_COMMIT_REF_NAME}.tar
- cd .docker-base
- docker build
-t $CI_REGISTRY_IMAGE_BASE .
......
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added (for new features)
- Tests for [#62](https://gitlab.com/caosdb/caosdb-server/-/issues/62)
in caosdb-server-project, i.e., renaming of a RecordType that should
be reflected in properties with that RT as datatype.
### Changed (for changes in existing functionality)
### Deprecated (for soon-to-be removed features)
......@@ -17,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed (for any bug fixes)
- Tests for NaN Double Values (see https://gitlab.com/caosdb/caosdb-server/issues/41)
* Tests for name queries. [caosdb-server#51](https://gitlab.com/caosdb/caosdb-server/-/issues/51)
### Security (in case of vulnerabilities)
......@@ -50,7 +50,8 @@ def setup():
def test_pass():
if not h.get_config().has_option("Connection", "password_method") or not h.get_config().get("Connection", "password_method") == "pass":
if not h.get_config().has_option("Connection", "password_method") or not h.get_config(
).get("Connection", "password_method") == "pass":
skip()
assert call(["pass", h.get_config().get("Connection",
"password_identifier")]) == 0
......
......@@ -75,7 +75,7 @@ def test_null_value():
# value was stored correctly
assert db.execute_query("FIND Record TestRT",
unique=True).get_property("TestProp").value == None
unique=True).get_property("TestProp").value is None
# query language works with null value
assert db.execute_query(
"FIND TestRT WHERE TestProp IS NULL", unique=True).id == r1.id
......@@ -127,7 +127,7 @@ def test_null_list():
# null list was stored correctly
assert db.execute_query("FIND Record TestRT",
unique=True).get_property("TestProp").value == None
unique=True).get_property("TestProp").value is None
assert db.execute_query(
"FIND TestRT WHERE TestProp IS NULL", unique=True).id == r1.id
......
......@@ -36,7 +36,7 @@ from lxml import etree
from pytest import raises
from nose.tools import (assert_equal, assert_false, # @UnresolvedImport
assert_is_not_none, assert_raises, assert_true,
nottest, with_setup)
nottest)
from caosdb import Info
from caosdb import administration as admin
......@@ -51,6 +51,7 @@ def setup_module():
def setup():
teardown()
with open("test.dat", "w") as upload_file:
upload_file.write("hello world\n")
os.makedirs("testfolder/subfolder")
......@@ -61,10 +62,9 @@ def setup():
def teardown():
try:
execute_query("FIND ENTITY WHICH HAS AN ID >= 100").delete()
except Exception as e:
print(e)
d = execute_query("FIND ENTITY WHICH HAS AN ID >= 100")
if len(d) > 0:
d.delete()
try:
shutil.rmtree("testfolder")
except Exception as e:
......@@ -79,7 +79,6 @@ def teardown():
print(e)
@with_setup(setup, teardown)
def test_file_with_space():
file_ = models.File(name="TestFile",
description="Testfile Desc",
......@@ -93,66 +92,51 @@ def test_file_with_space():
qfile.download("test2.dat")
@with_setup(setup, teardown)
def test_pickup_file():
d = models.DropOffBox()
d.sync()
try:
d = models.DropOffBox()
d.sync()
try:
pickup_file = open(os.path.join(d.path, "testpickup.dat"), "w")
except BaseException:
print("drop off box not on this system.")
else:
pickup_file.write("hello world\n")
pickup_file.close()
file_ = models.File(name="PickupTestfile",
description="Pickup test file desc",
path="testfiles/pickuptestfile.dat" +
hex(randint(0, maxint)),
pickup="testpickup.dat")
file_.insert()
assert_is_not_none(file_.id)
finally:
try:
file_.delete()
except BaseException:
pass
pickup_file = open(os.path.join(d.path, "testpickup.dat"), "w")
except BaseException:
print("drop off box not on this system.")
else:
pickup_file.write("hello world\n")
pickup_file.close()
file_ = models.File(name="PickupTestfile",
description="Pickup test file desc",
path="testfiles/pickuptestfile.dat" +
hex(randint(0, maxint)),
pickup="testpickup.dat")
file_.insert()
assert_is_not_none(file_.id)
@with_setup(setup, teardown)
def test_pickup_folder():
# pickup_folder
d = models.DropOffBox()
d.sync()
try:
# pickup_folder
d = models.DropOffBox()
d.sync()
try:
os.mkdir(d.path + "/testfolder")
except BaseException:
print("drop off box not on this system.")
else:
os.mkdir(d.path + "/testfolder/subfolder")
pickup_file = open(d.path + "/testfolder/testpickup1.dat", "w")
pickup_file.write("hello world\n")
pickup_file.close()
pickup_file = open(
d.path + "/testfolder/subfolder/testpickup2.dat", "w")
pickup_file.write("hello world\n")
pickup_file.close()
file_ = models.File(name="PickupTestfolder",
description="Pickup test folder desc",
path="testfiles/pickuptestfolder" +
hex(randint(0, maxint)) + "/",
pickup="testfolder/")
file_.insert()
finally:
try:
file_.delete()
except BaseException:
pass
os.mkdir(d.path + "/testfolder")
except BaseException:
print("drop off box not on this system.")
else:
os.mkdir(d.path + "/testfolder/subfolder")
pickup_file = open(d.path + "/testfolder/testpickup1.dat", "w")
pickup_file.write("hello world\n")
pickup_file.close()
pickup_file = open(
d.path + "/testfolder/subfolder/testpickup2.dat", "w")
pickup_file.write("hello world\n")
pickup_file.close()
file_ = models.File(name="PickupTestfolder",
description="Pickup test folder desc",
path="testfiles/pickuptestfolder" +
hex(randint(0, maxint)) + "/",
pickup="testfolder/")
file_.insert()
@with_setup(setup, teardown)
def test_file4():
try:
d = models.DropOffBox()
......@@ -187,7 +171,6 @@ def test_file4():
pass
@with_setup(setup, teardown)
def test_upload_complete_folder():
file1_ = models.File(name="Testfile1",
description="Testfile Desc",
......@@ -218,7 +201,6 @@ def test_upload_complete_folder():
c.delete()
@with_setup(setup, teardown)
def test_file6():
try:
# upload file to testfiles2/testfile...
......@@ -278,7 +260,6 @@ def test_file6():
pass
@with_setup(setup, teardown)
def test_file7():
try:
# upload file to testfiles2/testsub/testfile...
......@@ -335,7 +316,6 @@ def test_file7():
pass
@with_setup(setup, teardown)
def test_consistency_file_was_modified():
try:
......@@ -401,7 +381,6 @@ def test_consistency_file_was_modified():
pass
@with_setup(setup, teardown)
def test_consistency_file_does_not_exist():
try:
with open("test.dat", "w") as upload_file:
......@@ -457,7 +436,6 @@ def test_consistency_file_does_not_exist():
pass
@with_setup(setup, teardown)
def test_consistency_unknown_file():
c = runCheck(None, None)
assert c.messages["Info", 0] is not None
......@@ -477,7 +455,6 @@ def test_consistency_unknown_file():
assert c.messages["Info", 0][0] == "File system is consistent."
@with_setup(setup, teardown)
def test_insert_files_in_dir_error1():
c = models.Container()
......@@ -513,7 +490,6 @@ def test_insert_files_in_dir_error1():
assert_true(c.messages["Error", 0][0].startswith("Dir is not allowed"))
@with_setup(setup, teardown)
def test_insert_files_in_dir_with_symlink():
path = get_config().get("IntegrationTests",
"test_files.test_insert_files_in_dir.local") + "testfolder/"
......@@ -590,7 +566,6 @@ def test_insert_files_in_dir_with_symlink():
pass
@with_setup(None, teardown)
def test_insert_files_in_dir():
""" test if files in directories can be inserted as symlinks via the
InsertFilesInDir flag. This tests also verifies that the job can be
......@@ -690,7 +665,6 @@ def test_insert_files_in_dir():
pass
@with_setup(setup, teardown)
def test_insert_files_in_dir_regex():
path = get_config().get("IntegrationTests",
"test_files.test_insert_files_in_dir.local") + "testfolder/"
......@@ -733,7 +707,6 @@ def test_insert_files_in_dir_regex():
pass
@with_setup(setup, teardown)
def test_thumbnails():
file_ = models.File(name="TestFile",
description="Testfile Desc",
......
......@@ -46,7 +46,7 @@ def teardown():
setup_module()
# ########################### Issue tests start here ###########################
# ########################### Issue tests start here #####################
@with_setup(setup, teardown)
def test_issue_18():
......
......@@ -3,8 +3,9 @@
# ** header v3.0
# This file is a part of the CaosDB Project.
#
# Copyright (c) 2020 IndiScale GmbH (www.indiscale.com)
# Copyright (c) 2020 Daniel Hornung (d.hornung@indiscale.com)
# 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
......@@ -21,9 +22,11 @@
#
# ** end header
"""Tests for issues on gitlab.com, project caosdb-mysqlbackend."""
"""Tests for issues on gitlab.com, project caosdb-server."""
import caosdb as db
from caosdb.exceptions import EntityError
import pytest
def setup_module():
......@@ -43,7 +46,32 @@ def teardown():
setup_module()
# ########################### Issue tests start here ###########################
# ########################### Issue tests start here #####################
@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.
......
......@@ -27,6 +27,7 @@
"""
import caosdb as db
from pytest import raises, mark
from nose.tools import nottest, assert_true, assert_raises, assert_equal, with_setup, assert_is_not_none # @UnresolvedImport
......@@ -208,8 +209,45 @@ def test_recordtype_query():
"FIND TestRecordType", "FIND TestRT"])
@mark.xfail(reason="waiting for server, mysqlbackend merges of f-name-query")
def test_query_name_property():
""" Insert a Property which has a name parent. Add to Record and query the
record."""
# test behavior without the name parent
db.RecordType("TestPerson").insert()
db.Property("TestGivenName", datatype=db.TEXT).insert()
rec = db.Record("TestJohnDoe").add_parent("TestPerson")
rec.add_property("TestGivenName", "John")
rec.insert()
assert db.execute_query("FIND TestPerson WITH TestGivenName='John'",
unique=True).id == rec.id
with raises(db.EntityDoesNotExistError):
assert db.execute_query("FIND John", unique=True)
teardown()
# test behavior WITH the name parent
db.RecordType("TestPerson").insert()
db.Property("TestGivenName").add_parent("name").insert()
rec = db.Record("TestJohnDoe").add_parent("TestPerson")
rec.add_property("TestGivenName", "John")
rec.insert()
assert db.execute_query("FIND TestPerson WITH TestGivenName='John'",
unique=True).id == rec.id
assert db.execute_query("FIND John",
unique=True).id == rec.id
@with_setup(setup, teardown)
def test_query_with_pov():
def test_query_property_with_pov():
""" Insert a Record with a property which can be searched using two
different names.
The TestRating is the primary name of the property while TestRating is a
Synonym.
"""
db.RecordType(name="TestExperiment").insert()
db.Property(
name="TestSynonym",
......@@ -225,6 +263,7 @@ def test_query_with_pov():
name="TestExperiment").add_property(
name="TestRating",
value=4).insert()
assert_equal(
db.execute_query(
"FIND TestExperiment WHICH HAS A TestRating=4",
......@@ -249,6 +288,11 @@ def test_query_with_pov():
@with_setup(setup, teardown)
def test_query_with_reference():
""" Insert a Record with two names. Both work in a reference query.
The record has a primary name ("TestJohnDoe") and a property
`TestGivenName` (="John") with also works with the query.
"""
db.RecordType(name="TestExperiment").insert()
db.RecordType(name="TestPerson").insert()
db.Property(
......@@ -280,6 +324,11 @@ def test_query_with_reference():
@with_setup(setup, teardown)
def test_query_with_back_reference():
""" Insert a Record with two names. Both work in a back-ref query.
The record has a primary name ("TestMeasurement") and a property
`TestSynomym` (="TestObservation") with also works with the query.
"""
db.RecordType(name="TestPerson").insert()
db.Property(
name="TestSynonym",
......
......@@ -29,10 +29,10 @@
import caosdb as h
# @UnresolvedImport
from nose.tools import assert_true, assert_equal, assert_is_not_none, with_setup
from pytest import mark
from nose.tools import assert_true, assert_equal, assert_is_not_none
from caosdb.connection.connection import get_connection
from lxml import etree # @UnresolvedImport
from lxml import etree
def setup():
......@@ -43,10 +43,7 @@ def setup():
def teardown():
try:
h.execute_query("FIND Test*").delete()
except Exception as e:
print(e)
setup()
try:
import os
os.remove("test.dat")
......@@ -54,7 +51,6 @@ def teardown():
print(e)
@with_setup(setup, teardown)
def test_query_with_reference_by_parent():
h.RecordType("TestExperiment").insert()
h.RecordType("TestProtocolLog").insert()
......@@ -113,7 +109,6 @@ def test_query_with_reference_by_parent():
"FIND TestExperiment.TestProtocolLog1")))
@with_setup(setup, teardown)
def test_query_with_domains():
person = h.RecordType("TestPerson").insert()
h.Property("TestFirstName", datatype=h.TEXT).insert()
......@@ -156,7 +151,6 @@ def test_query_with_domains():
exp.id)
@with_setup(setup, teardown)
def test_query1():
p = (
h.Property(
......@@ -174,7 +168,6 @@ def test_query1():
unique=True).id)
@with_setup(setup, teardown)
def test_query2():
# create testfile
f = open("test.dat", "w")
......@@ -209,7 +202,6 @@ def test_query3():
assert_equal(3, len(xml))
@with_setup(setup, teardown)
def test_conjunction():
rt = h.RecordType(name="TestConjunctionTest").insert()
assert_true(rt.is_valid())
......@@ -300,7 +292,6 @@ def test_conjunction():
"FIND RECORD . TestConjunctionTestPropertyA=1 AND TestConjunctionTestPropertyB=0")))
@with_setup(setup, teardown)
def test_disjunction():
rt = h.RecordType(name="TestDisjunctionTest").insert()
assert_true(rt.is_valid())
......@@ -385,7 +376,6 @@ def test_disjunction():
"FIND TestDisjunctionTest . TestDisjunctionTestPropertyA=1 OR ( TestDisjunctionTestPropertyB=0 AND TestDisjunctionTestPropertyA=1)")))
@with_setup(setup, teardown)
def test_greatest():
pAB = h.Property(name="TestPropertyAB", datatype=h.DOUBLE).insert()
assert_true(pAB.is_valid())
......@@ -572,7 +562,6 @@ def test_greatest():
assert_equal(c[1].id, rec6.id)
@with_setup(setup, teardown)
def test_wildcard_values():
ptext = h.Property(name="TestTextProperty", datatype=h.TEXT).insert()
rt = h.RecordType(
......@@ -860,7 +849,6 @@ def test_stored_at_wildcards():
assert c.get_entity_by_id(file8.id) is not None
@with_setup(setup, teardown)
def test_int():
pint = h.Property(name="TestIntegerProperty", datatype=h.INTEGER).insert()
pdouble = h.Property(name="TestDoubleProperty", datatype=h.DOUBLE).insert()
......@@ -939,7 +927,6 @@ def test_int():
"FIND TestRecordType WITH TestDoubleProperty<=50")))
@with_setup(setup, teardown)
def test_query_benchmark():
h.Property("TestProperty", datatype=h.TEXT).insert()
......@@ -970,7 +957,6 @@ def test_like_query():
h.execute_query("FIND box with number = '7'")
@with_setup(setup, teardown)
def test_backref_like():
h.RecordType("TestData").insert()
other = h.Record("other").add_parent("TestData").insert()
......@@ -981,3 +967,39 @@ def test_backref_like():
h.execute_query("FIND ENTITY WHICH IS REFERENCED BY *m*", unique=True)
h.execute_query("FIND ENTITY WHICH IS REFERENCED BY s*", unique=True)
h.execute_query("FIND ENTITY WHICH IS REFERENCED BY *e", unique=True)
@mark.xfail(reason="waiting for server, mysqlbacken merges of f-query-name")
def test_query_by_name():
rt = h.RecordType("TestRT").insert()
rec1 = h.Record("TestRec1").add_parent("TestRT").insert()
rec2 = h.Record("TestRec2").add_parent("TestRT").insert()
assert len(h.execute_query("FIND TestRT")) == 3
assert len(h.execute_query("FIND RECORD TestRT")) == 2
assert len(h.execute_query("FIND RECORDTYPE TestRT")) == 1
# find rt via name
assert h.execute_query("FIND RECORDTYPE WITH name = 'TestRT'",
unique=True).id == rt.id
assert h.execute_query("FIND RECORDTYPE WITH NAME = 'TestRT'",
unique=True).id == rt.id
assert h.execute_query("FIND RECORDTYPE WITH NAme = 'TestRT'",
unique=True).id == rt.id
assert h.execute_query("FIND TestRT WITH NAme = 'TestRT'",