blob: 35d202ec9ea7dbd17ef51d4f47c0ad040f6ef758 [file] [edit]
############################################################################
# Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
############################################################################
"""A RunInJob Epilog gets none of the job exit variables.
With PrologFlags=RunInJob, slurmstepd runs the Epilog and does not know how
the job ended, so prolog_epilog.shtml says SLURM_JOB_EXIT_CODE,
SLURM_JOB_EXIT_CODE2, SLURM_JOB_DERIVED_EC and SLURM_JOB_RC are not set
there. EpilogSlurmctld still gets them, which shows the job did end with a
status the Epilog could have been told about.
"""
import pathlib
import pytest
import atf
EPILOG_PARAMETERS = ["Epilog", "EpilogSlurmctld"]
@pytest.fixture(scope="module", autouse=True)
def setup(epilog_env_dir):
# Configured before the daemons start, as in test_127_3.
atf.require_config_parameter_includes("PrologFlags", "RunInJob")
for parameter in EPILOG_PARAMETERS:
script = f"{epilog_env_dir}/{parameter}.sh"
atf.make_bash_script(
script,
f'echo "rc=${{SLURM_JOB_RC-UNSET}}'
f" ec=${{SLURM_JOB_EXIT_CODE-UNSET}}"
f" ec2=${{SLURM_JOB_EXIT_CODE2-UNSET}}"
f' dec=${{SLURM_JOB_DERIVED_EC-UNSET}}"'
f" > {epilog_env_dir}/{parameter}_$SLURM_JOB_ID\n",
)
# set_config_parameter, since require_config_parameter lowercases
# the value and so the script path.
atf.set_config_parameter(parameter, script)
atf.require_slurm_running()
@pytest.fixture(scope="module")
def epilog_env_dir():
"""Directory the hooks write to. They run as other users, so it is
world-writable, and the absolute path is baked into the scripts."""
path = pathlib.Path("epilog_env")
path.mkdir(exist_ok=True)
path.chmod(0o777)
yield str(path.absolute())
@pytest.mark.skipif(
atf.get_version("sbin/slurmd") < (26, 11),
reason="Ticket 24195: a RunInJob Epilog got the job exit variables as 0 "
"before 26.11",
)
@pytest.mark.parametrize(
"parameter, expected_env",
[
("Epilog", "rc=UNSET ec=UNSET ec2=UNSET dec=UNSET"),
# SLURM_JOB_EXIT_CODE is the raw wait(2) status, so exit 3 is 3 << 8.
("EpilogSlurmctld", "rc=0 ec=768 ec2=3:0 dec=0"),
],
)
def test_runinjob_epilog_gets_no_job_exit_variables(
epilog_env_dir, parameter, expected_env
):
"""Verify a RunInJob Epilog gets no job exit variables, and
EpilogSlurmctld still does"""
job_id = atf.submit_job_sbatch("-N1 --no-requeue --wrap 'exit 3'", fatal=True)
atf.wait_for_job_state(job_id, "DONE", fatal=True)
atf.assert_file_contents(
f"{epilog_env_dir}/{parameter}_{job_id}",
expected_env,
message=f"{parameter} under PrologFlags=RunInJob should see '{expected_env}'",
)