Skip to content

Commit

Permalink
testing: move build_capabilities into MetadataBuilder
Browse files Browse the repository at this point in the history
and rename the fixture to mbldr
  • Loading branch information
soxofaan committed Apr 5, 2023
1 parent cd2705b commit d86b02e
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 107 deletions.
83 changes: 42 additions & 41 deletions src/openeo_aggregator/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,52 +163,53 @@ def clock_mock(
return mock.patch.object(Clock, "_time", new=itertools.count(start, step=step).__next__)


def build_capabilities(
*,
api_version: str = "1.1.0",
stac_version: str = "0.9.0",
support_secondary_services: bool = False,
) -> dict:
"""
Helper to build a capabilities doc.
"""
# TODO: move this to MetadataBuilder
# Basic start point
capabilities = {
"api_version": api_version,
"backend_version": openeo_aggregator.about.__version__,
"stac_version": stac_version,
"id": "openeo-aggregator-testing",
"title": "Fake test backend (aggregator)",
"description": "Fake test backend for openEO Aggregator",
"endpoints": [
{"path": "/collections", "methods": ["GET"]},
{"path": "/collections/{collection_id}", "methods": ["GET"]},
{"path": "/processes", "methods": ["GET"]},
],
"links": [],
}

# Additional features
if support_secondary_services:
capabilities["endpoints"].extend(
[
{"path": "/service_types", "methods": ["GET"]},
{"path": "/services", "methods": ["GET", "POST"]},
{
"path": "/services/{service_id}",
"methods": ["GET", "PATCH", "DELETE"],
},
{"path": "/services/{service_id}/logs", "methods": ["GET"]},
]
)

return capabilities


class MetadataBuilder:
"""Helper for building openEO/STAC-style metadata dictionaries"""

def capabilities(
self,
*,
api_version: str = "1.1.0",
stac_version: str = "0.9.0",
secondary_services: bool = False,
) -> dict:
"""
Helper to build a capabilities doc.
"""
# Basic start point
capabilities = {
"api_version": api_version,
"backend_version": openeo_aggregator.about.__version__,
"stac_version": stac_version,
"id": "openeo-aggregator-testing",
"title": "Test openEO Aggregator",
"description": "Test instance of openEO Aggregator",
"endpoints": [
{"path": "/collections", "methods": ["GET"]},
{"path": "/collections/{collection_id}", "methods": ["GET"]},
{"path": "/processes", "methods": ["GET"]},
],
"links": [],
}

# Additional features
if secondary_services:
capabilities["endpoints"].extend(
[
{"path": "/service_types", "methods": ["GET"]},
{"path": "/services", "methods": ["GET", "POST"]},
{
"path": "/services/{service_id}",
"methods": ["GET", "PATCH", "DELETE"],
},
{"path": "/services/{service_id}/logs", "methods": ["GET"]},
]
)

return capabilities

def collection(self, id="S2", *, license="proprietary") -> dict:
"""Build collection metadata"""
return {
Expand Down
21 changes: 9 additions & 12 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@
MultiBackendConnection,
)
from openeo_aggregator.config import AggregatorConfig
from openeo_aggregator.testing import (
DummyKazooClient,
MetadataBuilder,
build_capabilities,
)
from openeo_aggregator.testing import DummyKazooClient, MetadataBuilder

_DEFAULT_PROCESSES = [
"load_collection",
Expand All @@ -31,31 +27,31 @@


@pytest.fixture
def backend1(requests_mock, bldr) -> str:
def backend1(requests_mock, mbldr) -> str:
domain = "https://b1.test/v1"
# TODO: how to work with different API versions?
requests_mock.get(domain + "/", json=build_capabilities())
requests_mock.get(domain + "/", json=mbldr.capabilities())
requests_mock.get(
domain + "/credentials/oidc",
json={
"providers": [{"id": "egi", "issuer": "https://egi.test", "title": "EGI"}]
},
)
requests_mock.get(domain + "/processes", json=bldr.processes(*_DEFAULT_PROCESSES))
requests_mock.get(domain + "/processes", json=mbldr.processes(*_DEFAULT_PROCESSES))
return domain


@pytest.fixture
def backend2(requests_mock, bldr) -> str:
def backend2(requests_mock, mbldr) -> str:
domain = "https://b2.test/v1"
requests_mock.get(domain + "/", json=build_capabilities())
requests_mock.get(domain + "/", json=mbldr.capabilities())
requests_mock.get(
domain + "/credentials/oidc",
json={
"providers": [{"id": "egi", "issuer": "https://egi.test", "title": "EGI"}]
},
)
requests_mock.get(domain + "/processes", json=bldr.processes(*_DEFAULT_PROCESSES))
requests_mock.get(domain + "/processes", json=mbldr.processes(*_DEFAULT_PROCESSES))
return domain


Expand Down Expand Up @@ -205,5 +201,6 @@ def catalog(multi_backend_connection, config) -> AggregatorCollectionCatalog:


@pytest.fixture
def bldr() -> MetadataBuilder:
def mbldr() -> MetadataBuilder:
"""Metadata builder"""
return MetadataBuilder()
56 changes: 31 additions & 25 deletions tests/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
_InternalCollectionMetadata,
)
from openeo_aggregator.caching import DictMemoizer
from openeo_aggregator.testing import build_capabilities, clock_mock
from openeo_aggregator.testing import clock_mock

from .conftest import DEFAULT_MEMOIZER_CONFIG

Expand Down Expand Up @@ -146,13 +146,6 @@ class TestAggregatorSecondaryServices:
# TODO: most tests here (the ones that do flask app stuff and auth)
# belong under test_views.py

CAPABILITIES_NO_SECONDARY_SERVICES = build_capabilities(
support_secondary_services=False
)
CAPABILITIES_WITH_SECONDARY_SERVICES = build_capabilities(
support_secondary_services=True
)

SERVICE_TYPES_ONLT_WMTS = {
"WMTS": {
"configuration": {
Expand Down Expand Up @@ -192,12 +185,13 @@ def test_get_supporting_backend_ids_all_supported(
backend1,
backend2,
requests_mock,
mbldr,
):
requests_mock.get(
backend1 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=True)
)
requests_mock.get(
backend2 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend2 + "/", json=mbldr.capabilities(secondary_services=True)
)
processing = AggregatorProcessing(
backends=multi_backend_connection, catalog=catalog, config=config
Expand All @@ -217,10 +211,13 @@ def test_get_supporting_backend_ids_only_one_supported(
backend1,
backend2,
requests_mock,
mbldr,
):
requests_mock.get(backend1 + "/", json=self.CAPABILITIES_NO_SECONDARY_SERVICES)
requests_mock.get(
backend2 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=False)
)
requests_mock.get(
backend2 + "/", json=mbldr.capabilities(secondary_services=True)
)
processing = AggregatorProcessing(
backends=multi_backend_connection, catalog=catalog, config=config
Expand All @@ -240,16 +237,17 @@ def test_service_types_simple(
backend1,
backend2,
requests_mock,
mbldr,
):
"""Given 2 backends and only 1 backend has a single service type, then the aggregator
returns that 1 service type's metadata.
"""
# Aggregator checks if the backend supports GET /service_types, so we have to mock that up too.
requests_mock.get(
backend1 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=True)
)
requests_mock.get(
backend2 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend2 + "/", json=mbldr.capabilities(secondary_services=True)
)
single_service_type = self.SERVICE_TYPES_ONLT_WMTS
requests_mock.get(backend1 + "/service_types", json=single_service_type)
Expand All @@ -269,6 +267,7 @@ def test_service_types_simple_cached(
backend1,
backend2,
requests_mock,
mbldr,
):
"""Scenario: The service_types call is cached:
When we get the service types several times, the second call that happens before the cache expires,
Expand All @@ -277,7 +276,7 @@ def test_service_types_simple_cached(
"""
# Aggregator checks if the backend supports GET /service_types, so we have to mock that up too.
requests_mock.get(
backend1 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=True)
)
# Just need one service type for the test.
single_service_type = self.SERVICE_TYPES_ONLT_WMTS
Expand Down Expand Up @@ -311,6 +310,7 @@ def test_service_types_skips_unsupported_backend(
backend1,
backend2,
requests_mock,
mbldr,
):
"""Given 2 backends and only 1 backend support secondary services, as states in its capabilities,
when the aggregator fulfills a request to list the service types,
Expand All @@ -319,10 +319,10 @@ def test_service_types_skips_unsupported_backend(
# We are testing that the aggregator checks if the backend supports GET /service_types, so we have to mock that up too.
# We want to verify that the capabilities are actually queried.
mock_b1_capabilities = requests_mock.get(
backend1 + "/", json=self.CAPABILITIES_NO_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=False)
)
mock_b2_capabilities = requests_mock.get(
backend2 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend2 + "/", json=mbldr.capabilities(secondary_services=True)
)

single_service_type = self.SERVICE_TYPES_ONLT_WMTS
Expand Down Expand Up @@ -353,15 +353,16 @@ def test_service_types_multiple_backends(
backend1,
backend2,
requests_mock,
mbldr,
):
"""Given 2 backends with each 1 service type, then the aggregator lists both service types."""

# Aggregator checks if the backend supports GET /service_types, so we have to mock that up too.
requests_mock.get(
backend1 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=True)
)
requests_mock.get(
backend2 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend2 + "/", json=mbldr.capabilities(secondary_services=True)
)
service_type_1 = {
"WMTS": {
Expand Down Expand Up @@ -413,6 +414,7 @@ def test_service_types_warns_about_duplicate_service(
backend2,
requests_mock,
caplog,
mbldr,
):
"""
Given 2 backends which have conflicting service types,
Expand All @@ -423,10 +425,10 @@ def test_service_types_warns_about_duplicate_service(
caplog.set_level(logging.WARNING)
# Aggregator checks if the backend supports GET /service_types, so we have to mock that up too.
requests_mock.get(
backend1 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=True)
)
requests_mock.get(
backend2 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend2 + "/", json=mbldr.capabilities(secondary_services=True)
)
service_type_1 = {
"WMS": {
Expand Down Expand Up @@ -567,12 +569,13 @@ def test_create_service_succeeds(
catalog,
backend1,
requests_mock,
mbldr,
):
"""When it gets a correct params for a new service, it successfully creates it."""

# Aggregator checks if the backend supports GET /service_types, so we have to mock that up too.
requests_mock.get(
backend1 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=True)
)

# Set up responses for creating the service in backend 1
Expand Down Expand Up @@ -613,12 +616,13 @@ def test_create_service_raises_serviceunsupportedexception(
catalog,
backend1,
requests_mock,
mbldr,
):
"""When it gets a request for a service type but no backend supports this service type, it raises ServiceUnsupportedException."""

# Aggregator checks if the backend supports GET /service_types, so we have to mock that up too.
mock_get_capabilities = requests_mock.get(
backend1 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=True)
)

# At least 1 service type must be present.
Expand Down Expand Up @@ -668,12 +672,13 @@ def test_create_service_backend_raises_openeoapiexception(
backend1,
requests_mock,
exception_class,
mbldr,
):
"""When the backend raises a general exception the aggregator raises an OpenEOApiException."""

# Aggregator checks if the backend supports GET /service_types, so we have to mock that up too.
mock_get_capabilities = requests_mock.get(
backend1 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=True)
)

# Set up responses for creating the service in backend 1:
Expand Down Expand Up @@ -713,14 +718,15 @@ def test_create_service_backend_reraises(
backend1,
requests_mock,
exception_class,
mbldr,
):
"""When the backend raises certain exception types of which we know it indicates client error / bad input data,
then the aggregator re-raises that exception.
"""

# Aggregator checks if the backend supports GET /service_types, so we have to mock that up too.
mock_get_capabilities = requests_mock.get(
backend1 + "/", json=self.CAPABILITIES_WITH_SECONDARY_SERVICES
backend1 + "/", json=mbldr.capabilities(secondary_services=True)
)

# Set up responses for creating the service in backend 1
Expand Down
Loading

0 comments on commit d86b02e

Please sign in to comment.