Skip to content

Commit 7d2b335

Browse files
committed
testing: replace _pytest_override_context with config_overrides
mock.patch based solution is simpler and more flexible
1 parent e3964a5 commit 7d2b335

File tree

7 files changed

+92
-22
lines changed

7 files changed

+92
-22
lines changed

openeo_driver/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.77.2a1"
1+
__version__ = "0.77.3a1"

openeo_driver/config/load.py

-13
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,6 @@ def flush(self):
9696
"""Flush the config, to force a reload on next get."""
9797
self._config = None
9898

99-
@contextlib.contextmanager
100-
def _pytest_override_context(self, overrides: Optional[dict] = None):
101-
"""
102-
Important: this context manger specifically intended for usage in pytest fixtures,
103-
to override specific config fields during the lifetime of a test
104-
"""
105-
orig = self.get()
106-
kwargs = {**attrs.asdict(orig, recurse=False), **overrides}
107-
overridden = self.expected_class(**kwargs)
108-
self._config = overridden
109-
yield overridden
110-
self.flush()
111-
11299

113100
# "Singleton by convention" config getter
114101
_backend_config_getter = ConfigGetter()

openeo_driver/dummy/dummy_config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def _valid_basic_auth(username: str, password: str) -> bool:
6666

6767

6868
config = OpenEoBackendConfig(
69-
id="dummy",
69+
id="openeo-python-driver-dummy",
7070
capabilities_title="Dummy openEO Backend",
7171
capabilities_description="Dummy openEO backend provided by [openeo-python-driver](https://github.com/Open-EO/openeo-python-driver).",
7272
capabilities_backend_version="1.2.3-foo",

openeo_driver/testing.py

+34
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from typing import Any, Callable, Collection, Dict, Optional, Pattern, Tuple, Union
1515
from unittest import mock
1616

17+
import attrs
1718
import openeo
1819
import openeo.processes
1920
import pytest
@@ -24,6 +25,7 @@
2425
from openeo.capabilities import ComparableVersion
2526
from werkzeug.datastructures import Headers
2627

28+
from openeo_driver.config.load import ConfigGetter, _backend_config_getter
2729
from openeo_driver.users.auth import HttpAuthHandler
2830
from openeo_driver.util.geometry import as_geojson_feature, as_geojson_feature_collection
2931
from openeo_driver.utils import generate_unique_id
@@ -667,3 +669,35 @@ def run(queue: multiprocessing.Queue):
667669
server_process.join(timeout=2)
668670
_log.info(f"ephemeral_fileserver: terminated with exitcode={server_process.exitcode}")
669671
server_process.close()
672+
673+
674+
def config_overrides(config_getter: ConfigGetter = _backend_config_getter, **kwargs):
675+
"""
676+
*Only to be used in tests*
677+
678+
`mock.patch` based mocker to override the config returned by `get_backend_config()`
679+
680+
Can be used as context manager
681+
682+
>>> with config_overrides(id="foobar"):
683+
... ...
684+
685+
in a fixture (as context manager):
686+
687+
>>> @pytest.fixture
688+
... def custom_setup()
689+
... with config_overrides(id="foobar"):
690+
... yield
691+
692+
or as test function decorator
693+
694+
>>> @config_overrides(id="foobar")
695+
... def test_stuff():
696+
"""
697+
orig_config = config_getter.get()
698+
config_kwargs = {
699+
**attrs.asdict(orig_config, recurse=False),
700+
**kwargs,
701+
}
702+
overriden_config = config_getter.expected_class(**config_kwargs)
703+
return mock.patch.object(config_getter, "_config", new=overriden_config)

tests/conftest.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from openeo_driver.backend import UserDefinedProcesses
1616
from openeo_driver.config import OpenEoBackendConfig
1717
from openeo_driver.dummy.dummy_backend import DummyBackendImplementation
18-
from openeo_driver.testing import UrllibMocker
18+
from openeo_driver.testing import UrllibMocker, config_overrides
1919
from openeo_driver.util.logging import (
2020
LOGGING_CONTEXT_BATCH_JOB,
2121
LOGGING_CONTEXT_FLASK,
@@ -52,9 +52,7 @@ def backend_config(backend_config_overrides) -> OpenEoBackendConfig:
5252
if backend_config_overrides is None:
5353
yield openeo_driver.config.load.get_backend_config()
5454
else:
55-
with openeo_driver.config.load._backend_config_getter._pytest_override_context(
56-
overrides=backend_config_overrides
57-
):
55+
with config_overrides(**backend_config_overrides):
5856
yield openeo_driver.config.load.get_backend_config()
5957

6058

tests/test_config.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,12 @@ class MyConfig(OpenEoBackendConfig):
158158
@pytest.mark.parametrize(
159159
["backend_config_overrides", "expected_id"],
160160
[
161-
(None, "dummy"),
162-
({}, "dummy"),
161+
(None, "openeo-python-driver-dummy"),
162+
({}, "openeo-python-driver-dummy"),
163163
({"id": "overridden!"}, "overridden!"),
164164
],
165165
)
166-
def test_pytest_override_context(backend_config, backend_config_overrides, expected_id):
166+
def test_backend_config_overrides(backend_config, backend_config_overrides, expected_id):
167167
config = get_backend_config()
168168
assert config.id == expected_id
169169

tests/test_testing.py

+51
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import pytest
1212
import requests
1313

14+
from openeo_driver.config import get_backend_config
1415
from openeo_driver.testing import (
1516
ApiTester,
1617
ApproxGeoJSONByBounds,
@@ -22,6 +23,7 @@
2223
UrllibMocker,
2324
approxify,
2425
caplog_with_custom_formatter,
26+
config_overrides,
2527
ephemeral_fileserver,
2628
preprocess_check_and_replace,
2729
)
@@ -348,3 +350,52 @@ def test_types(self):
348350
expected = ApproxGeoJSONByBounds(1, 1, 3, 4, types=["MultiPolygon"], abs=0.1)
349351
assert geometry != expected
350352
assert "Wrong type 'Polygon'" in repr(expected)
353+
354+
355+
class TestConfigOverrides:
356+
def test_baseline(self):
357+
assert get_backend_config().id == "openeo-python-driver-dummy"
358+
359+
def test_context(self):
360+
assert get_backend_config().id == "openeo-python-driver-dummy"
361+
with config_overrides(id="hello-inline-context"):
362+
assert get_backend_config().id == "hello-inline-context"
363+
assert get_backend_config().id == "openeo-python-driver-dummy"
364+
365+
def test_context_nesting(self):
366+
assert get_backend_config().id == "openeo-python-driver-dummy"
367+
with config_overrides(id="hello-inline-context"):
368+
assert get_backend_config().id == "hello-inline-context"
369+
with config_overrides(id="hello-again"):
370+
assert get_backend_config().id == "hello-again"
371+
assert get_backend_config().id == "hello-inline-context"
372+
assert get_backend_config().id == "openeo-python-driver-dummy"
373+
374+
@pytest.fixture
375+
def special_stuff(self):
376+
with config_overrides(id="hello-fixture"):
377+
yield
378+
379+
def test_fixture(self, special_stuff):
380+
assert get_backend_config().id == "hello-fixture"
381+
382+
def test_fixture_and_context(self, special_stuff):
383+
assert get_backend_config().id == "hello-fixture"
384+
with config_overrides(id="hello-inline-context"):
385+
assert get_backend_config().id == "hello-inline-context"
386+
assert get_backend_config().id == "hello-fixture"
387+
388+
@config_overrides(id="hello-decorator")
389+
def test_decorator(self):
390+
assert get_backend_config().id == "hello-decorator"
391+
392+
@config_overrides(id="hello-decorator")
393+
def test_decorator_and_context(self):
394+
assert get_backend_config().id == "hello-decorator"
395+
with config_overrides(id="hello-inline-context"):
396+
assert get_backend_config().id == "hello-inline-context"
397+
assert get_backend_config().id == "hello-decorator"
398+
399+
@config_overrides(id="hello-decorator")
400+
def test_decorator_vs_fixture(self, special_stuff):
401+
assert get_backend_config().id == "hello-decorator"

0 commit comments

Comments
 (0)