diff --git a/.dockerignore b/.dockerignore index 1a384c6bd..79b41de55 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,6 +5,7 @@ docker !docker/actinia-core-dev/actinia.cfg !docker/actinia-core-dev/endpoints.csv !docker/actinia-core-tests/actinia-test.cfg +!docker/actinia-core-tests/actinia-test-noauth.cfg .github .travis .travis.yml diff --git a/.flake8 b/.flake8 index d4ef350e3..b3da9504c 100644 --- a/.flake8 +++ b/.flake8 @@ -3,6 +3,7 @@ # E402 module level import not at top of file # E501 line too long (80 > 79 characters) # F401 '.health_check.health_check' imported but unused +# F811 redefinition of unused 'verify_password' from line 55 # F821 undefined name 'QFile' # W605 invalid escape sequence '\<' @@ -30,6 +31,7 @@ per-file-ignores = ./src/actinia_core/core/interim_results.py: W605 ./src/actinia_core/core/list_grass_modules.py: F821 ./src/actinia_core/testsuite.py: F401 + ./src/actinia_core/rest/base/user_auth.py: F811 ./src/actinia_core/rest/ephemeral_processing.py: W605 ./src/actinia_core/processing/actinia_processing/ephemeral_renderer_base/*: E501 ./src/actinia_core/processing/actinia_processing/ephemeral_with_export/raster_export.py: E501 diff --git a/.gitignore b/.gitignore index 6de62a88e..a5668ad23 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ docker/redis_queue_data/dump.rdb !docker/actinia-core-dev/actinia.cfg !docker/actinia-core-dev/endpoints.csv !docker/actinia-core-tests/actinia-test.cfg +!docker/actinia-core-tests/actinia-test-noauth.cfg diff --git a/Makefile b/Makefile index 961cc499d..24448f1f5 100644 --- a/Makefile +++ b/Makefile @@ -18,5 +18,8 @@ unittest: devtest: sh ./tests_with_redis.sh dev +noauthtest: + sh ./tests_with_redis.sh noauth + integrationtest: sh ./tests_with_redis.sh integrationtest diff --git a/docker/actinia-core-tests/Dockerfile b/docker/actinia-core-tests/Dockerfile index c0e8cf9ba..ebf731eac 100644 --- a/docker/actinia-core-tests/Dockerfile +++ b/docker/actinia-core-tests/Dockerfile @@ -40,6 +40,7 @@ RUN grass --tmp-location EPSG:4326 --exec g.extension -s \ # copy needed files and configs for test COPY docker/actinia-core-alpine/actinia.cfg /etc/default/actinia COPY docker/actinia-core-tests/actinia-test.cfg /etc/default/actinia_test +COPY docker/actinia-core-tests/actinia-test-noauth.cfg /etc/default/actinia_test_noauth RUN pip3 install pytest pytest-cov diff --git a/docker/actinia-core-tests/actinia-test-noauth.cfg b/docker/actinia-core-tests/actinia-test-noauth.cfg new file mode 100644 index 000000000..3d8b88483 --- /dev/null +++ b/docker/actinia-core-tests/actinia-test-noauth.cfg @@ -0,0 +1,26 @@ +[GRASS] +grass_database = /actinia_core/grassdb +grass_user_database = /actinia_core/userdata +grass_tmp_database = /actinia_core/workspace/temp_db +grass_resource_dir = /actinia_core/resources + +[API] +force_https_urls = True +authentication = False + +[LIMITS] +max_cell_limit = 22500000 +process_time_limt = 60 +process_num_limit = 20 + +[REDIS] +worker_logfile = /actinia_core/workspace/tmp/actinia_worker_test.log +redis_server_url = localhost +redis_server_port = 6379 + +[LOGGING] +log_level = 1 + +[MISC] +tmp_workdir = /actinia_core/workspace/tmp +download_cache = /actinia_core/workspace/download_cache diff --git a/docker/actinia-core-tests/actinia-test.cfg b/docker/actinia-core-tests/actinia-test.cfg index 004a9c9f2..472081fb0 100644 --- a/docker/actinia-core-tests/actinia-test.cfg +++ b/docker/actinia-core-tests/actinia-test.cfg @@ -1,43 +1,25 @@ [GRASS] -grass_gis_start_script = /usr/local/bin/grass grass_database = /actinia_core/grassdb grass_user_database = /actinia_core/userdata grass_tmp_database = /actinia_core/workspace/temp_db grass_resource_dir = /actinia_core/resources -grass_addon_path = /root/.grass8/addons/ -grass_gis_base = /usr/local/grass -grass_modules_xml_path = /usr/local/grass/gui/wxpython/xml/module_items.xml -grass_default_location = nc_spm_08 [API] -plugins = [] force_https_urls = True [LIMITS] max_cell_limit = 22500000 process_time_limt = 60 process_num_limit = 20 -number_of_workers = 3 [REDIS] +worker_logfile = /actinia_core/workspace/tmp/actinia_worker_test.log redis_server_url = localhost redis_server_port = 6379 -redis_queue_server_url = localhost -redis_queue_server_port = 6379 -worker_queue_name = actinia_job -worker_logfile = /actinia_core/workspace/tmp/actinia_worker_test.log [LOGGING] -log_interface = fluentd -log_fluent_host = fluentd -log_fluent_port = 24224 log_level = 1 [MISC] tmp_workdir = /actinia_core/workspace/tmp download_cache = /actinia_core/workspace/download_cache -secret_key = token_signing_key_changeme - -[MANAGEMENT] -default_user = user -default_user_group = group diff --git a/pyproject.toml b/pyproject.toml index 91b85376b..35ab53499 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,11 +98,12 @@ API_Docs = "https://redocly.github.io/redoc/?url=https://actinia.mundialis.de/la [tool.pytest.ini_options] minversion = "6.0" -addopts = "--cov actinia_core --cov-report term-missing --verbose --tb=line -x" +addopts = "--cov actinia_core --cov-report term-missing --verbose --tb=line -x -s" testpaths = [ "tests", ] markers = [ "dev: test current in development", "unittest: completely independent test", + "noauth: tests for actinia without authentication", ] diff --git a/src/actinia_core/core/common/app.py b/src/actinia_core/core/common/app.py index 60f48e123..7a6f37d8e 100644 --- a/src/actinia_core/core/common/app.py +++ b/src/actinia_core/core/common/app.py @@ -4,7 +4,7 @@ # performance processing of geographical data that uses GRASS GIS for # computational tasks. For details, see https://actinia.mundialis.de/ # -# Copyright (c) 2016-2018 Sören Gebbert and mundialis GmbH & Co. KG +# Copyright (c) 2016-2023 Sören Gebbert and mundialis GmbH & Co. KG # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -116,9 +116,9 @@ from actinia_api import API_VERSION, URL_PREFIX __license__ = "GPLv3" -__author__ = "Sören Gebbert, Julia Haas" +__author__ = "Sören Gebbert, Julia Haas, Anika Weinmann" __copyright__ = ( - "Copyright 2016-2021, Sören Gebbert and mundialis GmbH & Co. KG" + "Copyright 2016-2023, Sören Gebbert and mundialis GmbH & Co. KG" ) __maintainer__ = "mundialis" @@ -165,7 +165,7 @@ } } ] -else: +elif global_config.AUTHENTICATION: # Set the security definition in an unconventional way flask_api._swagger_object["securityDefinitions"] = { "basicAuth": {"type": "basic"} @@ -173,3 +173,6 @@ flask_api._swagger_object["security"] = [{"basicAuth": []}] auth = HTTPBasicAuth() +else: + # No authentication + auth = HTTPBasicAuth() diff --git a/src/actinia_core/core/common/config.py b/src/actinia_core/core/common/config.py index 300e19bf6..cf0dae6f9 100644 --- a/src/actinia_core/core/common/config.py +++ b/src/actinia_core/core/common/config.py @@ -4,7 +4,7 @@ # performance processing of geographical data that uses GRASS GIS for # computational tasks. For details, see https://actinia.mundialis.de/ # -# Copyright (c) 2016-2018 Sören Gebbert and mundialis GmbH & Co. KG +# Copyright (c) 2016-2023 Sören Gebbert and mundialis GmbH & Co. KG # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -34,7 +34,7 @@ __license__ = "GPLv3" __author__ = "Sören Gebbert, Anika Weinmann" __copyright__ = ( - "Copyright 2016-2022, Sören Gebbert and mundialis GmbH & Co. KG" + "Copyright 2016-2023, Sören Gebbert and mundialis GmbH & Co. KG" ) __maintainer__ = "mundialis GmbH & Co. KG" @@ -320,6 +320,8 @@ def __init__(self): self.PLUGINS = [] # ENDPOINTS_CONFIG: configuration csv file for endpoints self.ENDPOINTS_CONFIG = None + # AUTHENTICATION: If set False no authentication is needed + self.AUTHENTICATION = True """ KEYCLOAK: has only to be set if keycloak server is configured with @@ -560,6 +562,7 @@ def write(self, path=DEFAULT_CONFIG_PATH): config.set("API", "FORCE_HTTPS_URLS", str(self.FORCE_HTTPS_URLS)) config.set("API", "PLUGINS", str(self.PLUGINS)) config.set("API", "ENDPOINTS_CONFIG", str(self.ENDPOINTS_CONFIG)) + config.set("API", "AUTHENTICATION", str(self.AUTHENTICATION)) config.add_section("KEYCLOAK") config.set( @@ -810,6 +813,10 @@ def read(self, path=DEFAULT_CONFIG_PATH): self.ENDPOINTS_CONFIG = config.get( "API", "ENDPOINTS_CONFIG" ) + if config.has_option("API", "AUTHENTICATION"): + self.AUTHENTICATION = config.getboolean( + "API", "AUTHENTICATION" + ) if config.has_section("KEYCLOAK"): if config.has_option("KEYCLOAK", "CONFIG_PATH"): diff --git a/src/actinia_core/core/common/user_noauth.py b/src/actinia_core/core/common/user_noauth.py new file mode 100644 index 000000000..7631a0fb6 --- /dev/null +++ b/src/actinia_core/core/common/user_noauth.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +####### +# actinia-core - an open source REST API for scalable, distributed, high +# performance processing of geographical data that uses GRASS GIS for +# computational tasks. For details, see https://actinia.mundialis.de/ +# +# Copyright (c) 2023 mundialis GmbH & Co. KG +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +####### + +""" +User management for no authentication +""" + +# from passlib.apps import custom_app_context as pwd_context +# import jwt +# from datetime import datetime, timezone, timedelta +from actinia_core.core.common.config import global_config +from actinia_core.core.redis_user import redis_user_interface +from actinia_core.core.common.user import ActiniaUser + + +__author__ = "Anika Weinmann" +__copyright__ = "Copyright 2023, mundialis GmbH & Co. KG" +__maintainer__ = "mundialis GmbH & Co. KG" + + +class ActiniaUserNoAuth(ActiniaUser): + """ + The Actinia Core user management class for no authentication + """ + + db = redis_user_interface + + def __init__(self): + """Constructor + Initialize and create a user object for no authentication. + """ + self.user_id = global_config.DEFAULT_USER + self.user_group = global_config.DEFAULT_USER_GROUP + self.password_hash = None + self.user_role = "superadmin" + self.permissions = None + self.cell_limit = global_config.MAX_CELL_LIMIT + self.accessible_datasets = { + "nc_spm_08": ["PERMANENT", "user1", "landsat"], + "ECAD": ["PERMANENT"], + "latlong_wgs84": ["PERMANENT"], + } + self.accessible_modules = global_config.MODULE_ALLOW_LIST + self.process_num_limit = global_config.PROCESS_NUM_LIMIT + self.process_time_limit = global_config.PROCESS_TIME_LIMT + + @staticmethod + def create_user(): + """Create a new user object for no authentication and initialize it + + Returns: + actinia_core_api.common.user_noauth.ActiniaUserNoAuth: + A new user object in case of success, or None in case of failure + """ + user = ActiniaUserNoAuth() + user.hash_password("") + + if user.commit() is True: + return user + return None diff --git a/src/actinia_core/rest/base/user_auth.py b/src/actinia_core/rest/base/user_auth.py index a12e58f75..668069265 100644 --- a/src/actinia_core/rest/base/user_auth.py +++ b/src/actinia_core/rest/base/user_auth.py @@ -5,7 +5,7 @@ # performance processing of geographical data that uses GRASS GIS for # computational tasks. For details, see https://actinia.mundialis.de/ # -# Copyright (c) 2016-2018 Sören Gebbert and mundialis GmbH & Co. KG +# Copyright (c) 2016-2023 Sören Gebbert and mundialis GmbH & Co. KG # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -33,16 +33,29 @@ from actinia_core.core.common.app import auth from actinia_core.core.common.keycloak_user import ActiniaKeycloakUser from actinia_core.core.common.user import ActiniaUser +from actinia_core.core.common.user_noauth import ActiniaUserNoAuth from actinia_core.core.messages_logger import MessageLogger __license__ = "GPLv3" -__author__ = "Sören Gebbert, Julia Haas" +__author__ = "Sören Gebbert, Julia Haas, Anika Weinmann" __copyright__ = ( - "Copyright 2016-2022, Sören Gebbert and mundialis GmbH & Co. KG" + "Copyright 2016-2023, Sören Gebbert and mundialis GmbH & Co. KG" ) __maintainer__ = "mundialis" +if not global_config.AUTHENTICATION: + # No authentication + @auth.login_required + def login_required(a, b): + return False + + @auth.verify_password + def verify_password(username_or_token, password): + g.user = ActiniaUserNoAuth.create_user() + return True + + if global_config.KEYCLOAK_CONFIG_PATH: @auth.verify_token @@ -63,7 +76,7 @@ def verify_token(token): return True -if global_config.KEYCLOAK_CONFIG_PATH is None: +if global_config.KEYCLOAK_CONFIG_PATH is None and global_config.AUTHENTICATION: @auth.verify_password def verify_password(username_or_token, password): diff --git a/tests/test_common_base.py b/tests/test_common_base.py index a99c881a5..839eeeadd 100644 --- a/tests/test_common_base.py +++ b/tests/test_common_base.py @@ -103,7 +103,6 @@ class CommonTestCaseBase(unittest.TestCase): def setUpClass(cls): if custom_actinia_cfg is not False: global_config.read(custom_actinia_cfg) - print(global_config) else: global_config.REDIS_SERVER_URL = "localhost" global_config.REDIS_SERVER_PORT = 7000 diff --git a/tests/test_noauth.py b/tests/test_noauth.py new file mode 100644 index 000000000..c9a010029 --- /dev/null +++ b/tests/test_noauth.py @@ -0,0 +1,360 @@ +# -*- coding: utf-8 -*- +####### +# actinia-core - an open source REST API for scalable, distributed, high +# performance processing of geographical data that uses GRASS GIS for +# computational tasks. For details, see https://actinia.mundialis.de/ +# +# Copyright (c) 2023 Sören Gebbert and mundialis GmbH & Co. KG +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +####### + +""" +Tests: Location test case +""" +import os +from flask.json import dumps as json_dumps +from flask.json import loads as json_loads +import pytest +import unittest +from actinia_core.core.common.app import flask_app +from actinia_core.core.common.config import global_config +from actinia_core.core.common import redis_interface +from actinia_core.core.common.process_queue import create_process_queue +from actinia_core.testsuite import ( + ActiniaRequests, + ActiniaTestCaseBase, + URL_PREFIX, +) + +__license__ = "GPLv3" +__author__ = "Anika Weinmann" +__copyright__ = "Copyright 2023, mundialis GmbH & Co. KG" +__maintainer__ = "mundialis GmbH & Co. KG" +__email__ = "info@mundialis.de" + + +# Set this variable to use a actinia config file in a docker container +if "ACTINIA_CUSTOM_TEST_CFG" in os.environ: + custom_actinia_cfg = str(os.environ["ACTINIA_CUSTOM_TEST_CFG"]) + +PC = { + "version": 1, + "list": [ + { + "id": "1", + "module": "g.region", + "inputs": [{"param": "raster", "value": "elevation@PERMANENT"}], + "flags": "p", + }, + { + "id": "2", + "module": "r.colors.out_sld", + "inputs": [ + {"param": "map", "value": "elevation@PERMANENT"}, + {"param": "style_name", "value": "elevation"}, + ], + "stdout": {"id": "sld", "format": "list", "delimiter": "\n"}, + }, + { + "id": "3", + "module": "r.mapcalc", + "inputs": [{"param": "expression", "value": "baum = 5"}], + }, + { + "id": "4", + "module": "r.info", + "inputs": [{"param": "map", "value": "elevation@PERMANENT"}], + "flags": "g", + "stdout": {"id": "r_info_map1", "format": "kv", "delimiter": "="}, + }, + { + "id": "5", + "module": "g.list", + "inputs": [{"param": "type", "value": "raster"}], + }, + { + "id": "6", + "module": "r.info", + "inputs": [{"param": "map", "value": "baum"}], + "flags": "g", + "stdout": {"id": "r_info_map2", "format": "kv", "delimiter": "="}, + }, + ], +} + + +class ActiniaWithoutAuthentication(ActiniaTestCaseBase): + """Test base class to test actinia without autentication""" + + server_test = False + + if "ACTINIA_SERVER_TEST" in os.environ: + server_test = bool(os.environ["ACTINIA_SERVER_TEST"]) + + @classmethod + def setUpClass(cls): + if cls.server_test is False and cls.custom_actinia_cfg is False: + global_config.REDIS_SERVER_SERVER = "localhost" + global_config.REDIS_SERVER_PORT = 7000 + global_config.GRASS_RESOURCE_DIR = "/tmp" + global_config.DOWNLOAD_CACHE = "/tmp/download_cache" + global_config.REDIS_QUEUE_SERVER_URL = "localhost" + global_config.REDIS_QUEUE_SERVER_PORT = 6379 + global_config.NUMBER_OF_WORKERS = 3 + + # If the custom_actinia_cfg variable is set, then the actinia config + # file will be read to configure Redis queue + if cls.server_test is False and cls.custom_actinia_cfg is not False: + global_config.read(cls.custom_actinia_cfg) + # global_config.read(cls.custom_actinia_cfg) + # Start the redis interface + redis_args = ( + global_config.REDIS_SERVER_URL, + global_config.REDIS_SERVER_PORT, + ) + if ( + global_config.REDIS_SERVER_PW + and global_config.REDIS_SERVER_PW is not None + ): + redis_args = (*redis_args, global_config.REDIS_SERVER_PW) + + redis_interface.connect(*redis_args) + + # Process queue + create_process_queue(config=global_config) + + @classmethod + def tearDownClass(cls): + if cls.server_test is False: + redis_interface.disconnect() + + def setUp(self): + # We need to set the application context + self.app_context = flask_app.app_context() + self.app_context.push() + + # Check if the local or server site tests should be performed + if self.server_test is False: + flask_app.config["TESTING"] = True + + self.server = flask_app.test_client() + else: + self.server = ActiniaRequests() + + def tearDown(self): + self.app_context.pop() + + def waitAsyncStatusAssertHTTP( + self, + response, + http_status=200, + status="finished", + message_check=None, + ): + """Poll the status of a resource and assert its finished HTTP status + + The response will be checked if the resource was accepted. Hence it + must always be HTTP 200 status. + + The status URL from the response is then polled until status: finished, + error or terminated. + The result of the poll can be checked against its HTTP status and its + actinia status message. + + Args: + response: The accept response + http_status (int): The HTTP status that should be checked + status (str): The return status of the response + message_check (str): A string that must be in the message field + + Returns: response + + """ + resp_data = super().waitAsyncStatusAssertHTTP( + response, None, http_status, status, message_check + ) + return resp_data + + +@pytest.mark.noauth +class TestActiniaWithoutAuthentication(ActiniaWithoutAuthentication): + def test_01_version(self): + """Test version endpoint""" + rv = self.server.get(f"{URL_PREFIX}/version") + self.assertEqual( + rv.status_code, + 200, + "HTML status code is wrong %i" % rv.status_code, + ) + data = json_loads(rv.data) + self.assertIn("api_version", data) + self.assertIn("version", data) + self.assertIn("grass_version", data) + + def test_02_list_locations(self): + """Test list location endpoint""" + rv = self.server.get(f"{URL_PREFIX}/locations") + self.assertEqual( + rv.status_code, + 200, + "HTML status code is wrong %i" % rv.status_code, + ) + self.assertEqual( + rv.mimetype, "application/json", "Wrong mimetype %s" % rv.mimetype + ) + self.assertIn( + "locations", json_loads(rv.data), "No locations in response" + ) + locations = json_loads(rv.data)["locations"] + self.assertIn("nc_spm_08", locations, "Wrong location listed") + + def test_03_processing_ephemeral(self): + """Test job resumption with processing_async endpoint and stdout""" + endpoint = "/locations/nc_spm_08/processing_async" + rv = self.server.post( + f"{URL_PREFIX}{endpoint}", + data=json_dumps(PC), + content_type="application/json", + ) + resp = self.waitAsyncStatusAssertHTTP( + rv, + http_status=200, + status="finished", + ) + self.compare_stdout(resp) + + def test_04_processing_persistent(self): + """Test job resumption with persistent processing_async endpoint and + stdout + """ + endpoint = "/locations/nc_spm_08/mapsets/test/processing_async" + rv = self.server.post( + f"{URL_PREFIX}{endpoint}", + data=json_dumps(PC), + content_type="application/json", + ) + resp = self.waitAsyncStatusAssertHTTP( + rv, + http_status=200, + status="finished", + ) + self.compare_stdout(resp) + # check processing mapset + rv2 = self.server.get(f"{URL_PREFIX}/locations/nc_spm_08/mapsets") + self.assertEqual( + rv2.status_code, + 200, + f"HTML status code is wrong {rv2.status_code}", + ) + data = json_loads(rv2.data) + self.assertIn( + "test", data["process_results"], "Mapset 'test' does not exists" + ) + # check created raster + rv3 = self.server.get( + f"{URL_PREFIX}/locations/nc_spm_08/mapsets/test/raster_layers" + ) + self.assertEqual( + rv3.status_code, + 200, + f"HTML status code is wrong {rv3.status_code}", + ) + data = json_loads(rv3.data) + self.assertIn( + "baum", data["process_results"], "Raster 'baum' does not exists" + ) + # delete test mapset + self.admin_auth_header = None + self.delete_mapset("test", "nc_spm_08") + rv4 = self.server.get(f"{URL_PREFIX}/locations/nc_spm_08/mapsets") + self.assertEqual( + rv4.status_code, + 200, + f"HTML status code is wrong {rv4.status_code}", + ) + data = json_loads(rv4.data) + self.assertNotIn( + "test", data["process_results"], "Mapset 'test' exists" + ) + + def compare_stdout(self, resp): + proc_results = resp["process_results"] + self.assertIn( + "sld", proc_results, "'sld' not saved in process results" + ) + self.assertIn( + "r_info_map1", + proc_results, + "'r_info_map1' not saved in process results", + ) + self.assertIn( + "r_info_map2", + proc_results, + "'r_info_map2' not saved in process results", + ) + self.assertIsInstance( + proc_results["sld"], list, "'sld' result is not of type list" + ) + self.assertIsInstance( + proc_results["r_info_map1"], + dict, + "'r_info_map1' result is not of type dict", + ) + self.assertIsInstance( + proc_results["r_info_map2"], + dict, + "'r_info_map2' result is not of type dict", + ) + r_info_map1 = { + "cells": "2025000", + "cols": "1500", + "datatype": "FCELL", + "east": "645000", + "ewres": "10", + "ncats": "255", + "north": "228500", + "nsres": "10", + "rows": "1350", + "south": "215000", + "west": "630000", + } + self.assertEqual( + proc_results["r_info_map1"], + r_info_map1, + "'r_info_map1' is not equal to the region", + ) + r_info_map2 = { + "cells": "2025000", + "cols": "1500", + "datatype": "CELL", + "east": "645000", + "ewres": "10", + "ncats": "0", + "north": "228500", + "nsres": "10", + "rows": "1350", + "south": "215000", + "west": "630000", + } + self.assertEqual( + proc_results["r_info_map2"], + r_info_map2, + "'r_info_map2' is not equal to the region", + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests_with_redis.sh b/tests_with_redis.sh index 0e390dcb1..42e4b668d 100644 --- a/tests_with_redis.sh +++ b/tests_with_redis.sh @@ -1,5 +1,14 @@ #!/usr/bin/env sh +run_tests_noauth (){ + # change config run tests and change config bag + mv ${ACTINIA_CUSTOM_TEST_CFG} ${ACTINIA_CUSTOM_TEST_CFG}_tmp + cp /etc/default/actinia_test_noauth ${ACTINIA_CUSTOM_TEST_CFG} + pytest -m 'noauth' + mv ${ACTINIA_CUSTOM_TEST_CFG}_tmp ${ACTINIA_CUSTOM_TEST_CFG} +} + + # start redis server redis-server & sleep 1 @@ -13,19 +22,32 @@ sleep 10 echo $ACTINIA_CUSTOM_TEST_CFG echo $DEFAULT_CONFIG_PATH +TEST_RES=1 if [ "$1" == "dev" ] then echo "Executing only 'dev' tests ..." pytest -m 'dev' + TEST_RES=$? elif [ "$1" == "integrationtest" ] then - pytest -m 'not unittest' + pytest -m 'not unittest and not noauth' + TEST_RES=$? + if [ ${TEST_RES} -eq 0 ] + then + run_tests_noauth + TEST_RES=$? + else + echo "Skipping tests without authentication since other tests failed" + fi +elif [ "$1" == "noauth" ] +then + run_tests_noauth + TEST_RES=$? else pytest + TEST_RES=$? fi -TEST_RES=$? - # stop redis server redis-cli shutdown