diff --git a/.docker-base/Dockerfile b/.docker-base/Dockerfile index 3476e1193312f57e86778cd51422e7fc954e6e18..7dbf1794d249872005246589b2f9213fdf93e46a 100644 --- a/.docker-base/Dockerfile +++ b/.docker-base/Dockerfile @@ -5,11 +5,11 @@ FROM docker:19.03.0 ENV LANG C.UTF-8 # install dependencies -RUN apk add --no-cache py-pip python-dev py3-pip python3 python3-dev gcc make \ +RUN apk add --no-cache py3-pip python3 python3-dev gcc make \ git bash curl gettext py3-requests RUN apk add --no-cache libffi-dev openssl-dev libc-dev libxslt libxslt-dev \ libxml2 libxml2-dev -RUN pip install docker-compose==1.25 +RUN pip3 install docker-compose==1.25 # Script for waiting on LA server COPY wait-for-it.sh /opt/caosdb/wait-for-it.sh diff --git a/.docker/tester_pycaosdb.ini b/.docker/tester_pycaosdb.ini index 38247085d7c6ba681f7ed9b1553d76818109711a..2159dec250b3dcb2f16043d12bdbe73675e4d75c 100644 --- a/.docker/tester_pycaosdb.ini +++ b/.docker/tester_pycaosdb.ini @@ -25,7 +25,7 @@ username = admin cacert = /cert/caosdb.cert.pem debug = 0 -passwordmethod = plain +password_method = plain password = caosdb timeout = 500 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index db924c637a7818f90418a467d2c581d1998e3ed4..396a29b7bf0d8d282e37416b1224ec6d592170da 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -103,6 +103,7 @@ test: - echo $CI_REGISTRY_IMAGE - docker login -u gitlab+deploy-token-ci-pull -p $TOKEN_CI_PULL $CI_REGISTRY_INDISCALE + - time docker load < /image-cache/caosdb-${F_BRANCH}.tar || true - if [[ "$CAOSDB_TAG" == "" ]]; then if echo "$F_BRANCH" | grep -c "^f-" ; then CAOSDB_TAG=${DEPLOY_REF}_F_${F_BRANCH}-latest; @@ -132,6 +133,7 @@ test: - rc=`cat .docker/result` - exit $rc dependencies: [cert] + timeout: 3h artifacts: paths: - caosdb_log.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c8d1a205f6a69677c31bfc6be0f092a28ec2d3d..c1fa88411d45d57c7fc0517f1d02f33dc497c1aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added (for new features) +* Tests for version history +* Tests for inheritance bug (caosdb/caosdb-server!54) * Tests for versioning * Tests for deeply nested SELECT queries * Tests for [#62](https://gitlab.com/caosdb/caosdb-server/-/issues/62) @@ -20,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 in caosdb server which checks if quoted datetimes in queries are evaluated correctly. * Test for [caosdb-server#99](https://gitlab.com/caosdb/caosdb-server/-/issues/99). +* Tests for retrieving older versions. ### Changed (for changes in existing functionality) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..b2b57fc5eb95a30f104242bb26f79fb036e5c683 --- /dev/null +++ b/Makefile @@ -0,0 +1,54 @@ +# ** 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> +# +# 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 + +# Just a collection of scripts + +.PHONY: all autopep8 test help + +# Do the integration tests. +# Accepts freestyle arguments like so: +# `make test test_opts=test_foo.py -k test_function` +test: + cd tests && pytest $(test_opts) + + +# Just print the help. +define HELP +The most common targets: + +make test :: Do the integration tests. Accepts freestyle arguments like so: + `make test test_opts=test_foo.py -k test_function` +Prepare everything for running. +make autopep8 :: Autoformatting for all tests +make all :: Run autopep8 and test +endef +export HELP +help: + @echo "$$HELP" + + +# Run the tests through autopep8. +autopep8: + autopep8 -ri tests + + +# Meta target to call the other targets. +all: autopep8 test diff --git a/README.md b/README.md index 390cd85110657cdf739e59eca51221dc7f2c0d07..2a11f69baaa0c7004aa35a84bff7146cd05cedb4 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,13 @@ CaosDB project. # Getting started # -To run tests, start up a CaosDB server (documentation for this can be found -elsewhere). Then modify `pycaosdb.ini.template` accordingly and save it as -`pycaosdb.ini`. Then you can run the tests with `pytest` or `pytest-3` -(depending on your system). - -If you want to run just a single test, you can also select a single test file: -`pytest-3 tests/test_issues.py` +- To run tests, start up a CaosDB server with (documentation for this can be found elsewhere). + - The CaosDB server must have debugging enabled. + - Certificates must be valid and be listed in `pycaosdb.ini`. +- Modify `pycaosdb.ini.template` accordingly and save it as `pycaosdb.ini`. +- Run the tests with `pytest` or `pytest-3` (depending on your system). +- If you want to run just a single test, you can also select a single test file: + `pytest-3 tests/test_issues.py` # Further Reading diff --git a/pycaosdb.ini.template b/pycaosdb.ini.template index 8f1d9d40f7af1fc0d2a515fbde6138c9b63e618d..369b33f6f63d15b737d6a558422ab1bfe6c30f15 100644 --- a/pycaosdb.ini.template +++ b/pycaosdb.ini.template @@ -1,23 +1,28 @@ # -*- mode:conf; -*- ## This sections needs to exist in addition to the usual section [IntegrationTests] -test_server_side_scripting.bin_dir=/scripting-bin/ +test_server_side_scripting.bin_dir.local=/path/to/scripting/bin +test_server_side_scripting.bin_dir.server=/opt/caosdb/git/caosdb-server/scritping/bin # location of the files from the pyinttest perspective test_files.test_insert_files_in_dir.local=/extroot/test_insert_files_in_dir/ # location of the files from the caosdb_servers perspective test_files.test_insert_files_in_dir.server=/opt/caosdb/mnt/extroot/test_insert_files_in_dir/ +# location of the one-time tokens from the pyinttest's perspective +test_authentication.admin_token_crud = /authtoken/admin_token_crud.txt +test_authentication.admin_token_expired = /authtoken/admin_token_expired.txt +test_authentication.admin_token_3_attempts = /authtoken/admin_token_3_attempts.txt ## Insert your usual settings here [Connection] #url=https://caosdb-server:10443/ #username=admin -#cacert=/cert/caosdb.cert.pem +#cacert=/path/to/cert/caosdb.cert.pem #cacert=/etc/ssl/cert.pem #debug=0 -#passwordmethod=plain +#password_method=plain #password=caosdb #ssl_insecure=True diff --git a/tests/test_administration.py b/tests/test_administration.py index c951307472bc5a5eb7f2cea3b6da12de921bc0cd..474b431ada4cd8c155e9cd28fc62de0e95671275 100644 --- a/tests/test_administration.py +++ b/tests/test_administration.py @@ -26,14 +26,13 @@ @author: tf """ -from caosdb import (administration as admin, get_config) -from nose.tools import assert_true, assert_equal, assert_is_not_none, assert_raises -from caosdb.exceptions import (ClientErrorException, - HTTPAuthorizationException, - LoginFailedException, - ResourceNotFoundException) -from caosdb.connection.connection import get_connection, configure_connection -from pytest import raises +from caosdb import administration as admin +from caosdb import get_config +from caosdb.connection.connection import configure_connection, get_connection +from caosdb.exceptions import (ClientErrorException, HTTPAuthorizationException, + LoginFailedException, ResourceNotFoundException) +from nose.tools import (assert_equal, assert_is_not_none, assert_raises, + assert_true) test_role = "test_role" test_user = "test_user" @@ -237,6 +236,7 @@ def test_get_roles_success(): test_insert_role_success() r = admin._get_roles(username=test_user) assert_is_not_none(r) + return r @@ -525,6 +525,7 @@ def test_login_with_inactive_user_failure(): status="INACTIVE", email="email@example.com", entity=None)) - configure_connection(username=test_user + "2", password="secret1P!") + configure_connection(username=test_user + "2", password="secret1P!", + password_method="plain") with assert_raises(LoginFailedException): get_connection()._login() diff --git a/tests/test_datetime.py b/tests/test_datetime.py index 815db5181d1b8bba97af3d18326c478a346789e9..cda35a1f013833744f314fda6a5bd87547cda5b9 100644 --- a/tests/test_datetime.py +++ b/tests/test_datetime.py @@ -1418,3 +1418,510 @@ def test_greater_operator(): h.execute_query("FIND Simple*").delete() except BaseException: pass + + +def test_greater_equal_operator(): + try: + rec = set_up_rec() + # query with > Date YYYY-MM-ddThh:mm:ss + d = "2015-05-05T20:15:30" + assert_true(query_assertion(rec, d, ">=", d)) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05")) + assert_true(query_assertion(rec, d, ">=", "2015-05")) + assert_true(query_assertion(rec, d, ">=", "2015")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30.122")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30.124")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:29.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:29")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:15:31.123")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:15:31")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:14:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:14:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:14")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:16:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:16:30")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:16")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T19:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T19:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T19:15")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T19")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T21:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T21:15:30")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T21:15")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T21")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20:15")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05")) + assert_true(query_assertion(rec, d, ">=", "2015-04")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05")) + assert_false(query_assertion(rec, d, ">=", "2015-06")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05")) + assert_true(query_assertion(rec, d, ">=", "2014-05")) + assert_true(query_assertion(rec, d, ">=", "2014")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05")) + assert_false(query_assertion(rec, d, ">=", "2016-05")) + assert_false(query_assertion(rec, d, ">=", "2016")) + + # Date YYYY-MM-ddThh:mm:ss.ns + d = "2015-05-05T20:15:30.123" + assert_true(query_assertion(rec, d, ">=", d)) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05")) + assert_true(query_assertion(rec, d, ">=", "2015-05")) + assert_true(query_assertion(rec, d, ">=", "2015")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30.122")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:15:30.124")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:29.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:29")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:15:31.123")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:15:31")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:14:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:14:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:14")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:16:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:16:30")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T20:16")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T19:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T19:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T19:15")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T19")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T21:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T21:15:30")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T21:15")) + assert_false(query_assertion(rec, d, ">=", "2015-05-05T21")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20:15")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05")) + assert_true(query_assertion(rec, d, ">=", "2015-04")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05")) + assert_false(query_assertion(rec, d, ">=", "2015-06")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05")) + assert_true(query_assertion(rec, d, ">=", "2014-05")) + assert_true(query_assertion(rec, d, ">=", "2014")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05")) + assert_false(query_assertion(rec, d, ">=", "2016-05")) + assert_false(query_assertion(rec, d, ">=", "2016")) + + # Date YYYY-MM-dd + d = "2015-05-05" + assert_true(query_assertion(rec, d, ">=", d)) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05")) + assert_true(query_assertion(rec, d, ">=", "2015-05")) + assert_true(query_assertion(rec, d, ">=", "2015")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20:15")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06T20")) + assert_false(query_assertion(rec, d, ">=", "2015-05-06")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04T20")) + assert_true(query_assertion(rec, d, ">=", "2015-05-04")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05")) + assert_false(query_assertion(rec, d, ">=", "2015-06")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05")) + assert_true(query_assertion(rec, d, ">=", "2015-04")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05")) + assert_false(query_assertion(rec, d, ">=", "2016-05")) + assert_false(query_assertion(rec, d, ">=", "2016")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05")) + assert_true(query_assertion(rec, d, ">=", "2014-05")) + assert_true(query_assertion(rec, d, ">=", "2014")) + + # Date YYYY-MM + d = "2015-05" + assert_true(query_assertion(rec, d, ">=", d)) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05")) + assert_true(query_assertion(rec, d, ">=", "2015-05")) + assert_true(query_assertion(rec, d, ">=", "2015")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20:15")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05T20")) + assert_false(query_assertion(rec, d, ">=", "2015-06-05")) + assert_false(query_assertion(rec, d, ">=", "2015-06")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05T20")) + assert_true(query_assertion(rec, d, ">=", "2015-04-05")) + assert_true(query_assertion(rec, d, ">=", "2015-04")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05")) + assert_false(query_assertion(rec, d, ">=", "2016-05")) + assert_false(query_assertion(rec, d, ">=", "2016")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05")) + assert_true(query_assertion(rec, d, ">=", "2014-05")) + assert_true(query_assertion(rec, d, ">=", "2014")) + + # Date YYYY + d = "2015" + assert_true(query_assertion(rec, d, ">=", d)) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05T20")) + assert_true(query_assertion(rec, d, ">=", "2015-05-05")) + assert_true(query_assertion(rec, d, ">=", "2015-05")) + assert_true(query_assertion(rec, d, ">=", "2015")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15:30.123")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15:30")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20:15")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05T20")) + assert_false(query_assertion(rec, d, ">=", "2016-05-05")) + assert_false(query_assertion(rec, d, ">=", "2016-05")) + assert_false(query_assertion(rec, d, ">=", "2016")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15:30")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20:15")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05T20")) + assert_true(query_assertion(rec, d, ">=", "2014-05-05")) + assert_true(query_assertion(rec, d, ">=", "2014-05")) + assert_true(query_assertion(rec, d, ">=", "2014")) + + finally: + try: + h.execute_query("FIND Simple*").delete() + except BaseException: + pass + + +def test_smaller_equal_operator(): + try: + rec = set_up_rec() + + # Date YYYY-MM-ddThh:mm:ss + d = "2015-05-05T20:15:30" + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30.122")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30.124")) + assert_true(query_assertion(rec, d, "<=", d)) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05")) + assert_true(query_assertion(rec, d, "<=", "2015-05")) + assert_true(query_assertion(rec, d, "<=", "2015")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:15:29.123")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:15:29")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:31.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:31")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:14:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:14:30")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:14")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:16:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:16:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:16")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T19:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T19:15:30")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T19:15")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T19")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T21:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T21:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T21:15")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T21")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20:15")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05")) + assert_false(query_assertion(rec, d, "<=", "2015-04")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05")) + assert_true(query_assertion(rec, d, "<=", "2015-06")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05")) + assert_false(query_assertion(rec, d, "<=", "2014-05")) + assert_false(query_assertion(rec, d, "<=", "2014")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05")) + assert_true(query_assertion(rec, d, "<=", "2016-05")) + assert_true(query_assertion(rec, d, "<=", "2016")) + + # Date YYYY-MM-ddThh:mm:ss.ns + d = "2015-05-05T20:15:30.123" + assert_true(query_assertion(rec, d, "<=", d)) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05")) + assert_true(query_assertion(rec, d, "<=", "2015-05")) + assert_true(query_assertion(rec, d, "<=", "2015")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:15:30.122")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30.124")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:15:29.123")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:15:29")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:31.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:31")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:14:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:14:30")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T20:14")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:16:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:16:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:16")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T19:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T19:15:30")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T19:15")) + assert_false(query_assertion(rec, d, "<=", "2015-05-05T19")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T21:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T21:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T21:15")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T21")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20:15")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05")) + assert_false(query_assertion(rec, d, "<=", "2015-04")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05")) + assert_true(query_assertion(rec, d, "<=", "2015-06")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05")) + assert_false(query_assertion(rec, d, "<=", "2014-05")) + assert_false(query_assertion(rec, d, "<=", "2014")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05")) + assert_true(query_assertion(rec, d, "<=", "2016-05")) + assert_true(query_assertion(rec, d, "<=", "2016")) + + # Date YYYY-MM-dd + d = "2015-05-05" + assert_true(query_assertion(rec, d, "<=", d)) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05")) + assert_true(query_assertion(rec, d, "<=", "2015-05")) + assert_true(query_assertion(rec, d, "<=", "2015")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20:15")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04T20")) + assert_false(query_assertion(rec, d, "<=", "2015-05-04")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06T20")) + assert_true(query_assertion(rec, d, "<=", "2015-05-06")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05")) + assert_false(query_assertion(rec, d, "<=", "2015-04")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05")) + assert_true(query_assertion(rec, d, "<=", "2015-06")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05")) + assert_false(query_assertion(rec, d, "<=", "2014-05")) + assert_false(query_assertion(rec, d, "<=", "2014")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05")) + assert_true(query_assertion(rec, d, "<=", "2016-05")) + assert_true(query_assertion(rec, d, "<=", "2016")) + + # Date YYYY-MM + d = "2015-05" + assert_true(query_assertion(rec, d, "<=", d)) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05")) + assert_true(query_assertion(rec, d, "<=", "2015-05")) + assert_true(query_assertion(rec, d, "<=", "2015")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20:15")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05T20")) + assert_false(query_assertion(rec, d, "<=", "2015-04-05")) + assert_false(query_assertion(rec, d, "<=", "2015-04")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05T20")) + assert_true(query_assertion(rec, d, "<=", "2015-06-05")) + assert_true(query_assertion(rec, d, "<=", "2015-06")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05")) + assert_false(query_assertion(rec, d, "<=", "2014-05")) + assert_false(query_assertion(rec, d, "<=", "2014")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05")) + assert_true(query_assertion(rec, d, "<=", "2016-05")) + assert_true(query_assertion(rec, d, "<=", "2016")) + + # Date YYYY + d = "2015" + assert_true(query_assertion(rec, d, "<=", d)) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05T20")) + assert_true(query_assertion(rec, d, "<=", "2015-05-05")) + assert_true(query_assertion(rec, d, "<=", "2015-05")) + assert_true(query_assertion(rec, d, "<=", "2015")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15:30.123")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15:30")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20:15")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05T20")) + assert_false(query_assertion(rec, d, "<=", "2014-05-05")) + assert_false(query_assertion(rec, d, "<=", "2014-05")) + assert_false(query_assertion(rec, d, "<=", "2014")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15:30.123")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15:30")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20:15")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05T20")) + assert_true(query_assertion(rec, d, "<=", "2016-05-05")) + assert_true(query_assertion(rec, d, "<=", "2016-05")) + assert_true(query_assertion(rec, d, "<=", "2016")) + + finally: + try: + h.execute_query("FIND Simple*").delete() + except BaseException: + pass diff --git a/tests/test_inheritance.py b/tests/test_inheritance.py index 16e1ec026db33e69ed525752d53dcfc211b1c9a8..6b4fd2c293b88d6a3ae241b8302c186b84ac4ebd 100644 --- a/tests/test_inheritance.py +++ b/tests/test_inheritance.py @@ -27,30 +27,39 @@ """ -import caosdb as h -from nose.tools import assert_equal, assert_true, assert_is_not_none, with_setup +import caosdb as db + + +def setup(): + teardown() + + +def teardown(): + d = db.execute_query("FIND ENTITY WITH ID > 99") + if len(d) > 0: + d.delete() def test_inheritance_fix_properties(): try: """FIX PROPERTIES.""" '''insert simple property with unit''' - p1 = h.Property(name='UnitTestProperty', datatype='double', unit='m') + p1 = db.Property(name='UnitTestProperty', datatype='double', unit='m') p1.insert() - p1c = h.Property(id=p1.id).retrieve() - assert_true(p1c.is_valid()) - assert_equal('m', p1c.unit) + p1c = db.Property(id=p1.id).retrieve() + assert p1c.is_valid() + assert 'm' == p1c.unit '''subtyping with unit inheritance''' - p2 = h.Property( + p2 = db.Property( name='SubTypeOfUnitTestProperty').add_parent( id=p1.id, inheritance="FIX") print(p2) p2.insert() print(p2) - assert_true(p2.is_valid()) - assert_equal('m', p2.unit) + assert p2.is_valid() + assert 'm' == p2.unit finally: try: p2.delete() @@ -65,54 +74,52 @@ def test_inheritance_fix_properties(): def test_inheritance_obl_properties(): try: """OBLIGATORY PROPERTIES.""" - c = h.Container() + c = db.Container() c.append( - h.Property( + db.Property( name="SimpleTextProperty", description="simple text property (from test_inheritance.py)", datatype='text')) c.append( - h.Property( + db.Property( name="SimpleDoubleProperty", description="simple double property (from test_inheritance.py)", datatype='double')) c.append( - h.Property( + db.Property( name="SimpleIntegerProperty", description="simple integer property (from test_inheritance.py)", datatype='integer')) c.append( - h.Property( + db.Property( name="SimpleDatetimeProperty", description="simple datetime property (from test_inheritance.py)", datatype='datetime')) c.append( - h.Property( + db.Property( name="SimpleFileProperty", description="simple file property (from test_inheritance.py)", datatype='file')) - c.append( - h.RecordType( - name="SimpleRecordType", - description="simple recordType (from test_inheritance.py)") .add_property( - name='SimpleTextProperty', - importance="obligatory") .add_property( - name='SimpleDoubleProperty', - importance="obligatory") .add_property( - name='SimpleIntegerProperty', - importance="obligatory") .add_property( - name='SimpleDatetimeProperty') .add_property( - name='SimpleFileProperty')) + rt = db.RecordType( + name="SimpleRecordType", + description="simple recordType (from test_inheritance.py)") + rt.add_property(name='SimpleTextProperty', importance="obligatory") + rt.add_property(name='SimpleDoubleProperty', importance="obligatory") + rt.add_property(name='SimpleIntegerProperty', importance="obligatory") + rt.add_property(name='SimpleDatetimeProperty') + rt .add_property(name='SimpleFileProperty') + c.append(rt) c.insert() - rt = h.RecordType( + rt = db.RecordType( name="SubTypeOfSimpleRecordType", description="recordtype with inheritance (from test_inheritance.py)").add_parent( name="SimpleRecordType", inheritance="obligatory") rt.insert() - assert_equal(3, len(rt.get_properties())) + # only three properties are obligatory + assert 3 == len(rt.get_properties()) finally: try: rt.delete() @@ -125,69 +132,59 @@ def test_inheritance_obl_properties(): def test_inheritance_all_properties(): - try: - """ALL PROPERTIES.""" - c = h.Container() - c.append( - h.Property( - name="SimpleTextProperty", - description="simple text property (from test_inheritance.py)", - datatype='text')) - c.append( - h.Property( - name="SimpleDoubleProperty", - description="simple double property (from test_inheritance.py)", - datatype='double')) - c.append( - h.Property( - name="SimpleIntegerProperty", - description="simple integer property (from test_inheritance.py)", - datatype='integer')) - c.append( - h.Property( - name="SimpleDatetimeProperty", - description="simple datetime property (from test_inheritance.py)", - datatype='datetime')) - c.append( - h.Property( - name="SimpleFileProperty", - description="simple file property (from test_inheritance.py)", - datatype='file')) - - c.append( - h.RecordType( - name="SimpleRecordType", - description="simple recordType (from test_inheritance.py)") .add_property( - name='SimpleTextProperty', - importance="obligatory") .add_property( - name='SimpleDoubleProperty', - importance="obligatory") .add_property( - name='SimpleIntegerProperty', - importance="obligatory") .add_property( - name='SimpleDatetimeProperty') .add_property( - name='SimpleFileProperty')) - c.insert() - - rt = h.RecordType( - name="SubTypeOfSimpleRecordType", - description="recordtype with inheritance (from test_inheritance.py)").add_parent( + """ALL PROPERTIES.""" + c = db.Container() + c.append( + db.Property( + name="SimpleTextProperty", + description="simple text property (from test_inheritance.py)", + datatype='text')) + c.append( + db.Property( + name="SimpleDoubleProperty", + description="simple double property (from test_inheritance.py)", + datatype='double')) + c.append( + db.Property( + name="SimpleIntegerProperty", + description="simple integer property (from test_inheritance.py)", + datatype='integer')) + c.append( + db.Property( + name="SimpleDatetimeProperty", + description="simple datetime property (from test_inheritance.py)", + datatype='datetime')) + c.append( + db.Property( + name="SimpleFileProperty", + description="simple file property (from test_inheritance.py)", + datatype='file')) + + c.append( + db.RecordType( name="SimpleRecordType", - inheritance="obligatory") - rt.insert() - assert_equal(3, len(rt.get_properties())) - finally: - try: - rt.delete() - except BaseException: - pass - try: - c.delete() - except BaseException: - pass + description="simple recordType (from test_inheritance.py)") .add_property( + name='SimpleTextProperty', + importance="obligatory") .add_property( + name='SimpleDoubleProperty', + importance="obligatory") .add_property( + name='SimpleIntegerProperty', + importance="obligatory") .add_property( + name='SimpleDatetimeProperty') .add_property( + name='SimpleFileProperty')) + c.insert() + + rt = db.RecordType( + name="SubTypeOfSimpleRecordType", + description="recordtype with inheritance (from test_inheritance.py)").add_parent( + name="SimpleRecordType", + inheritance="obligatory") + rt.insert() + assert 3 == len(rt.get_properties()) def test_inheritance_unit(): - p = h.Property( + p = db.Property( name="SimpleIntProperty", datatype="INTEGER", unit="m") @@ -195,7 +192,7 @@ def test_inheritance_unit(): assert p.is_valid() assert p.unit == "m" - rt = h.RecordType( + rt = db.RecordType( name="SimpleRecordType") rt.add_property(p, unit="km") rt.insert() @@ -203,11 +200,11 @@ def test_inheritance_unit(): assert rt.is_valid() assert rt.get_property("SimpleIntProperty").unit == "km" - rt2 = h.execute_query("FIND SimpleRecordType", True) + rt2 = db.execute_query("FIND SimpleRecordType", True) assert rt2.id == rt.id assert rt2.get_property("SimpleIntProperty").unit == "km" - rt3 = h.RecordType( + rt3 = db.RecordType( name="SimpleRecordType2") rt3.add_parent(rt, inheritance="ALL") rt3.insert() @@ -215,12 +212,12 @@ def test_inheritance_unit(): assert rt3.get_property("SimpleIntProperty") is not None assert rt3.get_property("SimpleIntProperty").unit == "km" - rt4 = h.execute_query("FIND SimpleRecordType2", True) + rt4 = db.execute_query("FIND SimpleRecordType2", True) assert rt4.is_valid() assert rt4.id == rt3.id assert rt4.get_property("SimpleIntProperty").unit == "km" - rec = h.Record( + rec = db.Record( name="SimpleRecord") rec.add_parent(rt3) rec.add_property(name="SimpleIntProperty", value=1) @@ -231,43 +228,54 @@ def test_inheritance_unit(): _ENTITIES = [ - h.RecordType(name="Simulation").add_property(name="SimulationModel"), + db.RecordType(name="Simulation").add_property(name="SimulationModel"), - h.RecordType(name="PublicationReference").add_property(name="date"), - h.RecordType( + db.RecordType(name="PublicationReference").add_property(name="date"), + db.RecordType( name="SimulationModel").add_property( name="PublicationReference"), - h.Property(name="date", datatype=h.TEXT), - h.Property(name="blub", datatype=h.TEXT), + db.Property(name="date", datatype=db.TEXT), + db.Property(name="blub", datatype=db.TEXT), ] -def setup_subproperties(): - con = h.Container().extend(_ENTITIES) - con.insert() - - -def setup_module(): - old = h.execute_query("FIND ENTITY WITH ID > 100") - if old: - old.delete() - - -def teardown_module(): - setup_module() - - -@with_setup(setup_subproperties) def test_inherit_subproperties(): - valid = h.Container().extend(_ENTITIES).retrieve() - container = h.Container().extend(_ENTITIES) + con = db.Container().extend(_ENTITIES) + con.insert() + valid = db.Container().extend(_ENTITIES).retrieve() + container = db.Container().extend(_ENTITIES) container.get_entity_by_name("Simulation").add_property(name="blub") for valid_e in valid: for entity in container: for prop in entity.get_properties(): if valid_e.name == prop.name: prop.id = valid_e.id - entity.get_properties()._inheritance[prop] = h.ALL + entity.get_properties()._inheritance[prop] = db.ALL container.get_entity_by_name("SimulationModel").update() container.get_entity_by_name("Simulation").update() + + +def test_inheritance_in_same_container(): + """This test covers three cases: + + 1. inheritance=db.SUGGESTED + 2. inheritance=db.RECOMMENDED + 3. inheritance=db.OBLIGATORY + """ + p = db.Property("TestProperty1", datatype=db.TEXT) + rt1 = db.RecordType("TestRT1").add_property(p, importance=db.RECOMMENDED) + rt2 = db.RecordType("TestRT2").add_parent("TestRT1", + inheritance=db.SUGGESTED) + rt3 = db.RecordType("TestRT3").add_parent("TestRT1", + inheritance=db.RECOMMENDED) + rt4 = db.RecordType("TestRT4").add_parent("TestRT1", + inheritance=db.OBLIGATORY) + c = db.Container().extend([p, rt1, rt2, rt3, rt4]) + + c.insert() + + assert len(rt1.get_properties()) == 1 + assert len(rt2.get_properties()) == 1 + assert len(rt3.get_properties()) == 1 + assert len(rt4.get_properties()) == 0 diff --git a/tests/test_issues_server.py b/tests/test_issues_server.py index e2d538499975c1d68d3de030269bf41b0fe9cb3f..7b3744f4feaee5338a6fa5b2c6c186f1ceb4837c 100644 --- a/tests/test_issues_server.py +++ b/tests/test_issues_server.py @@ -147,7 +147,8 @@ 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. + # 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") @@ -168,3 +169,32 @@ def test_issue_99(): 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 diff --git a/tests/test_manual.py b/tests/test_manual.py index edfa08b101fef708d7b8d7540596dc1ed0b5bcbb..1ba0b50dfb8d68c6c32ae82a4fe94b5e79f2d32a 100644 --- a/tests/test_manual.py +++ b/tests/test_manual.py @@ -66,7 +66,7 @@ def test_references(): '''define conductor''' conductor = Property( name="TestConductor", - description="The guy who conducted an experiment.", + description="The person who conducted an experiment.", datatype=person) '''define experiment''' diff --git a/tests/test_misc.py b/tests/test_misc.py index 3bc92360d0e75f0bef32571e5fca179e88887f1f..30edb1c21370c6ca7fd5dbe1daec7313f97728bc 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -264,18 +264,6 @@ def test_annotation(): rt = execute_query("FIND AnnotationTest*").delete() -def test_history(): - try: - rt = RecordType(name="SimpleTestProperty").insert() - rt.retrieve(flags={"H": None}) - assert_equal(rt.messages["History"], ('Insert', None)) - finally: - try: - rt.delete() - except BaseException: - pass - - def test_info(): i = Info() assert_is_not_none(i.messages["Flags"]) diff --git a/tests/test_permissions.py b/tests/test_permissions.py index 69aab490fe11b5c6073e0c91c3cbe1e7fd033aee..0c54ffcbb9549d457eb061660062ad632f9e3e80 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -46,6 +46,7 @@ easy_pw = "1234" def setup_module(): + switch_to_admin_user() insert_test_user() @@ -877,12 +878,14 @@ def test_retrieve_acl(): assert te.value.has_error(db.AuthorizationException) -@with_setup(setup, teardown) def test_retrieve_history(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() assert p.is_valid() grant_permission(p, "RETRIEVE:ENTITY") + p.retrieve() + assert p.version is not None + assert p.version.username is None, "username belongs to history" '''Failure''' with raises(db.TransactionError) as te: @@ -893,7 +896,8 @@ def test_retrieve_history(): grant_permission(p, "RETRIEVE:HISTORY") p.retrieve(flags={"H": None}) - assert p.messages["History"] == ('Insert', None) + assert p.version is not None + assert p.version.username == db.get_config().get("Connection", "username") @with_setup(setup, teardown) diff --git a/tests/test_query_template.py b/tests/test_query_template.py index 92c9c1d044fbe2ecacd40347809fae00a3f5a89c..f44487ad26f8826cd841d3c36bd1a10e114cf7bd 100644 --- a/tests/test_query_template.py +++ b/tests/test_query_template.py @@ -31,6 +31,7 @@ from pytest import raises def setup_module(): + db.configure_connection() try: db.administration._delete_user(name="test_user") except Exception as e: @@ -82,12 +83,7 @@ def setup(): def teardown(): - try: - db.get_connection()._logout() - db.configure_connection() - db.get_connection()._login() - except Exception as e: - print(e) + db.configure_connection() try: db.execute_query("FIND QUERYTEMPLATE Test*").delete() except Exception as e: @@ -333,9 +329,7 @@ def test_query_without_permission(): r = db.execute_query("FIND TestPigExperiment", unique=True) assert_equal(r.name, "TestRecord") - db.get_connection()._logout() db.configure_connection() - db.get_connection()._login() e = db.Entity(id=qt.id) e.retrieve_acl() diff --git a/tests/test_query_version.py b/tests/test_query_version.py new file mode 100644 index 0000000000000000000000000000000000000000..0b152ee0f3015c08be7d46f680e1694eaeeaa8ca --- /dev/null +++ b/tests/test_query_version.py @@ -0,0 +1,670 @@ +# 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 +# +# 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 +# +import caosdb as db +import pytest +from caosdb import execute_query as query + +db.configure_connection() +CONTAINER = db.Container() +NAME_PROPERTY = db.Property("name").retrieve() +TEST_PROP_TEXT = db.Property("TestPropertyText", datatype=db.TEXT) +TEST_PROP_DOUBLE = db.Property("TestPropertyDouble", datatype=db.DOUBLE) +TEST_PROP_INTEGER = db.Property("TestPropertyInteger", datatype=db.INTEGER) +TEST_PROP_DATETIME = db.Property("TestPropertyDatetime", datatype=db.DATETIME) +TEST_PROP_DATE = db.Property("TestPropertyDate", datatype=db.DATETIME) +TEST_PROP_BOOLEAN = db.Property("TestPropertyBoolean", datatype=db.BOOLEAN) +TEST_PROP_NAME = db.Property("TestPropertyName", + datatype=db.TEXT).add_parent(NAME_PROPERTY) + +TEST_REF_RT = db.RecordType("TestRefRecordType") +TEST_REF_1 = db.Record("TestRef1", description="ref1").add_parent(TEST_REF_RT) +TEST_REF_2 = db.Record("TestRef2", description="ref2").add_parent(TEST_REF_RT) +TEST_REF_3 = db.Record("TestRef3", description="ref3").add_parent(TEST_REF_RT) + +TEST_RT_1 = db.RecordType("TestRecordType1") + +TEST_REC_1 = db.Record( + "TestRecord1", + description="v1").add_parent( + TEST_RT_1).add_property( + TEST_PROP_TEXT, + "val1").add_property( + TEST_PROP_DOUBLE, + 1.14).add_property( + TEST_PROP_INTEGER, + 100).add_property( + TEST_PROP_DATETIME, + "2021-12-24T20:15:00").add_property( + TEST_PROP_DATE, + "2021-12").add_property( + TEST_REF_RT, + TEST_REF_1).add_property( + TEST_PROP_BOOLEAN, + True).add_property( + TEST_PROP_NAME, + "Alias1") + + +TEST_PROP_TEXT_2 = db.Property("TestPropertyText2", datatype=db.TEXT) +TEST_BACKREF_RT = db.RecordType("TestBackRefRecordType") +TEST_BACKREF_0 = db.Record( + "TestBackRef0", + description="bref0").add_parent(TEST_BACKREF_RT).add_property( + TEST_RT_1, + "TestRecord1").add_property( + TEST_PROP_TEXT_2, + "val0") +TEST_BACKREF_1 = db.Record("TestBackRef1", description="bref1").add_parent( + TEST_BACKREF_RT).add_property(TEST_PROP_TEXT_2, "val1") +TEST_BACKREF_2 = db.Record("TestBackRef2", description="bref2").add_parent( + TEST_BACKREF_RT).add_property(TEST_PROP_TEXT_2, "val2") +TEST_BACKREF_3 = db.Record("TestBackRef3", description="bref3").add_parent( + TEST_BACKREF_RT).add_property(TEST_PROP_TEXT_2, "val3") + + +def teardown_module(): + CONTAINER.delete() + + +def setup_module(): + CONTAINER.extend([TEST_RT_1, TEST_REC_1, TEST_PROP_TEXT, TEST_PROP_DOUBLE, + TEST_PROP_INTEGER, TEST_PROP_DATETIME, TEST_PROP_DATE, + TEST_REF_RT, TEST_REF_1, TEST_REF_2, TEST_REF_3, + TEST_BACKREF_RT, TEST_BACKREF_0, TEST_PROP_TEXT_2, + TEST_PROP_BOOLEAN, TEST_PROP_NAME, + ]).insert() + CONTAINER.append(TEST_BACKREF_1) + TEST_BACKREF_1.add_property( + TEST_RT_1, str( + TEST_REC_1.id) + "@HEAD").insert() + + # update test_rec_1 two times + TEST_REC_1.description = "v2" + TEST_REC_1.get_property(TEST_PROP_TEXT).value = "val2" + TEST_REC_1.get_property(TEST_PROP_DOUBLE).value = 2.14 + TEST_REC_1.get_property(TEST_PROP_INTEGER).value = 200 + TEST_REC_1.get_property(TEST_PROP_DATETIME).value = "2022-12-24T20:15:00" + TEST_REC_1.get_property(TEST_PROP_DATE).value = "2022-12" + TEST_REC_1.get_property(TEST_REF_RT).value = TEST_REF_2 + TEST_REC_1.get_property(TEST_PROP_NAME).value = "Alias2" + TEST_REC_1.get_property(TEST_PROP_BOOLEAN).value = False + TEST_REC_1.update() + + CONTAINER.append(TEST_BACKREF_2) + TEST_BACKREF_2.add_property( + TEST_RT_1, str( + TEST_REC_1.id) + "@HEAD").insert() + + TEST_REC_1.description = "v3" + TEST_REC_1.get_property(TEST_PROP_TEXT).value = "val3" + TEST_REC_1.get_property(TEST_PROP_DOUBLE).value = 3.14 + TEST_REC_1.get_property(TEST_PROP_INTEGER).value = 300 + TEST_REC_1.get_property(TEST_PROP_DATETIME).value = "2023-12-24T20:15:00" + TEST_REC_1.get_property(TEST_PROP_DATE).value = "2023-12" + TEST_REC_1.get_property(TEST_REF_RT).value = TEST_REF_3 + TEST_REC_1.get_property(TEST_PROP_NAME).value = "Alias3" + TEST_REC_1.get_property(TEST_PROP_BOOLEAN).value = True + TEST_REC_1.update() + + CONTAINER.append(TEST_BACKREF_3) + TEST_BACKREF_3.add_property( + TEST_RT_1, str( + TEST_REC_1.id) + "@HEAD").insert() + + +def test_normal_find_record(): + result = query("FIND RECORD TestRecord1") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND RECORD TestRecordType1") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND RECORD TestRecord1 WITH TestPropertyText = val3") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND RECORD TestRecord1 WITH TestPropertyText = val1") + assert len(result) == 0 + + result = query("FIND RECORD TestRecord1 WITH TestPropertyDouble = 3.14") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND RECORD TestRecord1 WITH TestPropertyDouble = 1.14") + assert len(result) == 0 + + result = query("FIND RECORD TestRecord1 WITH TestPropertyInteger = 300") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND RECORD TestRecord1 WITH TestPropertyInteger = 100") + assert len(result) == 0 + + result = query( + "FIND RECORD TestRecord1 WITH TestPropertyDatetime = 2023-12-24T20:15:00") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND RECORD TestRecord1 WITH TestPropertyDatetime IN 2023-12") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND RECORD TestRecord1 WITH TestPropertyDatetime = 2021-12-24T20:15:00") + assert len(result) == 0 + + result = query("FIND RECORD TestRecord1 WITH TestPropertyDatetime IN 2021") + assert len(result) == 0 + + result = query("FIND RECORD TestRecord1 WITH TestPropertyDate = 2023-12") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND RECORD TestRecord1 WITH TestPropertyDate = 2021-12") + assert len(result) == 0 + + result = query("FIND RECORD TestRecord1 WITH TestPropertyDate in 2023") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND RECORD TestRecord1 WITH TestPropertyDate in 2021") + assert len(result) == 0 + + result = query("FIND RECORD TestRecord1 WITH TestRefRecordType = TestRef3") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND RECORD TestRecord1 WITH TestRefRecordType = TestRef1") + assert len(result) == 0 + + result = query( + "FIND RECORD TestRecord1 WITH TestRefRecordType -> TestRef3") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND RECORD TestRecord1 WITH TestRefRecordType -> TestRef1") + assert len(result) == 0 + + result = query("FIND RECORD WITH TestRefRecordType AND TestPropertyText") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND RECORD TestRefRecordType WITH NOT TestPropertyText") + assert len(result) == 3 + assert set(["ref1", "ref2", "ref3"]) == set( + [r.description for r in result]) + + result = query("FIND RECORD TestRecord1 WITH NOT TestPropertyText") + assert len(result) == 0 + + result = query("FIND RECORD WITH NOT TestPropertyText") + assert len(result) == 7 + assert set(["ref1", "ref2", "ref3", "bref0", "bref1", "bref2", + "bref3", ]) == set([r.description for r in result]) + + result = query("FIND RECORD WHICH IS REFERENCED BY TestBackRefRecordType") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND RECORD WHICH IS REFERENCED BY TestBackRef0") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND RECORD WHICH IS REFERENCED BY TestBackRefRecordType WITH TestPropertyText2=val0") + assert len(result) == 1 + assert result[0].description == "v3" + + +@pytest.mark.xfail( + reason=("Find queries which respect the version of the references are not supported yet and " + "return false positives.")) +def test_normal_find_with_versioned_reference(): + # current version is not referenced + result = query("FIND RECORD WHICH IS REFERENCED BY TestBackRef1") + assert len(result) == 0 + + +def test_find_any_version_of_record(): + result = query("FIND ANY VERSION OF RECORD") + assert len(result) == 10 + assert set(["v3", "v2", "v1", "ref1", "ref2", "ref3", "bref0", "bref1", + "bref2", "bref3"] + ) == {r.description for r in result} + + +def test_find_any_version_of_entity_by_name(): + result = query("FIND ANY VERSION OF ENTITY TestRecord1") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + +def test_find_any_version_of_record_by_name(): + result = query("FIND ANY VERSION OF RECORD TestRecord1") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + +def test_find_any_version_of_record_by_parent(): + result = query("FIND ANY VERSION OF RECORD TestRecordType1") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + +def test_find_any_version_of_named_entity_with_id_filter(): + result = query( + "FIND ANY VERSION OF TestRecord1 WITH id = " + str(TEST_REC_1.id)) + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + +def test_find_any_version_of_entity_with_id_filter(): + result = query("FIND ANY VERSION OF ENTITY WITH id = " + + str(TEST_REC_1.id)) + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + +def test_find_any_version_of_record_with_id_filter(): + result = query("FIND ANY VERSION OF RECORD WITH id = " + + str(TEST_REC_1.id)) + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + +def test_find_any_version_of_record_with_simple_pov_text_filter(): + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyText") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyText = val3") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyText = val2") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property("TestPropertyText").value == "val2" + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyText = val1") + assert len(result) == 1 + assert result[0].description == "v1" + + +def test_find_any_version_of_record_with_simple_pov_name_filter(): + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyName") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyName = Alias3") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyName = Alias2") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property("TestPropertyName").value == "Alias2" + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyName = Alias1") + assert len(result) == 1 + assert result[0].description == "v1" + + +def test_find_any_version_of_record_with_simple_pov_boolean_filter(): + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyBoolean") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyBoolean = TRUE AND TestPropertyText = val3") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyBoolean = FALSE") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property("TestPropertyBoolean").value is False + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyBoolean = TRUE AND TestPropertyText = val1") + assert len(result) == 1 + assert result[0].description == "v1" + + +def test_find_any_version_of_record_with_simple_pov_double_filter(): + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyDouble") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyDouble = 3.14") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyDouble = 2.14") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property("TestPropertyDouble").value == 2.14 + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyDouble = 1.14") + assert len(result) == 1 + assert result[0].description == "v1" + + +def test_find_any_version_of_record_with_simple_pov_integer_filter(): + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyInteger") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyInteger = 300") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyInteger = 200") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property("TestPropertyInteger").value == 200 + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyInteger = 100") + assert len(result) == 1 + assert result[0].description == "v1" + + +def test_find_any_version_of_record_with_simple_pov_datetime_filter(): + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyDatetime") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyDatetime = 2023-12-24T20:15:00") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyDatetime = 2022-12-24T20:15:00") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property( + "TestPropertyDatetime").value.startswith("2022") + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyDatetime = 2021-12-24T20:15:00") + assert len(result) == 1 + assert result[0].description == "v1" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyDatetime IN 2023") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyDatetime IN 2022") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property( + "TestPropertyDatetime").value.startswith("2022") + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyDatetime IN 2021") + assert len(result) == 1 + assert result[0].description == "v1" + + +def test_find_any_version_of_record_with_simple_pov_date_filter(): + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyDate") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyDate = 2023-12") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyDate = 2022-12") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property("TestPropertyDate").value.startswith("2022") + + result = query( + "FIND ANY VERSION OF RECORD WITH TestPropertyDate = 2021-12") + assert len(result) == 1 + assert result[0].description == "v1" + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyDate IN 2023") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyDate IN 2022") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property("TestPropertyDate").value.startswith("2022") + + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyDate IN 2021") + assert len(result) == 1 + assert result[0].description == "v1" + + +def test_find_any_version_of_record_with_simple_reference_filter(): + result = query("FIND ANY VERSION OF RECORD WITH TestRefRecordType") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef3") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef2") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property("TestRefRecordType").value == TEST_REF_2.id + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef1") + assert len(result) == 1 + assert result[0].description == "v1" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType -> TestRef3") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType -> TestRef2") + assert len(result) == 1 + assert result[0].description == "v2" + assert result[0].get_property("TestRefRecordType").value == TEST_REF_2.id + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType -> TestRef1") + assert len(result) == 1 + assert result[0].description == "v1" + + +def test_find_any_version_of_record_with_conjunction_filter(): + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType AND TestPropertyText") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef3 AND TestPropertyText") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef3 AND TestPropertyText = val3") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef2 AND TestPropertyText = val2") + assert len(result) == 1 + assert result[0].description == "v2" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef3 AND TestPropertyText = val2") + assert len(result) == 0 + + +def test_find_any_version_of_record_with_disjunction_filter(): + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType OR TestPropertyText") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef3 OR TestPropertyText") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef2 OR TestPropertyText") + assert len(result) == 3 + assert set(["v3", "v2", "v1"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef3 OR TestPropertyText = val3") + assert len(result) == 1 + assert result[0].description == "v3" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef2 OR TestPropertyText = val2") + assert len(result) == 1 + assert result[0].description == "v2" + + result = query( + "FIND ANY VERSION OF TestRecord1 WITH TestRefRecordType = TestRef2 OR TestPropertyText = val2") + assert len(result) == 1 + assert result[0].description == "v2" + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef2 OR TestPropertyText = val3") + assert len(result) == 2 + assert set(["v3", "v2"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD WITH TestRefRecordType = TestRef2 OR TestPropertyText = val3 OR TestPropertyInteger = 200") + assert len(result) == 2 + assert set(["v3", "v2"]) == {r.description for r in result} + + +def test_find_any_version_of_record_with_negation_filter(): + result = query( + "FIND ANY VERSION OF RECORD WHICH DOES NOT HAVE A TestPropertyText") + assert len(result) == 7 + assert set(["ref1", "ref2", "ref3", "bref0", "bref1", "bref2", + "bref3", ]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD WHICH DOES NOT HAVE A TestPropertyText=val2") + assert len(result) == 9 + assert set(["ref1", "ref2", "ref3", "bref0", "bref1", "bref2", "bref3", + "v1", "v3"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD TestRecord1 WHICH DOES NOT HAVE A TestPropertyText=val2") + assert len(result) == 2 + assert set(["v1", "v3"]) == {r.description for r in result} + + +def test_find_any_version_of_record_with_complex_filter(): + result = query("FIND ANY VERSION OF RECORD WITH TestPropertyText=val2 OR (TestPropertyInteger=200 AND NOT TestPropertyInteger=400 AND TestRefRecordType = TestRef2)") + assert len(result) == 1 + assert result[0].description == "v2" + + +def test_find_any_version_of_record_with_backref_filter(): + result = query( + "FIND ANY VERSION OF RECORD WHICH IS REFERENCED BY TestBackRefRecordType") + assert len(result) == 3 + assert set(["v1", "v2", "v3"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF RECORD TestRecord1 WHICH IS REFERENCED BY TestBackRefRecordType") + assert len(result) == 3 + assert set(["v1", "v2", "v3"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF TestRecord1 WHICH IS REFERENCED BY TestBackRefRecordType") + assert len(result) == 3 + assert set(["v1", "v2", "v3"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF TestRecord1 WHICH IS REFERENCED BY TestBackRef0") + assert len(result) == 3 + assert set(["v1", "v2", "v3"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF TestRecord1 WHICH IS REFERENCED BY TestBackRef0") + assert len(result) == 3 + assert set(["v1", "v2", "v3"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF TestRecord1 WHICH IS REFERENCED BY TestBackRef1") + assert len(result) == 1 + assert set(["v1"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF TestRecord1 WHICH IS REFERENCED BY TestBackRef2") + assert len(result) == 1 + assert set(["v2"]) == {r.description for r in result} + + result = query( + "FIND ANY VERSION OF TestRecord1 WHICH IS REFERENCED BY TestBackRef3") + assert len(result) == 1 + assert set(["v3"]) == {r.description for r in result} + + +@pytest.mark.xfail( + reason="versioned queries with subqueries are not supported yet") +def test_find_any_version_of_record_with_backref_and_subquery(): + result = query( + "FIND ANY VERSION OF RECORD WHICH IS REFERENCED BY TestBackRefRecordType WITH name = TestBackRef0") + assert len(result) == 1 + assert set(["v3"]) == {r.description for r in result} + + +@pytest.mark.xfail( + reason="versioned queries with subqueries are not supported yet") +def test_find_any_version_of_record_with_ref_and_subquery(): + result = query( + "FIND ANY VERSION OF RECORD WHICH REFERENCES TestRefRecordType WITH name = TestRef2") + assert len(result) == 1 + assert set(["v3"]) == {r.description for r in result} + + +@pytest.mark.xfail( + reason="versioned queries with aggregate functions are not supported yet") +def test_find_any_version_of_record_with_greatest_filter(): + result = query( + "FIND ANY VERSION OF RECORD WITH THE GREATEST TestPropertyInteger") + assert len(result) == 1 + assert set(["v3"]) == {r.description for r in result} diff --git a/tests/test_server_side_scripting.py b/tests/test_server_side_scripting.py index cff2017861e7779da9ded0d5541a77ce3a866751..ef0498cede01f96bfbceb305b87e7edf1083d95c 100644 --- a/tests/test_server_side_scripting.py +++ b/tests/test_server_side_scripting.py @@ -64,7 +64,7 @@ def setup(): def teardown(): - admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIR", + admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS", _ORIGINAL_SERVER_SCRIPTING_BIN_DIR) clean_database() @@ -72,7 +72,7 @@ def teardown(): def setup_module(): global _ORIGINAL_SERVER_SCRIPTING_BIN_DIR _ORIGINAL_SERVER_SCRIPTING_BIN_DIR = admin.get_server_property( - "SERVER_SIDE_SCRIPTING_BIN_DIR") + "SERVER_SIDE_SCRIPTING_BIN_DIRS") clean_database() from os import makedirs @@ -114,7 +114,7 @@ def test_call_script_non_existing(): def test_call_script_not_executable(): - admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIR", + admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS", _SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER) form = dict() form["call"] = "not_executable" @@ -124,7 +124,7 @@ def test_call_script_not_executable(): def test_call_ok(): - admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIR", + admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS", _SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER) form = dict() form["call"] = "ok" @@ -137,7 +137,7 @@ def test_call_ok(): def test_call_err(): - admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIR", + admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS", _SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER) form = dict() form["call"] = "err" @@ -353,7 +353,7 @@ def test_anonymous_script_calling_not_permitted(): def test_anonymous_script_calling_success(): - admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIR", + admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS", _SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER) form = dict() form["call"] = "ok_anonymous" @@ -380,3 +380,22 @@ def test_anonymous_script_calling_success(): assert xml.xpath("/Response/script/stdout")[0].text == "ok_anonymous" assert xml.xpath("/Response/script/stderr")[0].text is None assert xml.xpath("/Response/script/@code")[0] == "0" + + +def test_evil_path(): + subdir = os.path.join(_SERVER_SIDE_SCRIPTING_BIN_DIR_LOCAL, "subdir") + if not os.path.exists(subdir): + os.makedirs(subdir) + _REMOVE_FILES_AFTERWARDS.append(subdir) + admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS", + os.path.join(_SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER, + "subdir")) + + # ok exists one level up from "subdir" + assert os.path.exists( + os.path.join( + _SERVER_SIDE_SCRIPTING_BIN_DIR_LOCAL, + "ok")) + + with raises(EntityDoesNotExistError): + r = run_server_side_script("../ok") diff --git a/tests/test_version.py b/tests/test_version.py index b3b0a5c4347373b3819794d980df3acb27cd6a1f..401951524bcc0fb997560531b535e81cbb835c23 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -40,11 +40,14 @@ def test_version_object(): from caosdb.common.versioning import Version -def insertion(name="TestRT"): - rt = c.RecordType(name, description="TestDescription1").insert() +def insertion(name="TestRT", parents=[]): + rt = c.RecordType(name, description="TestDescription1") + for par in parents: + rt.add_parent(par) + rt.insert() assert rt.version is not None assert rt.version.id is not None - assert rt.version.date is not None + assert rt.version.is_head is True assert len(rt.version.predecessors) == 0 assert len(rt.version.successors) == 0 return rt @@ -55,7 +58,6 @@ def test_retrieve(): version = rt.version rt2 = c.execute_query("FIND RecordType TestRT", unique=True) - assert parse(rt2.version.date) == parse(version.date) assert rt2.version == version @@ -69,10 +71,8 @@ def test_update_description(): assert rt.description == new_desc assert rt.version is not None assert rt.version.id is not None - assert rt.version.date is not None assert rt.version != old_version - assert rt.version.date != old_version.date - assert parse(rt.version.date) > parse(old_version.date) + assert rt.version.is_head is True rt2 = c.execute_query("FIND RecordType TestRT", unique=True) assert rt2.version.id == rt.version.id @@ -89,11 +89,13 @@ def test_update_description(): "@" + old_version.id, sync=False)[0] assert rt_old.version.id == old_version.id assert rt_old.description == old_desc + assert rt_old.version.is_head is False def test_update_parent(): - par1 = insertion("TestRTParent1") - par2 = insertion("TestRTParent2") + superpar = insertion("TestRTParentSuper") + par1 = insertion("TestRTParent1", parents=[superpar]) + par2 = insertion("TestRTParent2", parents=[superpar]) rt = insertion("TestRTChild") assert len(rt.get_parents()) == 0 @@ -119,13 +121,16 @@ def test_update_parent(): assert len(c.execute_query("FIND TestRTParent2")) == 2 assert c.execute_query("FIND TestRTChild", unique=True).id == rt.id - rt_head = c.Container().retrieve(query=str(rt.id), sync=False)[0] + rt_head = c.Container().retrieve( + query=str( + rt.id), sync=False, flags={ + "cache": "false"})[0] rt_v1 = c.Container().retrieve(query=str(rt.id) + "@" + first_version.id, - sync=False)[0] + sync=False, flags={"cache": "false"})[0] rt_v2 = c.Container().retrieve(query=str(rt.id) + "@" + second_version.id, - sync=False)[0] + sync=False, flags={"cache": "false"})[0] rt_v3 = c.Container().retrieve(query=str(rt.id) + "@" + third_version.id, - sync=False)[0] + sync=False, flags={"cache": "false"})[0] assert rt_head.version == third_version assert rt_v1.version.id == first_version.id @@ -133,9 +138,11 @@ def test_update_parent(): assert rt_v3.version.id == third_version.id assert len(rt_v3.get_parents()) == 1 + print(rt_v3) assert rt_v3.get_parent("TestRTParent1") is None assert rt_v3.get_parent("TestRTParent2") is not None + print(rt_v2) assert len(rt_v2.get_parents()) == 1 assert rt_v2.get_parent("TestRTParent1") is not None assert rt_v2.get_parent("TestRTParent2") is None @@ -392,6 +399,37 @@ def test_bug_cached_parent_name_in_old_version(): assert old_rec.get_parent(del_rt_name) is None +@mark.xfail(reason="bug fix needed") +def test_bug_parent_name_in_old_version(): + """ mysql backend return current name even if this historically not + correct.""" + OLD_NAME = "TestRT1_old" + NEW_NAME = "TestRT1_cur" + rt = c.RecordType(name=OLD_NAME).insert() + + rec = c.Record(name="TestRec").add_parent(rt) + rec.insert() + rec.description = "v2" + rec.update() + + rec_v1 = c.Container().retrieve(str(rec.id) + "@HEAD~1", + sync=False, + flags={"cache": "false"}, + raise_exception_on_error=False)[0] + rec_v2 = c.Container().retrieve(str(rec.id) + "@HEAD", + sync=False, + flags={"cache": "false"}, + raise_exception_on_error=False)[0] + + assert [OLD_NAME] == [p.name for p in rec_v2.get_parents()] + assert [OLD_NAME] == [p.name for p in rec_v1.get_parents()] + + # change parent + rt.name = NEW_NAME + assert [NEW_NAME] == [p.name for p in rec_v2.get_parents()] + assert [OLD_NAME] == [p.name for p in rec_v1.get_parents()] + + def test_reference_deleted_in_old_version(): ref_rt = insertion("TestReferencedObject") rt = insertion("TestRT") @@ -703,10 +741,7 @@ def test_update_name(): assert rt.name == new_name assert rt.version is not None assert rt.version.id is not None - assert rt.version.date is not None assert rt.version != old_version - assert rt.version.date != old_version.date - assert parse(rt.version.date) > parse(old_version.date) assert len(c.execute_query("FIND RecordType {}".format(old_name))) == 0 rt2 = c.execute_query("FIND RecordType {}".format(new_name), unique=True) @@ -725,3 +760,93 @@ def test_update_name(): "@" + old_version.id, sync=False)[0] assert rt_old.version.id == old_version.id assert rt_old.name == old_name + + +def test_overridden_datatype(): + """A bug in the mysql backend resultet in a server error when the old + version of an entity was retrieved where the datatype of a property has + been overriden. + + Original error in the server logs: + ``` + org.caosdb.server.database.exceptions.TransactionException: java.sql.SQLSyntaxErrorException: Unknown column 'datatypeID' in 'where clause' + at org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveProperties.execute(MySQLRetrieveProperties.java:70) + ``` + """ + p = c.Property("TestProperty", datatype=c.TEXT).insert() + rt = c.RecordType("TestRT") + rt.add_property("TestProperty", datatype=c.LIST(c.TEXT)) + rt.insert() + + rt.description = "Updated TestRT" + rt.update() + + # retrieve the old version (cache flag must be set to "false") + rt_old = c.Container().retrieve(query=str(rt.id) + "@HEAD~1", + flags={"cache": "false"}, sync=False) + assert rt.get_property("TestProperty").datatype == c.LIST(c.TEXT) + + +def test_delete_referenced_entity(): + ref_rt = c.RecordType("TestReferencedRT").insert() + rt = c.RecordType("TestRT").insert() + ref = c.Record("TestRef1").add_parent(ref_rt).insert() + + rec = c.Record("TestRec").add_parent(rt).add_property(ref_rt, ref).insert() + + rec.description = "v2" + rec.remove_property(ref_rt) + rec.update() + + rec_v1 = c.Container().retrieve(query=str(rec.id) + "@HEAD~1", + flags={"cache": "false"}, sync=False)[0] + assert rec_v1.get_property(ref_rt).value == ref.id + + rec_v2 = c.Container().retrieve(query=str(rec.id) + "@HEAD", + flags={"cache": "false"}, sync=False)[0] + assert rec_v2.get_property(ref_rt) is None + + ref.delete() + + rec_v1 = c.Container().retrieve(query=str(rec.id) + "@HEAD~1", + flags={"cache": "false"}, sync=False)[0] + assert rec_v1.get_property(ref_rt).value is None + assert rec_v1.get_property(ref_rt).get_warnings()[ + 0].description == "The referenced entity has been deleted in the mean time and is not longer available." + + rec_v2 = c.Container().retrieve(query=str(rec.id) + "@HEAD", + flags={"cache": "false"}, sync=False)[0] + assert rec_v2.get_property(ref_rt) is None + + +def test_retrieve_history(): + rt = insertion() + versions = [] + desc = dict() + + versions.append(rt.version) + desc[rt.version.id] = rt.description + v5_version = None + + for i in range(10): + rt.description = rt.description + str(i) + rt.update() + versions.append(rt.version) + desc[rt.version.id] = rt.description + if i == 5: + v5_version = rt.version + + # retrieve history + rt_v5 = c.Container().retrieve(query=str(rt.id) + "@HEAD~4", + flags={"H": None}, + sync=False)[0] + assert rt_v5.version.is_complete_history is True + assert rt_v5.version.id == v5_version.id + history = rt_v5.version.get_history() + assert len(history) == len(versions) + # Compare actual and expected version + for act, exp in zip(history, versions): + assert act.id == exp.id + tst = c.Container().retrieve(query=str(rt.id) + "@" + act.id, + sync=False)[0] + assert tst.description == desc[act.id]