Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions libensemble/executors/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,10 +673,16 @@ def set_worker_info(self, comm=None, workerid=None) -> None:
self.workerID = workerid
self.comm = comm

def _check_app_exists(self, full_path: str) -> None:
def _check_app_exists(self, app: Application) -> None:
"""Allows submit function to check if app exists and error if not"""
if not os.path.isfile(full_path):
raise ExecutorException(f"Application does not exist {full_path}")
if app.precedent:
# Could be a container call in precedent. In that case,
# the executable is not available on the host system and
# we just forward what the user provided.
return

if not os.path.isfile(app.full_path):
raise ExecutorException(f"Application does not exist {app.full_path}")

def submit(
self,
Expand Down Expand Up @@ -745,7 +751,7 @@ def submit(
task = Task(app, app_args, default_workdir, stdout, stderr, self.workerID, dry_run)

if not dry_run:
self._check_app_exists(task.app.full_path)
self._check_app_exists(task.app)

runline = task.app.app_cmd.split()
if task.app_args is not None:
Expand Down
2 changes: 1 addition & 1 deletion libensemble/executors/mpi_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ def submit(
task = Task(app, app_args, default_workdir, stdout, stderr, self.workerID, dry_run)

if not dry_run:
self._check_app_exists(task.app.full_path)
self._check_app_exists(task.app)

if stage_inout is not None:
logger.warning("stage_inout option ignored in this " "executor - runs in-place")
Expand Down
20 changes: 20 additions & 0 deletions libensemble/tests/unit_tests/test_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,25 @@ def test_non_existent_app_mpi():
assert 0


def test_non_existent_app_precedent():
"""Tests exception on non-existent app is not thrown if precedent is set.
This is common when running apps in containers, where the executable is not
check-able from the host system."""
from libensemble.executors.executor import Executor

print(f"\nTest: {sys._getframe().f_code.co_name}\n")

exctr = Executor()

# Can register a non-existent app in case created as part of workflow.
exctr.register_app(full_path=non_existent_app, app_name="nonexist")

w_exctr = Executor.executor # simulate on worker

# all should be ok
w_exctr.submit(app_name="nonexist", dry_run=True)


def test_man_signal_unrec_tag():
print(f"\nTest: {sys._getframe().f_code.co_name}\n")

Expand Down Expand Up @@ -990,5 +1009,6 @@ def test_man_signal_unrec_tag():
test_dry_run()
test_non_existent_app()
test_non_existent_app_mpi()
test_non_existent_app_precedent()
test_man_signal_unrec_tag()
teardown_module(__file__)