Skip to content

Commit

Permalink
Issue #78 add more tests in test_views.py
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanKJSchreurs committed Nov 9, 2022
1 parent 7469979 commit d68a32c
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 15 deletions.
7 changes: 7 additions & 0 deletions src/openeo_aggregator/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,7 @@ def merge(formats: dict, to_add: dict):

def list_services(self, user_id: str) -> List[ServiceMetadata]:
"""https://openeo.org/documentation/1.0/developers/api/reference.html#operation/list-services"""
# TODO: user_id is not used, how to authenticate when we use the BackendConnection?

all_services = []
def merge(services, to_add):
Expand All @@ -837,6 +838,7 @@ def merge(services, to_add):

def service_info(self, user_id: str, service_id: str) -> ServiceMetadata:
"""https://openeo.org/documentation/1.0/developers/api/reference.html#operation/describe-service"""
# TODO: user_id is not used, how to authenticate when we use the BackendConnection?

# TODO: can there ever be a service with the same ID in multiple back-ends? (For the same user)
for con in self._backends:
Expand All @@ -855,6 +857,8 @@ def create_service(self, user_id: str, process_graph: dict, service_type: str, a
"""
https://openeo.org/documentation/1.0/developers/api/reference.html#operation/create-service
"""
# TODO: user_id is not used, how to authenticate when we use the BackendConnection?
# TODO: configuration is not used. What to do with it?

backend_id = self._processing.get_backend_for_process_graph(
process_graph=process_graph, api_version=api_version
Expand Down Expand Up @@ -902,6 +906,8 @@ def _find_connection_with_service_id(self, service_id: str) -> BackendConnection

def remove_service(self, user_id: str, service_id: str) -> None:
"""https://openeo.org/documentation/1.0/developers/api/reference.html#operation/delete-service"""
# TODO: user_id is not used, how to authenticate when we use the BackendConnection?

con = self._find_connection_with_service_id(service_id)
if not con:
raise ServiceNotFoundException(service_id)
Expand All @@ -921,6 +927,7 @@ def remove_service(self, user_id: str, service_id: str) -> None:

def update_service(self, user_id: str, service_id: str, process_graph: dict) -> None:
"""https://openeo.org/documentation/1.0/developers/api/reference.html#operation/update-service"""
# TODO: user_id is not used, how to authenticate when we use the BackendConnection?

con = self._find_connection_with_service_id(service_id)
if not con:
Expand Down
29 changes: 15 additions & 14 deletions tests/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,40 +447,43 @@ def test_create_service_backend_reraises(
configuration={}
)

def test_remove_service(
def test_remove_service_succeeds(
self, multi_backend_connection, config, backend1, backend2, requests_mock, service_metadata_wmts_foo
):
"""When it gets a correct service ID, it returns the expected ServiceMetadata."""
"""When remove_service is called with an existing service ID, it removes service and returns HTTP 204."""

# Also test that it can skip backends that don't have the service
m_get1 = requests_mock.get(
mock_get1 = requests_mock.get(
backend1 + "/services/wmts-foo",
status_code=404
)
# Delete should succeed in backend2 so service should be present first.
m_get2 = requests_mock.get(
mock_get2 = requests_mock.get(
backend2 + "/services/wmts-foo",
json=service_metadata_wmts_foo.prepare_for_json(),
status_code=200
)
m_del = requests_mock.delete(backend2 + "/services/wmts-foo", status_code=204)
mock_delete = requests_mock.delete(backend2 + "/services/wmts-foo", status_code=204)
abe_implementation = AggregatorBackendImplementation(backends=multi_backend_connection, config=config)

abe_implementation.remove_service(user_id=TEST_USER, service_id="wmts-foo")

# Make sure the aggregator asked the backend to remove the service.
assert m_del.called
assert mock_delete.called

# Check the other mocks were called too, just to be sure.
assert m_get1.called
assert m_get2.called
assert mock_get1.called
assert mock_get2.called

# TODO: it fails for the test case where the backend reports HTTP 400, because along the way the aggregator turns it into a HTTP 500.
# Also, I'm not sure is this test is the way to go.
@pytest.mark.parametrize("backend_status_code", [400, 500])
def test_remove_service_backend_response_is_an_error_status(
self, multi_backend_connection, config, backend1, requests_mock,
service_metadata_wmts_foo, backend_status_code
):
"""When the backend response is an error HTTP 400/500 then the aggregator raises an OpenEoApiError."""

# Will find it on the first backend, and it should skip the second backend so we don't add it to backend2.
requests_mock.get(
backend1 + "/services/wmts-foo",
Expand All @@ -494,16 +497,14 @@ def test_remove_service_backend_response_is_an_error_status(
abe_implementation.remove_service(user_id=TEST_USER, service_id="wmts-foo")

# If the backend reports HTTP 400/500, we would expect the same status code from the aggregator.
# TODO: Statement above is an assumption. Is that really what we expect?
assert e.value.http_status_code == backend_status_code

def test_remove_service_service_id_not_found(
self, multi_backend_connection, config, backend1, backend2, requests_mock, service_metadata_wmts_foo
):
"""When the service ID does not exist then the aggregator raises an ServiceNotFoundException."""
requests_mock.get(backend1 + "/services/wmts-foo", json=service_metadata_wmts_foo.prepare_for_json())
abe_implementation = AggregatorBackendImplementation(
backends=multi_backend_connection, config=config
)

# Neither backend has the service available, and the aggregator should detect this.
requests_mock.get(
backend1 + "/services/wmts-foo",
Expand All @@ -519,10 +520,10 @@ def test_remove_service_service_id_not_found(
with pytest.raises(ServiceNotFoundException):
abe_implementation.remove_service(user_id=TEST_USER, service_id="wmts-foo")

def test_update_service(
def test_update_service_succeeds(
self, api_tester, multi_backend_connection, config, backend1, backend2, requests_mock, service_metadata_wmts_foo
):
"""When it gets a correct service ID, it returns the expected ServiceMetadata."""
"""When it receives an existing service ID and a correct payload, it updates the expected service."""

# Also test that it can skip backends that don't have the service
set_backend_to_api_version(requests_mock, backend1, api_tester.api_version)
Expand Down
96 changes: 95 additions & 1 deletion tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from openeo_driver.backend import ServiceMetadata
from openeo_driver.testing import ApiTester, TEST_USER_AUTH_HEADER, TEST_USER, TEST_USER_BEARER_TOKEN, DictSubSet, \
RegexMatcher
from .conftest import assert_dict_subset, get_api100, get_flask_app
from .conftest import assert_dict_subset, get_api100, get_flask_app, set_backend_to_api_version


class TestGeneral:
Expand Down Expand Up @@ -1528,6 +1528,100 @@ def test_create_wmts_reports_500_server_error_api100(self, api100, requests_mock
resp = api100.post('/services', json=post_data)
assert resp.status_code == 500

def test_remove_service_succeeds(
self, api_tester, requests_mock, backend1, backend2, service_metadata_wmts_foo
):
"""When remove_service is called with an existing service ID, it removes service and returns HTTP 204."""
api_tester.set_auth_bearer_token(TEST_USER_BEARER_TOKEN)
set_backend_to_api_version(requests_mock, backend1, api_tester.api_version)
set_backend_to_api_version(requests_mock, backend2, api_tester.api_version)

# Also test that it can skip backends that don't have the service
requests_mock.get(
backend1 + "/services/wmts-foo",
status_code=404
)
# Delete should succeed in backend2 so service should be present first.
requests_mock.get(
backend2 + "/services/wmts-foo",
json=service_metadata_wmts_foo.prepare_for_json(),
status_code=200
)
mock_delete = requests_mock.delete(backend2 + "/services/wmts-foo", status_code=204)

resp = api_tester.delete("/services/wmts-foo")

assert resp.status_code == 204
# Make sure the aggregator asked the backend to remove the service.
assert mock_delete.called

# TODO: it fails for the test case where the backend reports HTTP 400, because along the way the aggregator turns it into a HTTP 500.
# Also, I'm not sure is this test is the way to go.
@pytest.mark.parametrize("backend_status_code", [400, 500])
def test_remove_service_backend_response_is_an_error_status(
self, api_tester, requests_mock, backend1, backend2,
service_metadata_wmts_foo, backend_status_code
):
"""When the backend response is an error HTTP 400/500 then the aggregator raises an OpenEoApiError."""
api_tester.set_auth_bearer_token(TEST_USER_BEARER_TOKEN)
set_backend_to_api_version(requests_mock, backend1, api_tester.api_version)
set_backend_to_api_version(requests_mock, backend2, api_tester.api_version)

# Will find it on the first backend, and it should skip the second backend so we don't add it to backend2.
requests_mock.get(
backend1 + "/services/wmts-foo",
json=service_metadata_wmts_foo.prepare_for_json(),
status_code=200
)
mock_delete = requests_mock.delete(
backend1 + "/services/wmts-foo",
status_code=backend_status_code,
json={
"id": "936DA01F-9ABD-4D9D-80C7-02AF85C822A8",
"code": "ErrorRemovingService",
"message": "Service 'wmts-foo' could not be removed.",
"url": "https://example.openeo.org/docs/errors/SampleError"
}
)

resp = api_tester.delete("/services/wmts-foo")

assert resp.status_code == backend_status_code
# Make sure the aggregator asked the backend to remove the service.
assert mock_delete.called

def test_remove_service_service_id_not_found(
self, api_tester, backend1, backend2, requests_mock, service_metadata_wmts_foo
):
"""When the service ID does not exist then the aggregator raises an ServiceNotFoundException."""
api_tester.set_auth_bearer_token(TEST_USER_BEARER_TOKEN)
set_backend_to_api_version(requests_mock, backend1, api_tester.api_version)
set_backend_to_api_version(requests_mock, backend2, api_tester.api_version)

# Neither backend has the service available, and the aggregator should detect this.
mock_get1 = requests_mock.get(
backend1 + "/services/wmts-foo",
json=service_metadata_wmts_foo.prepare_for_json(),
status_code=404
)
mock_get2 = requests_mock.get(
backend2 + "/services/wmts-foo",
status_code=404,
# json={
# "id": "936DA01F-9ABD-4D9D-80C7-02AF85C822A8",
# "code": "ServiceNotFound",
# "message": "Service 'wmts-foo' does not exist.",
# "url": "https://example.openeo.org/docs/errors/SampleError"
# }
)

resp = api_tester.delete("/services/wmts-foo")

assert resp.status_code == 404
# Make sure the aggregator asked the backend to remove the service.
assert mock_get1.called
assert mock_get2.called


class TestResilience:

Expand Down

0 comments on commit d68a32c

Please sign in to comment.