Skip to content

Commit

Permalink
Merge pull request #684 from gschwind/pr-sanitize-tests
Browse files Browse the repository at this point in the history
Sanitize tests suite
  • Loading branch information
cehbrecht authored Oct 30, 2023
2 parents a704cd3 + 0f6a42b commit 5304dae
Show file tree
Hide file tree
Showing 31 changed files with 530 additions and 374 deletions.
87 changes: 76 additions & 11 deletions default-sample.cfg
Original file line number Diff line number Diff line change
@@ -1,52 +1,117 @@
# Configuration file sample
#
# Comment line with leading '#' to fallback to the hardcoded default value
#
# The configuration is load in this order:
# - First the hardcoded value are loaded
# - If no configuration file is provided in wsgi script, the first file that exist will be loaded:
# * on Unix/Linux System:
# - `/etc/pywps.cfg`
# - `$HOME/.pywps.cfg`
# * on Windows:
# - `pywps\\etc\\default.cfg`
# - Then if PYWPS_CFG environment variable is set, this file will be loaded
#
# Last loaded file override setting from the previous one.


[metadata:main]
# Setup the title in GetCapabilities
identification_title=PyWPS Demo server
identification_abstract=PyWPS testing and development server. Do NOT use this server in production environement. You shall setup PyWPS as WSGI application for production. Please refer documentation for further detials.
# Setup the abstract in GetCapabilities
identification_abstract=PyWPS testing and development server. Do NOT use this server in production environment. You shall setup PyWPS as WSGI application for production. Please refer documentation for further detials.
# Setup the keywords in GetCapabilities
identification_keywords=WPS,GRASS,PyWPS, Demo, Dev
identification_keywords_type=theme
# Setup the fees in GetCapabilities
identification_fees=None
# Setup the AccessConstraints in GetCapabilities
identification_accessconstraints=None
provider_name=PyWPS Developement team
provider_url=https://pywps.org/'
# Setup provider name in GetCapabilities
provider_name=PyWPS Development team
# Setup provider URL (informative) in GetCapabilities
provider_url=https://pywps.org/

# Setup Contacts information for GetCapabilities (informative)
contact_name=Your Name
contact_position=Developer
contact_address=My Street
contact_city=My City
contact_stateorprovince=None
contact_postalcode=000 00
contact_country=World, Internet
contact_phone=+00 00 11 22 33
contact_fax=+00 99 88 77 66
contact_email=info@yourdomain.org
contact_phone=+xx-xxx-xxx-xxxx
contact_fax=+xx-xxx-xxx-xxxx
contact_email=contact@yourdomain.org
contact_url=https://pywps.org
contact_hours=8:00-20:00UTC
contact_instructions=Knock on the door
contact_role=pointOfContact

[server]
encoding=utf-8
language=en-US
url=http://localhost:5000/wps
maxsingleinputsize=1mb
maxrequestsize=3mb
url=http://localhost:5000/wps
outputurl=http://localhost:5000/outputs/
outputpath=outputs
workdir=workdir
maxprocesses=10
maxprocesses=30
parallelprocesses=2
storagetype=file

# hardcoded default : tempfile.gettempdir()
#temp_path=/tmp

processes_path=
# list of allowed input paths (file url input) seperated by ':'
allowedinputpaths=

# hardcoded default : tempfile.gettempdir()
#workdir=

# If this flag is enabled it will set the HOME environment for each process to
# its current workdir (a temp folder).
sethomedir=false

# If this flag is true PyWPS will remove the process temporary workdir after
# process has finished.
cleantempdir=true

storagetype=file

# File storage outputs can be copied, moved or linked from the workdir to the
# output folder.
# Allowed functions: "copy", "move", "link" (hardcoded default "copy")
storage_copy_function=copy

# Handles the default mimetype for requests.
# valid options: "text/xml", "application/json"
default_mimetype=text/xml

# Default indentation used for json data responses.
json_indent=2

[processing]
mode=default

# hardcoded default: os.path.dirname(os.path.realpath(sys.argv[0]))
#path=

# https://github.com/natefoo/slurm-drmaa
drmaa_native_specification=

[logging]
level=INFO
file=logs/pywps.log
database=sqlite:///logs/pywps-logs.sqlite3
database=sqlite:///:memory:
format=%(asctime)s] [%(levelname)s] file=%(pathname)s line=%(lineno)s module=%(module)s function=%(funcName)s %(message)s
prefix=pywps_

[grass]
gisbase=/usr/local/grass-7.3.svn/

[s3]
bucket=my-org-wps
region=us-east-1
Expand Down
4 changes: 4 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pytest]
addopts = --import-mode=importlib
pythonpath = tests
testpaths = tests
52 changes: 23 additions & 29 deletions pywps/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,60 +88,40 @@ def get_config_value(section, option, default_value=''):
return value


def load_configuration(cfgfiles=None):
"""Load PyWPS configuration from configuration files.
The later configuration file in the array overwrites configuration
from the first.
:param cfgfiles: list of configuration files
"""
def load_hardcoded_configuration():
"""Load PyWPS hardcoded configuration."""

global CONFIG

LOGGER.info('loading configuration')
LOGGER.debug('loading harcoded configuration')
CONFIG = configparser.ConfigParser(os.environ, interpolation=EnvInterpolation())

LOGGER.debug('setting default values')
tmpdir = tempfile.gettempdir()

CONFIG.add_section('server')
CONFIG.set('server', 'encoding', 'utf-8')
CONFIG.set('server', 'language', 'en-US')
CONFIG.set('server', 'url', 'http://localhost/wps')
CONFIG.set('server', 'maxprocesses', '30')
CONFIG.set('server', 'maxsingleinputsize', '1mb')
CONFIG.set('server', 'maxrequestsize', '3mb')
CONFIG.set('server', 'temp_path', tempfile.gettempdir())
CONFIG.set('server', 'temp_path', tmpdir)
CONFIG.set('server', 'processes_path', '')
outputpath = tempfile.gettempdir()
CONFIG.set('server', 'outputurl', file_uri(outputpath))
CONFIG.set('server', 'outputpath', outputpath)
# list of allowed input paths (file url input) seperated by ':'
CONFIG.set('server', 'outputurl', file_uri(tmpdir))
CONFIG.set('server', 'outputpath', tmpdir)
CONFIG.set('server', 'allowedinputpaths', '')
CONFIG.set('server', 'workdir', tempfile.gettempdir())
CONFIG.set('server', 'workdir', tmpdir)
CONFIG.set('server', 'parallelprocesses', '2')
# If this flag is enabled it will set the HOME environment
# for each process to its current workdir (a temp folder).
CONFIG.set('server', 'sethomedir', 'false')
# If this flag is enabled PyWPS will remove the process temporary workdir
# after process has finished.
CONFIG.set('server', 'cleantempdir', 'true')
CONFIG.set('server', 'storagetype', 'file')
# File storage outputs can be copied, moved or linked
# from the workdir to the output folder.
# Allowed functions: "copy", "move", "link" (default "copy")
CONFIG.set('server', 'storage_copy_function', 'copy')

# handles the default mimetype for requests.
# available options: "text/xml", "application/json"
CONFIG.set("server", "default_mimetype", "text/xml")

# default json indentation for responses.
CONFIG.set("server", "json_indent", "2")

CONFIG.add_section('processing')
CONFIG.set('processing', 'mode', 'default')
CONFIG.set('processing', 'path', os.path.dirname(os.path.realpath(sys.argv[0])))
# https://github.com/natefoo/slurm-drmaa
CONFIG.set('processing', 'drmaa_native_specification', '')

CONFIG.add_section('logging')
Expand Down Expand Up @@ -185,6 +165,20 @@ def load_configuration(cfgfiles=None):
CONFIG.set('s3', 'encrypt', 'false')
CONFIG.set('s3', 'region', '')


def load_configuration(cfgfiles=None):
"""Load PyWPS configuration from configuration files.
The later configuration file in the array overwrites configuration
from the first.
:param cfgfiles: list of configuration files
"""

global CONFIG

load_hardcoded_configuration()

if not cfgfiles:
cfgfiles = _get_default_config_files_location()

Expand Down
3 changes: 0 additions & 3 deletions pywps/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,3 @@ def assert_wps_version(response, version="1.0.0"):
'/ows:ServiceTypeVersion')
found_version = elem[0].text
assert version == found_version
tmp = Path(tempfile.mkdtemp())
with open(tmp / "out.xml", "wb") as out:
out.writelines(response.response)
44 changes: 22 additions & 22 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,28 @@
import configparser
import pywps.configuration as config

from tests import test_capabilities
from tests import test_configuration
from tests import test_describe
from tests import test_execute
from tests import test_exceptions
from tests import test_inout
from tests import test_literaltypes
from tests import validator
from tests import test_ows
from tests import test_formats
from tests import test_dblog
from tests import test_wpsrequest
from tests import test_service
from tests import test_process
from tests import test_processing
from tests import test_assync
from tests import test_grass_location
from tests import test_storage
from tests import test_filestorage
from tests import test_s3storage
from tests.validator import test_complexvalidators
from tests.validator import test_literalvalidators
import test_capabilities
import test_configuration
import test_describe
import test_execute
import test_exceptions
import test_inout
import test_literaltypes
import validator
import test_ows
import test_formats
import test_dblog
import test_wpsrequest
import test_service
import test_process
import test_processing
import test_assync
import test_grass_location
import test_storage
import test_filestorage
import test_s3storage
from validator import test_complexvalidators
from validator import test_literalvalidators


def find_grass():
Expand Down
37 changes: 37 additions & 0 deletions tests/basic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# coding=utf-8
import os
import unittest
import pywps.configuration
from tempfile import TemporaryDirectory


class TestBase(unittest.TestCase):

def setUp(self) -> None:
# Do not use load_configuration() that will load system configuration
# files such as /etc/pywps.cfg
pywps.configuration.load_hardcoded_configuration()

# Ensure all data goes into ontime temporary directory
self.tmpdir = TemporaryDirectory(prefix="pywps_test_")

# shortcut
set = pywps.configuration.CONFIG.set

set('server', 'temp_path', f"{self.tmpdir.name}/temp_path")
set('server', 'outputpath', f"{self.tmpdir.name}/outputpath")
set('server', 'workdir', f"{self.tmpdir.name}/workdir")

set('logging', 'level', 'DEBUG')
set('logging', 'file', f"{self.tmpdir.name}/logging-file.log")
set("logging", "database", f"sqlite:///{self.tmpdir.name}/test-pywps-logs.sqlite3")

set('processing', 'path', f"{self.tmpdir.name}/processing_path")

os.mkdir(f"{self.tmpdir.name}/temp_path")
os.mkdir(f"{self.tmpdir.name}/outputpath")
os.mkdir(f"{self.tmpdir.name}/workdir")
os.mkdir(f"{self.tmpdir.name}/processing_path")

def tearDown(self) -> None:
self.tmpdir.cleanup()
7 changes: 2 additions & 5 deletions tests/test_app_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
# licensed under MIT, Please consult LICENSE.txt for details #
##################################################################

import unittest
from basic import TestBase
from pywps.app.exceptions import format_message, ProcessError, DEFAULT_ALLOWED_CHARS


class AppExceptionsTest(unittest.TestCase):

def setUp(self):
pass
class AppExceptionsTest(TestBase):

def test_format_message(self):
assert format_message('no data available') == 'no data available'
Expand Down
23 changes: 8 additions & 15 deletions tests/test_assync.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
# licensed under MIT, Please consult LICENSE.txt for details #
##################################################################

import unittest
from basic import TestBase
import pytest
import time
from pywps import Service, configuration
from pywps import get_ElementMakerForVersion
from pywps.tests import client_for, assert_response_accepted, assert_response_success
from .processes import Sleep
from processes import Sleep
from owslib.wps import WPSExecution
from pathlib import Path
from tempfile import TemporaryDirectory
Expand All @@ -20,22 +20,13 @@
WPS, OWS = get_ElementMakerForVersion(VERSION)


class ExecuteTest(unittest.TestCase):
def setUp(self) -> None:

# Create temporary directory to create test database.
self.tmpdir = TemporaryDirectory()
class ExecuteTest(TestBase):

def setUp(self) -> None:
super().setUp()
# Running processes using the MultiProcessing scheduler and a file-based database
configuration.CONFIG.set('processing', 'mode', 'distributed')

configuration.CONFIG.set("logging", "database", f"sqlite:///{self.tmpdir.name}/test-pywps-logs.sqlite3")

def tearDown(self) -> None:
# Cleanup temporary database
configuration.load_configuration()
self.tmpdir.cleanup()

def test_async(self):
client = client_for(Service(processes=[Sleep()]))
wps = WPSExecution()
Expand All @@ -56,9 +47,10 @@ def test_async(self):

# Parse response to extract the status file path
url = resp.xml.xpath("//@statusLocation")[0]
print(url)

# OWSlib only reads from URLs, not local files. So we need to read the response manually.
p = Path(url[6:])
p = Path(configuration.get_config_value('server', 'outputpath')) / url.split('/')[-1]

# Poll the process until it completes
total_time = 0
Expand All @@ -77,6 +69,7 @@ def test_async(self):


def load_tests(loader=None, tests=None, pattern=None):
import unittest
if not loader:
loader = unittest.TestLoader()
suite_list = [
Expand Down
Loading

0 comments on commit 5304dae

Please sign in to comment.