From 8b4dc2a7d100700641ea5c44c54c9ba0c23d2d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Berland?= Date: Thu, 21 Nov 2024 13:36:40 +0100 Subject: [PATCH] Make find_smry() precise This solves a bug where find_unsmry() would not be able to locate the correct summary file even if it has the correct base for the Eclipse deck --- .../forward_models/res/script/ecl_run.py | 5 +- .../resources/test_ecl_run_new_config.py | 68 ++++++++++++++++++- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/ert/resources/forward_models/res/script/ecl_run.py b/src/ert/resources/forward_models/res/script/ecl_run.py index a5313fba2d9..f8351361e0a 100644 --- a/src/ert/resources/forward_models/res/script/ecl_run.py +++ b/src/ert/resources/forward_models/res/script/ecl_run.py @@ -167,10 +167,9 @@ def _is_unsmry(base: str, path: str) -> bool: "funsmry", ] - dir = basepath.parent base = basepath.name candidates: List[str] = list( - filter(lambda x: _is_unsmry(base, x), os.listdir(dir or ".")) + filter(lambda x: _is_unsmry(base, x), glob.glob(str(basepath) + "*")) ) if not candidates: return None @@ -178,7 +177,7 @@ def _is_unsmry(base: str, path: str) -> bool: raise ValueError( f"Ambiguous reference to unsmry in {basepath}, could be any of {candidates}" ) - return Path(dir) / candidates[0] + return Path(candidates[0]) def await_completed_unsmry_file( diff --git a/tests/ert/unit_tests/resources/test_ecl_run_new_config.py b/tests/ert/unit_tests/resources/test_ecl_run_new_config.py index 26d5a66a23e..7f2acde2b1e 100644 --- a/tests/ert/unit_tests/resources/test_ecl_run_new_config.py +++ b/tests/ert/unit_tests/resources/test_ecl_run_new_config.py @@ -154,6 +154,37 @@ def test_forward_model_cmd_line_api_works(source_root): assert Path("SPE1.OK").exists() +@pytest.mark.integration_test +@pytest.mark.requires_eclipse +@pytest.mark.usefixtures("use_tmpdir", "init_eclrun_config") +def test_eclrun_when_unsmry_is_ambiguous(source_root): + shutil.copy( + source_root / "test-data/ert/eclipse/SPE1.DATA", + "SPE1.DATA", + ) + # Mock files from another existing run + Path("PREVIOUS_SPE1.SMSPEC").touch() + Path("PREVIOUS_SPE1.UNSMRY").touch() + ecl_run.run(ecl_config.Ecl100Config(), ["SPE1.DATA", "--version=2019.3"]) + assert Path("SPE1.OK").exists() + + +@pytest.mark.integration_test +@pytest.mark.requires_eclipse +@pytest.mark.usefixtures("use_tmpdir", "init_eclrun_config") +def test_eclrun_when_unsmry_is_ambiguous_with_mpi(source_root): + deck = (source_root / "test-data/ert/eclipse/SPE1.DATA").read_text(encoding="utf-8") + deck = deck.replace("TITLE", "PARALLEL\n 2 /\n\nTITLE") + Path("SPE1.DATA").write_text(deck, encoding="utf-8") + # Mock files from another existing run + Path("PREVIOUS_SPE1.SMSPEC").touch() + Path("PREVIOUS_SPE1.UNSMRY").touch() + ecl_run.run( + ecl_config.Ecl100Config(), ["SPE1.DATA", "--version=2019.3", "--num-cpu=2"] + ) + assert Path("SPE1.OK").exists() + + @pytest.mark.integration_test @pytest.mark.requires_eclipse @pytest.mark.usefixtures("use_tmpdir", "init_eclrun_config") @@ -179,6 +210,19 @@ def test_eclrun_on_nosim(source_root): assert not Path("SPE1.UNSMRY").exists() +@pytest.mark.integration_test +@pytest.mark.requires_eclipse +@pytest.mark.usefixtures("use_tmpdir", "init_eclrun_config") +def test_eclrun_on_nosim_with_existing_unsmry_file(source_root): + """This emulates users rerunning Eclipse in an existing runpath""" + deck = (source_root / "test-data/ert/eclipse/SPE1.DATA").read_text(encoding="utf-8") + deck = deck.replace("TITLE", "NOSIM\n\nTITLE") + Path("SPE1.UNSMRY").write_text("", encoding="utf-8") + Path("SPE1.DATA").write_text(deck, encoding="utf-8") + ecl_run.run(ecl_config.Ecl100Config(), ["SPE1.DATA", "--version=2019.3"]) + assert Path("SPE1.OK").exists() + + @pytest.mark.integration_test @pytest.mark.requires_eclipse @pytest.mark.usefixtures("use_tmpdir", "init_eclrun_config") @@ -201,6 +245,27 @@ def test_await_completed_summary_file_times_out_on_nosim_with_mpi(source_root): ), "timeout in await_completed not triggered" +@pytest.mark.integration_test +@pytest.mark.requires_eclipse +@pytest.mark.usefixtures("use_tmpdir", "init_eclrun_config") +def test_eclrun_on_nosim_with_mpi_and_existing_unsmry_file(source_root): + """This emulates users rerunning Eclipse in an existing runpath, with MPI. + + The wait for timeout will not happen, since there is a summary file present. + + This test only effectively asserts that no crash occurs""" + deck = (source_root / "test-data/ert/eclipse/SPE1.DATA").read_text(encoding="utf-8") + deck = deck.replace("TITLE", "NOSIM\n\nPARALLEL\n 2 /\n\nTITLE") + Path("SPE1.UNSMRY").write_text("", encoding="utf-8") + Path("SPE1.DATA").write_text(deck, encoding="utf-8") + ecl_run.run( + ecl_config.Ecl100Config(), ["SPE1.DATA", "--version=2019.3", "--num-cpu=2"] + ) + # There is no assert on runtime because we cannot predict how long the Eclipse license + # checkout takes, otherwise we should assert that there is no await for unsmry completion. + assert Path("SPE1.OK").exists() + + @pytest.mark.integration_test @pytest.mark.requires_eclipse @pytest.mark.usefixtures("use_tmpdir", "init_eclrun_config") @@ -304,7 +369,7 @@ def test_mpi_run_is_managed_by_system_tool(source_root): (["foo/spe1.unsmry"], "foo/spe1", "foo/spe1.unsmry"), (["foo/SPE1.UNSMRY", "SPE1.UNSMRY"], "foo/SPE1", "foo/SPE1.UNSMRY"), (["foo/SPE1.UNSMRY", "SPE1.UNSMRY"], "SPE1", "SPE1.UNSMRY"), - (["EXTRA_SPE1.UNSMRY", "SPE1.UNSMRY"], "SPE1", "ValueError"), + (["EXTRA_SPE1.UNSMRY", "SPE1.UNSMRY"], "SPE1", "SPE1.UNSMRY"), (["EXTRA_SPE1.UNSMRY", "SPE1.UNSMRY"], "EXTRA_SPE1", "EXTRA_SPE1.UNSMRY"), (["SPE1.UNSMRY", "SPE1.FUNSMRY"], "SPE1", "ValueError"), ( @@ -325,7 +390,6 @@ def test_find_unsmry(paths_to_touch, basepath, expectation): ecl_run.find_unsmry(Path(basepath)) elif expectation is None: assert ecl_run.find_unsmry(Path(basepath)) is None - else: assert str(ecl_run.find_unsmry(Path(basepath))) == expectation