From fd4f8eea2df4f409e7aed37bfe9f0571b1c90ab6 Mon Sep 17 00:00:00 2001 From: Frode Aarstad Date: Fri, 22 Sep 2023 10:14:53 +0200 Subject: [PATCH] Fix runpath check for ensemble experiment --- src/ert/run_models/ensemble_experiment.py | 8 ++++ .../{models => run_models}/__init__.py | 0 tests/unit_tests/run_models/conftest.py | 15 ++++++ .../test_base_run_model.py | 15 ------ .../run_models/test_ensemble_experiment.py | 48 +++++++++++++++++++ .../test_multiple_data_assimilation.py | 0 6 files changed, 71 insertions(+), 15 deletions(-) rename tests/unit_tests/{models => run_models}/__init__.py (100%) create mode 100644 tests/unit_tests/run_models/conftest.py rename tests/unit_tests/{models => run_models}/test_base_run_model.py (89%) create mode 100644 tests/unit_tests/run_models/test_ensemble_experiment.py rename tests/unit_tests/{models => run_models}/test_multiple_data_assimilation.py (100%) diff --git a/src/ert/run_models/ensemble_experiment.py b/src/ert/run_models/ensemble_experiment.py index c4177f0bad3..20b5d5632d9 100644 --- a/src/ert/run_models/ensemble_experiment.py +++ b/src/ert/run_models/ensemble_experiment.py @@ -3,6 +3,7 @@ import asyncio import concurrent import logging +from pathlib import Path from typing import TYPE_CHECKING, Any, Dict from uuid import UUID @@ -169,3 +170,10 @@ def run_experiment( @classmethod def name(cls) -> str: return "Ensemble experiment" + + def check_if_runpath_exists(self) -> bool: + iteration = self._simulation_arguments.get("iter_num", 0) + active_mask = self._simulation_arguments.get("active_realizations", []) + active_realizations = [i for i in range(len(active_mask)) if active_mask[i]] + run_paths = self.facade.get_run_paths(active_realizations, iteration) + return any(Path(run_path).exists() for run_path in run_paths) diff --git a/tests/unit_tests/models/__init__.py b/tests/unit_tests/run_models/__init__.py similarity index 100% rename from tests/unit_tests/models/__init__.py rename to tests/unit_tests/run_models/__init__.py diff --git a/tests/unit_tests/run_models/conftest.py b/tests/unit_tests/run_models/conftest.py new file mode 100644 index 00000000000..08b14655fd4 --- /dev/null +++ b/tests/unit_tests/run_models/conftest.py @@ -0,0 +1,15 @@ +import os + +import pytest + + +@pytest.fixture +def create_dummy_run_path(tmpdir): + run_path = os.path.join(tmpdir, "out") + os.mkdir(run_path) + os.mkdir(os.path.join(run_path, "realization-0")) + os.mkdir(os.path.join(run_path, "realization-0/iter-0")) + os.mkdir(os.path.join(run_path, "realization-1")) + os.mkdir(os.path.join(run_path, "realization-1/iter-0")) + os.mkdir(os.path.join(run_path, "realization-1/iter-1")) + yield os.chdir(tmpdir) diff --git a/tests/unit_tests/models/test_base_run_model.py b/tests/unit_tests/run_models/test_base_run_model.py similarity index 89% rename from tests/unit_tests/models/test_base_run_model.py rename to tests/unit_tests/run_models/test_base_run_model.py index 39fe4002d72..17d27046f86 100644 --- a/tests/unit_tests/models/test_base_run_model.py +++ b/tests/unit_tests/run_models/test_base_run_model.py @@ -1,4 +1,3 @@ -import os from unittest.mock import MagicMock from uuid import UUID @@ -73,18 +72,6 @@ def test_run_ensemble_evaluator(): run_context.deactivate_realization.assert_called_with(0) -@pytest.fixture -def create_dummy_run_path(tmpdir): - run_path = os.path.join(tmpdir, "out") - os.mkdir(run_path) - os.mkdir(os.path.join(run_path, "realization-0")) - os.mkdir(os.path.join(run_path, "realization-0/iter-0")) - os.mkdir(os.path.join(run_path, "realization-1")) - os.mkdir(os.path.join(run_path, "realization-1/iter-0")) - os.mkdir(os.path.join(run_path, "realization-1/iter-1")) - yield os.chdir(tmpdir) - - @pytest.mark.parametrize( "run_path, number_of_iterations, start_iteration, active_mask, expected", [ @@ -116,11 +103,9 @@ def get_run_path_mock(realizations, iteration=None): return [f"out/realization-{r}" for r in realizations] brm = BaseRunModel(simulation_arguments, None, None, None, None) - brm.facade = MagicMock( run_path=run_path, number_of_iterations=number_of_iterations, get_run_paths=get_run_path_mock, ) - assert brm.check_if_runpath_exists() == expected diff --git a/tests/unit_tests/run_models/test_ensemble_experiment.py b/tests/unit_tests/run_models/test_ensemble_experiment.py new file mode 100644 index 00000000000..5ac56637565 --- /dev/null +++ b/tests/unit_tests/run_models/test_ensemble_experiment.py @@ -0,0 +1,48 @@ +from unittest.mock import MagicMock + +import pytest + +from ert.run_models import EnsembleExperiment + + +@pytest.mark.parametrize( + "run_path, number_of_iterations, iter_num, active_mask, expected", + [ + ("out/realization-%d/iter-%d", 4, 2, [True, True, True, True], False), + ("out/realization-%d/iter-%d", 4, 1, [True, True, True, True], True), + ("out/realization-%d/iter-%d", 4, 1, [False, False, True, False], False), + ("out/realization-%d/iter-%d", 4, 0, [False, False, False, False], False), + ("out/realization-%d/iter-%d", 4, 0, [], False), + ("out/realization-%d", 2, 1, [False, True, True], True), + ("out/realization-%d", 2, 0, [False, False, True], False), + ], +) +def test_check_if_runpath_exists( + create_dummy_run_path, + run_path: str, + number_of_iterations: int, + iter_num: int, + active_mask: list, + expected: bool, +): + simulation_arguments = { + "iter_num": iter_num, + "active_realizations": active_mask, + } + + def get_run_path_mock(realizations, iteration=None): + if iteration is not None: + return [f"out/realization-{r}/iter-{iteration}" for r in realizations] + return [f"out/realization-{r}" for r in realizations] + + ensemble_experiment = EnsembleExperiment( + simulation_arguments, None, None, None, None + ) + + ensemble_experiment.facade = MagicMock( + run_path=run_path, + number_of_iterations=number_of_iterations, + get_run_paths=get_run_path_mock, + ) + + assert ensemble_experiment.check_if_runpath_exists() == expected diff --git a/tests/unit_tests/models/test_multiple_data_assimilation.py b/tests/unit_tests/run_models/test_multiple_data_assimilation.py similarity index 100% rename from tests/unit_tests/models/test_multiple_data_assimilation.py rename to tests/unit_tests/run_models/test_multiple_data_assimilation.py