Skip to content

Commit

Permalink
testing: replace _pytest_override_context with config_overrides
Browse files Browse the repository at this point in the history
mock.patch based  solution is simpler and more flexible
  • Loading branch information
soxofaan committed Nov 17, 2023
1 parent e3964a5 commit 7d2b335
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 22 deletions.
2 changes: 1 addition & 1 deletion openeo_driver/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.77.2a1"
__version__ = "0.77.3a1"
13 changes: 0 additions & 13 deletions openeo_driver/config/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,6 @@ def flush(self):
"""Flush the config, to force a reload on next get."""
self._config = None

@contextlib.contextmanager
def _pytest_override_context(self, overrides: Optional[dict] = None):
"""
Important: this context manger specifically intended for usage in pytest fixtures,
to override specific config fields during the lifetime of a test
"""
orig = self.get()
kwargs = {**attrs.asdict(orig, recurse=False), **overrides}
overridden = self.expected_class(**kwargs)
self._config = overridden
yield overridden
self.flush()


# "Singleton by convention" config getter
_backend_config_getter = ConfigGetter()
Expand Down
2 changes: 1 addition & 1 deletion openeo_driver/dummy/dummy_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def _valid_basic_auth(username: str, password: str) -> bool:


config = OpenEoBackendConfig(
id="dummy",
id="openeo-python-driver-dummy",
capabilities_title="Dummy openEO Backend",
capabilities_description="Dummy openEO backend provided by [openeo-python-driver](https://github.com/Open-EO/openeo-python-driver).",
capabilities_backend_version="1.2.3-foo",
Expand Down
34 changes: 34 additions & 0 deletions openeo_driver/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from typing import Any, Callable, Collection, Dict, Optional, Pattern, Tuple, Union
from unittest import mock

import attrs
import openeo
import openeo.processes
import pytest
Expand All @@ -24,6 +25,7 @@
from openeo.capabilities import ComparableVersion
from werkzeug.datastructures import Headers

from openeo_driver.config.load import ConfigGetter, _backend_config_getter
from openeo_driver.users.auth import HttpAuthHandler
from openeo_driver.util.geometry import as_geojson_feature, as_geojson_feature_collection
from openeo_driver.utils import generate_unique_id
Expand Down Expand Up @@ -667,3 +669,35 @@ def run(queue: multiprocessing.Queue):
server_process.join(timeout=2)
_log.info(f"ephemeral_fileserver: terminated with exitcode={server_process.exitcode}")
server_process.close()


def config_overrides(config_getter: ConfigGetter = _backend_config_getter, **kwargs):
"""
*Only to be used in tests*
`mock.patch` based mocker to override the config returned by `get_backend_config()`
Can be used as context manager
>>> with config_overrides(id="foobar"):
... ...
in a fixture (as context manager):
>>> @pytest.fixture
... def custom_setup()
... with config_overrides(id="foobar"):
... yield
or as test function decorator
>>> @config_overrides(id="foobar")
... def test_stuff():
"""
orig_config = config_getter.get()
config_kwargs = {
**attrs.asdict(orig_config, recurse=False),
**kwargs,
}
overriden_config = config_getter.expected_class(**config_kwargs)
return mock.patch.object(config_getter, "_config", new=overriden_config)
6 changes: 2 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from openeo_driver.backend import UserDefinedProcesses
from openeo_driver.config import OpenEoBackendConfig
from openeo_driver.dummy.dummy_backend import DummyBackendImplementation
from openeo_driver.testing import UrllibMocker
from openeo_driver.testing import UrllibMocker, config_overrides
from openeo_driver.util.logging import (
LOGGING_CONTEXT_BATCH_JOB,
LOGGING_CONTEXT_FLASK,
Expand Down Expand Up @@ -52,9 +52,7 @@ def backend_config(backend_config_overrides) -> OpenEoBackendConfig:
if backend_config_overrides is None:
yield openeo_driver.config.load.get_backend_config()
else:
with openeo_driver.config.load._backend_config_getter._pytest_override_context(
overrides=backend_config_overrides
):
with config_overrides(**backend_config_overrides):
yield openeo_driver.config.load.get_backend_config()


Expand Down
6 changes: 3 additions & 3 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,12 @@ class MyConfig(OpenEoBackendConfig):
@pytest.mark.parametrize(
["backend_config_overrides", "expected_id"],
[
(None, "dummy"),
({}, "dummy"),
(None, "openeo-python-driver-dummy"),
({}, "openeo-python-driver-dummy"),
({"id": "overridden!"}, "overridden!"),
],
)
def test_pytest_override_context(backend_config, backend_config_overrides, expected_id):
def test_backend_config_overrides(backend_config, backend_config_overrides, expected_id):
config = get_backend_config()
assert config.id == expected_id

Expand Down
51 changes: 51 additions & 0 deletions tests/test_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import pytest
import requests

from openeo_driver.config import get_backend_config
from openeo_driver.testing import (
ApiTester,
ApproxGeoJSONByBounds,
Expand All @@ -22,6 +23,7 @@
UrllibMocker,
approxify,
caplog_with_custom_formatter,
config_overrides,
ephemeral_fileserver,
preprocess_check_and_replace,
)
Expand Down Expand Up @@ -348,3 +350,52 @@ def test_types(self):
expected = ApproxGeoJSONByBounds(1, 1, 3, 4, types=["MultiPolygon"], abs=0.1)
assert geometry != expected
assert "Wrong type 'Polygon'" in repr(expected)


class TestConfigOverrides:
def test_baseline(self):
assert get_backend_config().id == "openeo-python-driver-dummy"

def test_context(self):
assert get_backend_config().id == "openeo-python-driver-dummy"
with config_overrides(id="hello-inline-context"):
assert get_backend_config().id == "hello-inline-context"
assert get_backend_config().id == "openeo-python-driver-dummy"

def test_context_nesting(self):
assert get_backend_config().id == "openeo-python-driver-dummy"
with config_overrides(id="hello-inline-context"):
assert get_backend_config().id == "hello-inline-context"
with config_overrides(id="hello-again"):
assert get_backend_config().id == "hello-again"
assert get_backend_config().id == "hello-inline-context"
assert get_backend_config().id == "openeo-python-driver-dummy"

@pytest.fixture
def special_stuff(self):
with config_overrides(id="hello-fixture"):
yield

def test_fixture(self, special_stuff):
assert get_backend_config().id == "hello-fixture"

def test_fixture_and_context(self, special_stuff):
assert get_backend_config().id == "hello-fixture"
with config_overrides(id="hello-inline-context"):
assert get_backend_config().id == "hello-inline-context"
assert get_backend_config().id == "hello-fixture"

@config_overrides(id="hello-decorator")
def test_decorator(self):
assert get_backend_config().id == "hello-decorator"

@config_overrides(id="hello-decorator")
def test_decorator_and_context(self):
assert get_backend_config().id == "hello-decorator"
with config_overrides(id="hello-inline-context"):
assert get_backend_config().id == "hello-inline-context"
assert get_backend_config().id == "hello-decorator"

@config_overrides(id="hello-decorator")
def test_decorator_vs_fixture(self, special_stuff):
assert get_backend_config().id == "hello-decorator"

0 comments on commit 7d2b335

Please sign in to comment.