Skip to content

Commit

Permalink
Raise error on faulty result file and missing report steps
Browse files Browse the repository at this point in the history
(cherry-picked from commit dd7b260)
  • Loading branch information
yngve-sk authored and Yngve S. Kristiansen committed Jul 20, 2023
1 parent b5ab212 commit 4e07273
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 14 deletions.
35 changes: 22 additions & 13 deletions src/ert/_c_wrappers/enkf/ensemble_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from ert._c_wrappers.enkf.config.surface_config import SurfaceConfig
from ert._c_wrappers.enkf.config_keys import ConfigKeys
from ert.parsing import ConfigValidationError, ConfigWarning, ErrorInfo
from ert.parsing.context_values import ContextList, ContextValue
from ert.storage.field_utils.field_utils import Shape, get_shape

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -241,7 +242,7 @@ def __init__(
self.addNode(self.get_field_node(field, grid_file, dims))

@staticmethod
def gen_data_node(gen_data: List[str]) -> Optional[GenDataConfig]:
def gen_data_node(gen_data: ContextList[ContextValue]) -> Optional[GenDataConfig]:
options = _option_dict(gen_data, 1)
name = gen_data[0]
res_file = options.get(ConfigKeys.RESULT_FILE)
Expand All @@ -254,21 +255,29 @@ def gen_data_node(gen_data: List[str]) -> Optional[GenDataConfig]:
report_steps = rangestring_to_list(options.get(ConfigKeys.REPORT_STEPS, ""))

if os.path.isabs(res_file) or "%d" not in res_file:
logger.error(
f"The RESULT_FILE:{res_file} setting for {name} is invalid - "
"must have an embedded %d - and be a relative path"
result_file_context: ContextValue = next(
x for x in gen_data if x.startswith("RESULT_FILE:")
)
elif not report_steps:
logger.error(
"The GEN_DATA keywords must have a REPORT_STEPS:xxxx defined"
"Several report steps separated with ',' and ranges with '-'"
"can be listed"
raise ConfigValidationError.from_info(
ErrorInfo(
filename=result_file_context.token.filename,
message=f"The RESULT_FILE:{res_file} setting for {name} is "
f"invalid - must have an embedded %d and be a relative path",
).set_context(result_file_context)
)
else:
gdc = GenDataConfig(
name=name, input_file=res_file, report_steps=report_steps

if not report_steps:
raise ConfigValidationError.from_info(
ErrorInfo(
filename=gen_data.keyword_token.filename,
message="The GEN_DATA keywords must have REPORT_STEPS:xxxx"
" defined. Several report steps separated with ',' "
"and ranges with '-' can be listed",
).set_context_keyword(gen_data.keyword_token)
)
return gdc

gdc = GenDataConfig(name=name, input_file=res_file, report_steps=report_steps)
return gdc

@staticmethod
def get_surface_node(surface: List[str]) -> SurfaceConfig:
Expand Down
3 changes: 2 additions & 1 deletion src/ert/parsing/lark_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,8 @@ def _handle_includes(
filename=config_file,
).set_context(error_context)
)
continue

args = args[0:1]

file_to_include = _substitute_token(defines, args[0])

Expand Down
57 changes: 57 additions & 0 deletions tests/test_config_parsing/test_parser_error_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,17 @@ def assert_that_config_leads_to_error(

with pytest.raises(ConfigValidationError) as caught_error:
ErtConfig.from_file(config_filename, use_new_parser=True)
# If the ert config did not raise any errors
# we manually raise an "empty" error to make
# this raise an assertion error that can be
# acted upon from assert_that_config_does_not_lead_to_error
raise ConfigValidationError(errors=[])

collected_errors = caught_error.value.errors

if len(collected_errors) == 0:
raise AssertionError("Config did not lead to any errors")

# Find errors in matching file
errors_matching_filename = find_and_assert_errors_matching_filename(
errors=collected_errors, filename=expected_error.filename
Expand Down Expand Up @@ -1059,3 +1067,52 @@ def test_that_deprecations_are_handled(contents, expected_errors):
assert_that_config_leads_to_warning(
config_file_contents=contents, expected_error=expected_error
)


@pytest.mark.usefixtures("use_tmpdir")
def test_that_invalid_ensemble_result_file_errors():
assert_that_config_leads_to_error(
config_file_contents=dedent(
"""
NUM_REALIZATIONS 1
GEN_DATA RFT_3-1_R_DATA INPUT_FORMAT:ASCII REPORT_STEPS:100 RESULT_FILE:RFT_3-1_R_<ITER>
"""
),
expected_error=ExpectedErrorInfo(
match="must have an embedded %d",
line=3,
column=61,
end_column=89,
),
)


@pytest.mark.usefixtures("use_tmpdir")
def test_that_missing_report_steps_errors():
assert_that_config_leads_to_error(
config_file_contents=dedent(
"""
NUM_REALIZATIONS 1
GEN_DATA RFT_3-1_R_DATA INPUT_FORMAT:ASCII RESULT_FILE:RFT_3-1_R%d
"""
),
expected_error=ExpectedErrorInfo(
match="REPORT_STEPS",
line=3,
column=1,
end_column=9,
),
)


@pytest.mark.usefixtures("use_tmpdir")
def test_that_valid_gen_data_does_not_error():
assert_that_config_does_not_lead_to_error(
config_file_contents=dedent(
"""
NUM_REALIZATIONS 1
GEN_DATA RFT_3-1_R_DATA INPUT_FORMAT:ASCII REPORT_STEPS:100 RESULT_FILE:RFT_3-1_R%d
"""
),
unexpected_error=ExpectedErrorInfo(),
)

0 comments on commit 4e07273

Please sign in to comment.