Skip to content

Commit

Permalink
Issue #78 Adding tests for views for SecondaryServices
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanKJSchreurs committed Nov 7, 2022
1 parent 203ca21 commit e78e6d6
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 21 deletions.
4 changes: 3 additions & 1 deletion src/openeo_aggregator/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,6 @@ def create_service(self, user_id: str, process_graph: dict, service_type: str, a
configuration: dict) -> str:
"""
https://openeo.org/documentation/1.0/developers/api/reference.html#operation/create-service
:return: (location, openeo_identifier)
"""

backend_id = self._processing.get_backend_for_process_graph(
Expand All @@ -864,7 +863,10 @@ def create_service(self, user_id: str, process_graph: dict, service_type: str, a

con = self._backends.get_connection(backend_id)
try:
# create_service can raise ServiceUnsupportedException and OpenEOApiException.
service = con.create_service(graph=process_graph, type=service_type)

# TODO: This exception handling was copy-pasted. What do we actually need here?
except OpenEoApiError as e:
for exc_class in [ProcessGraphMissingException, ProcessGraphInvalidException]:
if e.code == exc_class.code:
Expand Down
19 changes: 19 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ def backend_implementation(flask_app) -> AggregatorBackendImplementation:
return flask_app.config["OPENEO_BACKEND_IMPLEMENTATION"]


@pytest.fixture(params=["0.4.0", "1.0.0"])
def api_version(request):
"""To go through all relevant API versions"""
return request.param


def get_api_version(flask_app, api_version) -> ApiTester:
return ApiTester(api_version=api_version, client=flask_app.test_client())


def get_api040(flask_app: flask.Flask) -> ApiTester:
return ApiTester(api_version="0.4.0", client=flask_app.test_client())

Expand All @@ -144,6 +154,15 @@ def get_api100(flask_app: flask.Flask) -> ApiTester:
return ApiTester(api_version="1.0.0", client=flask_app.test_client())


@pytest.fixture
def api(flask_app, api_version) -> ApiTester:
"""Get an ApiTester for each version.
Useful when it easy to test several API versions with (mostly) the same test code.
But when the difference is too big, just write separate tests.
"""
return get_api_version(flask_app, api_version)

@pytest.fixture
def api040(flask_app: flask.Flask) -> ApiTester:
return get_api040(flask_app)
Expand Down
97 changes: 77 additions & 20 deletions tests/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ def test_service_types_simple(self, multi_backend_connection, config, backend1,
}
requests_mock.get(backend1 + "/service_types", json=single_service_type)
requests_mock.get(backend2 + "/service_types", json=single_service_type)
implementation = AggregatorBackendImplementation(
abe_implementation = AggregatorBackendImplementation(
backends=multi_backend_connection, config=config
)
service_types = implementation.service_types()
service_types = abe_implementation.service_types()
assert service_types == single_service_type

def test_service_types_merging(self, multi_backend_connection, config, backend1, backend2, requests_mock):
Expand Down Expand Up @@ -180,13 +180,15 @@ def test_service_types_merging(self, multi_backend_connection, config, backend1,
}
requests_mock.get(backend1 + "/service_types", json=service_1)
requests_mock.get(backend2 + "/service_types", json=service_2)
implementation = AggregatorBackendImplementation(
abe_implementation = AggregatorBackendImplementation(
backends=multi_backend_connection, config=config
)
service_types = implementation.service_types()
expected = dict(service_1)
expected.update(service_2)
assert service_types == expected

actual_service_types = abe_implementation.service_types()

expected_service_types = dict(service_1)
expected_service_types.update(service_2)
assert actual_service_types == expected_service_types

# TODO: eliminate TEST_SERVICES (too long) when I find a better way to set up the test.
TEST_SERVICES = {
Expand Down Expand Up @@ -531,9 +533,9 @@ def test_list_services_simple(self, multi_backend_connection, config, backend1,
services2 = {}
requests_mock.get(backend1 + "/services", json=services1)
requests_mock.get(backend2 + "/services", json=services2)
implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)
abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

actual_services = implementation.list_services(user_id=TEST_USER)
actual_services = abe_implementation.list_services(user_id=TEST_USER)

# Construct expected result. We have get just data from the service in services1
# (there is only one) for conversion to a ServiceMetadata.
Expand Down Expand Up @@ -561,9 +563,9 @@ def test_list_services_merged(self, multi_backend_connection, config, backend1,
services2 = {"services": [serv_metadata_wmts_foo.prepare_for_json()], "links": []}
requests_mock.get(backend1 + "/services", json=services1)
requests_mock.get(backend2 + "/services", json=services2)
implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)
abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

actual_services = implementation.list_services(user_id=TEST_USER)
actual_services = abe_implementation.list_services(user_id=TEST_USER)

# Construct expected result. We have get just data from the service in
# services1 (there is only one) for conversion to a ServiceMetadata.
Expand Down Expand Up @@ -607,11 +609,11 @@ def test_list_services_merged_multiple(self, multi_backend_connection, config, b
}
requests_mock.get(backend1 + "/services", json=services1)
requests_mock.get(backend2 + "/services", json=services2)
implementation = AggregatorBackendImplementation(
abe_implementation = AggregatorBackendImplementation(
backends=multi_backend_connection, config=config
)

actual_services = implementation.list_services(user_id=TEST_USER)
actual_services = abe_implementation.list_services(user_id=TEST_USER)

# Construct expected result. We have get just data from the service in
# services1 (there is only one) for conversion to a ServiceMetadata.
Expand Down Expand Up @@ -651,14 +653,14 @@ def test_service_info(self, multi_backend_connection, config, backend1, backend2
)
requests_mock.get(backend1 + "/services/wmts-foo", json=service1.prepare_for_json())
requests_mock.get(backend2 + "/services/wms-bar", json=service2.prepare_for_json())
implementation = AggregatorBackendImplementation(
abe_implementation = AggregatorBackendImplementation(
backends=multi_backend_connection, config=config
)

actual_service1 = implementation.service_info(user_id=TEST_USER, service_id="wmts-foo")
actual_service1 = abe_implementation.service_info(user_id=TEST_USER, service_id="wmts-foo")
assert actual_service1 == service1

actual_service2 = implementation.service_info(user_id=TEST_USER, service_id="wms-bar")
actual_service2 = abe_implementation.service_info(user_id=TEST_USER, service_id="wms-bar")
assert actual_service2 == service2

def test_service_info_wrong_id(self, multi_backend_connection, config, backend1, backend2, requests_mock):
Expand Down Expand Up @@ -688,12 +690,12 @@ def test_service_info_wrong_id(self, multi_backend_connection, config, backend1,
)
requests_mock.get(backend1 + "/services/wmts-foo", json=service1.prepare_for_json())
requests_mock.get(backend2 + "/services/wms-bar", json=service2.prepare_for_json())
implementation = AggregatorBackendImplementation(
abe_implementation = AggregatorBackendImplementation(
backends=multi_backend_connection, config=config
)

with pytest.raises(ServiceNotFoundException):
_ = implementation.service_info(user_id=TEST_USER, service_id="doesnotexist")
_ = abe_implementation.service_info(user_id=TEST_USER, service_id="doesnotexist")

@pytest.mark.parametrize("api_version", ["0.4.0", "1.0.0", "1.1.0"])
def test_create_service(self, multi_backend_connection, config, backend1, requests_mock, api_version):
Expand All @@ -711,9 +713,9 @@ def test_create_service(self, multi_backend_connection, config, backend1, reques
},
status_code=201)

implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)
abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

actual_openeo_id = implementation.create_service(
actual_openeo_id = abe_implementation.create_service(
user_id=TEST_USER,
process_graph=process_graph,
service_type="WMTS",
Expand All @@ -723,6 +725,61 @@ def test_create_service(self, multi_backend_connection, config, backend1, reques

assert actual_openeo_id == expected_openeo_id

# TODO: test a failing case for test_create_service
@pytest.mark.parametrize("api_version", ["0.4.0", "1.0.0", "1.1.0"])
def test_create_service_backend_returns_error(
self, multi_backend_connection, config, backend1, requests_mock, api_version
):
from openeo.rest import OpenEoApiError, OpenEoRestError
# TODO: Two exception types should be re-raised: ProcessGraphMissingException, ProcessGraphInvalidException

for exc_class in [OpenEoApiError, OpenEoRestError]:
# Set up responses for creating the service in backend 1
process_graph = {"foo": {"process_id": "foo", "arguments": {}}}
requests_mock.post(
backend1 + "/services",
exc=exc_class("Some server error"),
)

abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

with pytest.raises(OpenEOApiException):
_ = abe_implementation.create_service(
user_id=TEST_USER,
process_graph=process_graph,
service_type="WMTS",
api_version=api_version,
configuration={}
)

@pytest.mark.parametrize("api_version", ["0.4.0", "1.0.0", "1.1.0"])
def test_create_service_backend_reraises(
self, multi_backend_connection, config, backend1, requests_mock, api_version
):
from openeo_driver.errors import ProcessGraphMissingException, ProcessGraphInvalidException, ServiceUnsupportedException

for exc_class in [ProcessGraphMissingException,
ProcessGraphInvalidException,
ServiceUnsupportedException]:
# Set up responses for creating the service in backend 1
process_graph = {"foo": {"process_id": "foo", "arguments": {}}}
requests_mock.post(
backend1 + "/services",
exc=exc_class("Some server error"),
)

abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

# These exception types should be re-raised, not become an OpenEOApiException.
with pytest.raises(exc_class):
_ = abe_implementation.create_service(
user_id=TEST_USER,
process_graph=process_graph,
service_type="WMTS",
api_version=api_version,
configuration={}
)


class TestInternalCollectionMetadata:

Expand Down
69 changes: 69 additions & 0 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1182,10 +1182,79 @@ def post_jobs(request: requests.Request, context):
}}}
]


class TestSecondaryServices:

# TODO: add view tests for list service types, list_services, servicfe_info

def test_service_types_simple(self, api, backend1, backend2, requests_mock):
single_service_type = {
"WMTS": {
"configuration": {
"colormap": {
"default": "YlGn",
"description":
"The colormap to apply to single band layers",
"type": "string"
},
"version": {
"default": "1.0.0",
"description": "The WMTS version to use.",
"enum": ["1.0.0"],
"type": "string"
}
},
"links": [],
"process_parameters": [],
"title": "Web Map Tile Service"
}
}
requests_mock.get(backend1 + "/service_types", json=single_service_type)
requests_mock.get(backend2 + "/service_types", json=single_service_type)

resp = api.get('/service_types').assert_status_code(200)
assert resp.json == single_service_type

def test_service_types_merging(self, api, backend1, backend2, requests_mock):
service_type_1 = {
"WMTS": {
"configuration": {
"colormap": {
"default": "YlGn",
"description":
"The colormap to apply to single band layers",
"type": "string"
},
"version": {
"default": "1.0.0",
"description": "The WMTS version to use.",
"enum": ["1.0.0"],
"type": "string"
}
},
"links": [],
"process_parameters": [],
"title": "Web Map Tile Service"
}
}
service_type_2 = {
"WMS": {
"title": "OGC Web Map Service",
"configuration": {},
"process_parameters": [],
"links": []
}
}
requests_mock.get(backend1 + "/service_types", json=service_type_1)
requests_mock.get(backend2 + "/service_types", json=service_type_2)

resp = api.get("/service_types").assert_status_code(200)
actual_service_types = resp.json

expected_service_types = dict(service_type_1)
expected_service_types.update(service_type_2)
assert actual_service_types == expected_service_types

def test_create_wmts_040(self, api040, requests_mock, backend1):
api040.set_auth_bearer_token(TEST_USER_BEARER_TOKEN)

Expand Down

0 comments on commit e78e6d6

Please sign in to comment.