blob: 7fdd752eba1a18d43864c83ad34d40d3855c794e [file] [edit]
############################################################################
# Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
############################################################################
"""Test job_submit/lua reading state_reason and state_desc of a job record."""
import pytest
import atf
# On modify, copy the state reason and description of the job record into
# the comment, where scontrol shows them, when the comment asks for it. A
# slash joins them, as the comment is read back as one space-free value.
job_submit_lua = """
function slurm_job_submit(job_desc, part_list, submit_uid)
return slurm.SUCCESS
end
function slurm_job_modify(job_desc, job_rec, part_list, modify_uid)
if job_desc.comment == "show_state" then
job_desc.comment = string.format("%s/%s",
tostring(job_rec.state_reason), tostring(job_rec.state_desc))
end
return slurm.SUCCESS
end
"""
@pytest.fixture(scope="module", autouse=True)
def setup():
atf.require_version(
(26, 11),
component="sbin/slurmctld",
reason="Issue 51114: the job record exposes state_reason and state_desc to lua in 26.11+",
)
# job_submit/lua is only built with lua support
atf.require_build_config("HAVE_LUA")
atf.require_config_parameter_includes("JobSubmitPlugins", "lua")
atf.require_config_file("job_submit.lua", job_submit_lua)
atf.require_slurm_running()
def show_state(job_id, user=None):
"""Return the "reason/description" slurm_job_modify() read."""
atf.run_command(
f"scontrol update JobId={job_id} Comment=show_state", user=user, fatal=True
)
return atf.get_job_parameter(job_id, "Comment", fatal=True)
def test_state_reason_and_desc():
"""slurm_job_modify() reads the reason a job waits for and its change.
A job waiting for its begin time reports BeginTime, and once an
administrator holds it JobHeldAdmin. A job record without a state
description gives nil, as for any unset string field of the record.
"""
job_id = atf.submit_job_sbatch(
"--begin=now+1hour -t1 -o /dev/null --wrap true", fatal=True
)
atf.wait_for_job_state(job_id, "PENDING", fatal=True)
assert (
show_state(job_id) == "BeginTime/nil"
), "A job waiting for its begin time should read BeginTime"
atf.run_command(
f"scontrol hold {job_id}", user=atf.properties["slurm-user"], fatal=True
)
assert (
show_state(job_id, user=atf.properties["slurm-user"]) == "JobHeldAdmin/nil"
), "A job held by an administrator should read JobHeldAdmin"