blob: 2f69ad0399c32dfb4ff7fd82caa6dd978605b15f [file] [edit]
############################################################################
# Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
############################################################################
"""Test scontrol requeue and requeuehold of external jobs."""
import pytest
import atf
@pytest.fixture(scope="module", autouse=True)
def setup():
atf.require_version(
(26, 11),
"sbin/slurmctld",
reason="Issue 166 (slurm-bridge): external job requeue added in 26.11",
)
atf.require_config_parameter("JobRequeue", "1")
atf.require_slurm_running()
@pytest.mark.parametrize("finished", [False, True], ids=["running", "finished"])
@pytest.mark.parametrize("command", ["requeue", "requeuehold"])
def test_requeue_external_job(command, finished):
"""Test that scontrol returns a running or finished external job to pending."""
job_id = atf.submit_job_sbatch("--external --requeue -N1 -t1", fatal=True)
atf.wait_for_job_state(job_id, "RUNNING", fatal=True)
if finished:
atf.cancel_jobs([job_id], fatal=True)
result = atf.run_command(
f"scontrol {command} {job_id}", user=atf.properties["slurm-user"]
)
assert (
result["exit_code"] == 0
), f"scontrol {command} {job_id} failed: {result['stderr']}"
assert atf.wait_for_job_state(
job_id, "PENDING"
), f"External job {job_id} did not return to pending"
job = atf.get_job(job_id)
assert job["Restarts"] == 1, job
assert job["BatchFlag"] == 0, job
if command == "requeuehold":
assert job["Priority"] == 0, job
atf.run_command(
f"scontrol release {job_id}",
user=atf.properties["slurm-user"],
fatal=True,
)
assert (
atf.get_job_parameter(job_id, "Priority") > 0
), f"External job {job_id} is still held after release"
@pytest.mark.parametrize(
"submit,error",
[
(
lambda: atf.submit_job_sbatch(
"--external --no-requeue -N1 -t1", fatal=True
),
"Requested operation is presently disabled",
),
(
lambda: atf.submit_job_salloc("--no-shell -N1 -t1", fatal=True),
"Only batch jobs are accepted or processed",
),
],
ids=["no_requeue", "salloc"],
)
def test_requeue_refused(submit, error):
"""Test that scontrol requeue still refuses jobs that can't be requeued."""
job_id = submit()
atf.wait_for_job_state(job_id, "RUNNING", fatal=True)
result = atf.run_command(
f"scontrol requeue {job_id}", user=atf.properties["slurm-user"], xfail=True
)
assert result["exit_code"] != 0, f"scontrol requeue {job_id} did not fail"
assert error in result["stderr"], result["stderr"]
assert (
atf.get_job_parameter(job_id, "JobState") == "RUNNING"
), f"Job {job_id} did not stay running"