blob: a8547feb67b7fdf1586d37f338e139d6eb002fa7 [file]
############################################################################
# Copyright (C) SchedMD LLC.
############################################################################
import re
import pytest
import atf
node_num = 3
# Setup
@pytest.fixture(scope="module", autouse=True)
def setup():
atf.require_nodes(node_num + 2)
atf.require_slurm_running()
def write_host_file(matches):
host_file = atf.module_tmp_path / "host_file"
with open(host_file, "w") as hf:
for line in matches:
hf.write(line[1] + "\n")
def test_hostfile():
"""Test of hostfile option (-hostfile)."""
host_file = atf.module_tmp_path / "host_file"
HOSTFILE_ENV = "SLURM_HOSTFILE"
output = atf.run_job_output(f"-N{node_num} -l printenv SLURMD_NODENAME", fatal=True)
matches = re.findall(r"(\d+): (\S+)", output)
matches += [matches.pop(0)]
match_ordered = []
for iter in range(len(matches)):
match_ordered.append((str(iter), matches[iter][1]))
write_host_file(matches)
if atf.get_version() >= (26, 5) and atf.config_parameter_includes(
"SelectTypeParameters", "CR_LLN"
):
# In 26.05+ --distribution=arbitrary cannot be used in job allocation if
# CR_LLN is configured
assert atf.run_job_exit(
"-l --distribution=arbitrary printenv SLURMD_NODENAME",
env_vars=f"{HOSTFILE_ENV}={host_file}",
xfail=True,
), "Jobs with --distribution=arbitrary should be rejected if CR_LLN is configured (in 26.05+)"
# Use exclusive allocation to test hostfile at step level
job_id = atf.submit_job_sbatch(
f"-N{node_num} --exclusive --wrap 'sleep infinity'", fatal=True
)
else:
# Use --distribution=arbitrary at job level
job_id = atf.submit_job_sbatch(
"--distribution=arbitrary --wrap 'sleep infinity'",
env_vars=f"{HOSTFILE_ENV}={host_file}",
fatal=True,
)
# Wait for the batch step to submit more external steps
atf.wait_for_step(job_id, "batch")
# Test pass 1
output = atf.run_job_output(
f"--jobid={job_id} -l --distribution=arbitrary printenv SLURMD_NODENAME",
env_vars=f"{HOSTFILE_ENV}={host_file}",
fatal=True,
)
matches = re.findall(r"(\d+): (\S+)", output)
for match in matches:
assert (
match in match_ordered
), f"On pass 1 Task {match[0]} not distributed by hostfile {match} not in {match_ordered}"
assert (
len(matches) == node_num
), f"On pass 1 {len(matches)} tasks were ran instead of {node_num} -- one task per node in the hostfile"
matches += [matches.pop(0)]
match_ordered = []
for iter in range(len(matches)):
match_ordered.append((str(iter), matches[iter][1]))
write_host_file(matches)
# Test pass 2
output = atf.run_job_output(
f"--jobid={job_id} -l --distribution=arbitrary printenv SLURMD_NODENAME",
env_vars=f"{HOSTFILE_ENV}={host_file}",
fatal=True,
)
matches = re.findall(r"(\d+): (\S+)", output)
for match in matches:
assert (
match in match_ordered
), f"On pass 2 Task {match[0]} not distributed by hostfile {match} not in {match_ordered}"
assert (
len(matches) == node_num
), f"On pass 2 {len(matches)} tasks were ran instead of {node_num} -- one task per node in the hostfile"