Skip to content

Commit b919f2d

Browse files
committed
additional tests, plus coverage adjusts, plus remove an exception block that can't happen
1 parent 276543f commit b919f2d

2 files changed

Lines changed: 70 additions & 35 deletions

File tree

libensemble/executors/flux_executor.py

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -166,27 +166,19 @@ def wait(self, timeout: float | None = None) -> None:
166166
if not self._check_poll():
167167
return
168168

169-
try:
170-
# Wait for job to complete
171-
start_time = time.time()
172-
while True:
173-
self.poll()
174-
if self.finished:
175-
break
176-
177-
if timeout is not None:
178-
elapsed = time.time() - start_time
179-
if elapsed >= timeout:
180-
raise TimeoutExpired(self.name, timeout)
181-
182-
time.sleep(0.1)
183-
184-
except TimeoutExpired:
185-
raise
186-
except Exception as e:
187-
logger.warning(f"Error waiting for Flux job {self.flux_jobid}: {e}")
188-
self.state = "FAILED"
189-
self.finished = True
169+
# Wait for job to complete
170+
start_time = time.time()
171+
while True:
172+
self.poll()
173+
if self.finished:
174+
break
175+
176+
if timeout is not None:
177+
elapsed = time.time() - start_time
178+
if elapsed >= timeout:
179+
raise TimeoutExpired(self.name, timeout)
180+
181+
time.sleep(0.1)
190182

191183
def kill(self, wait_time: int | None = 60) -> None:
192184
"""Kills/cancels the Flux job.
@@ -205,10 +197,6 @@ def kill(self, wait_time: int | None = 60) -> None:
205197
logger.warning(f"Trying to kill task that is no longer running. Task {self.name}: Status is {self.state}")
206198
return
207199

208-
if self.flux_jobid is None:
209-
logger.warning(f"Task {self.name} has no Flux job ID - cannot kill")
210-
return
211-
212200
logger.info(f"Canceling Flux job {self.flux_jobid} for task {self.name}")
213201

214202
try:
@@ -287,14 +275,6 @@ def __init__(self) -> None:
287275
self.resources = None
288276
self.platform_info: dict = {}
289277

290-
def set_resources(self, resources) -> None:
291-
"""Set resources for the executor."""
292-
self.resources = resources
293-
294-
def add_platform_info(self, platform_info: dict | None = None) -> None:
295-
"""Add platform info to the executor."""
296-
self.platform_info = platform_info or {}
297-
298278
def submit(
299279
self,
300280
calc_type: str | None = None,

libensemble/tests/unit_tests/test_flux.py

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,6 @@ def test_flux_executor_submit_builds_jobspec_with_environment_and_gpus():
398398

399399
executor = object.__new__(flux_executor.FluxExecutor)
400400
executor.flux_handle = object()
401-
executor.resources = None
402401
executor.platform_info = {}
403402
executor.workerID = 7
404403
executor.list_of_tasks = []
@@ -463,7 +462,6 @@ def test_flux_executor_init_connects_with_flux_uri():
463462

464463
fake_flux_module.Flux.assert_called_once_with()
465464
assert executor.flux_handle == "flux-handle"
466-
assert executor.resources is None
467465
assert executor.platform_info == {}
468466

469467

@@ -597,6 +595,52 @@ def test_flux_task_set_complete_handles_dry_run_and_return_codes():
597595
assert finished_task.success is False
598596
assert finished_task.state == "FAILED"
599597

598+
# cover waiting on a task that completes before timeout
599+
task = flux_executor.FluxTask(
600+
app=SimpleNamespace(name="app"),
601+
app_args=None,
602+
workdir=os.getcwd(),
603+
stdout="out.txt",
604+
stderr="err.txt",
605+
workerid=1,
606+
dry_run=False,
607+
)
608+
task._set_complete()
609+
task.flux_jobid = 123
610+
task.wait(timeout=10)
611+
task.kill()
612+
613+
614+
def test_flux_task_dry_run_exception_and_kill():
615+
"""Test FluxTask dry run exception attributes."""
616+
task = flux_executor.FluxTask(
617+
app=SimpleNamespace(name="app"),
618+
app_args=None,
619+
workdir=os.getcwd(),
620+
stdout="out.txt",
621+
stderr="err.txt",
622+
workerid=1,
623+
dry_run=True,
624+
)
625+
task.wait()
626+
assert task.finished is True
627+
assert task.success is True
628+
assert task.state == "FINISHED"
629+
task.kill()
630+
task = flux_executor.FluxTask(
631+
app=SimpleNamespace(name="app"),
632+
app_args=None,
633+
workdir=os.getcwd(),
634+
stdout="out.txt",
635+
stderr="err.txt",
636+
workerid=1,
637+
dry_run=True,
638+
)
639+
task.poll()
640+
assert task.finished is True
641+
assert task.success is True
642+
assert task.state == "FINISHED"
643+
600644

601645
def test_flux_task_wait_completes_and_times_out():
602646
"""Test FluxTask wait completes after polling and raises on timeout."""
@@ -716,6 +760,7 @@ def poll_side_effect():
716760
# Validator tests
717761
test_validator_accepts_flux()
718762
test_validator_accepts_all_runners()
763+
test_validator_rejects_invalid()
719764

720765
# Platform tests
721766
test_flux_allocation_platform()
@@ -724,4 +769,14 @@ def poll_side_effect():
724769
# EnvResources tests
725770
test_env_resources_flux_env_variable()
726771

772+
# Flux Executor tests
773+
test_flux_executor_init_connects_with_flux_uri()
774+
test_flux_executor_wait_on_start_polls_until_running()
775+
test_flux_task_poll_maps_completion_waiting_and_unknown_states()
776+
test_flux_task_handle_completion_success_and_failure()
777+
test_flux_task_set_complete_handles_dry_run_and_return_codes()
778+
test_flux_task_dry_run_exception_and_kill()
779+
test_flux_task_wait_completes_and_times_out()
780+
test_flux_task_kill_cancels_and_marks_user_killed()
781+
727782
print("All standalone tests passed!")

0 commit comments

Comments
 (0)