From 77304275cfeacf3394dbf936ee53fbd3a36091fe Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:24:00 +0100 Subject: [PATCH 1/7] Drop `keep_pickle_files` attribute from slurm executors --- .../runner/executors/slurm/ssh/executor.py | 31 ++++++------------- .../runner/executors/slurm/sudo/executor.py | 17 +++------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/fractal_server/app/runner/executors/slurm/ssh/executor.py b/fractal_server/app/runner/executors/slurm/ssh/executor.py index a99dd9d859..89ef4f4e2b 100644 --- a/fractal_server/app/runner/executors/slurm/ssh/executor.py +++ b/fractal_server/app/runner/executors/slurm/ssh/executor.py @@ -62,7 +62,6 @@ class FractalSlurmSSHExecutor(SlurmExecutor): shutdown_file: python_remote: Equal to `settings.FRACTAL_SLURM_WORKER_PYTHON` wait_thread_cls: Class for waiting thread - keep_pickle_files: workflow_dir_local: Directory for both the cfut/SLURM and fractal-server files and logs workflow_dir_remote: @@ -84,7 +83,6 @@ class FractalSlurmSSHExecutor(SlurmExecutor): python_remote: str wait_thread_cls = FractalSlurmWaitThread - keep_pickle_files: bool common_script_lines: list[str] slurm_account: Optional[str] @@ -100,8 +98,6 @@ def __init__( # Folders and files workflow_dir_local: Path, workflow_dir_remote: Path, - # Runner options - keep_pickle_files: bool = False, # Monitoring options slurm_poll_interval: Optional[int] = None, # SLURM submission script options @@ -120,7 +116,6 @@ def __init__( fractal_ssh: workflow_dir_local: workflow_dir_remote: - keep_pickle_files: slurm_poll_interval: common_script_lines: slurm_account: @@ -194,7 +189,6 @@ def __init__( raise e # Set/initialize some more options - self.keep_pickle_files = keep_pickle_files self.map_jobid_to_slurm_files_local = {} def _validate_common_script_lines(self): @@ -901,12 +895,11 @@ def _handle_remaining_jobs( pass for job_id in remaining_job_ids: self._cleanup(job_id) - if not self.keep_pickle_files: - for job in remaining_jobs: - for path in job.output_pickle_files_local: - path.unlink() - for path in job.input_pickle_files_local: - path.unlink() + for job in remaining_jobs: + for path in job.output_pickle_files_local: + path.unlink() + for path in job.input_pickle_files_local: + path.unlink() def _completion(self, job_ids: list[str]) -> None: """ @@ -1001,8 +994,7 @@ def _completion(self, job_ids: list[str]) -> None: f"Future {future} (SLURM job ID: {job_id}) " "was already cancelled." ) - if not self.keep_pickle_files: - in_path.unlink() + in_path.unlink() self._cleanup(job_id) self._handle_remaining_jobs( remaining_futures=remaining_futures, @@ -1062,17 +1054,15 @@ def _completion(self, job_ids: list[str]) -> None: remaining_job_ids=remaining_job_ids, ) return - if not self.keep_pickle_files: - out_path.unlink() + out_path.unlink() except InvalidStateError: logger.warning( f"Future {future} (SLURM job ID: {job_id}) was " "already cancelled, exit from " "FractalSlurmSSHExecutor._completion." ) - if not self.keep_pickle_files: - out_path.unlink() - in_path.unlink() + out_path.unlink() + in_path.unlink() self._cleanup(job_id) self._handle_remaining_jobs( @@ -1082,8 +1072,7 @@ def _completion(self, job_ids: list[str]) -> None: return # Clean up input pickle file - if not self.keep_pickle_files: - in_path.unlink() + in_path.unlink() self._cleanup(job_id) if job.single_task_submission: future.set_result(outputs[0]) diff --git a/fractal_server/app/runner/executors/slurm/sudo/executor.py b/fractal_server/app/runner/executors/slurm/sudo/executor.py index 3b63aef3ec..34faaa6535 100644 --- a/fractal_server/app/runner/executors/slurm/sudo/executor.py +++ b/fractal_server/app/runner/executors/slurm/sudo/executor.py @@ -219,7 +219,6 @@ class FractalSlurmExecutor(SlurmExecutor): workflow_dir_local: Path workflow_dir_remote: Path map_jobid_to_slurm_files: dict[str, tuple[str, str, str]] - keep_pickle_files: bool slurm_account: Optional[str] jobs: dict[str, tuple[Future, SlurmJob]] @@ -232,7 +231,6 @@ def __init__( user_cache_dir: Optional[str] = None, common_script_lines: Optional[list[str]] = None, slurm_poll_interval: Optional[int] = None, - keep_pickle_files: bool = False, slurm_account: Optional[str] = None, *args, **kwargs, @@ -253,7 +251,6 @@ def __init__( # raised within `__init__`). self.wait_thread.shutdown_callback = self.shutdown - self.keep_pickle_files = keep_pickle_files self.slurm_user = slurm_user self.slurm_account = slurm_account @@ -874,8 +871,7 @@ def _completion(self, jobid: str) -> None: " cancelled, exit from" " FractalSlurmExecutor._completion." ) - if not self.keep_pickle_files: - in_path.unlink() + in_path.unlink() self._cleanup(jobid) return @@ -917,23 +913,20 @@ def _completion(self, jobid: str) -> None: exc = TaskExecutionError(proxy.tb, **kwargs) fut.set_exception(exc) return - if not self.keep_pickle_files: - out_path.unlink() + out_path.unlink() except InvalidStateError: logger.warning( f"Future {fut} (SLURM job ID: {jobid}) was already" " cancelled, exit from" " FractalSlurmExecutor._completion." ) - if not self.keep_pickle_files: - out_path.unlink() - in_path.unlink() + out_path.unlink() + in_path.unlink() self._cleanup(jobid) return # Clean up input pickle file - if not self.keep_pickle_files: - in_path.unlink() + in_path.unlink() self._cleanup(jobid) if job.single_task_submission: fut.set_result(outputs[0]) From 233d60df3883b1cdb4c53d5e0eab5480d3badec7 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:26:42 +0100 Subject: [PATCH 2/7] Refactor slurm-unit tests from two modules --- .../09_backends/test_unit_slurm_executor.py | 40 ++++++++++++++++- .../test_unit_sudo_slurm_executor.py | 45 ------------------- 2 files changed, 39 insertions(+), 46 deletions(-) delete mode 100644 tests/v2/09_backends/test_unit_sudo_slurm_executor.py diff --git a/tests/v2/09_backends/test_unit_slurm_executor.py b/tests/v2/09_backends/test_unit_slurm_executor.py index 410e6c3fed..8b97c0b936 100644 --- a/tests/v2/09_backends/test_unit_slurm_executor.py +++ b/tests/v2/09_backends/test_unit_slurm_executor.py @@ -1,3 +1,4 @@ +import json import os import shlex import subprocess @@ -13,7 +14,7 @@ ) from fractal_server.app.runner.executors.slurm.sudo.executor import ( FractalSlurmExecutor, -) # noqa +) from fractal_server.logger import set_logger from tests.fixtures_slurm import run_squeue from tests.fixtures_slurm import SLURM_USER @@ -104,6 +105,43 @@ def test_slurm_sudo_executor_shutdown_before_job_submission( debug(exc_info.value) +def test_check_remote_runner_python_interpreter( + monkeypatch, override_settings_factory +): + remote_version = "1.0.0" + override_settings_factory(FRACTAL_SLURM_WORKER_PYTHON="/remote/python") + + def mock_subprocess_run_or_raise(cmd): + class MockCompletedProcess(object): + stdout: str = json.dumps({"fractal_server": remote_version}) + + return MockCompletedProcess() + + with pytest.raises( + RuntimeError, match="No such file or directory: '/remote/python'" + ): + FractalSlurmExecutor( + slurm_user="test_user", + workflow_dir_local=Path("/local/workflow"), + workflow_dir_remote=Path("/remote/workflow"), + ) + + monkeypatch.setattr( + ( + "fractal_server.app.runner.executors.slurm.sudo.executor" + "._subprocess_run_or_raise" + ), + mock_subprocess_run_or_raise, + ) + + with pytest.raises(RuntimeError, match="Fractal-server version mismatch"): + FractalSlurmExecutor( + slurm_user="test_user", + workflow_dir_local=Path("/local/workflow"), + workflow_dir_remote=Path("/remote/workflow"), + ) + + async def test_scancel_during_execution( tmp777_path: Path, monkey_slurm, slurm_working_folders ): diff --git a/tests/v2/09_backends/test_unit_sudo_slurm_executor.py b/tests/v2/09_backends/test_unit_sudo_slurm_executor.py deleted file mode 100644 index d5efd4fa2c..0000000000 --- a/tests/v2/09_backends/test_unit_sudo_slurm_executor.py +++ /dev/null @@ -1,45 +0,0 @@ -import json -from pathlib import Path - -import pytest - -from fractal_server.app.runner.executors.slurm.sudo.executor import ( - FractalSlurmExecutor, -) - - -def test_check_remote_runner_python_interpreter( - monkeypatch, override_settings_factory -): - remote_version = "1.0.0" - override_settings_factory(FRACTAL_SLURM_WORKER_PYTHON="/remote/python") - - def mock_subprocess_run_or_raise(cmd): - class MockCompletedProcess(object): - stdout: str = json.dumps({"fractal_server": remote_version}) - - return MockCompletedProcess() - - with pytest.raises( - RuntimeError, match="No such file or directory: '/remote/python'" - ): - FractalSlurmExecutor( - slurm_user="test_user", - workflow_dir_local=Path("/local/workflow"), - workflow_dir_remote=Path("/remote/workflow"), - ) - - monkeypatch.setattr( - ( - "fractal_server.app.runner.executors.slurm.sudo.executor" - "._subprocess_run_or_raise" - ), - mock_subprocess_run_or_raise, - ) - - with pytest.raises(RuntimeError, match="Fractal-server version mismatch"): - FractalSlurmExecutor( - slurm_user="test_user", - workflow_dir_local=Path("/local/workflow"), - workflow_dir_remote=Path("/remote/workflow"), - ) From b9c6bb3b2291ca2b7e1d423e5af63436f4d0c6ff Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:28:34 +0100 Subject: [PATCH 3/7] Refactor slurm-unit tests from two modules --- .../test_sudo_slurm_executor_scancel.py | 105 ++++++++++++++++++ ...or.py => test_sudo_slurm_executor_unit.py} | 98 ---------------- 2 files changed, 105 insertions(+), 98 deletions(-) create mode 100644 tests/v2/09_backends/test_sudo_slurm_executor_scancel.py rename tests/v2/09_backends/{test_unit_slurm_executor.py => test_sudo_slurm_executor_unit.py} (55%) diff --git a/tests/v2/09_backends/test_sudo_slurm_executor_scancel.py b/tests/v2/09_backends/test_sudo_slurm_executor_scancel.py new file mode 100644 index 0000000000..24ec2cda36 --- /dev/null +++ b/tests/v2/09_backends/test_sudo_slurm_executor_scancel.py @@ -0,0 +1,105 @@ +import os +import shlex +import subprocess +import time +from pathlib import Path + +import pytest + +from fractal_server.app.runner.exceptions import JobExecutionError +from fractal_server.app.runner.executors.slurm.sudo._subprocess_run_as_user import ( # noqa: E501 + _mkdir_as_user, +) +from fractal_server.app.runner.executors.slurm.sudo.executor import ( + FractalSlurmExecutor, +) +from tests.fixtures_slurm import run_squeue +from tests.fixtures_slurm import SLURM_USER +from tests.v2._aux_runner import get_default_slurm_config +from tests.v2._aux_runner import get_default_task_files + + +async def test_scancel_during_execution( + tmp777_path: Path, monkey_slurm, slurm_working_folders +): + """ + Test the scenario where `scancel` is called during a + `FractalSlurmExecutor` execution of `.submit` or `.map`. + """ + # Define and create folders and subfolders for both cases + base_dir_local, base_dir_remote = slurm_working_folders + job_folders = {} + for job_name in ["job1", "job2"]: + job_dir_local = base_dir_local / job_name + job_dir_remote = base_dir_remote / job_name + job_folders[job_name] = dict( + local=job_dir_local, + remote=job_dir_remote, + ) + task_files = get_default_task_files( + workflow_dir_local=job_dir_local, + workflow_dir_remote=job_dir_remote, + ) + umask = os.umask(0) + (job_dir_local / task_files.subfolder_name).mkdir(parents=True) + os.umask(umask) + _mkdir_as_user( + folder=str(job_dir_remote / task_files.subfolder_name), + user=SLURM_USER, + ) + + scancel_cmd = ( + f"sudo --non-interactive -u {SLURM_USER} scancel -u {SLURM_USER} -v" + ) + + # JOB 1: fail during `submit` + with pytest.raises(JobExecutionError) as exc_info: + with FractalSlurmExecutor( + workflow_dir_local=job_folders["job1"]["local"], + workflow_dir_remote=job_folders["job1"]["remote"], + slurm_user=SLURM_USER, + slurm_poll_interval=1, + ) as executor: + # Submit task + fut = executor.submit( + time.sleep, + 100, + slurm_config=get_default_slurm_config(), + task_files=task_files, + ) + # Wait and then scancel + while "RUNNING" not in run_squeue(squeue_format="%i %T"): + time.sleep(0.1) + subprocess.run( + shlex.split(scancel_cmd), capture_output=True, encoding="utf-8" + ) + # Trigger exception + fut.result() + job_execution_error = exc_info.value + assert "CANCELLED" in job_execution_error.assemble_error() + + # JOB 2: fail during `map` + with pytest.raises(JobExecutionError) as exc_info: + with FractalSlurmExecutor( + workflow_dir_local=job_folders["job2"]["local"], + workflow_dir_remote=job_folders["job2"]["remote"], + slurm_user=SLURM_USER, + slurm_poll_interval=1, + ) as executor: + # Submit task + res = executor.map( + time.sleep, + [100, 101], + slurm_config=get_default_slurm_config(), + task_files=task_files, + ) + # Wait and then scancel + while "RUNNING" not in run_squeue(squeue_format="%i %T"): + time.sleep(0.1) + subprocess.run( + shlex.split(scancel_cmd), capture_output=True, encoding="utf-8" + ) + # Trigger exception + list(res) + job_execution_error = exc_info.value + assert "CANCELLED" in job_execution_error.assemble_error() diff --git a/tests/v2/09_backends/test_unit_slurm_executor.py b/tests/v2/09_backends/test_sudo_slurm_executor_unit.py similarity index 55% rename from tests/v2/09_backends/test_unit_slurm_executor.py rename to tests/v2/09_backends/test_sudo_slurm_executor_unit.py index 8b97c0b936..562ee32ca5 100644 --- a/tests/v2/09_backends/test_unit_slurm_executor.py +++ b/tests/v2/09_backends/test_sudo_slurm_executor_unit.py @@ -1,28 +1,16 @@ import json -import os -import shlex -import subprocess -import time from pathlib import Path import pytest from devtools import debug from fractal_server.app.runner.exceptions import JobExecutionError -from fractal_server.app.runner.executors.slurm.sudo._subprocess_run_as_user import ( # noqa: E501 - _mkdir_as_user, -) from fractal_server.app.runner.executors.slurm.sudo.executor import ( FractalSlurmExecutor, ) -from fractal_server.logger import set_logger -from tests.fixtures_slurm import run_squeue -from tests.fixtures_slurm import SLURM_USER from tests.v2._aux_runner import get_default_slurm_config from tests.v2._aux_runner import get_default_task_files -logger = set_logger(__file__) - def test_slurm_sudo_executor_shutdown_before_job_submission( tmp_path: Path, @@ -140,89 +128,3 @@ class MockCompletedProcess(object): workflow_dir_local=Path("/local/workflow"), workflow_dir_remote=Path("/remote/workflow"), ) - - -async def test_scancel_during_execution( - tmp777_path: Path, monkey_slurm, slurm_working_folders -): - """ - Test the scenario where `scancel` is called during a - `FractalSlurmExecutor` execution of `.submit` or `.map`. - """ - # Define and create folders and subfolders for both cases - base_dir_local, base_dir_remote = slurm_working_folders - job_folders = {} - for job_name in ["job1", "job2"]: - job_dir_local = base_dir_local / job_name - job_dir_remote = base_dir_remote / job_name - job_folders[job_name] = dict( - local=job_dir_local, - remote=job_dir_remote, - ) - task_files = get_default_task_files( - workflow_dir_local=job_dir_local, - workflow_dir_remote=job_dir_remote, - ) - umask = os.umask(0) - (job_dir_local / task_files.subfolder_name).mkdir(parents=True) - os.umask(umask) - _mkdir_as_user( - folder=str(job_dir_remote / task_files.subfolder_name), - user=SLURM_USER, - ) - - scancel_cmd = ( - f"sudo --non-interactive -u {SLURM_USER} scancel -u {SLURM_USER} -v" - ) - - # JOB 1: fail during `submit` - with pytest.raises(JobExecutionError) as exc_info: - with FractalSlurmExecutor( - workflow_dir_local=job_folders["job1"]["local"], - workflow_dir_remote=job_folders["job1"]["remote"], - slurm_user=SLURM_USER, - slurm_poll_interval=1, - ) as executor: - # Submit task - fut = executor.submit( - time.sleep, - 100, - slurm_config=get_default_slurm_config(), - task_files=task_files, - ) - # Wait and then scancel - while "RUNNING" not in run_squeue(squeue_format="%i %T"): - time.sleep(0.1) - subprocess.run( - shlex.split(scancel_cmd), capture_output=True, encoding="utf-8" - ) - # Trigger exception - fut.result() - job_execution_error = exc_info.value - assert "CANCELLED" in job_execution_error.assemble_error() - - # JOB 2: fail during `map` - with pytest.raises(JobExecutionError) as exc_info: - with FractalSlurmExecutor( - workflow_dir_local=job_folders["job2"]["local"], - workflow_dir_remote=job_folders["job2"]["remote"], - slurm_user=SLURM_USER, - slurm_poll_interval=1, - ) as executor: - # Submit task - res = executor.map( - time.sleep, - [100, 101], - slurm_config=get_default_slurm_config(), - task_files=task_files, - ) - # Wait and then scancel - while "RUNNING" not in run_squeue(squeue_format="%i %T"): - time.sleep(0.1) - subprocess.run( - shlex.split(scancel_cmd), capture_output=True, encoding="utf-8" - ) - # Trigger exception - list(res) - job_execution_error = exc_info.value - assert "CANCELLED" in job_execution_error.assemble_error() From 62379d6bef16552665c71f710f0ad2489fce1b96 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:37:10 +0100 Subject: [PATCH 4/7] Add `test_SlurmJob` --- .../test_sudo_slurm_executor_unit.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/v2/09_backends/test_sudo_slurm_executor_unit.py b/tests/v2/09_backends/test_sudo_slurm_executor_unit.py index 562ee32ca5..c6a3920ab7 100644 --- a/tests/v2/09_backends/test_sudo_slurm_executor_unit.py +++ b/tests/v2/09_backends/test_sudo_slurm_executor_unit.py @@ -8,6 +8,7 @@ from fractal_server.app.runner.executors.slurm.sudo.executor import ( FractalSlurmExecutor, ) +from fractal_server.app.runner.executors.slurm.sudo.executor import SlurmJob from tests.v2._aux_runner import get_default_slurm_config from tests.v2._aux_runner import get_default_task_files @@ -128,3 +129,35 @@ class MockCompletedProcess(object): workflow_dir_local=Path("/local/workflow"), workflow_dir_remote=Path("/remote/workflow"), ) + + +def test_SlurmJob(): + job = SlurmJob( + single_task_submission=False, + num_tasks_tot=2, + wftask_file_prefixes=("0", "1"), + slurm_config=get_default_slurm_config(), + slurm_file_prefix="prefix", + ) + assert job.wftask_file_prefixes == ("0", "1") + + job = SlurmJob( + single_task_submission=False, + num_tasks_tot=2, + wftask_file_prefixes=None, + slurm_config=get_default_slurm_config(), + slurm_file_prefix="prefix", + ) + assert job.wftask_file_prefixes == ( + "default_wftask_prefix", + "default_wftask_prefix", + ) + + with pytest.raises(ValueError, match="Trying to initialize"): + SlurmJob( + single_task_submission=True, + num_tasks_tot=2, + wftask_file_prefixes=("0", "1"), + slurm_config=get_default_slurm_config(), + slurm_file_prefix="prefix", + ) From fb28d6d201cdede81546aa02ffa7ba88fc377f1c Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:41:07 +0100 Subject: [PATCH 5/7] Add `test_FractalSlurmExecutor_init` --- .../test_sudo_slurm_executor_unit.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/v2/09_backends/test_sudo_slurm_executor_unit.py b/tests/v2/09_backends/test_sudo_slurm_executor_unit.py index c6a3920ab7..4eedb1c60f 100644 --- a/tests/v2/09_backends/test_sudo_slurm_executor_unit.py +++ b/tests/v2/09_backends/test_sudo_slurm_executor_unit.py @@ -161,3 +161,45 @@ def test_SlurmJob(): slurm_config=get_default_slurm_config(), slurm_file_prefix="prefix", ) + + +def test_FractalSlurmExecutor_init( + tmp_path, + override_settings_factory, +): + + override_settings_factory(FRACTAL_SLURM_WORKER_PYTHON=None) + + with pytest.raises( + RuntimeError, + match="Missing attribute FractalSlurmExecutor.slurm_user", + ): + with FractalSlurmExecutor( + slurm_user=None, + workflow_dir_local=tmp_path / "job_dir1", + workflow_dir_remote=tmp_path / "remote_job_dir1", + ): + pass + + with pytest.raises( + RuntimeError, + match="Missing attribute FractalSlurmExecutor.slurm_user", + ): + with FractalSlurmExecutor( + slurm_user="", + workflow_dir_local=tmp_path / "job_dir1", + workflow_dir_remote=tmp_path / "remote_job_dir1", + ): + pass + + with pytest.raises( + RuntimeError, + match="SLURM account must be set via the request body", + ): + with FractalSlurmExecutor( + slurm_user="something", + workflow_dir_local=tmp_path / "job_dir1", + workflow_dir_remote=tmp_path / "remote_job_dir1", + common_script_lines=["#SBATCH --account=myaccount"], + ): + pass From 565ec336690ea7cfa826efd7ad33251b83f0d3d6 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:42:24 +0100 Subject: [PATCH 6/7] CHANGELOG [skip ci] --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7efda5f07..7db6356115 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,10 +12,11 @@ * Sudo/SLURM executor checks the fractal-server version using `FRACTAL_SLURM_WORKER_PYTHON` config variable, if set (\#2240). * Handle `_COMPONENT_KEY_`-related errors in sudo/SLURM executor, to simplify testing (\#2245). * Drop obsolete `SlurmJob.workflow_task_file_prefix` for both SSH/sudo executors (\#2245). + * Drop obsolete `keep_pickle_files` attribute from slurm executors (\#2246). * Dependencies: * Bump `uvicorn` version (\#2242). * Testing: - * Add tests for `scancel` during execution (\#2245). + * Improve testing of sudo-Slurm executor (\#2245, \#2246). # 2.12.0 From 71b741c7024ef95dd5041e302f64920cbdcc61e7 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:44:32 +0100 Subject: [PATCH 7/7] test style --- .../09_backends/test_sudo_slurm_executor_unit.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/v2/09_backends/test_sudo_slurm_executor_unit.py b/tests/v2/09_backends/test_sudo_slurm_executor_unit.py index 4eedb1c60f..5ee900e843 100644 --- a/tests/v2/09_backends/test_sudo_slurm_executor_unit.py +++ b/tests/v2/09_backends/test_sudo_slurm_executor_unit.py @@ -95,17 +95,11 @@ def test_slurm_sudo_executor_shutdown_before_job_submission( def test_check_remote_runner_python_interpreter( - monkeypatch, override_settings_factory + monkeypatch, + override_settings_factory, ): - remote_version = "1.0.0" override_settings_factory(FRACTAL_SLURM_WORKER_PYTHON="/remote/python") - def mock_subprocess_run_or_raise(cmd): - class MockCompletedProcess(object): - stdout: str = json.dumps({"fractal_server": remote_version}) - - return MockCompletedProcess() - with pytest.raises( RuntimeError, match="No such file or directory: '/remote/python'" ): @@ -115,6 +109,12 @@ class MockCompletedProcess(object): workflow_dir_remote=Path("/remote/workflow"), ) + def mock_subprocess_run_or_raise(cmd): + class MockCompletedProcess(object): + stdout: str = json.dumps({"fractal_server": "9.9.9"}) + + return MockCompletedProcess() + monkeypatch.setattr( ( "fractal_server.app.runner.executors.slurm.sudo.executor"