From 3011470bd757f01d4a463ad75bad8df5159564c3 Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Sun, 21 Feb 2021 14:18:44 +0000
Subject: [PATCH] add more tests to the "local_server" collection

and handle missing configuration for local tests
---
 pytest.ini                          |  4 ++++
 tests/test_authentication.py        |  6 ++++++
 tests/test_datetime.py              |  9 +++++++++
 tests/test_file.py                  |  8 +++++++-
 tests/test_issues_server.py         |  1 +
 tests/test_query.py                 |  4 ++++
 tests/test_query_version.py         |  1 +
 tests/test_server_side_scripting.py | 27 ++++++++++++++++++++-------
 tests/test_tickets.py               |  1 +
 tests/test_xmlparsing.py            |  2 ++
 tox.ini                             |  3 ++-
 11 files changed, 57 insertions(+), 9 deletions(-)
 create mode 100644 pytest.ini

diff --git a/pytest.ini b/pytest.ini
new file mode 100644
index 0000000..529a96a
--- /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_authentication.py b/tests/test_authentication.py
index e064b59..ef0657c 100644
--- a/tests/test_authentication.py
+++ b/tests/test_authentication.py
@@ -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,6 +195,7 @@ 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"]')
@@ -217,6 +220,7 @@ def test_one_time_token_invalid():
         "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",
@@ -239,6 +243,7 @@ def test_one_time_token_expired():
         "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")
 
@@ -293,6 +298,7 @@ def test_one_time_token_3_attempts():
         "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_datetime.py b/tests/test_datetime.py
index cda35a1..b6254d5 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_file.py b/tests/test_file.py
index edf45da..354fee1 100644
--- a/tests/test_file.py
+++ b/tests/test_file.py
@@ -33,7 +33,7 @@ from random import randint
 from sys import maxsize as maxint
 
 from lxml import etree
-from pytest import raises
+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
@@ -88,6 +88,7 @@ def test_file_with_space():
     qfile.download("test2.dat")
 
 
+@mark.local_server
 def test_pickup_file():
     d = models.DropOffBox()
     d.sync()
@@ -107,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()
@@ -133,6 +135,7 @@ def test_pickup_folder():
         file_.insert()
 
 
+@mark.local_server
 def test_file4():
     try:
         d = models.DropOffBox()
@@ -489,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/"
@@ -565,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
@@ -664,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 7b3744f..b5c16cb 100644
--- a/tests/test_issues_server.py
+++ b/tests/test_issues_server.py
@@ -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_query.py b/tests/test_query.py
index 4e98803..eccd303 100644
--- a/tests/test_query.py
+++ b/tests/test_query.py
@@ -208,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())
@@ -298,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())
@@ -382,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())
@@ -864,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()
diff --git a/tests/test_query_version.py b/tests/test_query_version.py
index 0b152ee..860bc68 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_server_side_scripting.py b/tests/test_server_side_scripting.py
index d61cc5f..96172dd 100644
--- a/tests/test_server_side_scripting.py
+++ b/tests/test_server_side_scripting.py
@@ -27,7 +27,8 @@ 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
@@ -41,12 +42,19 @@ 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 = ""
@@ -113,6 +121,7 @@ def test_call_script_non_existing():
         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)
@@ -123,6 +132,7 @@ def test_call_script_not_executable():
     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)
@@ -136,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)
@@ -277,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"]
 
@@ -352,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)
diff --git a/tests/test_tickets.py b/tests/test_tickets.py
index 58bbe15..cdaee95 100644
--- a/tests/test_tickets.py
+++ b/tests/test_tickets.py
@@ -715,6 +715,7 @@ def test_ticket_143():
             pass
 
 
+@pytest.mark.slow
 def test_ticket_147():
 
     try:
diff --git a/tests/test_xmlparsing.py b/tests/test_xmlparsing.py
index e387f25..50fbbfc 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 babdf47..26c5d15 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
-- 
GitLab