Skip to content

Commit

Permalink
Raise error on invalid use of runpath placeholders
Browse files Browse the repository at this point in the history
  • Loading branch information
andreas-el committed Dec 1, 2023
1 parent 86a31ef commit b4899ed
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 7 deletions.
4 changes: 2 additions & 2 deletions docs/reference/configuration/keywords.rst
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,8 @@ Commonly used keywords
will be replaced by the realization number and iteration number when ERT creates the folders.
By default, RUNPATH is set to "simulations/realization-<IENS>/iter-<ITER>".

Deprecated syntax still allow use of two %d specifers. Use of less than two %d is prohibited.
The behaviour is identical to the default substitution.
Deprecated syntax still allow use of two `%d` specifers. Use of more than two `%d` specifiers,
using multiple `<IENS>` or `<ITER>` keywords or mixing styles is prohibited.

*Example:*

Expand Down
26 changes: 23 additions & 3 deletions src/ert/config/model_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,31 @@ def __init__(
self.history_source = history_source
self.jobname_format_string = _replace_runpath_format(jobname_format_string)
self.eclbase_format_string = _replace_runpath_format(eclbase_format_string)
self.runpath_format_string = _replace_runpath_format(runpath_format_string)

if self.runpath_format_string is not None and not any(
x in self.runpath_format_string for x in ["<ITER>", "<IENS>"]
# do not combine styles
if "%d" in runpath_format_string and any(
x in runpath_format_string for x in ["<ITER>", "<IENS>"]
):
raise ConfigValidationError(
f"RUNPATH provided is invalid: `{runpath_format_string}`. Valid example `{DEFAULT_RUNPATH}`"
)

# do not allow multiple occurrences
for kw in ["<ITER>", "<IENS>"]:
if runpath_format_string.count(kw) > 1:
raise ConfigValidationError(
f"RUNPATH provided is invalid: `{runpath_format_string}`. Valid example `{DEFAULT_RUNPATH}`"
)

# do not allow too many placeholders
if runpath_format_string.count("%d") > 2:
raise ConfigValidationError(
f"RUNPATH provided is invalid: `{runpath_format_string}`. Valid example `{DEFAULT_RUNPATH}`"
)

self.runpath_format_string = _replace_runpath_format(runpath_format_string)

if not any(x in self.runpath_format_string for x in ["<ITER>", "<IENS>"]):
logger.warning(
"RUNPATH keyword contains no value placeholders: "
f"`{runpath_format_string}`. Valid example: "
Expand Down
2 changes: 1 addition & 1 deletion tests/unit_tests/config/test_parser_error_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ def test_that_executable_directory_errors(dirname):
(
"""
NUM_REALIZATIONS 1
RUNPATH %d
RUNPATH %d/%d
RELPERM
MULTZ Hehe 2 l 1 2
Expand Down
36 changes: 35 additions & 1 deletion tests/unit_tests/test_run_path_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import pytest

from ert.config import ErtConfig
from ert.config import ConfigValidationError, ErtConfig
from ert.enkf_main import create_run_path, ensemble_context, sample_prior
from ert.run_context import RunContext
from ert.runpaths import Runpaths
Expand Down Expand Up @@ -469,3 +469,37 @@ def test_num_cpu_subst(monkeypatch, tmp_path, append, numcpu, storage):

with open("simulations/realization-0/iter-0/jobs.json", encoding="utf-8") as f:
assert f'"argList": ["{numcpu}"]' in f.read()


@pytest.mark.parametrize(
"run_path, expected_raise",
[
("simulations/realization-<IENS>/iter-<ITER>", False),
("simulations/realization-%d/iter-%d", False),
("simulations/realization-%d", False),
("simulations/realization-<IENS>/iter-%d", True),
("simulations/realization-<IENS>/iter-<IENS>", True),
("simulations/realization-<ITER>/iter-<ITER>", True),
("simulations/realization-%d/iter-%d/more-%d", True),
],
)
@pytest.mark.usefixtures("use_tmpdir")
def test_that_runpath_shall_contain_zero_or_two_substitutions(run_path, expected_raise):
"""
This checks that RUNPATH does not include too many or few substitution placeholders
"""
config_text = dedent(
"""
NUM_REALIZATIONS 2
"""
)
Path("config.ert").write_text(config_text + f"RUNPATH {run_path}", encoding="utf-8")

if expected_raise:
with pytest.raises(
ConfigValidationError,
match=f"RUNPATH provided is invalid: `.*{run_path}`.",
):
_ = ErtConfig.from_file("config.ert")
else:
_ = ErtConfig.from_file("config.ert")

0 comments on commit b4899ed

Please sign in to comment.