diff --git a/src/ert/cli/workflow.py b/src/ert/cli/workflow.py index c41806dda56..d53d9a5257c 100644 --- a/src/ert/cli/workflow.py +++ b/src/ert/cli/workflow.py @@ -3,6 +3,7 @@ import logging from typing import TYPE_CHECKING +from ert.runpaths import Runpaths from ert.workflow_runner import WorkflowRunner if TYPE_CHECKING: @@ -20,7 +21,14 @@ def execute_workflow( msg = "Workflow {} is not in the list of available workflows" logger.error(msg.format(workflow_name)) return - runner = WorkflowRunner(workflow=workflow, storage=storage, ert_config=ert_config) + run_paths = Runpaths( + jobname_format=ert_config.model_config.jobname_format_string, + runpath_format=ert_config.model_config.runpath_format_string, + filename=str(ert_config.runpath_file), + substitutions=ert_config.substitutions, + eclbase=ert_config.model_config.eclbase_format_string, + ) + runner = WorkflowRunner(workflow=workflow, storage=storage, run_paths=run_paths) runner.run_blocking() if not all(v["completed"] for v in runner.workflowReport().values()): logger.error(f"Workflow {workflow_name} failed!") diff --git a/src/ert/gui/tools/export/exporter.py b/src/ert/gui/tools/export/exporter.py index 1c405847bf7..95480601663 100644 --- a/src/ert/gui/tools/export/exporter.py +++ b/src/ert/gui/tools/export/exporter.py @@ -29,7 +29,7 @@ def run_export(self, parameters: list[Any]) -> None: export_job_runner = WorkflowJobRunner(self.export_job) user_warn = export_job_runner.run( - fixtures={"storage": self._notifier.storage, "ert_config": self.config}, + fixtures={"storage": self._notifier.storage}, arguments=parameters, ) if export_job_runner.hasFailed(): diff --git a/src/ert/gui/tools/plugins/plugin_runner.py b/src/ert/gui/tools/plugins/plugin_runner.py index 1fea02f6edc..2c50441fbd0 100644 --- a/src/ert/gui/tools/plugins/plugin_runner.py +++ b/src/ert/gui/tools/plugins/plugin_runner.py @@ -6,12 +6,12 @@ from _ert.threading import ErtThread from ert.config import CancelPluginException +from ert.runpaths import Runpaths from ert.workflow_runner import WorkflowJobRunner from .process_job_dialog import ProcessJobDialog if TYPE_CHECKING: - from ert.config import ErtConfig from ert.storage import LocalStorage from .plugin import Plugin @@ -19,13 +19,12 @@ class PluginRunner: def __init__( - self, plugin: Plugin, ert_config: ErtConfig, storage: LocalStorage + self, plugin: Plugin, run_paths: Runpaths, storage: LocalStorage ) -> None: super().__init__() - self.ert_config = ert_config + self.run_paths = run_paths self.storage = storage self.__plugin = plugin - self.__plugin_finished_callback: Callable[[], None] = lambda: None self.__result = None @@ -35,9 +34,8 @@ def __init__( def run(self) -> None: try: plugin = self.__plugin - arguments = plugin.getArguments( - fixtures={"storage": self.storage, "ert_config": self.ert_config} + fixtures={"storage": self.storage, "run_paths": self.run_paths} ) dialog = ProcessJobDialog(plugin.getName(), plugin.getParentWindow()) dialog.setObjectName("process_job_dialog") @@ -45,7 +43,7 @@ def run(self) -> None: dialog.cancelConfirmed.connect(self.cancel) fixtures = { k: getattr(self, k) - for k in ["storage", "ert_config"] + for k in ["storage", "run_paths"] if getattr(self, k) } workflow_job_thread = ErtThread( diff --git a/src/ert/gui/tools/plugins/plugins_tool.py b/src/ert/gui/tools/plugins/plugins_tool.py index b1153553836..7d6d3b4603c 100644 --- a/src/ert/gui/tools/plugins/plugins_tool.py +++ b/src/ert/gui/tools/plugins/plugins_tool.py @@ -6,6 +6,7 @@ from PyQt6.QtWidgets import QMenu from ert.gui.tools import Tool +from ert.runpaths import Runpaths from .plugin_runner import PluginRunner @@ -35,8 +36,15 @@ def __init__( self.__plugins = {} self.menu = QMenu("&Plugins") + runpaths = Runpaths( + jobname_format=ert_config.model_config.jobname_format_string, + runpath_format=ert_config.model_config.runpath_format_string, + filename=str(ert_config.runpath_file), + substitutions=ert_config.substitutions, + eclbase=ert_config.model_config.eclbase_format_string, + ) for plugin in plugin_handler: - plugin_runner = PluginRunner(plugin, ert_config, notifier.storage) + plugin_runner = PluginRunner(plugin, runpaths, notifier.storage) plugin_runner.setPluginFinishedCallback(self.trigger) self.__plugins[plugin] = plugin_runner diff --git a/src/ert/gui/tools/workflows/run_workflow_widget.py b/src/ert/gui/tools/workflows/run_workflow_widget.py index 2fe3157f2c7..1d31f18e89e 100644 --- a/src/ert/gui/tools/workflows/run_workflow_widget.py +++ b/src/ert/gui/tools/workflows/run_workflow_widget.py @@ -20,6 +20,7 @@ from _ert.threading import ErtThread from ert.gui.ertwidgets import EnsembleSelector from ert.gui.tools.workflows.workflow_dialog import WorkflowDialog +from ert.runpaths import Runpaths from ert.workflow_runner import WorkflowRunner if TYPE_CHECKING: @@ -128,6 +129,13 @@ def startWorkflow(self) -> None: workflow, storage=self.storage, ensemble=self.source_ensemble_selector.currentData(), + run_paths=Runpaths( + jobname_format=self.config.model_config.jobname_format_string, + runpath_format=self.config.model_config.runpath_format_string, + filename=str(self.config.runpath_file), + substitutions=self.config.substitutions, + eclbase=self.config.model_config.eclbase_format_string, + ), ) self._workflow_runner.run() diff --git a/src/ert/plugins/hook_implementations/workflows/csv_export.py b/src/ert/plugins/hook_implementations/workflows/csv_export.py index e271c27af89..1e96931775f 100644 --- a/src/ert/plugins/hook_implementations/workflows/csv_export.py +++ b/src/ert/plugins/hook_implementations/workflows/csv_export.py @@ -1,12 +1,14 @@ import json import os from collections.abc import Sequence +from typing import TYPE_CHECKING import pandas as pd from ert import ErtScript, LibresFacade -from ert.config import ErtConfig -from ert.storage import Storage + +if TYPE_CHECKING: + from ert.storage import Ensemble def loadDesignMatrix(filename: str) -> pd.DataFrame: @@ -52,8 +54,6 @@ def getDescription() -> str: def run( self, - ert_config: ErtConfig, - storage: Storage, workflow_args: Sequence[str], ) -> str: output_file = workflow_args[0] @@ -61,14 +61,13 @@ def run( design_matrix_path = None if len(workflow_args) < 3 else workflow_args[2] _ = True if len(workflow_args) < 4 else workflow_args[3] drop_const_cols = False if len(workflow_args) < 5 else workflow_args[4] - facade = LibresFacade(ert_config) ensemble_data_as_dict = ( json.loads(ensemble_data_as_json) if ensemble_data_as_json else {} ) # Use the keys (UUIDs as strings) to get ensembles - ensembles = [] + ensembles: list[Ensemble] = [] for ensemble_id in ensemble_data_as_dict: assert self.storage is not None ensemble = self.storage.get_ensemble(ensemble_id) @@ -96,12 +95,12 @@ def run( if not design_matrix_data.empty: ensemble_data = ensemble_data.join(design_matrix_data, how="outer") - misfit_data = facade.load_all_misfit_data(ensemble) + misfit_data = LibresFacade.load_all_misfit_data(ensemble) if not misfit_data.empty: ensemble_data = ensemble_data.join(misfit_data, how="outer") - - summary_data = ensemble.load_all_summary_data() - if not summary_data.empty: + realizations = ensemble.get_realization_list_with_responses() + summary_data = ensemble.load_responses("summary", tuple(realizations)) + if not summary_data.is_empty(): ensemble_data = ensemble_data.join(summary_data, how="outer") else: ensemble_data["Date"] = None @@ -114,8 +113,8 @@ def run( ) data = pd.concat([data, ensemble_data]) - - data = data.reorder_levels(["Realization", "Iteration", "Date", "Ensemble"]) + if not data.empty: + data = data.reorder_levels(["Realization", "Iteration", "Date", "Ensemble"]) if drop_const_cols: data = data.loc[:, (data != data.iloc[0]).any()] diff --git a/src/ert/plugins/hook_implementations/workflows/export_misfit_data.py b/src/ert/plugins/hook_implementations/workflows/export_misfit_data.py index f7e44887a0c..77fc662b6d0 100644 --- a/src/ert/plugins/hook_implementations/workflows/export_misfit_data.py +++ b/src/ert/plugins/hook_implementations/workflows/export_misfit_data.py @@ -8,7 +8,6 @@ from ert.exceptions import StorageError if TYPE_CHECKING: - from ert.config import ErtConfig from ert.storage import Ensemble @@ -23,17 +22,14 @@ class ExportMisfitDataJob(ErtScript): ((response_value - observation_data) / observation_std)**2 """ - def run( - self, ert_config: ErtConfig, ensemble: Ensemble, workflow_args: list[Any] - ) -> None: + def run(self, ensemble: Ensemble, workflow_args: list[Any]) -> None: target_file = "misfit.hdf" if not workflow_args else workflow_args[0] realizations = ensemble.get_realization_list_with_responses() from ert import LibresFacade # noqa: PLC0415 (circular import) - facade = LibresFacade(ert_config) - misfit = facade.load_all_misfit_data(ensemble) + misfit = LibresFacade.load_all_misfit_data(ensemble) if len(realizations) == 0 or misfit.empty: raise StorageError("No responses loaded") misfit.columns = pd.Index([val.split(":")[1] for val in misfit.columns]) diff --git a/src/ert/plugins/hook_implementations/workflows/export_runpath.py b/src/ert/plugins/hook_implementations/workflows/export_runpath.py index 18e78be5f5e..b951f9a61d1 100644 --- a/src/ert/plugins/hook_implementations/workflows/export_runpath.py +++ b/src/ert/plugins/hook_implementations/workflows/export_runpath.py @@ -7,7 +7,7 @@ from ert.validation import rangestring_to_list if TYPE_CHECKING: - from ert.config import ErtConfig + from ert.storage import Ensemble class ExportRunpathJob(ErtScript): @@ -33,20 +33,18 @@ class ExportRunpathJob(ErtScript): file. """ - def run(self, ert_config: ErtConfig, workflow_args: list[Any]) -> None: + def run( + self, run_paths: Runpaths, ensemble: Ensemble, workflow_args: list[Any] + ) -> None: args = " ".join(workflow_args).split() # Make sure args is a list of words - run_paths = Runpaths( - jobname_format=ert_config.model_config.jobname_format_string, - runpath_format=ert_config.model_config.runpath_format_string, - filename=str(ert_config.runpath_file), - substitutions=ert_config.substitutions, - eclbase=ert_config.model_config.eclbase_format_string, - ) + assert ensemble + iter = ensemble.iteration + reals = ensemble.ensemble_size run_paths.write_runpath_list( *self.get_ranges( args, - ert_config.analysis_config.num_iterations, - ert_config.model_config.num_realizations, + iter, + reals, ) ) diff --git a/src/ert/run_models/base_run_model.py b/src/ert/run_models/base_run_model.py index 0bba4d2c818..6433683a7ec 100644 --- a/src/ert/run_models/base_run_model.py +++ b/src/ert/run_models/base_run_model.py @@ -677,11 +677,12 @@ def validate_successful_realizations_count(self) -> None: def run_workflows( self, runtime: HookRuntime, - storage: Storage | None = None, ensemble: Ensemble | None = None, ) -> None: for workflow in self._hooked_workflows[runtime]: - WorkflowRunner(workflow, storage, ensemble).run_blocking() + WorkflowRunner( + workflow, self._storage, ensemble, self.run_paths + ).run_blocking() def _evaluate_and_postprocess( self, @@ -703,7 +704,7 @@ def _evaluate_and_postprocess( context_env=self._context_env, ) - self.run_workflows(HookRuntime.PRE_SIMULATION, self._storage, ensemble) + self.run_workflows(HookRuntime.PRE_SIMULATION, ensemble) successful_realizations = self.run_ensemble_evaluator( run_args, ensemble, @@ -729,7 +730,7 @@ def _evaluate_and_postprocess( f"{self.ensemble_size - num_successful_realizations}" ) logger.info(f"Experiment run finished in: {self.get_runtime()}s") - self.run_workflows(HookRuntime.POST_SIMULATION, self._storage, ensemble) + self.run_workflows(HookRuntime.POST_SIMULATION, ensemble) return num_successful_realizations @@ -802,8 +803,8 @@ def update( prior_ensemble=prior, ) if prior.iteration == 0: - self.run_workflows(HookRuntime.PRE_FIRST_UPDATE, self._storage, prior) - self.run_workflows(HookRuntime.PRE_UPDATE, self._storage, prior) + self.run_workflows(HookRuntime.PRE_FIRST_UPDATE, prior) + self.run_workflows(HookRuntime.PRE_UPDATE, prior) try: smoother_update( prior, @@ -825,5 +826,5 @@ def update( "Update algorithm failed for iteration:" f"{posterior.iteration}. The following error occurred: {e}" ) from e - self.run_workflows(HookRuntime.POST_UPDATE, self._storage, prior) + self.run_workflows(HookRuntime.POST_UPDATE, prior) return posterior diff --git a/src/ert/run_models/ensemble_experiment.py b/src/ert/run_models/ensemble_experiment.py index a7aac4d0563..318018c9864 100644 --- a/src/ert/run_models/ensemble_experiment.py +++ b/src/ert/run_models/ensemble_experiment.py @@ -93,7 +93,6 @@ def run_experiment( raise ErtRunError(str(exc)) from exc if not restart: - self.run_workflows(HookRuntime.PRE_EXPERIMENT) self.experiment = self._storage.create_experiment( name=self.experiment_name, parameters=( @@ -109,6 +108,7 @@ def run_experiment( name=self.ensemble_name, ensemble_size=self.ensemble_size, ) + self.run_workflows(HookRuntime.PRE_EXPERIMENT, self.ensemble) else: self.active_realizations = self._create_mask_from_failed_realizations() @@ -143,7 +143,7 @@ def run_experiment( self.ensemble, evaluator_server_config, ) - self.run_workflows(HookRuntime.POST_EXPERIMENT) + self.run_workflows(HookRuntime.POST_EXPERIMENT, self.ensemble) @classmethod def name(cls) -> str: diff --git a/src/ert/run_models/ensemble_smoother.py b/src/ert/run_models/ensemble_smoother.py index 1a6f8cf3382..85529fe460e 100644 --- a/src/ert/run_models/ensemble_smoother.py +++ b/src/ert/run_models/ensemble_smoother.py @@ -74,7 +74,6 @@ def run_experiment( ) -> None: self.log_at_startup() self.restart = restart - self.run_workflows(HookRuntime.PRE_EXPERIMENT) ensemble_format = self.target_ensemble_format experiment = self._storage.create_experiment( parameters=self._parameter_configuration, @@ -89,6 +88,7 @@ def run_experiment( ensemble_size=self.ensemble_size, name=ensemble_format % 0, ) + self.run_workflows(HookRuntime.PRE_EXPERIMENT, prior) self.set_env_key("_ERT_ENSEMBLE_ID", str(prior.id)) prior_args = create_run_arguments( self.run_paths, @@ -120,7 +120,7 @@ def run_experiment( posterior, evaluator_server_config, ) - self.run_workflows(HookRuntime.POST_EXPERIMENT) + self.run_workflows(HookRuntime.POST_EXPERIMENT, posterior) @classmethod def name(cls) -> str: diff --git a/src/ert/run_models/multiple_data_assimilation.py b/src/ert/run_models/multiple_data_assimilation.py index 8b799a44af8..badb7bdc126 100644 --- a/src/ert/run_models/multiple_data_assimilation.py +++ b/src/ert/run_models/multiple_data_assimilation.py @@ -116,7 +116,6 @@ def run_experiment( f"Prior ensemble with ID: {id} does not exists" ) from err else: - self.run_workflows(HookRuntime.PRE_EXPERIMENT) sim_args = {"weights": self._relative_weights} experiment = self._storage.create_experiment( parameters=self._parameter_configuration, @@ -132,6 +131,7 @@ def run_experiment( iteration=0, name=self.target_ensemble_format % 0, ) + self.run_workflows(HookRuntime.PRE_EXPERIMENT, prior) self.set_env_key("_ERT_EXPERIMENT_ID", str(experiment.id)) self.set_env_key("_ERT_ENSEMBLE_ID", str(prior.id)) prior_args = create_run_arguments( @@ -171,7 +171,7 @@ def run_experiment( ) prior = posterior - self.run_workflows(HookRuntime.POST_EXPERIMENT) + self.run_workflows(HookRuntime.POST_EXPERIMENT, prior) @staticmethod def parse_weights(weights: str) -> list[float]: diff --git a/src/ert/workflow_runner.py b/src/ert/workflow_runner.py index 232ed13a8f9..e87fe7dd5a9 100644 --- a/src/ert/workflow_runner.py +++ b/src/ert/workflow_runner.py @@ -5,7 +5,8 @@ from concurrent.futures import Future from typing import TYPE_CHECKING, Any, Self -from ert.config import ErtConfig, ErtScript, ExternalErtScript, Workflow, WorkflowJob +from ert.config import ErtScript, ExternalErtScript, Workflow, WorkflowJob +from ert.runpaths import Runpaths if TYPE_CHECKING: from ert.storage import Ensemble, Storage @@ -109,12 +110,12 @@ def __init__( workflow: Workflow, storage: Storage | None = None, ensemble: Ensemble | None = None, - ert_config: ErtConfig | None = None, + run_paths: Runpaths | None = None, ) -> None: self.__workflow = workflow self.storage = storage self.ensemble = ensemble - self.ert_config = ert_config + self.run_paths = run_paths self.__workflow_result: bool | None = None self._workflow_executor = futures.ThreadPoolExecutor(max_workers=1) @@ -152,7 +153,7 @@ def run_blocking(self) -> None: self.__running = True fixtures = { k: getattr(self, k) - for k in ["storage", "ensemble", "ert_config"] + for k in ["storage", "ensemble", "run_paths"] if getattr(self, k) } diff --git a/tests/ert/unit_tests/cli/test_cli_workflow.py b/tests/ert/unit_tests/cli/test_cli_workflow.py index bde6a4e49e7..9c7dfddb938 100644 --- a/tests/ert/unit_tests/cli/test_cli_workflow.py +++ b/tests/ert/unit_tests/cli/test_cli_workflow.py @@ -12,7 +12,7 @@ def test_executing_workflow(storage): with ErtPluginContext(): with open("test_wf", "w", encoding="utf-8") as wf_file: - wf_file.write("EXPORT_RUNPATH") + wf_file.write("CSV_EXPORT test_workflow_output.csv") config_file = "poly.ert" with open(config_file, "a", encoding="utf-8") as file_handle: @@ -21,4 +21,4 @@ def test_executing_workflow(storage): rc = ErtConfig.from_file(config_file) args = Namespace(name="test_wf") execute_workflow(rc, storage, args.name) - assert os.path.isfile(".ert_runpath_list") + assert os.path.isfile("test_workflow_output.csv") diff --git a/tests/ert/unit_tests/cli/test_model_hook_order.py b/tests/ert/unit_tests/cli/test_model_hook_order.py index ea2b3872b7a..bbbbd70b8ce 100644 --- a/tests/ert/unit_tests/cli/test_model_hook_order.py +++ b/tests/ert/unit_tests/cli/test_model_hook_order.py @@ -14,15 +14,15 @@ ) EXPECTED_CALL_ORDER = [ - call(HookRuntime.PRE_EXPERIMENT), - call(HookRuntime.PRE_SIMULATION, ANY, ANY), - call(HookRuntime.POST_SIMULATION, ANY, ANY), - call(HookRuntime.PRE_FIRST_UPDATE, ANY, ANY), - call(HookRuntime.PRE_UPDATE, ANY, ANY), - call(HookRuntime.POST_UPDATE, ANY, ANY), - call(HookRuntime.PRE_SIMULATION, ANY, ANY), - call(HookRuntime.POST_SIMULATION, ANY, ANY), - call(HookRuntime.POST_EXPERIMENT), + call(HookRuntime.PRE_EXPERIMENT, ANY), + call(HookRuntime.PRE_SIMULATION, ANY), + call(HookRuntime.POST_SIMULATION, ANY), + call(HookRuntime.PRE_FIRST_UPDATE, ANY), + call(HookRuntime.PRE_UPDATE, ANY), + call(HookRuntime.POST_UPDATE, ANY), + call(HookRuntime.PRE_SIMULATION, ANY), + call(HookRuntime.POST_SIMULATION, ANY), + call(HookRuntime.POST_EXPERIMENT, ANY), ] diff --git a/tests/ert/unit_tests/plugins/test_export_misfit.py b/tests/ert/unit_tests/plugins/test_export_misfit.py index ae7b14cbca1..9e7a8e4166a 100644 --- a/tests/ert/unit_tests/plugins/test_export_misfit.py +++ b/tests/ert/unit_tests/plugins/test_export_misfit.py @@ -14,8 +14,8 @@ sys.platform.startswith("darwin"), reason="https://github.com/equinor/ert/issues/7533", ) -def test_export_misfit(snake_oil_case_storage, snake_oil_default_storage, snapshot): - ExportMisfitDataJob().run(snake_oil_case_storage, snake_oil_default_storage, []) +def test_export_misfit(snake_oil_default_storage, snapshot): + ExportMisfitDataJob().run(snake_oil_default_storage, []) result = pd.read_hdf("misfit.hdf") snapshot.assert_match( result.to_csv(), @@ -25,7 +25,7 @@ def test_export_misfit(snake_oil_case_storage, snake_oil_default_storage, snapsh def test_export_misfit_no_responses_in_storage(poly_case, new_ensemble): with pytest.raises(StorageError, match="No responses loaded"): - ExportMisfitDataJob().run(poly_case, new_ensemble, []) + ExportMisfitDataJob().run(new_ensemble, []) def test_export_misfit_data_job_is_loaded(): diff --git a/tests/ert/unit_tests/plugins/test_export_runpath.py b/tests/ert/unit_tests/plugins/test_export_runpath.py index d63693b1a51..d6fd53a0504 100644 --- a/tests/ert/unit_tests/plugins/test_export_runpath.py +++ b/tests/ert/unit_tests/plugins/test_export_runpath.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from unittest.mock import Mock, patch +from unittest.mock import MagicMock, Mock, patch import pytest @@ -30,17 +30,36 @@ def writing_setup(setup_case): def test_export_runpath_empty_range(writing_setup): writing_setup, config = writing_setup - writing_setup.export_job.run(config, []) + run_paths = Runpaths( + jobname_format=config.model_config.jobname_format_string, + runpath_format=config.model_config.runpath_format_string, + filename=str(config.runpath_file), + substitutions=config.substitutions, + eclbase=config.model_config.eclbase_format_string, + ) + mock_ensemble = MagicMock() + mock_ensemble.iteration = 0 + mock_ensemble.ensemble_size = 25 + writing_setup.export_job.run(run_paths, mock_ensemble, []) writing_setup.write_mock.assert_called_with( - [0], - list(range(25)), + [0], list(range(mock_ensemble.ensemble_size)) ) def test_export_runpath_star_parameter(writing_setup): writing_setup, config = writing_setup - writing_setup.export_job.run(config, ["* | *"]) + run_paths = Runpaths( + jobname_format=config.model_config.jobname_format_string, + runpath_format=config.model_config.runpath_format_string, + filename=str(config.runpath_file), + substitutions=config.substitutions, + eclbase=config.model_config.eclbase_format_string, + ) + mock_ensemble = MagicMock() + mock_ensemble.iteration = 1 + mock_ensemble.ensemble_size = 25 + writing_setup.export_job.run(run_paths, mock_ensemble, ["* | *"]) writing_setup.write_mock.assert_called_with( list(range(1)), @@ -50,7 +69,18 @@ def test_export_runpath_star_parameter(writing_setup): def test_export_runpath_range_parameter(writing_setup): writing_setup, config = writing_setup - writing_setup.export_job.run(config, ["* | 1-2"]) + + run_paths = Runpaths( + jobname_format=config.model_config.jobname_format_string, + runpath_format=config.model_config.runpath_format_string, + filename=str(config.runpath_file), + substitutions=config.substitutions, + eclbase=config.model_config.eclbase_format_string, + ) + mock_ensemble = MagicMock() + mock_ensemble.iteration = 0 + mock_ensemble.ensemble_size = 25 + writing_setup.export_job.run(run_paths, mock_ensemble, ["* | 1-2"]) writing_setup.write_mock.assert_called_with( [1, 2], @@ -60,7 +90,17 @@ def test_export_runpath_range_parameter(writing_setup): def test_export_runpath_comma_parameter(writing_setup): writing_setup, config = writing_setup - writing_setup.export_job.run(config, ["3,4 | 1-2"]) + run_paths = Runpaths( + jobname_format=config.model_config.jobname_format_string, + runpath_format=config.model_config.runpath_format_string, + filename=str(config.runpath_file), + substitutions=config.substitutions, + eclbase=config.model_config.eclbase_format_string, + ) + mock_ensemble = MagicMock() + mock_ensemble.iteration = 0 + mock_ensemble.ensemble_size = 25 + writing_setup.export_job.run(run_paths, mock_ensemble, ["3,4 | 1-2"]) writing_setup.write_mock.assert_called_with( [1, 2], @@ -70,7 +110,17 @@ def test_export_runpath_comma_parameter(writing_setup): def test_export_runpath_combination_parameter(writing_setup): writing_setup, config = writing_setup - writing_setup.export_job.run(config, ["1,2-3 | 1-2"]) + run_paths = Runpaths( + jobname_format=config.model_config.jobname_format_string, + runpath_format=config.model_config.runpath_format_string, + filename=str(config.runpath_file), + substitutions=config.substitutions, + eclbase=config.model_config.eclbase_format_string, + ) + mock_ensemble = MagicMock() + mock_ensemble.iteration = 0 + mock_ensemble.ensemble_size = 25 + writing_setup.export_job.run(run_paths, mock_ensemble, ["1,2-3 | 1-2"]) writing_setup.write_mock.assert_called_with( [1, 2], @@ -80,8 +130,18 @@ def test_export_runpath_combination_parameter(writing_setup): def test_export_runpath_bad_arguments(writing_setup): writing_setup, config = writing_setup + run_paths = Runpaths( + jobname_format=config.model_config.jobname_format_string, + runpath_format=config.model_config.runpath_format_string, + filename=str(config.runpath_file), + substitutions=config.substitutions, + eclbase=config.model_config.eclbase_format_string, + ) + mock_ensemble = MagicMock() + mock_ensemble.iteration = 0 + mock_ensemble.ensemble_size = 25 with pytest.raises(ValueError, match="Expected \\|"): - writing_setup.export_job.run(config, ["wat"]) + writing_setup.export_job.run(run_paths, mock_ensemble, ["wat"]) def test_export_runpath_job_is_loaded():