diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 396a29b7bf0d8d282e37416b1224ec6d592170da..4f99d127ddd22f6133c5942d4c8e46c6af1a725e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,6 +28,7 @@ stages: - cert - style - test + - deploy # During the test stage the CI pipeline (which runs in a "root" docker) starts @@ -123,6 +124,11 @@ test: - cd .docker # here the server and the mysql backend docker are being started - CAOSDB_TAG=$CAOSDB_TAG docker-compose up -d + # store versions of CaosDB parts + - docker exec -u 0 -t docker_caosdb-server_1 cat /opt/caosdb/git/caosdb_pylib_commit > hash_pylib + - docker exec -u 0 -t docker_caosdb-server_1 cat /opt/caosdb/git/caosdb_webui_commit > hash_webui + - docker exec -u 0 -t docker_caosdb-server_1 cat /opt/caosdb/git/caosdb_server_commit > hash_server + - docker exec -u 0 -t docker_caosdb-server_1 cat /opt/caosdb/git/caosdb_mysqlbackend_commit > hash_mysql # the pyinttest docker writes the return value of the tests into the # file result - /bin/sh ./run.sh @@ -138,7 +144,7 @@ test: paths: - caosdb_log.txt - mariadb_log.txt - when: on_failure + - .docker/hash_* expire_in: 1 week build-testenv: @@ -193,3 +199,25 @@ style: script: - autopep8 -r --diff --exit-code . allow_failure: true + + +store-version: + tags: [docker] + stage: deploy + dependencies: [test] + image: $CI_REGISTRY_IMAGE + script: + - curl -u gitlab:$REVISONSTOREPW + --data server=$(cat .docker/hash_server) + --data mysql=$(cat .docker/hash_mysql) + --data pylib=$(cat .docker/hash_pylib) + --data webui=$(cat .docker/hash_webui) + --data save=1 https://caosdb.org/revisions/saverev.php + allow_failure: true + only: + - dev + - master + # TODO remove + - f-versions + - web + diff --git a/CHANGELOG.md b/CHANGELOG.md index 0682590eca1a575646eeed6084849e88c27a0b68..54331f5ebb34f4b9af7c3592358a62dc5e1d5b2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed (for changes in existing functionality) +* Tests comply with the new entity error handling (see + [#32](https://gitlab.com/caosdb/caosdb-pylib/-/issues/32) in + caosdb-pylib). * `test_recursive_parents.py` now tests inserted entities; set to xfail until [caosdb-pylib#34](https://gitlab.com/caosdb/caosdb-pylib/-/issues/34) @@ -36,6 +39,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed (for now removed features) +- Some redundant tests from `test_tickets.py` that checked + functionality that was already tested in `test_error_stuff.py`. + ### Fixed (for any bug fixes) * Tests for NaN Double Values (see https://gitlab.com/caosdb/caosdb-server/issues/41) diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000000000000000000000000000000000000..529a96a81c76e6d2607e1cddcc79024981d3cc56 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,4 @@ +[pytest] +markers = + local_server: mark a test as requiring a local caosdb server + slow: mark a test as slow (execution regularly takes 5s or longer) diff --git a/tests/test_administration.py b/tests/test_administration.py index 9ca57c659079f7f3b6cbd39a4b83a89f53621f20..9ecc1360dc537852463c8ab3c2abc945266711e2 100644 --- a/tests/test_administration.py +++ b/tests/test_administration.py @@ -27,12 +27,12 @@ """ from caosdb import administration as admin -from caosdb import get_config from caosdb.connection.connection import configure_connection, get_connection -from caosdb.exceptions import (AuthorizationException, ClientErrorException, - LoginFailedException, TransactionError) +from caosdb.exceptions import (HTTPClientError, HTTPForbiddenError, + LoginFailedError, HTTPResourceNotFoundError) from nose.tools import (assert_equal, assert_is_not_none, assert_raises, assert_true) +from pytest import raises test_role = "test_role" test_user = "test_user" @@ -104,16 +104,14 @@ def test_insert_role_success(): def test_insert_role_failure_permission(): switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._insert_role(name=test_role, description=test_role_desc) - assert_equal( - cm.exception.msg, - "You are not permitted to insert a new role.") + assert cm.value.msg == "You are not permitted to insert a new role." def test_insert_role_failure_name_duplicates(): test_insert_role_success() - with assert_raises(ClientErrorException) as cm: + with assert_raises(HTTPClientError) as cm: admin._insert_role(name=test_role, description=test_role_desc) assert_equal( cm.exception.msg, @@ -132,17 +130,15 @@ def test_update_role_success(): def test_update_role_failure_permissions(): test_insert_role_success() switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._update_role(name=test_role, description=test_role_desc + "asdf") - assert_equal( - cm.exception.msg, - "You are not permitted to update this role.") + assert cm.value.msg == "You are not permitted to update this role." def test_update_role_failure_non_existing(): - with assert_raises(TransactionError) as cm: + with raises(HTTPResourceNotFoundError) as cm: admin._update_role(name=test_role, description=test_role_desc + "asdf") - assert_equal(cm.exception.msg, "Role does not exist.") + assert cm.value.msg == "Role does not exist." def test_delete_role_success(): @@ -153,17 +149,15 @@ def test_delete_role_success(): def test_delete_role_failure_permissions(): test_insert_role_success() switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._delete_role(name=test_role) - assert_equal( - cm.exception.msg, - "You are not permitted to delete this role.") + assert cm.value.msg == "You are not permitted to delete this role." def test_delete_role_failure_non_existing(): - with assert_raises(TransactionError) as cm: + with raises(HTTPResourceNotFoundError) as cm: admin._delete_role(name=test_role) - assert_equal(cm.exception.msg, "Role does not exist.") + assert cm.value.msg == "Role does not exist." def test_retrieve_role_success(): @@ -175,17 +169,15 @@ def test_retrieve_role_success(): def test_retrieve_role_failure_permission(): test_insert_role_success() switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._retrieve_role(name=test_role) - assert_equal( - cm.exception.msg, - "You are not permitted to retrieve this role.") + assert cm.value.msg == "You are not permitted to retrieve this role." def test_retrieve_role_failure_non_existing(): - with assert_raises(TransactionError) as cm: + with raises(HTTPResourceNotFoundError) as cm: admin._retrieve_role(name=test_role) - assert_equal(cm.exception.msg, "Role does not exist.") + assert cm.value.msg == "Role does not exist." def test_set_permissions_success(): @@ -202,23 +194,21 @@ def test_set_permissions_success(): def test_set_permissions_failure_permissions(): test_insert_role_success() switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._set_permissions( role=test_role, permission_rules=[ admin.PermissionRule( "Grant", "BLA:BLA:BLA")]) - assert_equal( - cm.exception.msg, - "You are not permitted to set this role's permissions.") + assert cm.value.msg == "You are not permitted to set this role's permissions." def test_set_permissions_failure_non_existing(): - with assert_raises(TransactionError) as cm: + with raises(HTTPResourceNotFoundError) as cm: admin._set_permissions( role=test_role, permission_rules=[ admin.PermissionRule( "Grant", "BLA:BLA:BLA")]) - assert_equal(cm.exception.msg, "Role does not exist.") + assert cm.value.msg == "Role does not exist." def test_get_permissions_success(): @@ -231,17 +221,15 @@ def test_get_permissions_success(): def test_get_permissions_failure_permissions(): test_set_permissions_success() switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._get_permissions(role=test_role) - assert_equal( - cm.exception.msg, - "You are not permitted to retrieve this role's permissions.") + assert cm.value.msg == "You are not permitted to retrieve this role's permissions." def test_get_permissions_failure_non_existing(): - with assert_raises(TransactionError) as cm: + with raises(HTTPResourceNotFoundError) as cm: admin._get_permissions(role="non-existing-role") - assert_equal(cm.exception.msg, "Role does not exist.") + assert cm.value.msg == "Role does not exist." def test_get_roles_success(): @@ -255,17 +243,15 @@ def test_get_roles_success(): def test_get_roles_failure_permissions(): test_insert_role_success() switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._get_roles(username=test_user) - assert_equal( - cm.exception.msg, - "You are not permitted to retrieve this user's roles.") + assert cm.value.msg == "You are not permitted to retrieve this user's roles." def test_get_roles_failure_non_existing(): - with assert_raises(TransactionError) as cm: + with raises(HTTPResourceNotFoundError) as cm: admin._get_roles(username="non-existing-user") - assert_equal(cm.exception.msg, "User does not exist.") + assert cm.value.msg == "User does not exist." def test_set_roles_success(): @@ -290,16 +276,14 @@ def test_set_roles_failure_permissions(): roles = {test_role} roles.union(roles_old) switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._set_roles(username=test_user, roles=roles_old) - assert_equal( - cm.exception.msg, - "You are not permitted to set this user's roles.") + assert cm.value.msg == "You are not permitted to set this user's roles." def test_set_roles_failure_non_existing_role(): roles = {"non-existing-role"} - with assert_raises(ClientErrorException) as cm: + with assert_raises(HTTPClientError) as cm: admin._set_roles(username=test_user, roles=roles) assert_equal(cm.exception.msg, "Role does not exist.") @@ -307,9 +291,9 @@ def test_set_roles_failure_non_existing_role(): def test_set_roles_failure_non_existing_user(): test_insert_role_success() roles = {test_role} - with assert_raises(TransactionError) as cm: + with raises(HTTPResourceNotFoundError) as cm: admin._set_roles(username="non-existing-user", roles=roles) - assert_equal(cm.exception.msg, "User does not exist.") + assert cm.value.msg == "User does not exist." def test_insert_user_success(): @@ -323,21 +307,19 @@ def test_insert_user_success(): def test_insert_user_failure_permissions(): switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._insert_user( name=test_user, password="secret1P!", status="ACTIVE", email="email@example.com", entity=None) - assert_equal( - cm.exception.msg, - "You are not permitted to insert a new user.") + assert cm.value.msg == "You are not permitted to insert a new user." def test_insert_user_failure_name_in_use(): test_insert_user_success() - with assert_raises(ClientErrorException) as cm: + with assert_raises(HTTPClientError) as cm: test_insert_user_success() assert_equal(cm.exception.msg, "User name is already in use.") @@ -350,17 +332,15 @@ def test_delete_user_success(): def test_delete_user_failure_permissions(): test_insert_user_success() switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._delete_user(name="non_existing_user") - assert_equal( - cm.exception.msg, - "You are not permitted to delete this user.") + assert cm.value.msg == "You are not permitted to delete this user." def test_delete_user_failure_non_existing(): - with assert_raises(TransactionError) as cm: + with raises(HTTPResourceNotFoundError) as cm: admin._delete_user(name="non_existing_user") - assert_equal(cm.exception.msg, "User does not exist.") + assert cm.value.msg == "User does not exist." def test_update_user_success_status(): @@ -427,15 +407,12 @@ def test_update_user_success_password(): def test_update_user_failure_permissions_status(): - assert_is_not_none( - admin._insert_user( - name=test_user + "2", - password="secret1P!", - status="INACTIVE", - email="email@example.com", - entity=None)) + assert admin._insert_user(name=test_user + "2", + password="secret1P!", + status="INACTIVE", + email="email@example.com", entity=None) is not None switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._update_user( realm=None, name=test_user + "2", @@ -443,21 +420,15 @@ def test_update_user_failure_permissions_status(): status="ACTIVE", email=None, entity=None) - assert_equal( - cm.exception.msg, - "You are not permitted to update this user.") + assert cm.value.msg == "You are not permitted to update this user." def test_update_user_failure_permissions_email(): - assert_is_not_none( - admin._insert_user( - name=test_user + "2", - password="secret1P!", - status="ACTIVE", - email="email@example.com", - entity=None)) + assert admin._insert_user(name=test_user + "2", + password="secret1P!", status="ACTIVE", + email="email@example.com", entity=None) is not None switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._update_user( realm=None, name=test_user + "2", @@ -465,21 +436,15 @@ def test_update_user_failure_permissions_email(): status=None, email="newemail@example.com", entity=None) - assert_equal( - cm.exception.msg, - "You are not permitted to update this user.") + assert cm.value.msg == "You are not permitted to update this user." def test_update_user_failure_permissions_entity(): - assert_is_not_none( - admin._insert_user( - name=test_user + "2", - password="secret1P!", - status="ACTIVE", - email="email@example.com", - entity=None)) + assert admin._insert_user(name=test_user + "2", + password="secret1P!", status="ACTIVE", + email="email@example.com", entity=None) is not None switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._update_user( realm=None, name=test_user + "2", @@ -487,21 +452,15 @@ def test_update_user_failure_permissions_entity(): status=None, email=None, entity=21) - assert_equal( - cm.exception.msg, - "You are not permitted to update this user.") + assert cm.value.msg == "You are not permitted to update this user." def test_update_user_failure_permissions_password(): - assert_is_not_none( - admin._insert_user( - name=test_user + "2", - password="secret1P!", - status="ACTIVE", - email="email@example.com", - entity=None)) + assert admin._insert_user(name=test_user + "2", + password="secret1P!", status="ACTIVE", + email="email@example.com", entity=None) is not None switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._update_user( realm=None, name=test_user + "2", @@ -509,13 +468,11 @@ def test_update_user_failure_permissions_password(): status=None, email=None, entity=None) - assert_equal( - cm.exception.msg, - "You are not permitted to update this user.") + assert cm.value.msg == "You are not permitted to update this user." def test_update_user_failure_non_existing_user(): - with assert_raises(TransactionError) as cm: + with raises(HTTPResourceNotFoundError) as cm: admin._update_user( realm=None, name="non-existing-user", @@ -523,18 +480,14 @@ def test_update_user_failure_non_existing_user(): status="ACTIVE", email="email@example.com", entity=None) - assert_equal(cm.exception.msg, "User does not exist.") + assert cm.value.msg == "User does not exist." def test_update_user_failure_non_existing_entity(): - assert_is_not_none( - admin._insert_user( - name=test_user + "2", - password="secret1P!", - status="ACTIVE", - email="email@example.com", - entity=None)) - with assert_raises(ClientErrorException) as cm: + assert admin._insert_user(name=test_user + "2", + password="secret1P!", status="ACTIVE", + email="email@example.com", entity=None) is not None + with raises(HTTPClientError) as cm: admin._update_user( realm=None, name=test_user + "2", @@ -542,7 +495,7 @@ def test_update_user_failure_non_existing_entity(): status=None, email=None, entity=100000) - assert_equal(cm.exception.msg, "Entity does not exist.") + assert cm.value.msg == "Entity does not exist." def test_retrieve_user_success(): @@ -553,17 +506,15 @@ def test_retrieve_user_success(): def test_retrieve_user_failure_permissions(): test_insert_user_success() switch_to_normal_user() - with assert_raises(AuthorizationException) as cm: + with raises(HTTPForbiddenError) as cm: admin._retrieve_user(realm=None, name=test_user + "2") - assert_equal( - cm.exception.msg, - "You are not permitted to retrieve this user.") + assert cm.value.msg == "You are not permitted to retrieve this user." def test_retrieve_user_failure_non_existing(): - with assert_raises(TransactionError) as cm: + with raises(HTTPResourceNotFoundError) as cm: admin._retrieve_user(realm=None, name="non_existing") - assert_equal(cm.exception.msg, "User does not exist.") + assert cm.value.msg == "User does not exist." def test_login_with_inactive_user_failure(): @@ -576,5 +527,5 @@ def test_login_with_inactive_user_failure(): entity=None)) configure_connection(username=test_user + "2", password="secret1P!", password_method="plain") - with assert_raises(LoginFailedException): + with assert_raises(LoginFailedError): get_connection()._login() diff --git a/tests/test_affiliation.py b/tests/test_affiliation.py index 0b9f011d04708f68dd21e9059dac6bc23a5a159d..bdd73d117488ceb09210fdcdc0a92ba3b0794c3e 100644 --- a/tests/test_affiliation.py +++ b/tests/test_affiliation.py @@ -25,9 +25,10 @@ @author: tf """ -import caosdb as db import os -from nose.tools import nottest, assert_true, assert_raises, assert_equal, with_setup, assert_is_not_none # @UnresolvedImport +import caosdb as db +from nose.tools import nottest, assert_true, assert_equal, with_setup, assert_is_not_none +from pytest import raises def setup_module(): @@ -85,31 +86,33 @@ def test_rec_rt_is_instantiation(): @with_setup(setup, teardown) def test_rec_prop_is_invalid(): - with assert_raises(db.EntityError) as cm: + with raises(db.TransactionError) as cm: db.Record(name="TestRecordChild").add_parent(name=prop_name).insert() - assert_equal( - cm.exception.get_errors()[0].msg, - "Affiliation is not defined for this child-parent constellation.") + assert cm.value.has_error(db.UnqualifiedParentsError) + # TransactionError with UnqualifiedParentsError with EntityError + # caused by wrong affiliation + ee = cm.value.errors[0].errors[0] + assert ee.msg == "Affiliation is not defined for this child-parent constellation." @with_setup(setup, teardown) def test_rec_file_is_invalid(): - with assert_raises(db.EntityError) as cm: + with raises(db.TransactionError) as cm: db.Record(name="TestRecordChild").add_parent(name=file_name).insert() - assert_equal( - cm.exception.get_errors()[0].msg, - "Affiliation is not defined for this child-parent constellation.") + assert cm.value.has_error(db.UnqualifiedParentsError) + ee = cm.value.errors[0].errors[0] + assert ee.msg == "Affiliation is not defined for this child-parent constellation." @with_setup(setup, teardown) def test_rt_rec_is_invalid(): - with assert_raises(db.EntityError) as cm: + with raises(db.TransactionError) as cm: db.RecordType( name="TestRecordTypeChild").add_parent( name=rec_name).insert() - assert_equal( - cm.exception.get_errors()[0].msg, - "Affiliation is not defined for this child-parent constellation.") + assert cm.value.has_error(db.UnqualifiedParentsError) + ee = cm.value.errors[0].errors[0] + assert ee.msg == "Affiliation is not defined for this child-parent constellation." @with_setup(setup, teardown) @@ -121,48 +124,48 @@ def test_rt_rt_is_subtyping(): @with_setup(setup, teardown) def test_rt_prop_is_invalid(): - with assert_raises(db.EntityError) as cm: + with raises(db.TransactionError) as cm: db.RecordType( name="TestRecordTypeChild").add_parent( name=prop_name).insert() - assert_equal( - cm.exception.get_errors()[0].msg, - "Affiliation is not defined for this child-parent constellation.") + assert cm.value.has_error(db.UnqualifiedParentsError) + ee = cm.value.errors[0].errors[0] + assert ee.msg == "Affiliation is not defined for this child-parent constellation." @with_setup(setup, teardown) def test_rt_file_is_invalid(): - with assert_raises(db.EntityError) as cm: + with raises(db.TransactionError) as cm: db.RecordType( name="TestRecordTypeChild").add_parent( name=file_name).insert() - assert_equal( - cm.exception.get_errors()[0].msg, - "Affiliation is not defined for this child-parent constellation.") + assert cm.value.has_error(db.UnqualifiedParentsError) + ee = cm.value.errors[0].errors[0] + assert ee.msg == "Affiliation is not defined for this child-parent constellation." @with_setup(setup, teardown) def test_prop_rec_is_invalid(): - with assert_raises(db.EntityError) as cm: + with raises(db.TransactionError) as cm: db.Property( name="TestPropertyChild", datatype=db.TEXT).add_parent( name=rec_name).insert() - assert_equal( - cm.exception.get_errors()[0].msg, - "Affiliation is not defined for this child-parent constellation.") + assert cm.value.has_error(db.UnqualifiedParentsError) + ee = cm.value.errors[0].errors[0] + assert ee.msg == "Affiliation is not defined for this child-parent constellation." @with_setup(setup, teardown) def test_prop_rt_is_invalid(): - with assert_raises(db.EntityError) as cm: + with raises(db.TransactionError) as cm: db.Property( name="TestPropertyChild", datatype=db.TEXT).add_parent( name=recty_name).insert() - assert_equal( - cm.exception.get_errors()[0].msg, - "Affiliation is not defined for this child-parent constellation.") + assert cm.value.has_error(db.UnqualifiedParentsError) + ee = cm.value.errors[0].errors[0] + assert ee.msg == "Affiliation is not defined for this child-parent constellation." @with_setup(setup, teardown) @@ -176,14 +179,14 @@ def test_prop_prop_is_subtyping(): @with_setup(setup, teardown) def test_prop_file_is_invalid(): - with assert_raises(db.EntityError) as cm: + with raises(db.TransactionError) as cm: db.Property( name="TestPropertyChild", datatype=db.TEXT).add_parent( name=file_name).insert() - assert_equal( - cm.exception.get_errors()[0].msg, - "Affiliation is not defined for this child-parent constellation.") + assert cm.value.has_error(db.UnqualifiedParentsError) + ee = cm.value.errors[0].errors[0] + assert ee.msg == "Affiliation is not defined for this child-parent constellation." @with_setup(setup, teardown) @@ -208,28 +211,28 @@ def test_file_rt_is_instantiation(): @with_setup(setup, teardown) def test_file_prop_is_invalid(): - with assert_raises(db.EntityError) as cm: + with raises(db.TransactionError) as cm: db.File( name="TestFileChild", file=file_path, path="testfilechild.dat").add_parent( name=prop_name).insert() - assert_equal( - cm.exception.get_errors()[0].msg, - "Affiliation is not defined for this child-parent constellation.") + assert cm.value.has_error(db.UnqualifiedParentsError) + ee = cm.value.errors[0].errors[0] + assert ee.msg == "Affiliation is not defined for this child-parent constellation." @with_setup(setup, teardown) def test_file_file_is_invalid(): - with assert_raises(db.EntityError) as cm: + with raises(db.TransactionError) as cm: db.File( name="TestFileChild", file=file_path, path="testfilechild.dat").add_parent( name=file_name).insert() - assert_equal( - cm.exception.get_errors()[0].msg, - "Affiliation is not defined for this child-parent constellation.") + assert cm.value.has_error(db.UnqualifiedParentsError) + ee = cm.value.errors[0].errors[0] + assert ee.msg == "Affiliation is not defined for this child-parent constellation." @nottest diff --git a/tests/test_authentication.py b/tests/test_authentication.py index ce2a095bab5f6b2d70afbea1a2a96af624c71389..ef0657cbe215743e79ce1e2110a1b172cb980c36 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -33,7 +33,7 @@ import ssl from subprocess import call from lxml import etree from pytest import raises, mark -from caosdb.exceptions import LoginFailedException +from caosdb.exceptions import LoginFailedError import caosdb as db from .test_server_side_scripting import request @@ -86,7 +86,7 @@ def test_https_support(): def test_login_via_post_form_data_failure(): - with raises(LoginFailedException): + with raises(LoginFailedError): db.get_connection().post_form_data( "login", { "username": db.get_config().get("Connection", "username"), @@ -145,6 +145,7 @@ def test_login_while_anonymous_is_active(): "/Response/UserInfo/Roles/Role")[0].text == "administration" +@mark.local_server def test_authtoken_config(): assert db.administration.get_server_property( "AUTHTOKEN_CONFIG") == "conf/core/authtoken.example.yaml" @@ -174,6 +175,7 @@ def get_one_time_token(testcase): return auth_token +@mark.local_server def test_one_time_token(): assert db.Info().user_info.roles == ["administration"] assert db.Info().user_info.name == db.get_config().get("Connection", "username") @@ -193,13 +195,14 @@ def test_one_time_token(): "username") +@mark.local_server def test_one_time_token_invalid(): auth_token = get_one_time_token("admin_token_crud") auth_token = auth_token.replace("[]", '["permission"]') db.configure_connection(password_method="auth_token", auth_token=auth_token) - with raises(db.LoginFailedException) as lfe: + with raises(db.LoginFailedError) as lfe: db.Info() assert lfe.value.args[0] == ( "The authentication token is expired or you have been logged out otherwise. The auth_token " @@ -210,18 +213,19 @@ def test_one_time_token_invalid(): db.administration.set_server_property("AUTH_OPTIONAL", "TRUE") db.configure_connection(password_method="auth_token", auth_token=auth_token) - with raises(db.LoginFailedException) as lfe: + with raises(db.LoginFailedError) as lfe: db.Info() assert lfe.value.args[0] == ( "The authentication token is expired or you have been logged out otherwise. The auth_token " "authenticator cannot log in again. You must provide a new authentication token.") +@mark.local_server def test_one_time_token_expired(): auth_token = get_one_time_token("admin_token_expired") db.configure_connection(password_method="auth_token", auth_token=auth_token) - with raises(db.LoginFailedException) as lfe: + with raises(db.LoginFailedError) as lfe: db.Info() assert lfe.value.args[0] == ( "The authentication token is expired or you have been logged out otherwise. The auth_token " @@ -232,13 +236,14 @@ def test_one_time_token_expired(): db.administration.set_server_property("AUTH_OPTIONAL", "TRUE") db.configure_connection(password_method="auth_token", auth_token=auth_token) - with raises(db.LoginFailedException) as lfe: + with raises(db.LoginFailedError) as lfe: db.Info() assert lfe.value.args[0] == ( "The authentication token is expired or you have been logged out otherwise. The auth_token " "authenticator cannot log in again. You must provide a new authentication token.") +@mark.local_server def test_one_time_token_3_attempts(): auth_token = get_one_time_token("admin_token_3_attempts") @@ -273,7 +278,7 @@ def test_one_time_token_3_attempts(): db.configure_connection(password_method="auth_token", auth_token=auth_token) assert db.get_connection()._authenticator.auth_token == auth_token - with raises(db.LoginFailedException) as lfe: + with raises(db.LoginFailedError) as lfe: db.Info() assert lfe.value.args[0] == ( "The authentication token is expired or you have been logged out otherwise. The auth_token " @@ -286,13 +291,14 @@ def test_one_time_token_3_attempts(): db.configure_connection(password_method="auth_token", auth_token=auth_token) assert db.get_connection()._authenticator.auth_token == auth_token - with raises(db.LoginFailedException) as lfe: + with raises(db.LoginFailedError) as lfe: db.Info() assert lfe.value.args[0] == ( "The authentication token is expired or you have been logged out otherwise. The auth_token " "authenticator cannot log in again. You must provide a new authentication token.") +@mark.local_server def test_crud_with_one_time_token(): auth_token = get_one_time_token("admin_token_crud") db.configure_connection(password_method="auth_token", diff --git a/tests/test_boolean.py b/tests/test_boolean.py index 60ad1cbd80d34a6892fcdd3304e0b401840a02e2..296dfab0be6524461861f58d4e5eb26087463b8f 100644 --- a/tests/test_boolean.py +++ b/tests/test_boolean.py @@ -28,8 +28,9 @@ import caosdb as h # @UnresolvedImport -from nose.tools import assert_true, assert_equal, assert_false, assert_raises -from caosdb.exceptions import EntityError +from nose.tools import assert_true, assert_equal, assert_false +from caosdb.exceptions import TransactionError +from pytest import raises def test_property(): @@ -126,7 +127,8 @@ def test_record(): rec3 = h.Record( name="SimpleRecord3").add_parent(rt).add_property( p.name, value="BLABLA") - assert_raises(EntityError, rec3.insert) + with raises(TransactionError): + rec3.insert() assert_false(rec3.is_valid()) assert_equal( diff --git a/tests/test_datatype.py b/tests/test_datatype.py index ce800b49b8c12f6a949a48489b5ac9e00ee1010c..56dd247eb54b31b3f7e798684d35b29576b9c7ad 100644 --- a/tests/test_datatype.py +++ b/tests/test_datatype.py @@ -54,7 +54,9 @@ def test_override_with_non_existing_ref(): name="TestProperty", datatype=rt2, value="Non-Existing").add_parent(rt1).insert() - assert cm.value.get_errors()[0].msg == "Referenced entity does not exist." + assert cm.value.has_error(db.UnqualifiedPropertiesError) + assert (cm.value.errors[0].errors[0].msg == + "Referenced entity does not exist.") def test_override_with_existing_ref(): @@ -139,29 +141,23 @@ def test_generic_reference_failure(): def test_unknown_datatype1(): p = db.Property(name="TestP", datatype="Non-Existing") - try: + with raises(db.TransactionError) as te: p.insert() - assert False is True - except db.TransactionError as e: - assert e.msg == "Unknown datatype." + assert te.value.errors[0].msg == "Unknown datatype." def test_unknown_datatype2(): p = db.Property(name="TestP", datatype="12345687654334567") - try: + with raises(db.TransactionError) as te: p.insert() - assert False is True - except db.TransactionError as e: - assert e.msg == "Unknown datatype." + assert te.value.errors[0].msg == "Unknown datatype." def test_unknown_datatype3(): p = db.Property(name="TestP", datatype="-134") - try: + with raises(db.TransactionError) as te: p.insert() - assert False is True - except db.TransactionError as e: - assert e.msg == "Unknown datatype." + assert te.value.errors[0].msg == "Unknown datatype." def test_wrong_refid(): @@ -169,10 +165,10 @@ def test_wrong_refid(): rt2 = db.RecordType(name="TestRT2").insert() rt3 = db.RecordType(name="TestRT3").insert() p = db.Property(name="TestP1", datatype=rt1.id).insert() - assert p.is_valid() is True - assert rt1.is_valid() is True - assert rt2.is_valid() is True - assert rt3.is_valid() is True + assert p.is_valid() + assert rt1.is_valid() + assert rt2.is_valid() + assert rt3.is_valid() rec1 = db.Record().add_parent(name="TestRT1").insert() rec2 = db.Record().add_parent(name="TestRT2").insert() @@ -180,20 +176,18 @@ def test_wrong_refid(): name="TestRT3").add_property( name="TestP1", value=rec2.id) - try: + with raises(db.TransactionError): rec3.insert() - assert False is True - except db.TransactionError: - desc = ('Reference not qualified. The value of this Reference ' - 'Property is to be a child of its data type.') - err = rec3.get_property("TestP1").get_errors()[0] - assert err.description == desc + desc = ('Reference not qualified. The value of this Reference ' + 'Property is to be a child of its data type.') + err = rec3.get_property("TestP1").get_errors()[0] + assert err.description == desc rec4 = db.Record().add_parent( name="TestRT3").add_property( name="TestP1", value=rec1.id).insert() - assert rec4.is_valid() is True + assert rec4.is_valid() def test_datatype_mismatch_in_response(): @@ -210,4 +204,4 @@ def test_datatype_mismatch_in_response(): with raises(db.TransactionError) as exc: # should not raise ValueError but transaction error. rt.insert() - assert exc.value.get_errors()[0].msg == "Cannot parse value to double." + assert exc.value.errors[0].errors[0].msg == "Cannot parse value to double." diff --git a/tests/test_datatype_inheritance.py b/tests/test_datatype_inheritance.py index eba41766c8a989c6abefe335ab488ccdbea716f6..307d6c48b5b8583893b315156f11038d271ebd16 100644 --- a/tests/test_datatype_inheritance.py +++ b/tests/test_datatype_inheritance.py @@ -28,7 +28,8 @@ from caosdb.connection.connection import get_connection # @UnresolvedImport from nose.tools import assert_is_not_none, assert_true, assert_equal, with_setup -from caosdb.exceptions import EntityError +from caosdb.exceptions import TransactionError +from pytest import raises def setup(): @@ -150,12 +151,11 @@ def test_datatype_overriding_update(): str("TEXT").lower(), rt.get_properties()[0].datatype.lower()) - try: + with raises(TransactionError) as te: p.datatype = "INT" p.update() - raise AssertionError("This should raise an EntityError!") - except EntityError as e: - assert_equal("Unknown datatype.", e.msg) + + assert "Unknown datatype." == te.value.errors[0].msg p.datatype = "INTEGER" p.update() diff --git a/tests/test_datetime.py b/tests/test_datetime.py index cda35a1f013833744f314fda6a5bd87547cda5b9..b6254d5d5930e2cce0f659a6013c9e499406e59d 100644 --- a/tests/test_datetime.py +++ b/tests/test_datetime.py @@ -26,6 +26,7 @@ @author: tf """ +import pytest from nose.tools import assert_true, assert_false # @UnresolvedImport import caosdb as h @@ -136,6 +137,7 @@ def test_date_storage(): pass +@pytest.mark.slow def test_in_operator(): try: rec = set_up_rec() @@ -438,6 +440,7 @@ def test_in_operator(): pass +@pytest.mark.slow def test_not_in_operator(): try: rec = set_up_rec() @@ -778,6 +781,7 @@ def test_not_in_operator(): pass +@pytest.mark.slow def test_eq_operator(): try: rec = set_up_rec() @@ -844,6 +848,7 @@ def test_eq_operator(): pass +@pytest.mark.slow def test_neq_operator(): try: rec = set_up_rec() @@ -912,6 +917,7 @@ def test_neq_operator(): pass +@pytest.mark.slow def test_smaller_operator(): try: rec = set_up_rec() @@ -1166,6 +1172,7 @@ def test_smaller_operator(): pass +@pytest.mark.slow def test_greater_operator(): try: rec = set_up_rec() @@ -1420,6 +1427,7 @@ def test_greater_operator(): pass +@pytest.mark.slow def test_greater_equal_operator(): try: rec = set_up_rec() @@ -1673,6 +1681,7 @@ def test_greater_equal_operator(): pass +@pytest.mark.slow def test_smaller_equal_operator(): try: rec = set_up_rec() diff --git a/tests/test_error_stuff.py b/tests/test_error_stuff.py index 5e2e11837d5ede6a330252751da3eff61bcc1ea5..d6eb85b74bf288e91de02c4d6d95e1f1298b2c0f 100644 --- a/tests/test_error_stuff.py +++ b/tests/test_error_stuff.py @@ -5,6 +5,8 @@ # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen +# Copyright (C) 2020 Indiscale GmbH <info@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,367 +23,320 @@ # # ** end header # -"""Created on 19.02.2015. +"""Test different entity errors. + +Created on 19.02.2015. @author: tf + """ -from caosdb.exceptions import EntityDoesNotExistError, UniqueNamesError,\ - TransactionError, EntityError, UnqualifiedPropertiesError,\ - EntityHasNoDatatypeError, UnqualifiedParentsError +import caosdb as h +from caosdb.exceptions import (AmbiguousEntityError, + EntityDoesNotExistError, EntityError, + EntityHasNoDatatypeError, + TransactionError, UniqueNamesError, + UnqualifiedParentsError, + UnqualifiedPropertiesError) +import pytest -def test_retrieval_no_exception_raised(): - import caosdb as h - from nose.tools import assert_true, assert_false # @UnresolvedImport +def setup(): + try: + h.execute_query("FIND Test*").delete() + except BaseException: + pass - p = h.Property(name="Non-ExsistentProperty").retrieve(unique=True, - raise_exception_on_error=False) - assert_false(p.is_valid()) - assert_true(p.id is None or p.id < 0) +def teardown(): + """Delete everything.""" + setup() -def test_retrieval_exception_raised(): - import caosdb as h - from nose.tools import assert_true, assert_is_not_none, assert_equal # @UnresolvedImport - # special error: EntityDoesNotExistError - try: - h.Property(name="Non-ExistentProperty").retrieve(unique=True, - raise_exception_on_error=True) - assert_true(False) - except EntityDoesNotExistError as e: - print("print(" + str(id(e)) + ")") - print(e) - assert_is_not_none(e.get_entity()) - - # more general error: EntityError - try: - h.Property(name="Non-ExistentProperty").retrieve(unique=True, - raise_exception_on_error=True) - assert_true(False) - except EntityError as e: - print(e) - assert_is_not_none(e.get_entity()) - assert_equal('Non-ExistentProperty', e.get_entity().name) - - # most general error: TransactionError - try: - h.Property(name="Non-ExistentProperty").retrieve(unique=True, - raise_exception_on_error=True) - assert_true(False) - except EntityDoesNotExistError as e: - print(e) - assert_is_not_none(e.get_entities()) - print(e.get_entities()) - assert_is_not_none(e.get_entity()) - print(e.get_entity()) - assert_equal(1, len(e.get_entities())) - assert_equal('Non-ExistentProperty', e.get_entities()[0].name) +def test_retrieval_no_exception_raised(): + """Test whether retrieval fails but error is suppressed.""" + p = h.Property(name="TestNon-ExsistentProperty").retrieve( + unique=True, raise_exception_on_error=False) + assert not p.is_valid() + assert (p.id is None or p.id < 0) -def test_insertion_no_exception_raised(): - import caosdb as h - from nose.tools import assert_false, assert_true # @UnresolvedImport +def test_retrieval_exception_raised(): + """Test if a TransactionError with the correct child is raised, and if + the child has the correct super classes. + + """ + propname = "TestNon-ExistentProperty" + with pytest.raises(TransactionError) as te: + h.Property(name="TestNon-ExistentProperty").retrieve(unique=True, + raise_exception_on_error=True) + assert len(te.value.errors) == 1 + ee = te.value.errors[0] + # Check for type incl. inheritance + assert isinstance(ee, EntityDoesNotExistError) + assert isinstance(ee, EntityError) + assert isinstance(ee, TransactionError) + # Correct entity causing the error: + assert ee.entity is not None + assert ee.entity.name == propname + assert not ee.entity.is_valid() + assert ee.entity.has_errors() + + +@pytest.mark.xfail(reason=("Error treatment on server-side" + "has to be implemented first.")) +def test_ambiguous_retrieval(): + """Test if a TransactionError containing an AmbiguousEntityError is + raised correctly if there are two possible candidates. + + """ + h.RecordType(name="TestType").insert() + h.Record(name="TestRec").add_parent(name="TestType").insert() + # Insert twice, so unique=False + h.Record(name="TestRec").add_parent(name="TestType").insert(unique=False) + with pytest.raises(TransactionError) as te: + h.Record(name="TestRec").retrieve() + assert te.value.has_error(AmbiguousEntityError) + assert te.value.errors[0].entity.name == "TestRec" - try: - p = h.Property( - name="NoTypeProperty").insert( - raise_exception_on_error=False) - assert_false(p.is_valid()) - assert_true(p.id is None or p.id < 0) - finally: - try: - p.delete() - except BaseException: - pass +def test_insertion_no_exception_raised(): + """Test whether insertion fails but no error is raised.""" + p = h.Property(name="TestNoTypeProperty").insert( + raise_exception_on_error=False) + assert not p.is_valid() + assert (p.id is None or p.id < 0) -def test_insertion_exception_raised(): - import caosdb as h - from nose.tools import assert_true # @UnresolvedImport - try: - p = h.Property(name="NoTypeProperty") +def test_insertion_exception_raised(): + """Test insertion of a property with missing datatype.""" + p = h.Property(name="TestNoTypeProperty") + with pytest.raises(TransactionError) as te: p.insert(raise_exception_on_error=True) - assert_true(False) - except EntityError as e: - print(e) - finally: - try: - p.delete() - except BaseException: - pass + assert te.value.has_error(EntityHasNoDatatypeError) def test_insertion_with_invalid_parents(): - import caosdb as h - # @UnresolvedImport - from nose.tools import assert_false, assert_true, assert_is_not_none, assert_equal - - try: + with pytest.raises(TransactionError) as te: p = h.Property( - name="NoTypeProperty", + name="TestNoTypeProperty", datatype="Text").add_parent( id=-1) p.insert(raise_exception_on_error=True) - assert_true(False) - except EntityError as e: - print(e) - assert_true(isinstance(e, UnqualifiedParentsError)) - assert_is_not_none(e.get_entity()) - assert_equal(e.get_entity().name, p.name) - assert_equal(e.get_entity().id, p.id) - assert_true(e.get_entity().has_errors()) - assert_false(p.is_valid()) - assert_false(e.get_entity().is_valid()) - assert_is_not_none(e.get_entities()) - finally: - try: - p.delete() - except BaseException: - pass + upe = te.value.errors[0] + print(upe) + assert isinstance(upe, UnqualifiedParentsError) + assert upe.entity is not None + assert upe.entity.name == p.name + assert upe.entity.id == p.id + assert upe.entity.has_errors() + assert not p.is_valid() + assert not upe.entity.is_valid() + assert upe.entities is not None def test_insertion_with_invalid_properties(): - import caosdb as h - # @UnresolvedImport - from nose.tools import assert_false, assert_true, assert_is_not_none, assert_equal - - try: - try: - h.execute_query("FIND NoTypeProperty").delete() - except BaseException: - pass + with pytest.raises(TransactionError) as te: p = h.Property( - name="NoTypeProperty", + name="TestNoTypeProperty", datatype="Text").add_property( id=-1) p.insert(raise_exception_on_error=True) - raise AssertionError( - "This should raise an UnqualifiedPropertiesError.") - except EntityError as e: - assert_true(isinstance(e, UnqualifiedPropertiesError)) - assert_is_not_none(e.get_entity()) - assert_equal(e.get_entity().name, p.name) - assert_true(e.get_entity().has_errors()) - assert_true(p.has_errors()) - assert_false(p.is_valid()) - assert_false(e.get_entity().is_valid()) - finally: - try: - p.delete() - except BaseException: - pass + upe = te.value.errors[0] + assert isinstance(upe, UnqualifiedPropertiesError) + assert upe.entity is not None + assert upe.entity.name == p.name + assert upe.entity.has_errors() + assert p.has_errors() + assert not p.is_valid() + assert not upe.entity.is_valid() def test_entity_does_not_exist(): - import caosdb as h - # @UnresolvedImport - from nose.tools import assert_true, assert_false, assert_equal, assert_is_not_none + """When retrieving a container with existing and non-existing + entities, only those that don't exist should cause + EntityDoesNotExistErrors. + + """ + p1 = h.Property(name="TestNon-ExistentProperty1").retrieve( + raise_exception_on_error=False) + p2 = h.Property(name="TestNon-ExistentProperty2").retrieve( + raise_exception_on_error=False) + p3 = h.Property(name="TestNon-ExistentProperty3").retrieve( + raise_exception_on_error=False) + # None of them should exist + assert not p1.is_valid() + assert (p1.id is None or p1.id < 0) + assert not p2.is_valid() + assert (p2.id is None or p2.id < 0) + assert not p3.is_valid() + assert (p3.id is None or p3.id < 0) + + pe = h.Property(name="TestExistentProperty", datatype="text").insert() + + c = h.Container().extend( + [ + h.Property( + name="TestNon-ExistentProperty1"), + h.Property( + name="TestNon-ExistentProperty2"), + h.Property( + name="TestNon-ExistentProperty3"), + h.Property( + name="TestExistentProperty")]) - try: - p1 = h.Property( - name="Non-ExistentProperty1").retrieve(raise_exception_on_error=False) - p2 = h.Property( - name="Non-ExistentProperty2").retrieve(raise_exception_on_error=False) - p3 = h.Property( - name="Non-ExistentProperty3").retrieve(raise_exception_on_error=False) - assert_false(p1.is_valid()) - assert_true(p1.id is None or p1.id < 0) - assert_false(p2.is_valid()) - assert_true(p2.id is None or p2.id < 0) - assert_false(p3.is_valid()) - assert_true(p3.id is None or p3.id < 0) - - pe = h.Property(name="ExistentProperty", datatype="text").insert() - - c = h.Container().extend( - [ - h.Property( - name="Non-ExistentProperty1"), - h.Property( - name="Non-ExistentProperty2"), - h.Property( - name="Non-ExistentProperty3"), - h.Property( - name="ExistentProperty")]) - - try: - c.retrieve() - except EntityDoesNotExistError as e: - assert_equal(3, len(e.get_entities())) - for entity in e.get_entities(): - assert_is_not_none(entity.name) - assert_true(entity.name.startswith("Non-ExistentProperty")) - finally: - try: - pe.delete() - except BaseException: - pass + with pytest.raises(TransactionError) as te: + c.retrieve() + te = te.value + assert te.has_error(EntityDoesNotExistError) + # Only non-existing entities caused the container error + assert not pe.name in [x.name for x in te.all_entities] + for p in (p1, p2, p3): + assert p.name in [x.name for x in te.all_entities] def test_insert_existent_entity(): - import caosdb as h - # @UnresolvedImport - from nose.tools import assert_true, assert_false, assert_equal, assert_is_not_none + """Insertion of an already existing entity should cause a + UniqueNamesError. + + """ + p1 = h.Property(name="TestNon-ExistentProperty1").retrieve( + raise_exception_on_error=False) + p2 = h.Property(name="TestNon-ExistentProperty2").retrieve( + raise_exception_on_error=False) + p3 = h.Property(name="TestNon-ExistentProperty3").retrieve( + raise_exception_on_error=False) + # None of them should exist + assert not p1.is_valid() + assert (p1.id is None or p1.id < 0) + assert not p2.is_valid() + assert (p2.id is None or p2.id < 0) + assert not p3.is_valid() + assert (p3.id is None or p3.id < 0) + + pe = h.Property(name="TestExistentProperty", datatype="text").insert() + assert pe.is_valid() + + c = h.Container().extend( + [ + h.Property( + name="TestNon-ExistentProperty1", + datatype="text"), + h.Property( + name="TestNon-ExistentProperty2", + datatype="text"), + h.Property( + name="TestNon-ExistentProperty3", + datatype="text"), + h.Property( + name="TestExistentProperty", + datatype="text")]) - try: - p1 = h.Property( - name="Non-ExistentProperty1").retrieve(raise_exception_on_error=False) - p2 = h.Property( - name="Non-ExistentProperty2").retrieve(raise_exception_on_error=False) - p3 = h.Property( - name="Non-ExistentProperty3").retrieve(raise_exception_on_error=False) - assert_false(p1.is_valid()) - assert_true(p1.id is None or p1.id < 0) - assert_false(p2.is_valid()) - assert_true(p2.id is None or p2.id < 0) - assert_false(p3.is_valid()) - assert_true(p3.id is None or p3.id < 0) - - pe = h.Property(name="ExistentProperty", datatype="text").insert() - assert_true(pe.is_valid()) - - c = h.Container().extend( - [ - h.Property( - name="Non-ExistentProperty1", - datatype="text"), - h.Property( - name="Non-ExistentProperty2", - datatype="text"), - h.Property( - name="Non-ExistentProperty3", - datatype="text"), - h.Property( - name="ExistentProperty", - datatype="text")]) - - try: - c.insert(unique=True) - except UniqueNamesError as e: - assert_equal(1, len(e.get_entities())) - for entity in e.get_entities(): - assert_is_not_none(entity.name) - assert_equal(pe.name, entity.name) - - finally: - try: - c.delete() - except BaseException: - pass - try: - pe.delete() - except BaseException: - pass - try: - p3.delete() - except BaseException: - pass - try: - p2.delete() - except BaseException: - pass - try: - p1.delete() - except BaseException: - pass + with pytest.raises(TransactionError) as te: + c.insert(unique=True) + te = te.value + assert te.has_error(UniqueNamesError) + une = te.errors[0] + assert une.entity is not None + assert pe.name == une.entity.name + for p in (p1, p2, p3): + assert p not in te.all_entities def test_double_insertion(): - import caosdb as h - from nose.tools import assert_true, assert_equal, assert_is_not_none # @UnresolvedImport - c1 = h.Container() - try: - c1.append( - h.Property( - name="SimpleTextProperty", - description="simple text property (from test_error_stuff.py)", - datatype='text')) - c1.append( - h.Property( - name="SimpleDoubleProperty", - description="simple double property (from test_error_stuff.py)", - datatype='double')) - c1.append( - h.Property( - name="SimpleIntegerProperty", - description="simple integer property (from test_error_stuff.py)", - datatype='integer')) - c1.append( - h.Property( - name="SimpleDatetimeProperty", - description="simple datetime property (from test_error_stuff.py)", - datatype='datetime')) - - c1.append( - h.RecordType( - name="SimpleRecordType", - description="simple recordType (from test_error_stuff.py)") .add_property( - name='SimpleTextProperty') .add_property( - name='SimpleDoubleProperty') .add_property( - name='SimpleIntegerProperty') .add_property( - name='SimpleDatetimeProperty')) - - c1.insert() - - c2 = h.Container() - c2.append( - h.Property( - name="SimpleTextProperty", - description="simple text property (from test_error_stuff.py)", - datatype='text')) - c2.append( - h.Property( - name="SimpleDoubleProperty", - description="simple double property (from test_error_stuff.py)", - datatype='double')) - c2.append( - h.Property( - name="SimpleIntegerProperty", - description="simple integer property (from test_error_stuff.py)", - datatype='integer')) - c2.append( - h.Property( - name="SimpleDatetimeProperty", - description="simple datetime property (from test_error_stuff.py)", - datatype='datetime')) - - c2.append( - h.RecordType( - name="SimpleRecordType", - description="simple recordType (from test_error_stuff.py)") .add_property( - name='SimpleTextProperty') .add_property( - name='SimpleDoubleProperty') .add_property( - name='SimpleIntegerProperty') .add_property( - name='SimpleDatetimeProperty')) - try: - c2.insert() - except TransactionError as te: - assert_true(isinstance(te, EntityError)) - assert_true(isinstance(te, UniqueNamesError)) - assert_true(hasattr(te, 'get_errors')) - assert_is_not_none(te.get_errors) - assert_is_not_none(te.get_errors()) - assert_true(hasattr(te, 'get_error')) - assert_is_not_none(te.get_error) - assert_is_not_none(te.get_error()) - assert_true(hasattr(te, 'get_entities')) - assert_is_not_none(te.get_entities) - assert_is_not_none(te.get_entities()) - assert_equal(5, len(te.get_entities())) - assert_true(hasattr(te, 'get_container')) - assert_is_not_none(te.get_container) - assert_is_not_none(te.get_container()) - assert_equal(c2, te.get_container()) - - finally: - try: - c2.delete() - except BaseException: - pass - try: - c1.delete() - except BaseException: - pass + + c1.append( + h.Property( + name="TestSimpleTextProperty", + description="simple text property (from test_error_stuff.py)", + datatype='text')) + c1.append( + h.Property( + name="TestSimpleDoubleProperty", + description="simple double property (from test_error_stuff.py)", + datatype='double')) + c1.append( + h.Property( + name="TestSimpleIntegerProperty", + description="simple integer property (from test_error_stuff.py)", + datatype='integer')) + c1.append( + h.Property( + name="TestSimpleDatetimeProperty", + description="simple datetime property (from test_error_stuff.py)", + datatype='datetime')) + + c1.append( + h.RecordType( + name="TestSimpleRecordType", + description="simple recordType (from test_error_stuff.py)").add_property( + name='TestSimpleTextProperty').add_property( + name='TestSimpleDoubleProperty').add_property( + name='TestSimpleIntegerProperty').add_property( + name='TestSimpleDatetimeProperty')) + + c1.insert() + + c2 = h.Container() + c2.append( + h.Property( + name="TestSimpleTextProperty", + description="simple text property (from test_error_stuff.py)", + datatype='text')) + c2.append( + h.Property( + name="TestSimpleDoubleProperty", + description="simple double property (from test_error_stuff.py)", + datatype='double')) + c2.append( + h.Property( + name="TestSimpleIntegerProperty", + description="simple integer property (from test_error_stuff.py)", + datatype='integer')) + c2.append( + h.Property( + name="TestSimpleDatetimeProperty", + description="simple datetime property (from test_error_stuff.py)", + datatype='datetime')) + + c2.append( + h.RecordType( + name="TestSimpleRecordType", + description="simple recordType (from test_error_stuff.py)").add_property( + name='TestSimpleTextProperty').add_property( + name='TestSimpleDoubleProperty').add_property( + name='TestSimpleIntegerProperty').add_property( + name='TestSimpleDatetimeProperty')) + with pytest.raises(TransactionError) as te: + c2.insert() + te = te.value + assert te.has_error(UniqueNamesError) + # c2 caused the ContainerError + assert te.container == c2 + # exactly 5 faulty entities in c2 + assert len(te.entities) == 5 + + +def test_update_acl_errors(): + """Test the special cases of entity errors when using + `Entity.update_acl` + + """ + rec_ne = h.Record("TestRecordNonExisting") + + with pytest.raises(TransactionError) as te: + + rec_ne.update_acl() + + assert te.value.has_error(EntityDoesNotExistError) + assert te.value.errors[0].entity.name == rec_ne.name + + rt = h.RecordType(name="TestType").insert() + rec = h.Record(name="TestRecord").add_parent(rt).insert() + h.Record(name=rec.name).add_parent(rt).insert(unique=False) + + with pytest.raises(TransactionError) as te: + + h.Record(name=rec.name).update_acl() + + assert te.value.has_error(AmbiguousEntityError) diff --git a/tests/test_file.py b/tests/test_file.py index 4dbf4fd9a25e20378294c6f519154c1b25a16c54..354fee19c9ed4a0498c7e9562ff200f76f1530b6 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -33,16 +33,12 @@ from random import randint from sys import maxsize as maxint 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) - -from caosdb import Info -from caosdb import administration as admin +from pytest import raises, mark +from nose.tools import (assert_equal, assert_false, assert_is_not_none, + assert_true) from caosdb import execute_query, get_config, get_connection from caosdb.common import models -from caosdb.exceptions import EntityError +from caosdb.exceptions import EntityError, TransactionError from caosdb.utils.checkFileSystemConsistency import runCheck @@ -92,6 +88,7 @@ def test_file_with_space(): qfile.download("test2.dat") +@mark.local_server def test_pickup_file(): d = models.DropOffBox() d.sync() @@ -111,6 +108,7 @@ def test_pickup_file(): assert_is_not_none(file_.id) +@mark.local_server def test_pickup_folder(): # pickup_folder d = models.DropOffBox() @@ -137,6 +135,7 @@ def test_pickup_folder(): file_.insert() +@mark.local_server def test_file4(): try: d = models.DropOffBox() @@ -241,9 +240,10 @@ def test_file6(): path="testfiles2/", pickup=path) - with raises(EntityError) as cm: + with raises(TransactionError) as te: folder_.insert() - errors = cm.value.entity.get_errors() + cm = te.value.errors[0] + errors = cm.entity.get_errors() assert errors[0].description == 'This target path does already exist.' finally: try: @@ -300,7 +300,9 @@ def test_file7(): path="testfiles2/", pickup="path") - assert_raises(EntityError, folder_.insert) + with raises(TransactionError) as te: + folder_.insert() + assert te.value.has_error(EntityError) finally: try: folder_.delete() @@ -490,6 +492,7 @@ def test_insert_files_in_dir_error1(): assert_true(c.messages["Error", 0][0].startswith("Dir is not allowed")) +@mark.local_server def test_insert_files_in_dir_with_symlink(): path = get_config().get("IntegrationTests", "test_files.test_insert_files_in_dir.local") + "testfolder/" @@ -566,6 +569,7 @@ def test_insert_files_in_dir_with_symlink(): pass +@mark.local_server 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 @@ -665,6 +669,7 @@ def test_insert_files_in_dir(): pass +@mark.local_server def test_insert_files_in_dir_regex(): path = get_config().get("IntegrationTests", "test_files.test_insert_files_in_dir.local") + "testfolder/" diff --git a/tests/test_issues_server.py b/tests/test_issues_server.py index bb3a3490837687483bfc564d9f255feb7a1b4478..b5c16cb0edc031ac865e57a5bb84874447566481 100644 --- a/tests/test_issues_server.py +++ b/tests/test_issues_server.py @@ -29,7 +29,7 @@ import tempfile import time import caosdb as db -from caosdb.exceptions import EntityError, TransactionError +from caosdb.exceptions import TransactionError import pytest @@ -94,7 +94,7 @@ def test_issue_62(): 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): + with pytest.raises(TransactionError): prop2.insert() @@ -143,6 +143,7 @@ def test_issue_85_b(): C.update() # Failed at this step +@pytest.mark.local_server def test_issue_99(): """Checksum updating failed with versioning enabled. """ diff --git a/tests/test_list.py b/tests/test_list.py index 17f9e5baae10215f86a35cd28015548ae6a30607..98a7bb6fae1bb5940c05e4f9d2ce8e1611f5c69a 100644 --- a/tests/test_list.py +++ b/tests/test_list.py @@ -27,9 +27,10 @@ """ import os import caosdb as db -from caosdb.exceptions import TransactionError -from nose.tools import nottest, assert_true, assert_raises, assert_equal -from pytest import mark +from caosdb.exceptions import (TransactionError, + UnqualifiedPropertiesError) +from nose.tools import assert_true, assert_equal +from pytest import raises def setup(): @@ -63,9 +64,9 @@ def test_list_of_files(): db.FILE), value=[ file_.id]).insert() - assert_true(rec.is_valid()) + assert rec.is_valid() - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.Record( name="TestRecNotOk").add_parent(recty).add_property( name="TestListProperty", @@ -73,9 +74,9 @@ def test_list_of_files(): db.FILE), value=[ p.id]).insert() - assert_equal( - tr_err.exception.errors[0].msg, - "Reference not qualified. The value of this Reference Property is to be a child of its data type.") + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + "Reference not qualified. The value of this Reference Property is to be a child of its data type.") def test_list_datatype_know(): @@ -205,36 +206,35 @@ def test_error_on_wrong_value(): db.INTEGER)).insert() assert_true(p.is_valid()) - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.RecordType( name="TestRT").add_property( name="TestListProperty", value=["this is not an int"]).insert() - assert_equal(tr_err.exception.msg, "Entity has unqualified properties.") - assert_equal( - tr_err.exception.get_errors()[0].msg, - "Cannot parse value to integer.") + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + "Cannot parse value to integer.") def test_data_type_with_non_existing_ref1(): - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.Property(name="TestListProperty", datatype=db.LIST("non_existing")).insert() - assert_equal(tr_err.exception.msg, "Unknown datatype.") + assert tr_err.value.errors[0].msg == "Unknown datatype." def test_data_type_with_non_existing_ref2(): - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.Property( name="TestListProperty", datatype=db.LIST(234233234)).insert() - assert_equal(tr_err.exception.msg, "Unknown datatype.") + assert tr_err.value.errors[0].msg == "Unknown datatype." def test_data_type_with_non_existing_ref3(): - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.Property(name="TestListProperty", datatype=db.LIST(-2341)).insert() - assert_equal(tr_err.exception.msg, "Unknown datatype.") + assert tr_err.value.errors[0].msg == "Unknown datatype." def test_data_type_with_existing_ref1(): @@ -373,44 +373,45 @@ def test_single_ref_value_scope_error(): rt2 = db.RecordType(name="TestRT2").insert() db.Property(name="TestProp", datatype=db.LIST(rt2)).insert() - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.RecordType( name="TestRT3").add_property( name="TestProp", value=[rec]).insert() - assert_equal( - tr_err.exception.get_errors()[0].msg, - "Reference not qualified. The value of this Reference Property is to be a child of its data type.") + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + "Reference not qualified. The value of this Reference " + + "Property is to be a child of its data type.") def test_error_single_non_existing_ref_value(): rt = db.RecordType(name="TestRT").insert() db.Property(name="TestProp", datatype=db.LIST(rt)).insert() - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.RecordType( name="TestRT2").add_property( name="TestProp", value=["non_existing"]).insert() - assert_equal( - tr_err.exception.get_errors()[0].msg, - "Referenced entity does not exist.") + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + "Referenced entity does not exist.") - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.RecordType( name="TestRT2").add_property( name="TestProp", value=[213425234234]).insert() - assert_equal( - tr_err.exception.get_errors()[0].msg, - "Referenced entity does not exist.") + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + "Referenced entity does not exist.") - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.RecordType(name="TestRT2").add_property( name="TestProp", value=[-1234]).insert() - assert_equal( - tr_err.exception.get_errors()[0].msg, - "Referenced entity does not exist.") + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + "Referenced entity does not exist.") def test_error_multi_non_existing_ref_value(): @@ -419,7 +420,7 @@ def test_error_multi_non_existing_ref_value(): db.Record(name="TestRec2").add_parent(name="TestRT").insert() db.Property(name="TestProp", datatype=db.LIST(rt)).insert() - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.RecordType( name="TestRT2").add_property( name="TestProp", @@ -427,11 +428,11 @@ def test_error_multi_non_existing_ref_value(): "TestRec1", "non_existing", "TestRec2"]).insert() - assert_equal( - tr_err.exception.get_errors()[0].msg, - "Referenced entity does not exist.") + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + "Referenced entity does not exist.") - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.RecordType( name="TestRT2").add_property( name="TestProp", @@ -439,18 +440,18 @@ def test_error_multi_non_existing_ref_value(): 213425234234, "TestRec2", "TestRec1"]).insert() - assert_equal( - tr_err.exception.get_errors()[0].msg, - "Referenced entity does not exist.") + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + "Referenced entity does not exist.") - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.RecordType( name="TestRT2").add_property( name="TestProp", value=[ "TestRec1", "TestRec2", -1234]).insert() - assert_equal( - tr_err.exception.get_errors()[0].msg, - "Referenced entity does not exist.") + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + "Referenced entity does not exist.") def test_multi_ref_value_scope_error(): @@ -462,7 +463,7 @@ def test_multi_ref_value_scope_error(): db.Record(name="TestRec2").add_parent(name="TestRT2").insert() db.Property(name="TestProp", datatype=db.LIST(rt2)).insert() - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.RecordType( name="TestRT3").add_property( name="TestProp", @@ -470,9 +471,10 @@ def test_multi_ref_value_scope_error(): rec, "TestRec1", "TestRec2"]).insert() - assert_equal( - tr_err.exception.get_errors()[0].msg, - "Reference not qualified. The value of this Reference Property is to be a child of its data type.") + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + "Reference not qualified. The value of this Reference " + + "Property is to be a child of its data type.") def test_multi_ref_value(): @@ -635,37 +637,38 @@ def test_list_of_references(): name="Test_RT1", datatype=db.LIST("Test_RT1")).insert() p = rt2.get_properties()[0] - assert_equal(p.id, rt1.id) - assert_equal(p.name, rt1.name) - assert_equal(p.datatype, db.LIST(rt1.name)) + assert p.id == rt1.id + assert p.name == rt1.name + assert p.datatype == db.LIST(rt1.name) p = db.execute_query("FIND Test_RT2", unique=True).get_properties()[0] - assert_equal(p.id, rt1.id) - assert_equal(p.name, rt1.name) - assert_equal(p.datatype, db.LIST(rt1.name)) + assert p.id == rt1.id + assert p.name == rt1.name + assert p.datatype == db.LIST(rt1.name) rt1rec1 = db.Record(name="Test_RT1_Rec1").add_parent("Test_RT1").insert() - assert_true(rt1rec1.is_valid()) + assert rt1rec1.is_valid() - with assert_raises(TransactionError) as tr_err: + with raises(TransactionError) as tr_err: db.Record( name="Test_RT2_Rec").add_parent("Test_RT2").add_property( name="Test_RT1", value=[rt1rec1]).insert() - assert_equal( - tr_err.exception.get_errors()[0].msg, - 'This datatype does not accept collections of values (e.g. Lists).') + print(tr_err.value) + assert tr_err.value.has_error(UnqualifiedPropertiesError) + assert (tr_err.value.errors[0].errors[0].msg == + 'This datatype does not accept collections of values (e.g. Lists).') rt2rec = db.Record(name="Test_RT2_Rec").add_parent("Test_RT2").add_property( name="Test_RT1", datatype=db.LIST("Test_RT1"), value=[rt1rec1]).insert() - assert_true(rt2rec.is_valid()) + assert rt2rec.is_valid() def test_list_in_sub_property(): - rt1 = db.RecordType(name="TestRT1").insert() - rt2 = db.RecordType(name="TestRT2").insert() - p = db.Property(name="TestProperty", datatype="TestRT1").insert() - p2 = db.Property(name="TestBogusProperty", datatype=db.TEXT).insert() - rec1 = db.Record(name="TestRT1Rec1").add_parent("TestRT1").insert() + db.RecordType(name="TestRT1").insert() + db.RecordType(name="TestRT2").insert() + db.Property(name="TestProperty", datatype="TestRT1").insert() + db.Property(name="TestBogusProperty", datatype=db.TEXT).insert() + db.Record(name="TestRT1Rec1").add_parent("TestRT1").insert() rec2 = db.Record(name="TestRT2Rec2").add_parent("TestRT2").add_property( "TestProperty", "TestRT1Rec1") rec2.get_property("TestProperty").add_property("TestBogusProperty", diff --git a/tests/test_misc.py b/tests/test_misc.py index 1d0b6b9ded8854d500cb71481d309801f61c5c67..0da3bffd7b48cd7840ee106954489befe210eb15 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -27,12 +27,13 @@ @author: tf """ from nose.tools import (assert_equal, assert_is_not_none, # @UnresolvedImport - assert_not_equal, assert_raises, assert_true, nottest, + assert_not_equal, assert_true, nottest, with_setup) import caosdb as db from caosdb import (Container, Info, Property, Record, RecordType, execute_query) +from pytest import raises def setup(): @@ -142,16 +143,18 @@ def test_error_no_such_role(): xml = "<Insert><Entity name='test'/></Insert>" r = db.get_connection().insert(entity_uri_segment=["Entity"], body=xml) c = Container._response_to_entities(r) - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: db.raise_errors(c) - assert_equal(cm.exception.msg, "There is no such role 'Entity'.") + assert (cm.value.errors[0].msg == + "There is no such role 'Entity'.") xml = "<Insert><ASDF name='test'/></Insert>" r = db.get_connection().insert(entity_uri_segment=["Entity"], body=xml) c = Container._response_to_entities(r) - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: db.raise_errors(c) - assert_equal(cm.exception.msg, "There is no such role 'ASDF'.") + assert (cm.value.errors[0].msg == + "There is no such role 'ASDF'.") @with_setup(setup, setup) @@ -181,22 +184,21 @@ def test_parent_duplicate_2(): inheritance=db.ALL).add_parent( name="TestRT1", inheritance=db.NONE) - assert_equal(len(rt2.get_parents()), 2) - with assert_raises(db.TransactionError) as cm: + assert len(rt2.get_parents()) == 2 + with raises(db.TransactionError) as cm: rt2.insert() - assert_equal( - cm.exception.msg, - "This entity had parent duplicates. Parent duplicates are meaningless and would be ignored (and inserted only once). But these parents had diverging inheritance instructions which cannot be processed.") + assert (cm.value.errors[0].msg == + "This entity had parent duplicates. Parent duplicates are meaningless and would be ignored (and inserted only once). But these parents had diverging inheritance instructions which cannot be processed.") def test_server_error(): con = db.get_connection() con._login() - with assert_raises(db.ServerErrorException) as cm: + with raises(db.HTTPServerError) as cm: con._http_request( method="GET", path="Entity?debug=throwNullPointerException") - assert_true("SRID = " in cm.exception.msg) + assert_true("SRID = " in cm.value.msg) def test_annotation(): diff --git a/tests/test_name_properties.py b/tests/test_name_properties.py index d7f9a56908b7ee259c5972f4bd41168e6d1e2010..028592b7c0a728587f9939e427eb40ba74b9be43 100644 --- a/tests/test_name_properties.py +++ b/tests/test_name_properties.py @@ -221,8 +221,8 @@ def test_query_name_property(): 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) + with raises(db.BadQueryError): + db.execute_query("FIND John", unique=True) teardown() diff --git a/tests/test_permissions.py b/tests/test_permissions.py index 3528a63eb8a16bc28938ae4b4d0074cc241f89f0..1953b388a7d87629f9695332c83b2484c7c3cb4b 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -29,13 +29,14 @@ from __future__ import absolute_import import caosdb as db -from nose.tools import (assert_true, assert_equal, assert_raises, assert_false, - assert_is_none, assert_is_not_none, nottest, - with_setup) # @UnresolvedImport +from nose.tools import (assert_true, + assert_equal, + assert_raises, + assert_false, + assert_is_none, + assert_is_not_none, + nottest) from pytest import raises -from nose.tools import (assert_equal, assert_false, # @UnresolvedImport - assert_is_none, assert_is_not_none, assert_raises, - assert_true, nottest, with_setup) from .test_misc import test_info @@ -116,7 +117,7 @@ def insert_test_user(): except BaseException: pass - with assert_raises(db.ClientErrorException) as cee: + with assert_raises(db.HTTPClientError) as cee: db.administration._insert_user( name=test_user, password=easy_pw, @@ -160,7 +161,6 @@ def setup(): test_info() -@with_setup(setup, teardown) def test_basic_acl_stuff(): p = db.Property( name="TestProperty", @@ -196,7 +196,6 @@ def test_basic_acl_stuff(): assert_false("DELETE" in other_role_permissions) -@with_setup(setup, teardown) def test_query(): person = db.RecordType("TestPerson").insert() db.Property("TestFirstName", datatype=db.TEXT).insert() @@ -211,30 +210,21 @@ def test_query(): name="TestConductor", value=dan.id).insert() - assert_equal( - db.execute_query( - "FIND TestExperiment WHICH HAS A TestConductor->TestPerson", - unique=True).id, - exp.id) - assert_equal( - db.execute_query( - "FIND TestExperiment WHICH HAS A TestConductor=TestPerson", - unique=True).id, - exp.id) - assert_equal( - db.execute_query( - "FIND TestExperiment WHICH HAS A TestConductor=" + str(dan.id), - unique=True).id, exp.id) - assert_equal( - db.execute_query( - "FIND TestExperiment", - unique=True).id, - exp.id) - assert_equal( - db.execute_query( - "FIND TestExperiment WHICH HAS A TestConductor WHICH has a TestFirstName=Daniel", - unique=True).id, - exp.id) + assert db.execute_query( + "FIND TestExperiment WHICH HAS A TestConductor->TestPerson", + unique=True).id == exp.id + assert db.execute_query( + "FIND TestExperiment WHICH HAS A TestConductor=TestPerson", + unique=True).id == exp.id + assert db.execute_query( + "FIND TestExperiment WHICH HAS A TestConductor=" + str(dan.id), + unique=True).id == exp.id + assert db.execute_query( + "FIND TestExperiment", + unique=True).id == exp.id + assert db.execute_query( + "FIND TestExperiment WHICH HAS A TestConductor WHICH has a TestFirstName=Daniel", + unique=True).id == exp.id '''success''' grant_permission(person, "RETRIEVE:*") @@ -242,11 +232,9 @@ def test_query(): grant_permission(exp, "RETRIEVE:*") switch_to_test_user() - assert_equal( - db.execute_query( - "FIND TestExperiment WHICH HAS A TestConductor WHICH has a TestFirstName=Daniel", - unique=True).id, - exp.id) + assert db.execute_query( + "FIND TestExperiment WHICH HAS A TestConductor WHICH has a TestFirstName=Daniel", + unique=True).id == exp.id '''failure - dan''' deny_permission(dan, "RETRIEVE:*") @@ -254,40 +242,31 @@ def test_query(): # this fails if server is configured with # QUERY_FILTER_ENTITIES_WITHOUT_RETRIEVE_PERMISSIONS = FALSE - with assert_raises(db.TransactionError) as cm: + with raises(db.EmptyUniqueQueryError): db.execute_query( "FIND TestExperiment WHICH HAS A TestConductor WHICH has a TestFirstName=Daniel", unique=True) - assert_equal(cm.exception.msg, "No such entity found.") '''... but works without the which clause''' - assert_equal( - db.execute_query( - "FIND TestExperiment", - unique=True).id, - exp.id) + assert db.execute_query("FIND TestExperiment", unique=True).id == exp.id '''and with the id''' - assert_equal( - db.execute_query( - "FIND TestExperiment WHICH HAS A TestConductor=" + str(dan.id), - unique=True).id, exp.id) + assert db.execute_query( + "FIND TestExperiment WHICH HAS A TestConductor=" + str(dan.id), + unique=True).id == exp.id '''failure - exp''' grant_permission(dan, "RETRIEVE:*") deny_permission(exp, "RETRIEVE:*") switch_to_test_user() - with assert_raises(db.TransactionError) as cm: + with raises(db.EmptyUniqueQueryError): db.execute_query( "FIND TestExperiment WHICH HAS A TestConductor=TestDaniel", unique=True) - assert_equal(cm.exception.msg, "No such entity found.") - with assert_raises(db.TransactionError) as cm: + with raises(db.EmptyUniqueQueryError): db.execute_query("FIND TestExperiment", unique=True) - assert_equal(cm.exception.msg, "No such entity found.") -@with_setup(setup, teardown) def test_update_acl(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() assert_true(p.is_valid()) @@ -363,40 +342,32 @@ def test_update_acl(): p3.acl.deny( username=db.get_config().get("Connection", "username"), permission="USE:AS_PROPERTY") - try: + with raises(db.TransactionError) as te: p3.update_acl() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) p3 = db.execute_query( "FIND TestProperty", unique=True, flags={ "ACL": None}) - assert_true(p3.is_valid()) - assert_is_not_none(p3.acl) - assert_true( - "USE:AS_PROPERTY" in p3.acl.get_permissions_for_user( - db.get_config().get("Connection", "username"))) - assert_false( - "USE:AS_DATA_TYPE" in p3.acl.get_permissions_for_user( - db.get_config().get("Connection", "username"))) - assert_false( - "EDIT:ACL" in p3.acl.get_permissions_for_user( + assert p3.is_valid() + assert p3.acl is not None + assert ("USE:AS_PROPERTY" in p3.acl.get_permissions_for_user( db.get_config().get("Connection", "username"))) + assert not ("USE:AS_DATA_TYPE" in p3.acl.get_permissions_for_user( + db.get_config().get("Connection", "username"))) + assert not ("EDIT:ACL" in p3.acl.get_permissions_for_user( + db.get_config().get("Connection", "username"))) '''Failure''' switch_to_test_user() p3.acl.grant(username=test_user, permission="EDIT:ACL") - try: + with raises(db.TransactionError) as te: p3.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) -@with_setup(setup, teardown) def test_update_name(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() assert_true(p.is_valid()) @@ -420,18 +391,15 @@ def test_update_name(): assert_false("UPDATE:NAME" in p.permissions) p.name = "TestPropertyEvenNewer" - try: + with raises(db.TransactionError) as te: p.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) p2 = db.execute_query("FIND Test*", unique=True) - assert_true(p2.is_valid()) - assert_equal(p2.name, "TestPropertyNew") + assert p2.is_valid() + assert p2.name == "TestPropertyNew" -@with_setup(setup, teardown) def test_update_desc(): p = db.Property( name="TestProperty", @@ -456,18 +424,15 @@ def test_update_desc(): '''Failure''' p.description = "DescriptionEvenNewer" - try: + with raises(db.TransactionError) as te: p.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) p2 = db.execute_query("FIND Test*", unique=True) - assert_true(p2.is_valid()) - assert_equal(p2.description, "DescriptionNew") + assert p2.is_valid() + assert p2.description == "DescriptionNew" -@with_setup(setup, teardown) def test_update_data_type(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() assert_true(p.is_valid()) @@ -488,18 +453,15 @@ def test_update_data_type(): '''Failure''' p.datatype = db.DOUBLE - try: + with raises(db.TransactionError) as te: p.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) p2 = db.execute_query("FIND Test*", unique=True) - assert_true(p2.is_valid()) - assert_equal(p2.datatype, db.INTEGER) + assert p2.is_valid() + assert p2.datatype == db.INTEGER -@with_setup(setup, teardown) def test_update_role(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() assert_true(p.is_valid()) @@ -518,18 +480,15 @@ def test_update_role(): '''Failure''' rec = db.Record(name="TestProperty").retrieve() - try: + with raises(db.TransactionError) as te: rec.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) rt2 = db.execute_query("FIND Test*", unique=True) - assert_true(rt2.is_valid()) - assert_true(isinstance(rt2, db.RecordType)) + assert rt2.is_valid() + assert isinstance(rt2, db.RecordType) -@with_setup(setup, teardown) def test_update_move_file(): upload_file = open("test.dat", "w") upload_file.write("hello world\n") @@ -555,38 +514,33 @@ def test_update_move_file(): '''FAILURE''' f.path = "/againotherpermissiontestfiles/test.dat" - try: + with raises(db.TransactionError) as te: f.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) f2 = db.execute_query("FIND TestFile", unique=True) - assert_equal(f2.path, "/otherpermissiontestfiles/test.dat") + assert f2.path == "/otherpermissiontestfiles/test.dat" -@with_setup(setup, teardown) def test_update_add_file(): upload_file = open("test.dat", "w") upload_file.write("test update add file: #here#\n") upload_file.close() f = db.File(name="TestFile").insert() - assert_true(f.is_valid()) + assert f.is_valid() grant_permission(f, "RETRIEVE:ENTITY") '''FAILURE''' f.path = "/permissiontestfiles/newtest.dat" f.file = upload_file - try: + with raises(db.TransactionError) as te: f.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) f2 = db.execute_query("FIND TestFile", unique=True) - assert_is_none(f2.path) + assert f2.path is None '''SUCCESS''' grant_permission(f, "UPDATE:FILE:ADD") @@ -601,7 +555,6 @@ def test_update_add_file(): assert_equal(f2.path, "/permissiontestfiles/newtest.dat") -@with_setup(setup, teardown) def test_update_change_file(): upload_file = open("test.dat", "w") upload_file.write("hello world\n") @@ -623,16 +576,14 @@ def test_update_change_file(): deny_permission(f, "UPDATE:FILE:REMOVE") f.file = upload_file2 - try: + with raises(db.TransactionError) as te: f.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) f2 = db.execute_query("FIND TestFile", unique=True) download_file = f2.download() - assert_equal(db.File._get_checksum(download_file), - db.File._get_checksum(upload_file)) + assert db.File._get_checksum( + download_file) == db.File._get_checksum(upload_file) '''SUCCESS''' print('#################################################################') @@ -646,15 +597,14 @@ def test_update_change_file(): f2 = db.execute_query("FIND TestFile", unique=True) f2.file = upload_file2 f2.update() - assert_true(f2.is_valid()) + assert f2.is_valid() f2 = db.execute_query("FIND TestFile", unique=True) download_file = f2.download() - assert_equal(db.File._get_checksum(download_file), - db.File._get_checksum(upload_file2)) + assert db.File._get_checksum( + download_file) == db.File._get_checksum(upload_file2) -@with_setup(setup, teardown) def test_update_add_property(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() assert_true(p.is_valid()) @@ -685,30 +635,25 @@ def test_update_add_property(): '''Failure - add p to rt''' rt.add_property(name="TestProperty", id=p.id) - try: + with raises(db.TransactionError) as te: rt.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) rt2 = db.execute_query("FIND TestRecordType", unique=True) - assert_equal(len(rt2.get_properties()), 1) - assert_is_not_none(rt2.get_property("TestProperty")) + assert len(rt2.get_properties()) == 1 + assert rt2.get_property("TestProperty") is not None '''Failure - add p2 to rt''' rt.add_property(name="TestProperty2", id=p2.id) - try: + with raises(db.TransactionError) as te: rt.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) rt2 = db.execute_query("FIND TestRecordType", unique=True) - assert_equal(len(rt2.get_properties()), 1) - assert_is_not_none(rt2.get_property("TestProperty")) + assert len(rt2.get_properties()) == 1 + assert rt2.get_property("TestProperty") is not None -@with_setup(setup, teardown) def test_update_remove_property(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() assert_true(p.is_valid()) @@ -745,18 +690,15 @@ def test_update_remove_property(): '''Failure - remove p from rt''' rt.remove_property("TestProperty") - try: + with raises(db.TransactionError) as te: rt.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) rt2 = db.execute_query("FIND TestRecordType", unique=True) - assert_equal(len(rt2.get_properties()), 1) - assert_is_not_none(rt2.get_property("TestProperty")) + assert len(rt2.get_properties()) == 1 + assert rt2.get_property("TestProperty") is not None -@with_setup(setup, teardown) def test_update_add_parent(): rt = db.RecordType(name="TestRecordType").insert() assert_true(rt.is_valid()) @@ -786,31 +728,26 @@ def test_update_add_parent(): '''Failure - add par1 to rt''' rt.add_parent(name="TestRecordTypePar1", id=par1.id) - try: + with raises(db.TransactionError) as te: rt.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) rt2 = db.execute_query("FIND TestRecordType", unique=True) - assert_equal(len(rt2.get_parents()), 1) - assert_is_not_none(rt2.get_parent("TestRecordTypePar1")) + assert len(rt2.get_parents()) == 1 + assert rt2.get_parent("TestRecordTypePar1") is not None '''Failure - add par2 to rt''' rt.add_parent(name="TestRecordTypePar2", id=par2.id) - try: + with raises(db.TransactionError) as te: rt.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) rt2 = db.execute_query("FIND TestRecordType", unique=True) - assert_equal(len(rt2.get_parents()), 1) - assert_is_not_none(rt2.get_parent("TestRecordTypePar1")) - assert_is_none(rt2.get_parent("TestRecordTypePar2")) + assert len(rt2.get_parents()) == 1 + assert rt2.get_parent("TestRecordTypePar1") is not None + assert rt2.get_parent("TestRecordTypePar2") is None -@with_setup(setup, teardown) def test_update_remove_parent(): par1 = db.RecordType(name="TestRecordTypePar1").insert() assert_true(par1.is_valid()) @@ -844,29 +781,26 @@ def test_update_remove_parent(): '''Failure''' rt.remove_parent("TestRecordTypePar1") - try: + with raises(db.TransactionError) as te: rt.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) rt = db.execute_query("FIND TestRecordType", unique=True) - assert_equal(len(rt.get_parents()), 1) - assert_is_not_none(rt.get_parent("TestRecordTypePar1")) - assert_is_none(rt.get_parent("TestRecordTypePar2")) + assert len(rt.get_parents()) == 1 + assert rt.get_parent("TestRecordTypePar1") is not None + assert rt.get_parent("TestRecordTypePar2") is None -@with_setup(setup, teardown) def test_update_value(): p = db.Property( name="TestProperty", datatype=db.TEXT, value="Value").insert() - assert_true(p.is_valid()) + assert p.is_valid() p = db.execute_query("FIND Test*", unique=True) - assert_true(p.is_valid()) - assert_equal(p.value, "Value") + assert p.is_valid() + assert p.value == "Value" grant_permission(p, "RETRIEVE:ENTITY") grant_permission(p, "UPDATE:VALUE") @@ -876,53 +810,47 @@ def test_update_value(): p.update() p = db.execute_query("FIND Test*", unique=True) - assert_true(p.is_valid()) - assert_equal(p.value, "NewValue") + assert p.is_valid() + assert p.value == "NewValue" deny_permission(p, "UPDATE:VALUE") '''Failure''' p.value = "EvenNewerValue" - try: + with raises(db.TransactionError) as te: p.update() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) p2 = db.execute_query("FIND Test*", unique=True) - assert_true(p2.is_valid()) - assert_equal(p2.value, "NewValue") + assert p2.is_valid() + assert p2.value == "NewValue" -@with_setup(setup, teardown) def test_deletion(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() - assert_true(p.is_valid()) + assert p.is_valid() grant_permission(p, "RETRIEVE:ENTITY") '''Failure''' p = db.execute_query("FIND Test*", unique=True) - assert_true(p.is_valid()) - try: + assert p.is_valid() + with raises(db.TransactionError) as te: p.delete() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) '''Success''' grant_permission(p, "DELETE") + print(p) p.delete() - assert_equal( - p.get_messages()[0].description, - "This entity has been deleted successfully.") + assert p.get_messages()[ + 0].description == "This entity has been deleted successfully." -@with_setup(setup, teardown) def test_retrieve_acl(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() - assert_true(p.is_valid()) + assert p.is_valid() '''Success''' grant_permission(p, "RETRIEVE:*") @@ -931,16 +859,14 @@ def test_retrieve_acl(): '''Failure''' deny_permission(p, "RETRIEVE:ACL") - try: + with raises(db.TransactionError) as te: p.retrieve_acl() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) def test_retrieve_history(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() - assert_true(p.is_valid()) + assert p.is_valid() grant_permission(p, "RETRIEVE:ENTITY") p.retrieve() @@ -948,9 +874,9 @@ def test_retrieve_history(): assert p.version.username is None, "username belongs to history" '''Failure''' - with raises(db.TransactionError) as exc: + with raises(db.TransactionError) as te: p.retrieve(flags={"H": None}) - assert "You are not allowed to do this." in str(exc.value) + assert te.value.has_error(db.AuthorizationError) '''Success''' grant_permission(p, "RETRIEVE:HISTORY") @@ -960,11 +886,10 @@ def test_retrieve_history(): assert p.version.username == db.get_config().get("Connection", "username") -@with_setup(setup, teardown) def test_retrieve_entity(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() - assert_true(p.is_valid()) + assert p.is_valid() ''' Success''' grant_permission(p, "RETRIEVE:*") @@ -973,27 +898,22 @@ def test_retrieve_entity(): '''Failure''' deny_permission(p, "RETRIEVE:ENTITY") - try: + with raises(db.TransactionError) as te: p.retrieve() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) -@with_setup(setup, teardown) def test_retrieve_owner(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() - assert_true(p.is_valid()) + assert p.is_valid() '''Failure''' grant_permission(p, "RETRIEVE:ENTITY") deny_permission(p, "RETRIEVE:OWNER") - try: + with raises(db.TransactionError) as te: p.retrieve(flags={"owner": None}) - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, "You are not allowed to do this.") + assert te.value.has_error(db.AuthorizationError) '''Success''' grant_permission(p, "RETRIEVE:OWNER") @@ -1001,7 +921,6 @@ def test_retrieve_owner(): p.retrieve(flags={"owner": None}) -@with_setup(setup, teardown) def test_download_file(): upload_file = open("test.dat", "w") upload_file.write("hello world\n") @@ -1011,7 +930,7 @@ def test_download_file(): name="TestFile", file=upload_file, path="permissiontestfiles/test.dat").insert() - assert_true(f.is_valid()) + assert f.is_valid() '''FAILURE''' f2 = db.execute_query("FIND TestFile", unique=True) @@ -1019,81 +938,65 @@ def test_download_file(): grant_permission(f2, "RETRIEVE:ENTITY") deny_permission(f2, "RETRIEVE:FILE") - try: + with raises(db.HTTPForbiddenError): f.download() - except db.TransactionError as e: - assert_equal( - e.msg, - "Request failed. The response returned with status 403.") '''SUCCESS''' grant_permission(f2, "RETRIEVE:FILE") f2 = db.execute_query("FIND TestFile", unique=True) download_file = f2.download() - assert_equal(db.File._get_checksum(download_file), - db.File._get_checksum(upload_file)) + assert db.File._get_checksum( + download_file) == db.File._get_checksum(upload_file) -@with_setup(setup, teardown) def test_grant_priority_permission(): p = db.Property(name="TestProperty2", datatype=db.TEXT).insert() switch_to_test_user() - try: + with raises(db.TransactionError) as te: # other user cannot delete this. p.delete() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, 'You are not allowed to do this.') + assert te.value.has_error(db.AuthorizationError) deny_permission(p, "DELETE") - try: + with raises(db.TransactionError) as te: # still not working p.delete() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, 'You are not allowed to do this.') + assert te.value.has_error(db.AuthorizationError) # now its working grant_permission(p, "DELETE", priority=True) p.delete() -@with_setup(setup, teardown) def test_deny_priority_permission(): p = db.Property(name="TestProperty1", datatype=db.TEXT).insert() switch_to_test_user() - try: + with raises(db.TransactionError) as te: # other user cannot delete this. p.delete() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, 'You are not allowed to do this.') + assert te.value.has_error(db.AuthorizationError) deny_permission(p, "DELETE") - try: + with raises(db.TransactionError) as te: # still not working p.delete() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, 'You are not allowed to do this.') + assert te.value.has_error(db.AuthorizationError) - # now its working + # now it's working grant_permission(p, "DELETE") + # now it's not deny_permission(p, "DELETE", priority=True) - try: + with raises(db.TransactionError) as te: # still not working p.delete() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, 'You are not allowed to do this.') + assert te.value.has_error(db.AuthorizationError) -@with_setup(setup, teardown) def test_change_priority_permission(): entity = db.Property(name="TestProperty1", datatype=db.TEXT).insert() grant_permission(entity, "*") @@ -1105,14 +1008,11 @@ def test_change_priority_permission(): permission="USE:AS_PROPERTY", priority=True) - try: + with raises(db.TransactionError) as te: entity.update_acl() - assert_true(False) - except db.TransactionError as e: - assert_equal(e.msg, 'You are not allowed to do this.') + assert te.value.has_error(db.AuthorizationError) -@with_setup(setup, teardown) def test_permissions_there(): entity = db.Property(name="TestProperty1", datatype=db.TEXT).insert() assert_is_not_none(entity.permissions) @@ -1123,15 +1023,14 @@ def test_permissions_there(): assert_true(entity2.is_permitted("RETRIEVE:ACL")) -@with_setup(setup, teardown) def test_grant_nonsense_permission(): entity = db.Property(name="TestProperty1", datatype=db.TEXT).insert() entity.retrieve_acl() entity.grant(username="someone", permission="PAINT:BLUE") - assert_raises(db.TransactionError, entity.update_acl) + with raises(db.TransactionError): + entity.update_acl() -@with_setup(setup, teardown) def test_global_acl_there(): assert_is_not_none(db.get_global_acl()) assert_true(isinstance(db.get_global_acl(), db.ACL)) @@ -1141,31 +1040,28 @@ def test_global_acl_there(): print(db.get_global_acl()) -@with_setup(setup, teardown) def test_use_as_property(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() - assert_true(p.is_valid()) + assert p.is_valid() switch_to_test_user() rt = db.RecordType(name="TestRecordType").add_property(name="TestProperty") deny_permission(p, "USE:AS_PROPERTY") '''Failure''' deny_permission(p, "USE:AS_PROPERTY") - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: rt.insert() - ex = cm.exception - assert_equal(ex.msg, "Entity has unqualified properties.") - assert_equal(rt.get_property("TestProperty").get_errors()[0].code, "403") + assert cm.value.has_error(db.UnqualifiedPropertiesError) + assert int(rt.get_property("TestProperty").get_errors()[0].code) == 403 '''Success''' grant_permission(p, "USE:AS_PROPERTY") rt2 = db.RecordType( name="TestRecordType").add_property( name="TestProperty").insert() - assert_true(rt2.is_valid()) + assert rt2.is_valid() -@with_setup(setup, teardown) def test_use_as_data_type(): dt_name = "TestPersonRecordType" dt = db.RecordType(name=dt_name).insert() @@ -1176,12 +1072,11 @@ def test_use_as_data_type(): db.Property(name="TestConductorProperty", datatype=dt_name).insert() deny_permission(dt, "USE:AS_DATA_TYPE") - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: db.Property(name="TestConductorProperty2", datatype=dt_name).insert() - assert_equal(cm.exception.msg, "You are not allowed to do this.") + assert cm.value.has_error(db.AuthorizationError) -@with_setup(setup, teardown) def test_use_as_reference(): p = db.RecordType(name="TestRecordTypeForReference").insert() @@ -1196,23 +1091,22 @@ def test_use_as_reference(): name="TestRecordType").add_property( name="TestRecordTypeForReference", value=rec).insert() - assert_true(rt.is_valid()) + assert rt.is_valid() deny_permission(rec, "USE:AS_REFERENCE") rt2 = db.RecordType( name="TestRecordType2").add_property( name="TestRecordTypeForReference", value=rec) - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: rt2.insert() - assert_equal(cm.exception.msg, "Entity has unqualified properties.") - assert_equal(rt2.get_property(p.name).get_errors()[0].code, "403") + assert cm.value.has_error(db.UnqualifiedPropertiesError) + assert int(rt2.get_property(p.name).get_errors()[0].code) == 403 -@with_setup(setup, teardown) def test_use_as_parent(): p = db.Property(name="TestProperty", datatype=db.TEXT).insert() - assert_true(p.is_valid()) + assert p.is_valid() switch_to_test_user() p2 = db.Property( @@ -1223,20 +1117,19 @@ def test_use_as_parent(): deny_permission(p, "USE:AS_PARENT") '''Failure''' deny_permission(p, "USE:AS_PARENT") - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: p2.insert() - assert_equal(cm.exception.msg, "Entity has unqualified parents.") - assert_equal(p2.get_parent("TestProperty").get_errors()[0].code, "403") + assert cm.value.has_error(db.UnqualifiedParentsError) + assert int(p2.get_parent("TestProperty").get_errors()[0].code) == 403 '''Success''' grant_permission(p, "USE:AS_PARENT") p3 = db.Property( name="TestPropertyChild").add_parent( name="TestProperty").insert() - assert_true(p3.is_valid()) + assert p3.is_valid() -@with_setup(setup, teardown) def test_access_control_job_bug(): """test_access_control_job_bug. @@ -1247,12 +1140,12 @@ def test_access_control_job_bug(): """ revoke_permissions_test_role() switch_to_test_user() - with raises(db.AuthorizationException): + with raises(db.TransactionError) as te: rt1 = db.RecordType(name="TestRT").add_parent(id=-5).insert() + assert te.value.has_error(db.AuthorizationError) set_transaction_permissions_test_role() -@with_setup(setup, teardown) def test_check_entity_acl_roles(): '''Test the CheckEntityACLRoles class. @@ -1277,7 +1170,7 @@ def test_check_entity_acl_roles(): with raises(db.TransactionError) as cm: grant_permission(p, "USE:AS_PARENT", username="asdf-non-existing", switch=False) - errors = cm.value.entity.get_errors() + errors = cm.value.entities[0].get_errors() assert errors[0].description == "User Role does not exist." db.administration.set_server_property( "CHECK_ENTITY_ACL_ROLES_MODE", "SHOULD") diff --git a/tests/test_query.py b/tests/test_query.py index 8432b37d92c87d772ff07c0b4772def48b6aaab1..eccd303cccb3370ceba1fc6a48c98017a43789a6 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -27,6 +27,8 @@ """ +import os +import random import caosdb as h from pytest import mark @@ -35,6 +37,10 @@ from caosdb.connection.connection import get_connection from lxml import etree +def setup_module(): + h.administration.set_server_property("AUTH_OPTIONAL", "TRUE") + + def setup(): try: h.execute_query("FIND Test*").delete() @@ -43,9 +49,9 @@ def setup(): def teardown(): + h.configure_connection() setup() try: - import os os.remove("test.dat") except Exception as e: print(e) @@ -202,6 +208,7 @@ def test_query3(): assert_equal(3, len(xml)) +@mark.slow def test_conjunction(): rt = h.RecordType(name="TestConjunctionTest").insert() assert_true(rt.is_valid()) @@ -292,6 +299,7 @@ def test_conjunction(): "FIND RECORD . TestConjunctionTestPropertyA=1 AND TestConjunctionTestPropertyB=0"))) +@mark.slow def test_disjunction(): rt = h.RecordType(name="TestDisjunctionTest").insert() assert_true(rt.is_valid()) @@ -376,6 +384,7 @@ def test_disjunction(): "FIND TestDisjunctionTest . TestDisjunctionTestPropertyA=1 OR ( TestDisjunctionTestPropertyB=0 AND TestDisjunctionTestPropertyA=1)"))) +@mark.slow def test_greatest(): pAB = h.Property(name="TestPropertyAB", datatype=h.DOUBLE).insert() assert_true(pAB.is_valid()) @@ -636,40 +645,49 @@ def test_wildcard_values(): assert_equal(0, len(c)) +def store_file(path, name=None, f=None): + """insert a file for testing purposes.""" + tmp_file = None + if f is None: + tmp_file = open("test.dat", "w") + tmp_file.write("hello world\n") + tmp_file.close() + f = tmp_file + if name is None: + name = "TestFile%030x" % random.randrange(16**30) + + file_ = h.File(name=name, + description="Testfile Desc", + path=path, + file="test.dat") + file_.insert() + + if tmp_file is not None: + os.remove("test.dat") + return file_ + + def test_stored_at_wildcards(): upload_file = open("test.dat", "w") upload_file.write("hello world\n") upload_file.close() - global i - i = 1 + file1 = store_file("test1.dat", f=upload_file) - def store_file(path): - global i - file_ = h.File(name="TestTestFile" + str(i), - description="Testfile Desc", - path=path, - file="test.dat") - i += 1 - file_.insert() - return file_ + file2 = store_file("/rootdir/test2.dat", f=upload_file) - file1 = store_file("test1.dat") + file3 = store_file("/rootdir/subdir1/test3.dat", f=upload_file) - file2 = store_file("/rootdir/test2.dat") + file4 = store_file("/rootdir/subdir1/subdir2/test4.dat", f=upload_file) - file3 = store_file("/rootdir/subdir1/test3.dat") + file5 = store_file("test5.dat", f=upload_file) - file4 = store_file("/rootdir/subdir1/subdir2/test4.dat") + file6 = store_file("rootdir/test*6.dat", f=upload_file) - file5 = store_file("test5.dat") + file7 = store_file("rootdir/subdir1/test%7.dat", f=upload_file) - file6 = store_file("rootdir/test*6.dat") - - file7 = store_file("rootdir/subdir1/test%7.dat") - - file8 = store_file("rootdir/subdir1/test%8.dat") + file8 = store_file("rootdir/subdir1/test%8.dat", f=upload_file) c = h.execute_query("FIND FILE WHICH IS STORED AT /*.dat") assert_equal(len(c), 2) @@ -849,6 +867,7 @@ def test_stored_at_wildcards(): assert c.get_entity_by_id(file8.id) is not None +@mark.slow def test_int(): pint = h.Property(name="TestIntegerProperty", datatype=h.INTEGER).insert() pdouble = h.Property(name="TestDoubleProperty", datatype=h.DOUBLE).insert() @@ -1024,3 +1043,191 @@ def test_referenced_as(): "TestParty AS Guests") assert len(guests) == 3 assert set([e.id for e in guests]) == guest_ids + + +def test_query_cache(): + entity = h.RecordType("TestRT").insert() + + # fill cache + query = h.Query("COUNT TestRT") + assert query.cached is None + response = query.execute() + assert response == 1 + assert query.cached == False + + # cached == True + query = h.Query("COUNT TestRT") + assert query.cached is None + response = query.execute() + assert response == 1 + assert query.cached == True + + # cached == True + query = h.Query("FIND TestRT") + assert query.cached is None + response = query.execute(unique=True) + assert response.id == entity.id + assert query.cached == True + + # cached == True + query = h.Query("SELECT bla FROM TestRT") + assert query.cached is None + response = query.execute(unique=True) + assert response.id == entity.id + assert query.cached == True + + # no cache flag + query = h.Query("SELECT bla FROM TestRT") + assert query.cached is None + response = query.execute(unique=True, cache=False) + assert response.id == entity.id + assert query.cached == False + + # cached == True + query = h.Query("SELECT bla FROM TestRT") + assert query.cached is None + response = query.execute(unique=True) + assert response.id == entity.id + assert query.cached == True + + # write resets cache + another_entity = h.Record().add_parent("TestRT").insert() + + # cached == False + query = h.Query("COUNT TestRT") + assert query.cached is None + response = query.execute() + assert response == 2 + assert query.cached == False + + # cached == True + query = h.Query("COUNT TestRT") + assert query.cached is None + response = query.execute() + assert response == 2 + assert query.cached == True + + +def test_query_cache_with_permissions(): + h.RecordType("TestRT").insert() + h.RecordType("TestRT2").insert() + public_record = h.Record().add_parent("TestRT").insert() + referenced = h.Record().add_parent("TestRT2").insert() + private_record = h.Record().add_parent( + "TestRT").add_property("TestRT2", + referenced).insert(flags={"ACL": None}) + + # proof: query as anonymous works in principle + h.configure_connection(password_method="unauthenticated") + query = h.Query("COUNT Record TestRT") + response = query.execute() + assert response == 2 + assert query.cached == False + + query = h.Query("COUNT Record WHICH IS REFERENCED BY TestRT") + response = query.execute() + assert response == 1 + assert query.cached == False + + # remove permissions for anonymous + h.configure_connection() + private_record.deny(role="anonymous", permission="RETRIEVE:*") + private_record.update_acl() # note: this clears the cache + + # as authenticated user to fill the cache + query = h.Query("COUNT Record TestRT") + response = query.execute() + assert response == 2 + assert query.cached == False + + query = h.Query("COUNT Record WHICH IS REFERENCED BY TestRT") + response = query.execute() + assert response == 1 + assert query.cached == False + + # as anonymous + h.configure_connection(password_method="unauthenticated") + query = h.Query("COUNT Record TestRT") + response = query.execute() + assert response == 1 + assert query.cached == True + + query = h.Query("COUNT Record WHICH IS REFERENCED BY TestRT") + response = query.execute() + assert response == 0 + # Caching was not possible due to complex permissions + assert query.cached == False + + # try again as authenticated user + h.configure_connection() + query = h.Query("COUNT Record TestRT") + response = query.execute() + assert query.cached == True + assert response == 2 + + query = h.Query("COUNT Record WHICH IS REFERENCED BY TestRT") + response = query.execute() + assert response == 1 + # Caching was not possible due to complex permissions + assert query.cached == False + + +def test_find_star(): + """related: caosdb-server#116""" + rt = h.RecordType("TestRT").insert() + response = h.execute_query("FIND *")[0] + assert response.id == rt.id + + +def test_find_entity(): + rt = h.RecordType("TestRT").insert() + response = h.execute_query("FIND ENTITY")[0] + assert response.id == rt.id + + +def test_count_any_version_of_entity(): + vcount1 = h.execute_query("COUNT ANY VERSION OF ENTITY") + ecount1 = h.execute_query("COUNT ENTITY") + assert ecount1 == 0 + assert vcount1 == 0 + + rt = h.RecordType("TestRT").insert() + vcount2 = h.execute_query("COUNT ANY VERSION OF ENTITY") + ecount2 = h.execute_query("COUNT ENTITY") + assert vcount2 == vcount1 + 1 + assert ecount2 == ecount1 + 1 + + rt.description = "update" + rt.update() + vcount3 = h.execute_query("COUNT ANY VERSION OF ENTITY") + ecount3 = h.execute_query("COUNT ENTITY") + assert vcount3 == vcount2 + 1 + assert ecount3 == ecount2 + + +def test_find_nasty_path(): + """related: caosdb-server#31""" + file_1 = store_file("0in.txt") + assert h.execute_query( + "FIND FILE WHICH IS STORED AT 0in.txt", + unique=True).id == file_1.id + + file_2 = store_file(".asdf.txt") + assert h.execute_query( + "FIND FILE WHICH IS STORED AT .asdf.txt", + unique=True).id == file_2.id + + file_3 = store_file(".WITH") + assert h.execute_query( + "FIND FILE WHICH IS STORED AT .WITH", + unique=True).id == file_3.id + + file_4 = store_file("STORED") + assert h.execute_query( + "FIND FILE WHICH IS STORED AT STORED", + unique=True).id == file_4.id + + file_5 = store_file("STORED AT") # hehe + assert h.execute_query( + "FIND FILE WHICH IS STORED AT STORED AT", + unique=True).id == file_5.id diff --git a/tests/test_query_template.py b/tests/test_query_template.py index e2b1c77a3b815419e45f24ad5b4a2131fdab331a..c5fc3c7858e9b87eff6aca6e6d04a8d3d055b8b3 100644 --- a/tests/test_query_template.py +++ b/tests/test_query_template.py @@ -26,9 +26,8 @@ @author: tf """ import caosdb as db -from nose.tools import (assert_equal, assert_is_none, # @UnresolvedImport - assert_is_not_none, assert_raises, assert_true, - nottest, with_setup) +from nose.tools import assert_true, assert_equal, assert_is_not_none +from pytest import raises def setup_module(): @@ -91,7 +90,6 @@ def teardown(): print(e) -@with_setup(setup, teardown) def test_insertion_success(): return db.QueryTemplate( name="TestQueryTemplate", @@ -99,63 +97,54 @@ def test_insertion_success(): query="FIND RECORD Experiment WHICH HAS A animal=Pig").insert() -@with_setup(setup, teardown) def test_insertion_failure_syntax(): q = db.QueryTemplate( name="TestQueryTemplate", description="Find some interesting things with via a simple name.", query="SDASDUASIUF") - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: q.insert() - print(cm.exception) - assert_equal( - cm.exception.msg, - "An error occured during the parsing of this query. Maybe you use a wrong syntax?") + print(cm.value) + assert (cm.value.errors[0].msg == + "An error occured during the parsing of this query. Maybe you use a wrong syntax?") -@with_setup(setup, teardown) def test_insertion_failure_count_query_not_allowed(): q = db.QueryTemplate( name="TestQueryTemplate", description="Find some interesting things with via a simple name.", query="COUNT something") - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: q.insert() - assert_equal( - cm.exception.msg, - "QueryTemplates may not be defined by 'COUNT...' queries for consistency reasons.") + assert (cm.value.errors[0].msg == + "QueryTemplates may not be defined by 'COUNT...' queries for consistency reasons.") -@with_setup(setup, teardown) def test_insertion_failure_select_query_not_allowed(): query_def = "SELECT TestAnimal FROM TestExperiment WHICH HAS A TestAnimal = Pig" q = db.QueryTemplate( name="TestQueryTemplate", description="Find some interesting things with via a simple name.", query=query_def) - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: q.insert() - assert_equal( - cm.exception.msg, - "QueryTemplates may not be defined by 'SELECT... FROM...' queries for consistency reasons.") + assert (cm.value.errors[0].msg == + "QueryTemplates may not be defined by 'SELECT... FROM...' queries for consistency reasons.") -@with_setup(setup, teardown) def test_deletion_success(): eid = test_insertion_success().id q = db.QueryTemplate(id=eid).delete() assert_true(q.is_deleted()) -@with_setup(setup, teardown) def test_deletion_failure_non_existing(): q = db.QueryTemplate(id="12342") - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: q.delete() - assert_equal(cm.exception.msg, "Entity does not exist.") + assert cm.value.has_error(db.EntityDoesNotExistError) -@with_setup(setup, teardown) def test_retrieve_success(): test_insertion_success() q = db.QueryTemplate(name="TestQueryTemplate").retrieve(sync=False) @@ -164,71 +153,60 @@ def test_retrieve_success(): assert_equal(q.query, "FIND RECORD Experiment WHICH HAS A animal=Pig") -@with_setup(setup, teardown) def test_retrieve_failure_non_existing(): q = db.QueryTemplate(id="12342") - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: q.retrieve() - assert_equal(cm.exception.msg, "Entity does not exist.") + assert cm.value.has_error(db.EntityDoesNotExistError) -@with_setup(setup, teardown) def test_update_success(): q = test_insertion_success() q.query = "FIND NewStuff" q.update() -@with_setup(setup, teardown) def test_update_failure_syntax(): q = test_insertion_success() q.query = "ashdjfkasjdf" - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: q.update() - assert_equal( - cm.exception.msg, - "An error occured during the parsing of this query. Maybe you use a wrong syntax?") + assert(cm.value.errors[0].msg == + "An error occured during the parsing of this query. Maybe you use a wrong syntax?") -@with_setup(setup, teardown) def test_update_failure_count_query_not_allowed(): q = test_insertion_success() q.query = "COUNT somethingNew" - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: q.update() - assert_equal( - cm.exception.msg, - "QueryTemplates may not be defined by 'COUNT...' queries for consistency reasons.") + assert (cm.value.errors[0].msg == + "QueryTemplates may not be defined by 'COUNT...' queries for consistency reasons.") -@with_setup(setup, teardown) def test_update_failure_select_query_not_allowed(): q = test_insertion_success() q.query = "SELECT TestAnimal FROM TestExperiment WHICH HAS A TestAnimal = Pig" - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: q.update() - assert_equal( - cm.exception.msg, - "QueryTemplates may not be defined by 'SELECT... FROM...' queries for consistency reasons.") + assert (cm.value.errors[0].msg == + "QueryTemplates may not be defined by 'SELECT... FROM...' queries for consistency reasons.") -@with_setup(setup, teardown) def test_update_failure_non_existing(): q = db.QueryTemplate(id="12342") q.query = "FIND NewStuff" - with assert_raises(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: q.update() - assert_equal(cm.exception.msg, "Entity does not exist.") + assert cm.value.has_error(db.EntityDoesNotExistError) -@with_setup(setup, teardown) def test_retrieve_as_entity_success(): q = test_insertion_success() e = db.Entity(id=q.id).retrieve() assert_equal(e.id, q.id) -@with_setup(setup, teardown) def test_query_simple_find(): query_def = "FIND TestExperiment WHICH HAS A TestAnimal = Pig" r = db.execute_query(query_def, unique=True) @@ -252,7 +230,6 @@ def test_query_simple_find(): "TestRecord") -@with_setup(setup, teardown) def test_query_with_select_in_outer_query(): query_def = "FIND TestExperiment WHICH HAS A TestAnimal = Pig" r = db.execute_query(query_def, unique=True) @@ -281,7 +258,6 @@ def test_query_with_select_in_outer_query(): assert_equal(len(r.get_properties()), 1) -@with_setup(setup, teardown) def test_query_with_other_filters(): query_def = "FIND TestExperiment WHICH HAS A TestAnimal" db.QueryTemplate(name="TestAnimalExperiment", query=query_def).insert() @@ -295,7 +271,6 @@ def test_query_with_other_filters(): assert_equal(r.name, "TestRecord") -@with_setup(setup, teardown) def test_query_simple_find_with_wildcard(): query_def = "FIND TestExperiment WHICH HAS A TestAnimal = Pig" db.QueryTemplate(name="TestAnimalExperiment", query=query_def).insert() @@ -309,7 +284,6 @@ def test_query_simple_find_with_wildcard(): assert_equal(r.name, "TestRecord") -@with_setup(setup, teardown) def test_query_select_from_with_wildcard(): query_def = "FIND TestExperiment WHICH HAS A TestAnimal = Pig" db.QueryTemplate(name="TestAnimalExperiment", query=query_def).insert() @@ -320,7 +294,6 @@ def test_query_select_from_with_wildcard(): assert_equal(len(r.get_entity_by_name("TestAnimal").get_properties()), 0) -@with_setup(setup, teardown) def test_query_without_permission(): query_def = "FIND TestExperiment WHICH HAS A TestAnimal = Pig" qt = db.QueryTemplate(name="TestPigExperiment", query=query_def).insert() @@ -353,7 +326,6 @@ def test_query_without_permission(): assert_equal(len(r), 0) -@with_setup(setup, teardown) def test_query_with_subquery_referenced_by(): assert_equal( db.execute_query( diff --git a/tests/test_query_version.py b/tests/test_query_version.py index 0b152ee0f3015c08be7d46f680e1694eaeeaa8ca..860bc68514327a8bbfc90777abac4974344b820f 100644 --- a/tests/test_query_version.py +++ b/tests/test_query_version.py @@ -133,6 +133,7 @@ def setup_module(): TEST_REC_1.id) + "@HEAD").insert() +@pytest.mark.slow def test_normal_find_record(): result = query("FIND RECORD TestRecord1") assert len(result) == 1 diff --git a/tests/test_select.py b/tests/test_select.py index 66c3992d1519f101b7b18941924b9bd939fa0066..af2bf3a244e262f65b24becb2bada1137adbaa7a 100644 --- a/tests/test_select.py +++ b/tests/test_select.py @@ -41,15 +41,22 @@ def setup_module(): name="TestPropertyOne", value="v1").add_property( name="TestPropertyTwo", value="v2").insert() rt_house = db.RecordType("TestHouse", description="TestHouseDesc").insert() - db.RecordType("TestWindow").insert() + db.RecordType("TestHousePart", description="TestHousePartDesc").insert() + db.RecordType("TestWindow").add_parent("TestHousePart").insert() + db.RecordType("TestDoor").add_parent("TestHousePart").insert() rt_person = db.RecordType("TestPerson", description="TestPersonDesc").insert() db.RecordType("TestParty", description="TestPartyDesc").insert() + db.Property("TestHouseProperty", datatype=db.TEXT).insert() db.Property("TestHeight", description="TestHeightDesc", datatype=db.DOUBLE, - unit="ft").insert() + unit="ft").add_parent("TestHouseProperty").insert() db.Property("TestDate", description="TestDateDesc", datatype=db.DATETIME).insert() + door = db.Record("Door1", + description="Door1Desc").add_parent("TestDoor") + door.add_property("TestHeight", "21.5", unit="ft") + door.insert() window = db.Record("Window1", description="Window1Desc").add_parent("TestWindow") window.add_property("TestHeight", 20.5, unit="ft") @@ -61,7 +68,9 @@ def setup_module(): house.description = "A rather large house" house.add_parent("TestHouse") house.add_property(rt_person, name="TestOwner", value=owner) - house.add_property("TestWindow", window).insert() + house.add_property("TestWindow", [window], datatype=db.LIST("TestWindow")) + house.add_property("TestDoor", door) + house.insert() g1 = db.Record().add_parent("TestPerson").insert() g2 = db.Record().add_parent("TestPerson").insert() @@ -183,33 +192,71 @@ def test_sub2(): def test_subref(): - window = db.execute_query("FIND RECORD TestWindow", unique=True) - s = db.execute_query("SELECT name, TestWindow.TestHeight.value, " - "TestWindow.TestHeight.unit FROM RECORD TestHouse") + door = db.execute_query("FIND RECORD TestDoor", unique=True) + s = db.execute_query("SELECT name, TestDoor.TestHeight.value, " + "TestDoor.TestHeight.unit FROM RECORD TestHouse") assert len(s) == 1 - row = s.get_property_values("name", "TestWindow")[0] + row = s.get_property_values("name", "TestDoor")[0] assert row[0] == "Buckingham Palace" - assert row[1] == window.id + assert row[1] == door.id - row = s.get_property_values("name", ("TestWindow", "TestHeight"))[0] + row = s.get_property_values("name", ("TestDoor", "TestHeight"))[0] assert row[0] == "Buckingham Palace" - assert row[1] == 20.5 + assert row[1] == 21.5 row = s.get_property_values( - "name", ("TestWindow", "TestHeight", "unit"))[0] + "name", ("TestDoor", "TestHeight", "unit"))[0] assert row[0] == "Buckingham Palace" assert row[1] == "ft" +def test_subref_list(): + window = db.execute_query("FIND RECORD TestWindow", unique=True) + s = db.execute_query("SELECT name, TestWindow.TestHeight.value, " + "TestWindow.TestHeight.unit FROM RECORD TestHouse") + + assert len(s) == 1 + + row = s.get_property_values("name", "TestWindow")[0] + assert row[0] == "Buckingham Palace" + assert row[1][0].id == window.id + + # current limitation of get_property_values - no lists + # row = s.get_property_values("name", ("TestWindow", "TestHeight"))[0] + # assert row[0] == "Buckingham Palace" + # assert row[1] == 20.5 + assert row[1][0].get_property("TestHeight").value == 20.5 + + # current limitation of get_property_values - no lists + # row = s.get_property_values( + # "name", ("TestWindow", "TestHeight", "unit"))[0] + # assert row[0] == "Buckingham Palace" + # assert row[1] == "ft" + assert row[1][0].get_property("TestHeight").unit == "ft" + + def test_subref_deep(): p = db.execute_query( - "SELECT name, Testdate, location, location.TestWindow.Testheight FROM " + "SELECT name, Testdate, location, location.TestDoor.Testheight FROM " "RECORD TestParty", unique=True) row = p.get_property_values("name", "Testdate", - ("location", "Testwindow", "Testheight")) - assert row == ("Diamond Jubilee of Elizabeth II", "2012-02-06", 20.5) + ("location", "Testdoor", "Testheight")) + assert row == ("Diamond Jubilee of Elizabeth II", "2012-02-06", 21.5) + + +def test_subref_deep_list(): + p = db.execute_query( + "SELECT name, Testdate, location, location.TestWindow.Testheight FROM " + "RECORD TestParty", unique=True) + + # current limitation of get_property_values - no lists + # row = p.get_property_values("name", "Testdate", + # ("location", "Testwindow", "Testheight")) + # assert row == ("Diamond Jubilee of Elizabeth II", "2012-02-06", 20.5) + assert p.get_property_values(("location", "TestWindow"))[ + 0][0].get_property("TestHeight").value == 20.5 def test_select_list(): @@ -218,6 +265,7 @@ def test_select_list(): s = db.execute_query("SELECT guests FROM RECORD TestParty", unique=True) column = s.get_property_values("guests")[0] + print(s) assert len(column) == len(guests) for eid in [e.id for e in guests]: @@ -233,17 +281,35 @@ def test_select_unit(): column = s.get_property_values("unit") assert column == ("ft",) - s = db.execute_query("SELECT TestWindow.TestHeight.unit FROM " + s = db.execute_query("SELECT TestDoor.TestHeight.unit FROM " "RECORD TestHouse", unique=True) - column = s.get_property_values(("TestWindow", "TestHeight", "unit")) + column = s.get_property_values(("TestDoor", "TestHeight", "unit")) assert column == ("ft",) - s = db.execute_query("SELECT TestHeight.unit.TestWindow FROM " - "RECORD TestWindow", unique=True) - column = s.get_property_values(("TestHeight", "unit", "TestWindow")) + s = db.execute_query("SELECT TestHeight.unit.TestDoor FROM " + "RECORD TestDoor", unique=True) + column = s.get_property_values(("TestHeight", "unit", "TestDoor")) assert column == (None,) +def test_select_unit_list(): + s = db.execute_query("SELECT unit FROM RECORD TestHouse", unique=True) + column = s.get_property_values("unit") + assert column == (None,) + + s = db.execute_query("SELECT unit FROM PROPERTY TestHeight", unique=True) + column = s.get_property_values("unit") + assert column == ("ft",) + + s = db.execute_query("SELECT TestWindow.TestHeight.unit FROM " + "RECORD TestHouse", unique=True) + # current limitation of get_property_values - no lists + # column = s.get_property_values(("TestWindow", "TestHeight", "unit")) + # assert column == ("ft",) + assert s.get_property_values(("TestWindow"))[ + 0][0].get_property("TestHeight").unit == "ft" + + def test_select_description(): s = db.execute_query("SELECT description FROM RECORD TestPerson") column = s.get_property_values("description") @@ -260,21 +326,50 @@ def test_select_description(): assert column == ("A rather large house",) s = db.execute_query("SELECT TestHeight.description FROM " - "RECORD TestWindow", unique=True) + "RECORD TestDoor", unique=True) column = s.get_property_values(("TestHeight", "description")) assert column == ('TestHeightDesc',) - s = db.execute_query("SELECT TestWindow.TestHeight.description FROM " + s = db.execute_query("SELECT TestDoor.TestHeight.description FROM " "RECORD TestHouse", unique=True) - column = s.get_property_values(("TestWindow", "TestHeight", "description")) + column = s.get_property_values(("TestDoor", "TestHeight", "description")) assert column == ('TestHeightDesc',) - s = db.execute_query("SELECT TestHeight.description.TestWindow FROM " - "RECORD TestWindow", unique=True) - column = s.get_property_values(("TestHeight", "description", "TestWindow")) + s = db.execute_query("SELECT TestHeight.description.TestDoor FROM " + "RECORD TestDoor", unique=True) + column = s.get_property_values(("TestHeight", "description", "TestDoor")) assert column == (None,) +def test_select_description_list(): + s = db.execute_query("SELECT description FROM RECORD TestPerson") + column = s.get_property_values("description") + assert column == [(None,), (None,), (None,), (None,)] + + s = db.execute_query("SELECT description" + "FROM RECORD TestHouse", unique=True) + column = s.get_property_values(("description")) + assert column == ("A rather large house",) + + s = db.execute_query("SELECT location.description" + "FROM RECORD TestParty", unique=True) + column = s.get_property_values(("location", "description")) + assert column == ("A rather large house",) + + s = db.execute_query("SELECT TestHeight.description FROM " + "RECORD TestWindow", unique=True) + column = s.get_property_values(("TestHeight", "description")) + assert column == ('TestHeightDesc',) + + s = db.execute_query("SELECT TestWindow.TestHeight.description FROM " + "RECORD TestHouse", unique=True) + # current limitation of get_property_values - no lists + # column = s.get_property_values(("TestWindow", "TestHeight", "description")) + # assert column == ('TestHeightDesc',) + assert s.get_property_values(("TestWindow"))[0][0].get_property( + "TestHeight").description == "TestHeightDesc" + + def test_select_id(): house_id = db.execute_query("FIND RECORD TestHouse", unique=True).id s = db.execute_query("SELECT id FROM RECORD TestHouse", unique=True) @@ -292,17 +387,43 @@ def test_select_id(): column = s.get_property_values("id") assert column == (height_id,) - s = db.execute_query("SELECT TestWindow.TestHeight.id FROM " + s = db.execute_query("SELECT TestDoor.TestHeight.id FROM " "RECORD TestHouse", unique=True) - column = s.get_property_values(("TestWindow", "TestHeight", "id")) + column = s.get_property_values(("TestDoor", "TestHeight", "id")) assert column == (height_id,) - s = db.execute_query("SELECT TestHeight.id.TestWindow FROM " - "RECORD TestWindow", unique=True) - column = s.get_property_values(("TestHeight", "id", "TestWindow")) + s = db.execute_query("SELECT TestHeight.id.TestDoor FROM " + "RECORD TestDoor", unique=True) + column = s.get_property_values(("TestHeight", "id", "TestDoor")) assert column == (None,) +def test_select_id_list(): + house_id = db.execute_query("FIND RECORD TestHouse", unique=True).id + s = db.execute_query("SELECT id FROM RECORD TestHouse", unique=True) + column = s.get_property_values("id") + assert column == (house_id,) + + s = db.execute_query( + "SELECT location.id FROM RECORD TestHouse", + unique=True) + column = s.get_property_values("id") + assert column == (house_id,) + + height_id = db.execute_query("FIND PROPERTY TestHeight", unique=True).id + s = db.execute_query("SELECT id FROM PROPERTY TestHeight", unique=True) + column = s.get_property_values("id") + assert column == (height_id,) + + s = db.execute_query("SELECT TestWindow.TestHeight.id FROM " + "RECORD TestHouse", unique=True) + # current limitation of get_property_values - no lists + # column = s.get_property_values(("TestWindow", "TestHeight", "id")) + # assert column == (height_id,) + assert s.get_property_values(("TestWindow"))[0][0].get_property( + "TestHeight").id == height_id + + def test_select_name(): s = db.execute_query("SELECT name FROM RECORD TestHouse", unique=True) column = s.get_property_values("name") @@ -317,12 +438,84 @@ def test_select_name(): column = s.get_property_values("name") assert column == ("TestHeight",) - s = db.execute_query("SELECT TestWindow.TestHeight.name FROM " + s = db.execute_query("SELECT TestDoor.TestHeight.name FROM " "RECORD TestHouse", unique=True) - column = s.get_property_values(("TestWindow", "TestHeight", "name")) + column = s.get_property_values(("TestDoor", "TestHeight", "name")) assert column == ("TestHeight",) - s = db.execute_query("SELECT TestHeight.name.TestWindow FROM " - "RECORD TestWindow", unique=True) - column = s.get_property_values(("TestHeight", "name", "TestWindow")) + s = db.execute_query("SELECT TestHeight.name.TestDoor FROM " + "RECORD TestDoor", unique=True) + column = s.get_property_values(("TestHeight", "name", "TestDoor")) assert column == (None,) + + +def test_select_name_list(): + s = db.execute_query("SELECT name FROM RECORD TestHouse", unique=True) + column = s.get_property_values("name") + assert column == ("Buckingham Palace",) + + s = db.execute_query("SELECT location.name FROM RECORD TestHouse", + unique=True) + column = s.get_property_values("name") + assert column == ("Buckingham Palace",) + + s = db.execute_query("SELECT name FROM PROPERTY TestHeight", unique=True) + column = s.get_property_values("name") + assert column == ("TestHeight",) + + s = db.execute_query("SELECT TestWindow.TestHeight.name FROM " + "RECORD TestHouse", unique=True) + # current limitation of get_property_values - no lists + # column = s.get_property_values(("TestWindow", "TestHeight", "name")) + # assert column == ("TestHeight",) + assert s.get_property_values(("TestWindow"))[0][0].get_property( + "TestHeight").name == "TestHeight" + + +def test_select_with_subtyping_semantics(): + s = db.execute_query( + "SELECT name FROM RECORD TestHouse WITH TestHousePart", + unique=True) + column = s.get_property_values("name") + assert column == ("Buckingham Palace",) + + s = db.execute_query( + "SELECT TestDoor.TestHeight FROM RECORD TestHouse WITH TestHousePart", + unique=True) + column = s.get_property_values(("TestDoor", "TestHeight")) + assert column == (21.5,) + + s = db.execute_query( + "SELECT TestHousePart.TestHeight FROM RECORD TestHouse WITH TestHousePart", + unique=True) + column = s.get_property_values(("TestHousePart", "TestHeight")) + # this is a current limitation of get_property_values which will only + # return the value of the first matching property + # assert column == ([[20.5], 21.5,]) + + assert len(s.properties) == 2 + # both the door and the window have been returned + print(s.properties[0].value) + assert (s.properties[0].name, + s.properties[1].name) == ("TestHousePart", "TestHousePart") + assert (s.properties[0].value[0].properties[0].value, + s.properties[1].value.properties[0].value) == (20.5, 21.5) + + +def test_select_with_subtyping_semantics_second_level(): + s = db.execute_query( + "SELECT TestHousePart.TestHouseProperty FROM RECORD TestHouse WITH TestHousePart", + unique=True) + + assert len(s.properties) == 2 + # both the door and the window have been returned + assert (s.properties[0].name, + s.properties[1].name) == ("TestHousePart", "TestHousePart") + assert (s.properties[0].value[0].properties[0].value, + s.properties[1].value.properties[0].value) == (20.5, 21.5) + + +def test_select_with_subtyping_semantics_and_name_duplicates(): + db.Property(name="TestHousePart", description="This is a duplicate", + datatype=db.TEXT).insert(unique=False) + test_select_with_subtyping_semantics() diff --git a/tests/test_server_side_scripting.py b/tests/test_server_side_scripting.py index 7ecc50121a2e2fc2eaaf3d31659d5ff0bc2bc604..96172dd2fcbe8bfbe6fce1f2ca1494e410c561d6 100644 --- a/tests/test_server_side_scripting.py +++ b/tests/test_server_side_scripting.py @@ -27,25 +27,34 @@ Integration tests for the implementation of the server-side-scripting api. """ from __future__ import print_function, unicode_literals import os -from pytest import raises +import tempfile +from pytest import raises, mark import json from lxml import etree from http.client import HTTPSConnection import ssl from caosdb import get_connection, get_config, Info, execute_query, RecordType -from caosdb.exceptions import (EntityDoesNotExistError, ClientErrorException) +from caosdb.exceptions import (HTTPClientError, + HTTPResourceNotFoundError) from caosdb.connection.encode import MultipartParam, multipart_encode from caosdb.connection.utils import urlencode, urlparse from caosdb import administration as admin from caosdb.utils.server_side_scripting import run_server_side_script _TEST_SCRIPTS = ["not_executable", "ok", "err", "ok_anonymous"] -_SERVER_SIDE_SCRIPTING_BIN_DIR_LOCAL = get_config().get( - "IntegrationTests", - "test_server_side_scripting.bin_dir.local") -_SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER = get_config().get( - "IntegrationTests", - "test_server_side_scripting.bin_dir.server") + +try: + _SERVER_SIDE_SCRIPTING_BIN_DIR_LOCAL = get_config().get( + "IntegrationTests", + "test_server_side_scripting.bin_dir.local") +except Exception: + _SERVER_SIDE_SCRIPTING_BIN_DIR_LOCAL = tempfile.mkdtemp() +try: + _SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER = get_config().get( + "IntegrationTests", + "test_server_side_scripting.bin_dir.server") +except Exception: + _SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER = "" _TEST_SCRIPTS_DIR = "./resources/" _REMOVE_FILES_AFTERWARDS = [] _ORIGINAL_SERVER_SCRIPTING_BIN_DIR = "" @@ -108,20 +117,22 @@ def teardown_module(): def test_call_script_non_existing(): form = dict() form["call"] = "non_existing_script" - with raises(EntityDoesNotExistError): + with raises(HTTPResourceNotFoundError): get_connection().post_form_data("scripting", form) +@mark.local_server def test_call_script_not_executable(): admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS", _SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER) form = dict() form["call"] = "not_executable" - with raises(ClientErrorException) as exc_info: + with raises(HTTPClientError) as exc_info: get_connection().post_form_data("scripting", form) assert "not executable" in exc_info.value.body.decode("utf-8") +@mark.local_server def test_call_ok(): admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS", _SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER) @@ -135,6 +146,7 @@ def test_call_ok(): assert xml.xpath("/Response/script/@code")[0] == "0" +@mark.local_server def test_call_err(): admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS", _SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER) @@ -276,6 +288,7 @@ def test_diagnostics_with_file_upload(): assert xml.xpath("/Response/script/stderr")[0].text is None +@mark.local_server def test_call_as_anonymous_with_administration_role(): assert Info().user_info.roles == ["administration"] @@ -351,6 +364,7 @@ def test_anonymous_script_calling_not_permitted(): assert response.getheader("Set-Cookie") is None # no auth token returned +@mark.local_server def test_anonymous_script_calling_success(): admin.set_server_property("SERVER_SIDE_SCRIPTING_BIN_DIRS", _SERVER_SIDE_SCRIPTING_BIN_DIR_SERVER) @@ -396,5 +410,5 @@ def test_evil_path(): _SERVER_SIDE_SCRIPTING_BIN_DIR_LOCAL, "ok")) - with raises(EntityDoesNotExistError): + with raises(HTTPResourceNotFoundError): r = run_server_side_script("../ok") diff --git a/tests/test_tickets.py b/tests/test_tickets.py index 3afd753beae2673eba0387e657a2292f127097bb..cdaee95f647cec1574563b08922a7d9be08bad07 100644 --- a/tests/test_tickets.py +++ b/tests/test_tickets.py @@ -26,12 +26,13 @@ @author: tf """ import caosdb as db -from caosdb.exceptions import (AmbiguityException, CaosDBException, - EntityDoesNotExistError, EntityError, +from caosdb.exceptions import (CaosDBException, TransactionError, UniqueNamesError) from nose.tools import (assert_equal, assert_false, assert_is_none, assert_is_not_none, assert_raises, assert_true, nottest) +import pytest +from tests import test_misc def setup(): @@ -52,75 +53,74 @@ def test_ticket_103a(): # insert w/o strict flag haswarnings = False rt.insert(strict=False) - assert_true(rt.is_valid()) + assert rt.is_valid() for w in rt.get_warnings(): haswarnings = True break - assert_true(haswarnings) + assert haswarnings # update w/o strict flag haswarnings = False rt.name = "TestRecordTypeUpdate" rt.update(strict=False) - assert_true(rt.is_valid()) + assert rt.is_valid() for w in rt.get_warnings(): haswarnings = True break - assert_true(haswarnings) + assert haswarnings # update w/ strict flag rt.name = "TestRecordTypeUpdate2" - try: + with pytest.raises(TransactionError) as e: rt.update(strict=True) - assert_true(False, "This should have raised an 128-Error (strict)") - except TransactionError as exc: - print(exc) - assert_equal(128, int(exc.get_code())) - rt = exc.get_entities()[0] - assert_false(rt.is_valid()) + exc = e.value + print(exc) + assert 128 == int(exc.errors[0].code) + rt = exc.entities[0] + assert not rt.is_valid() for w in rt.get_warnings(): haswarnings = True break - assert_true(haswarnings) + assert haswarnings for w in rt.get_errors(): - if w.get_code() == 128: + if int(w.get_code()) == 128: hasstricterror = True break - assert_true(hasstricterror) + assert hasstricterror finally: try: rt.delete() except BaseException: pass - # insert w/ strict flag + # insert w/ strict flag without raising an exception haswarnings = False hasstricterror = False rt = db.RecordType(name="TestRecordType") try: rt.insert(strict=True, raise_exception_on_error=False) - assert_false(rt.is_valid()) + assert not rt.is_valid() for w in rt.get_warnings(): haswarnings = True break - assert_true(haswarnings) + assert haswarnings for w in rt.get_errors(): if w.get_code() == 128: hasstricterror = True break - assert_true(hasstricterror) + assert hasstricterror finally: try: rt.delete() @@ -148,19 +148,17 @@ def test_ticket_103b(): # unique flag try: - rt1 = db.RecordType(name="NameDuplicatesEntity") - rt2 = db.RecordType(name="NameDuplicatesEntity") + rt1 = db.RecordType(name="TestNameDuplicatesEntity") + rt2 = db.RecordType(name="TestNameDuplicatesEntity") rt1.insert( unique=True, strict=False) - assert_true(rt1.is_valid()) - try: + assert rt1.is_valid() + with pytest.raises(TransactionError) as te: rt2.insert(unique=True) - assert_true(False) - except UniqueNamesError: - pass + assert te.value.has_error(UniqueNamesError) - assert_false(rt2.is_valid()) + assert not rt2.is_valid() finally: try: @@ -173,24 +171,6 @@ def test_ticket_103b(): pass -def test_ticket_102(): - """EntityDoesNotExistException.""" - - try: - p = db.Property(name="Non-ExistentProperty") - p.retrieve( - unique=True, raise_exception_on_error=True) - assert_true(False) - except CaosDBException as e: - assert_true(isinstance(e, EntityDoesNotExistError)) - assert_is_not_none(e.get_entity()) - assert_equal(e.get_entity().name, p.name) - assert_true(e.get_entity().has_errors()) - assert_false(p.has_errors()) - assert_false(p.is_valid()) - assert_false(e.get_entity().is_valid()) - - def test_ticket_101(): """RecordType and Property constructor work differently?""" @@ -224,35 +204,6 @@ def test_ticket_100(): pass -def test_ticket_96(): - - try: - rt1 = db.RecordType(name="a_b") - rt2 = db.RecordType(name="a_b") - rt1.insert() - rt2.insert(unique=False) - - c = db.Container().append( - db.RecordType(name="a_b")).retrieve(unique=False) - assert_equal(len(c), 2) - - try: - c = db.Container().append( - db.RecordType(name="a_b")).retrieve(unique=True) - assert_true(False) - except AmbiguityException as e: - print(repr(e)) - finally: - try: - rt2.delete() - except BaseException: - pass - try: - rt1.delete() - except BaseException: - pass - - def test_ticket_114(): try: db.execute_query("FIND rt_nice").delete() @@ -579,7 +530,7 @@ def test_ticket_39(): scratch = os.path.realpath(db.get_config().get( "EndToEndTests", "test_tickets.test_ticket_39.scratch")) - assert_true(os.path.isdir(scratch)) + assert os.path.isdir(scratch) testfile = os.path.join(scratch, "test.dat") try: # insert RecordType @@ -590,19 +541,16 @@ def test_ticket_39(): # check if the server can connect to this filesystem f = db.File(path="testfiles/file1", pickup=testfile).insert() - assert_true(f.is_valid()) + assert f.is_valid() f.delete() # make unreadable os.chmod(testfile, 0o000) - try: + with pytest.raises(TransactionError) as te: f = db.File( path="testfiles/file1", pickup=testfile).insert() - except EntityError as e: - assert_equal( - "Insufficient read permission for this file. " - "Please make it readable.", - e.msg) + e = te.value.errors[0] + assert e.msg == "Insufficient read permission for this file. Please make it readable." finally: os.chmod(testfile, 0o600) @@ -620,7 +568,7 @@ def test_ticket_128(): try: db.execute_query(r"FIND 5\#):xw;;-`;BY6~PjsI^*g.$+eY#n.aA9zm") except TransactionError as e: - assert_equal(13, int(e.get_error().code)) + assert 13 == int(e.error.code) def test_ticket_123a(): @@ -767,6 +715,7 @@ def test_ticket_143(): pass +@pytest.mark.slow def test_ticket_147(): try: @@ -925,13 +874,10 @@ def test_ticket_147(): assert_equal(r21.id, s[0].id) # typo: SMALLES - try: + with pytest.raises(TransactionError): s = db.execute_query( "FIND ticket147_Fre* WHICH HAS THE SMALLEST ticket147_ObstacleRadius AND A PROPERTY ( ticket147_BarkleyModelSimulation WHICH HAS THE SMALLES ticket147_TimeStep)" ) - raise AssertionError("This should raise a TransactionError") - except TransactionError: - pass finally: try: @@ -1148,28 +1094,6 @@ def test_ticket_166(): pass -def test_ticket_161(): - - try: - rt = db.RecordType(name="RecordTypeTest") - rt.insert() - - assert_true(rt.is_valid()) - - rt2 = db.RecordType(name="RecordTypeTest") - assert_raises(UniqueNamesError, rt2.insert) - - finally: - try: - rt2.delete() - except BaseException: - pass - try: - rt.delete() - except BaseException: - pass - - def test_ticket_178(): from lxml import etree diff --git a/tests/test_tickets_200.py b/tests/test_tickets_200.py index 19255cc9f3a9cb74468bfd58454f6e2726e0ba40..1b242c865f9020be629a5a86efd0016edeca74fa 100644 --- a/tests/test_tickets_200.py +++ b/tests/test_tickets_200.py @@ -25,13 +25,12 @@ """ from __future__ import print_function, unicode_literals -from nose.tools import (assert_equal, assert_is_none, # @UnresolvedImport - assert_is_not_none, assert_raises, assert_true, - nottest) +from nose.tools import (assert_equal, assert_is_none, assert_is_not_none, + assert_true) from pytest import raises import caosdb as h -from caosdb.common.models import Container, Property, RecordType +from caosdb.common.models import Property, RecordType def setup_module(): @@ -199,7 +198,7 @@ def test_ticket_232(): for i in range(1000): uri.append("longname" + str(i)) - # with raises(h.URITooLongException) as exc_info: + # with raises(h.HTTPURITooLongError) as exc_info: # h.get_connection().retrieve(uri) c = h.Container().extend(uri).retrieve(raise_exception_on_error=False) @@ -327,10 +326,11 @@ def test_ticket_239(): p, value="SimpleRecord3") c = h.Container().extend([rec4]) - assert_raises(h.TransactionError, c.insert) - assert_equal(c[0].get_property( - "SimpleReferenceProperty").get_errors()[0].description, - "Referenced entity does not exist.") + with raises(h.TransactionError) as te: + c.insert() + assert te.value.has_error(h.UnqualifiedPropertiesError) + assert c[0].get_property("SimpleReferenceProperty").get_errors()[ + 0].description == "Referenced entity does not exist." rec3 = h.Record(name="SimpleRecord3").add_parent(rt) c = h.Container().extend([rec3, rec4]).insert() @@ -570,5 +570,9 @@ def test_ticket_233(): e1 = h.Entity("sdlkavhjawriluvyruksvnkuhndb") e2 = h.Entity("ösdlkavhjawriluvyruksvnkuhndb") - assert_raises(h.EntityDoesNotExistError, e1.retrieve) - assert_raises(h.EntityDoesNotExistError, e2.retrieve) + with raises(h.TransactionError) as te: + e1.retrieve() + assert te.value.has_error(h.EntityDoesNotExistError) + with raises(h.TransactionError) as te: + e2.retrieve() + assert te.value.has_error(h.EntityDoesNotExistError) diff --git a/tests/test_tickets_300.py b/tests/test_tickets_300.py index 1b36d343d5b84f3223ad93fc0366ba3535aa70aa..43fbd97f0fc3ea67e23736657d9cac07886fff35 100644 --- a/tests/test_tickets_300.py +++ b/tests/test_tickets_300.py @@ -5,6 +5,8 @@ # # Copyright (C) 2018 Research Group Biomedical Physics, # Max-Planck-Institute for Dynamics and Self-Organization Göttingen +# Copyright (C) 2020 Indiscale GmbH <info@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 @@ -25,12 +27,12 @@ from __future__ import unicode_literals, print_function import caosdb as db -from nose.tools import with_setup, assert_raises as raiz, assert_equal as eq +from pytest import raises def _delete_test_entities(): try: - db.execute_query("FIND Entity WITH id >= 100").delete() + db.execute_query("FIND Test*").delete() except Exception as e: print(e) @@ -43,14 +45,23 @@ def teardown_module(): _delete_test_entities() -@with_setup(_delete_test_entities, _delete_test_entities) +def setup(): + setup_module() + + +def teardown(): + teardown_module() + + def test_ticket_350_insert_with_invalid_ref(): c = db.Container() - e = db.Entity(name="SomeName") - rt1 = db.RecordType(name="RT1") - rt2 = db.RecordType(name="RT2").add_property(name="RT1", value="SomeName") + e = db.Entity(name="TestEnt") + rt1 = db.RecordType(name="TestRT1") + rt2 = db.RecordType(name="TestRT2").add_property( + name="TestRT1", value="TestEnt") c.extend([e, rt1, rt2]) - with raiz(db.TransactionError) as cm: + with raises(db.TransactionError) as cm: c.insert() - eq(cm.exception.errors[0].msg, "There is no such role 'Entity'.") - eq(cm.exception.errors[1].msg, "Entity has unqualified properties.") + assert any( + [x.msg == "There is no such role 'Entity'." for x in cm.value.errors]) + assert cm.value.has_error(db.UnqualifiedPropertiesError) diff --git a/tests/test_version.py b/tests/test_version.py index 784c23b0754ad4f9710ced3930a776af7a2747ee..2b8aafa882832a419fe1b796a703b0b31cb3b766 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -22,7 +22,6 @@ # ** end header # from pytest import mark, raises -from dateutil.parser import parse import caosdb as c @@ -212,10 +211,10 @@ def test_retrieve_relative_to_head(): assert first_version == rt_head.version, "head is first version" # no HEAD~1 before first update - with raises(c.EntityDoesNotExistError) as exc: + with raises(c.TransactionError) as exc: # no head~2 c.Container().retrieve(query=str(rt.id) + "@HEAD~1", sync=False) - + assert exc.value.has_error(c.EntityDoesNotExistError) # update rt.description = "TestDescription4" rt.update() @@ -244,9 +243,10 @@ def test_retrieve_relative_to_head(): assert rt_pre_head.version.successors[0].id == rt_new_head.version.id, ( "successor of head~1 is head") - with raises(c.EntityDoesNotExistError) as exc: + with raises(c.TransactionError) as exc: # no head~2 c.Container().retrieve(query=str(rt.id) + "@HEAD~2", sync=False) + assert exc.value.has_error(c.EntityDoesNotExistError) @mark.xfail(reason="bug fix needed") @@ -263,9 +263,10 @@ def test_bug_cached_delete(): c.execute_query("FIND RecordType TestRT").delete() - with raises(c.EntityDoesNotExistError) as exc: + with raises(c.TransactionError) as exc: c.Container().retrieve(query=str(rt.id) + "@" + old_version, sync=False)[0] + assert exc.value.has_error(c.EntityDoesNotExistError) @mark.xfail(reason=("TODO: What is the desired behavior? " @@ -458,7 +459,7 @@ def test_reference_deleted_in_old_version(): rec.remove_property(ref_rt) rec.update() - with raises(c.EntityDoesNotExistError) as exc: + with raises(c.EmptyUniqueQueryError) as exc: c.execute_query( "FIND RECORD TestRec2 WHICH REFERENCES {}".format( referenced_rec.id), @@ -499,12 +500,13 @@ def test_reference_deleted_in_old_version(): assert old_rec.get_property(p).value == "blablabla" assert old_rec.get_property(ref_rt).value == referenced_id - with raises(c.EntityDoesNotExistError) as exc: + with raises(c.EmptyUniqueQueryError) as exc: c.execute_query("FIND ENTITY WITH ID = {}".format(referenced_id), unique=True) - with raises(c.EntityDoesNotExistError) as exc: + with raises(c.TransactionError) as exc: c.Record(id=referenced_id).retrieve() + assert exc.value.has_error(c.EntityDoesNotExistError) def test_reference_version_head(): diff --git a/tests/test_xmlparsing.py b/tests/test_xmlparsing.py index e387f25404ec8a87d9c0275c2c0c28234f07ecfb..50fbbfc07d37aeda1982c7db5c2fc256826a027c 100644 --- a/tests/test_xmlparsing.py +++ b/tests/test_xmlparsing.py @@ -25,8 +25,10 @@ @author: tf """ +import pytest +@pytest.mark.local_server def test_parse_xml(): from lxml import etree from nose.tools import assert_equal # @UnresolvedImport diff --git a/tox.ini b/tox.ini index babdf47e254755b64599e386c96c708bca2b043c..26c5d1594c48fe755a355a3aee711fd6608c6f97 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,9 @@ [tox] -envlist=py36, py37, py38 +envlist=py36, py37, py38, py39 skip_missing_interpreters = true [testenv] setenv = PASSWORD_STORE_DIR = {env:HOME}/.password-store +passenv = PYCAOSDBINI deps=pytest nose pytest-cov