From 3423c5a8f4ebf981cd4a1fdaa8cd2642a0885209 Mon Sep 17 00:00:00 2001 From: "Kernchen, Sophie" Date: Fri, 11 Jul 2025 10:19:37 +0200 Subject: [PATCH 1/8] Tests for HermesContext and HermesCache --- test/__init__.py | 0 test/hermes_test/model/test_base_context.py | 57 +++++++++++++++++---- 2 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 test/__init__.py diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/hermes_test/model/test_base_context.py b/test/hermes_test/model/test_base_context.py index bdf016b7..a83019dd 100644 --- a/test/hermes_test/model/test_base_context.py +++ b/test/hermes_test/model/test_base_context.py @@ -3,33 +3,70 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileContributor: Michael Meinel - +import pytest from pathlib import Path -from hermes.model.context import HermesContext +from hermes.model.context_manager import HermesContext, HermesCache def test_context_hermes_dir_default(): ctx = HermesContext() - assert ctx.hermes_dir == Path('.') / '.hermes' + assert ctx.cache_dir == Path('./.hermes').absolute() def test_context_hermes_dir_custom(): - ctx = HermesContext('spam') - assert ctx.hermes_dir == Path('spam') / '.hermes' + ctx = HermesContext('spam') # TODO: #367 + assert ctx.cache_dir == Path('spam') / '.hermes' + + +def test_get_context_default(): + ctx = HermesContext() + ctx.prepare_step("ham") + assert ctx["spam"]._cache_dir == Path('./.hermes/ham/spam').absolute() + + +def test_finalize_context(): + ctx = HermesContext() + ctx.prepare_step("ham") # TODO: #373 to fix, then you can delete one prepare_step + ctx.prepare_step("spam") + ctx.finalize_step("spam") + assert ctx["spam"]._cache_dir == Path('./.hermes/ham/spam').absolute() -def test_context_get_cache_default(): +def test_finalize_context_error_list_one_element(): ctx = HermesContext() - assert ctx.get_cache('spam', 'eggs') == Path('.') / '.hermes' / 'spam' / 'eggs.json' + ctx.prepare_step("ham") + with pytest.raises(ValueError): # TODO: #373 to fix, index out of range + ctx.finalize_step("spam") -def test_context_get_cache_cached(): +def test_finalize_context_error(): ctx = HermesContext() - ctx._caches[('spam', 'eggs')] = Path('spam_and_eggs') - assert ctx.get_cache('spam', 'eggs') == Path('spam_and_eggs') + ctx.prepare_step("ham") + ctx.prepare_step("eggs") + with pytest.raises(ValueError, match=f"Cannot end step spam while in eggs."): # TODO: #373 format string and error message + ctx.finalize_step("spam") + +@pytest.mark.dev +def test_cache(tmpdir): + ctx = HermesContext(Path(tmpdir)) + ctx.prepare_step("ham") + with ctx["spam"] as c: + c["bacon"] = {"data": "goose", "num": 2} + + path = Path('tmpdir/.hermes') / 'ham' / 'spam' / 'bacon.json' + + assert path.exists() + assert c._cached_data["bacon"] == {"data": "goose", "num": 2} + + +def test_hermes_cache_set(tmpdir): + cache = HermesCache(Path(tmpdir)) + cache["bacon"] = "eggs" + assert cache._cached_data == {"bacon": "eggs"} +@pytest.mark.dev def test_context_get_cache_create(tmpdir): ctx = HermesContext(tmpdir) subdir = Path(tmpdir) / '.hermes' / 'spam' From 6f4de13ecbf3e0fae48aaf804a26c90bb5408588 Mon Sep 17 00:00:00 2001 From: "Kernchen, Sophie" Date: Fri, 11 Jul 2025 10:29:06 +0200 Subject: [PATCH 2/8] Last tests for basic functionality --- test/hermes_test/model/test_base_context.py | 22 ++++++++++----------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/test/hermes_test/model/test_base_context.py b/test/hermes_test/model/test_base_context.py index a83019dd..7a3a3de5 100644 --- a/test/hermes_test/model/test_base_context.py +++ b/test/hermes_test/model/test_base_context.py @@ -1,8 +1,9 @@ -# SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR) +# SPDX-FileCopyrightText: 2025 German Aerospace Center (DLR) # # SPDX-License-Identifier: Apache-2.0 # SPDX-FileContributor: Michael Meinel +# SPDX-FileContributor: Sophie Kernchen import pytest from pathlib import Path @@ -44,18 +45,18 @@ def test_finalize_context_error(): ctx = HermesContext() ctx.prepare_step("ham") ctx.prepare_step("eggs") - with pytest.raises(ValueError, match=f"Cannot end step spam while in eggs."): # TODO: #373 format string and error message + # TODO: #373 format string and error message + with pytest.raises(ValueError, match=f"Cannot end step spam while in eggs."): ctx.finalize_step("spam") -@pytest.mark.dev + def test_cache(tmpdir): ctx = HermesContext(Path(tmpdir)) ctx.prepare_step("ham") with ctx["spam"] as c: c["bacon"] = {"data": "goose", "num": 2} - path = Path('tmpdir/.hermes') / 'ham' / 'spam' / 'bacon.json' - + path = tmpdir / Path('.hermes') / 'ham' / 'spam' / 'bacon.json' assert path.exists() assert c._cached_data["bacon"] == {"data": "goose", "num": 2} @@ -66,10 +67,7 @@ def test_hermes_cache_set(tmpdir): assert cache._cached_data == {"bacon": "eggs"} -@pytest.mark.dev -def test_context_get_cache_create(tmpdir): - ctx = HermesContext(tmpdir) - subdir = Path(tmpdir) / '.hermes' / 'spam' - - assert ctx.get_cache('spam', 'eggs', create=True) == subdir / 'eggs.json' - assert subdir.exists() +def test_hermes_cache_get(tmpdir): + cache = HermesCache(Path(tmpdir)) + cache._cached_data = {"bacon": "eggs"} + assert cache["bacon"] == "eggs" From 8933bde422dba324bb547b219fcdf400e2d3b2fc Mon Sep 17 00:00:00 2001 From: "Kernchen, Sophie" Date: Fri, 11 Jul 2025 13:11:33 +0200 Subject: [PATCH 3/8] Change tests to parameter type path is mandatory --- test/hermes_test/__init__.py | 3 --- test/hermes_test/model/test_base_context.py | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 test/hermes_test/__init__.py diff --git a/test/hermes_test/__init__.py b/test/hermes_test/__init__.py deleted file mode 100644 index faf5a2f5..00000000 --- a/test/hermes_test/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR) -# -# SPDX-License-Identifier: Apache-2.0 diff --git a/test/hermes_test/model/test_base_context.py b/test/hermes_test/model/test_base_context.py index 7a3a3de5..dba77ba0 100644 --- a/test/hermes_test/model/test_base_context.py +++ b/test/hermes_test/model/test_base_context.py @@ -16,7 +16,7 @@ def test_context_hermes_dir_default(): def test_context_hermes_dir_custom(): - ctx = HermesContext('spam') # TODO: #367 + ctx = HermesContext(Path('spam')) assert ctx.cache_dir == Path('spam') / '.hermes' From c886fbc0af01965dce7f2c82757bdf7b3a177e1a Mon Sep 17 00:00:00 2001 From: Sophie <133236526+SKernchen@users.noreply.github.com> Date: Mon, 14 Jul 2025 13:04:23 +0200 Subject: [PATCH 4/8] Apply suggestions with minimal changes Co-authored-by: Michael Meinel --- test/hermes_test/model/test_base_context.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/hermes_test/model/test_base_context.py b/test/hermes_test/model/test_base_context.py index dba77ba0..12c0e160 100644 --- a/test/hermes_test/model/test_base_context.py +++ b/test/hermes_test/model/test_base_context.py @@ -46,7 +46,7 @@ def test_finalize_context_error(): ctx.prepare_step("ham") ctx.prepare_step("eggs") # TODO: #373 format string and error message - with pytest.raises(ValueError, match=f"Cannot end step spam while in eggs."): + with pytest.raises(ValueError, match="Cannot end step spam while in eggs."): ctx.finalize_step("spam") @@ -58,6 +58,7 @@ def test_cache(tmpdir): path = tmpdir / Path('.hermes') / 'ham' / 'spam' / 'bacon.json' assert path.exists() + assert path.read() == '{"data": "goose", "num": 2}' assert c._cached_data["bacon"] == {"data": "goose", "num": 2} From e7002eb086d6a4259543b61a240772e510310095 Mon Sep 17 00:00:00 2001 From: "Kernchen, Sophie" Date: Mon, 14 Jul 2025 13:18:55 +0200 Subject: [PATCH 5/8] Fixme docstring and improve style --- src/hermes/model/context_manager.py | 10 ++++++++++ test/__init__.py | 3 +++ test/hermes_test/__init__.py | 3 +++ .../{test_base_context.py => test_context_manager.py} | 6 +++--- 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 test/hermes_test/__init__.py rename test/hermes_test/model/{test_base_context.py => test_context_manager.py} (89%) diff --git a/src/hermes/model/context_manager.py b/src/hermes/model/context_manager.py index e6975481..a6fc7687 100644 --- a/src/hermes/model/context_manager.py +++ b/src/hermes/model/context_manager.py @@ -54,11 +54,21 @@ def __init__(self, project_dir: pathlib.Path = pathlib.Path.cwd()): def prepare_step(self, step: str, *depends: str) -> None: self._current_step.append(step) + ''' @FIXME #373: + + def finalize_step(self, step: str) -> None: + current_step = self._current_step[-1] + if current_step != step: + raise ValueError(f"Cannot end step {step} while in {self._current_step[-1]}.") + self._current_step.pop() + ''' def finalize_step(self, step: str) -> None: current_step = self._current_step.pop() if current_step != step: raise ValueError("Cannot end step %s while in %s.", step, self._current_step[-1]) + + def __getitem__(self, source_name: str) -> HermesCache: subdir = self.cache_dir / self._current_step[-1] / source_name return HermesCache(subdir) diff --git a/test/__init__.py b/test/__init__.py index e69de29b..0e85f01e 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2025 German Aerospace Center (DLR) +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/test/hermes_test/__init__.py b/test/hermes_test/__init__.py new file mode 100644 index 00000000..0e85f01e --- /dev/null +++ b/test/hermes_test/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2025 German Aerospace Center (DLR) +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/test/hermes_test/model/test_base_context.py b/test/hermes_test/model/test_context_manager.py similarity index 89% rename from test/hermes_test/model/test_base_context.py rename to test/hermes_test/model/test_context_manager.py index 12c0e160..6a7514b9 100644 --- a/test/hermes_test/model/test_base_context.py +++ b/test/hermes_test/model/test_context_manager.py @@ -28,7 +28,7 @@ def test_get_context_default(): def test_finalize_context(): ctx = HermesContext() - ctx.prepare_step("ham") # TODO: #373 to fix, then you can delete one prepare_step + ctx.prepare_step("ham") # FIXME: #373 to fix, then you can delete one prepare_step ctx.prepare_step("spam") ctx.finalize_step("spam") assert ctx["spam"]._cache_dir == Path('./.hermes/ham/spam').absolute() @@ -37,7 +37,7 @@ def test_finalize_context(): def test_finalize_context_error_list_one_element(): ctx = HermesContext() ctx.prepare_step("ham") - with pytest.raises(ValueError): # TODO: #373 to fix, index out of range + with pytest.raises(ValueError): # FIXME: #373 to fix, index out of range ctx.finalize_step("spam") @@ -45,7 +45,7 @@ def test_finalize_context_error(): ctx = HermesContext() ctx.prepare_step("ham") ctx.prepare_step("eggs") - # TODO: #373 format string and error message + # FIXME: #373 format string and error message with pytest.raises(ValueError, match="Cannot end step spam while in eggs."): ctx.finalize_step("spam") From b9aaa9517986689df2d91503f3754745d4d844d2 Mon Sep 17 00:00:00 2001 From: Sophie <133236526+SKernchen@users.noreply.github.com> Date: Tue, 15 Jul 2025 14:14:25 +0200 Subject: [PATCH 6/8] Add consistent docstring for fixes for later Co-authored-by: Stephan Druskat --- src/hermes/model/context_manager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hermes/model/context_manager.py b/src/hermes/model/context_manager.py index a6fc7687..b9edbf6c 100644 --- a/src/hermes/model/context_manager.py +++ b/src/hermes/model/context_manager.py @@ -54,7 +54,8 @@ def __init__(self, project_dir: pathlib.Path = pathlib.Path.cwd()): def prepare_step(self, step: str, *depends: str) -> None: self._current_step.append(step) - ''' @FIXME #373: + ''' + FIXME: Implement this to fix #373 def finalize_step(self, step: str) -> None: current_step = self._current_step[-1] From d9561f4831b659e9a5309be056d7b7155412d9b7 Mon Sep 17 00:00:00 2001 From: "Kernchen, Sophie" Date: Mon, 28 Jul 2025 10:54:48 +0200 Subject: [PATCH 7/8] Fix Issues in context --- src/hermes/model/context_manager.py | 18 +++++------- .../hermes_test/model/test_context_manager.py | 29 ++++++++++++++----- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/hermes/model/context_manager.py b/src/hermes/model/context_manager.py index b9edbf6c..159e7922 100644 --- a/src/hermes/model/context_manager.py +++ b/src/hermes/model/context_manager.py @@ -54,22 +54,20 @@ def __init__(self, project_dir: pathlib.Path = pathlib.Path.cwd()): def prepare_step(self, step: str, *depends: str) -> None: self._current_step.append(step) - ''' - FIXME: Implement this to fix #373 - def finalize_step(self, step: str) -> None: + if len(self._current_step) < 1: + raise ValueError("There is no step to end.") current_step = self._current_step[-1] if current_step != step: raise ValueError(f"Cannot end step {step} while in {self._current_step[-1]}.") self._current_step.pop() - ''' - def finalize_step(self, step: str) -> None: - current_step = self._current_step.pop() - if current_step != step: - raise ValueError("Cannot end step %s while in %s.", step, self._current_step[-1]) - - def __getitem__(self, source_name: str) -> HermesCache: + if len(self._current_step) < 1: + raise HermesContexError("Prepare a step first.") subdir = self.cache_dir / self._current_step[-1] / source_name return HermesCache(subdir) + + +class HermesContexError(Exception): + pass diff --git a/test/hermes_test/model/test_context_manager.py b/test/hermes_test/model/test_context_manager.py index 6a7514b9..231e4df1 100644 --- a/test/hermes_test/model/test_context_manager.py +++ b/test/hermes_test/model/test_context_manager.py @@ -7,7 +7,7 @@ import pytest from pathlib import Path -from hermes.model.context_manager import HermesContext, HermesCache +from hermes.model.context_manager import HermesContext, HermesCache, HermesContexError def test_context_hermes_dir_default(): @@ -26,27 +26,40 @@ def test_get_context_default(): assert ctx["spam"]._cache_dir == Path('./.hermes/ham/spam').absolute() +def test_context_get_error(): + ctx = HermesContext() + ctx.prepare_step("ham") + ctx.finalize_step("ham") + with pytest.raises(HermesContexError, match="Prepare a step first."): + ctx["spam"]._cache_dir == Path('./.hermes/spam').absolute() + + +def test_finalize_context_one_item(): + ctx = HermesContext() + ctx.prepare_step("ham") + ctx.finalize_step("ham") + assert ctx._current_step == [] + + def test_finalize_context(): ctx = HermesContext() - ctx.prepare_step("ham") # FIXME: #373 to fix, then you can delete one prepare_step + ctx.prepare_step("ham") ctx.prepare_step("spam") ctx.finalize_step("spam") assert ctx["spam"]._cache_dir == Path('./.hermes/ham/spam').absolute() + assert ctx._current_step == ["ham"] -def test_finalize_context_error_list_one_element(): +def test_finalize_context_error_no_item(): ctx = HermesContext() - ctx.prepare_step("ham") - with pytest.raises(ValueError): # FIXME: #373 to fix, index out of range + with pytest.raises(ValueError, match="There is no step to end."): ctx.finalize_step("spam") def test_finalize_context_error(): ctx = HermesContext() ctx.prepare_step("ham") - ctx.prepare_step("eggs") - # FIXME: #373 format string and error message - with pytest.raises(ValueError, match="Cannot end step spam while in eggs."): + with pytest.raises(ValueError, match="Cannot end step spam while in ham."): ctx.finalize_step("spam") From 051f0ab95f36e46436539034df4a0d2ec4d51714 Mon Sep 17 00:00:00 2001 From: Sophie <133236526+SKernchen@users.noreply.github.com> Date: Mon, 28 Jul 2025 12:59:47 +0200 Subject: [PATCH 8/8] Remove unnecessary variable Co-authored-by: Michael Meinel --- src/hermes/model/context_manager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hermes/model/context_manager.py b/src/hermes/model/context_manager.py index 159e7922..0c641619 100644 --- a/src/hermes/model/context_manager.py +++ b/src/hermes/model/context_manager.py @@ -57,8 +57,7 @@ def prepare_step(self, step: str, *depends: str) -> None: def finalize_step(self, step: str) -> None: if len(self._current_step) < 1: raise ValueError("There is no step to end.") - current_step = self._current_step[-1] - if current_step != step: + if self._current_step[-1] != step: raise ValueError(f"Cannot end step {step} while in {self._current_step[-1]}.") self._current_step.pop()