blob: 08afbfea141917391a7c4dae1d147967ba2d5381 [file]
############################################################################
# Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
############################################################################
"""Test sinfo --states name parsing (ticket 25499)."""
import pytest
import atf
# Setup
@pytest.fixture(scope="module", autouse=True)
def setup():
atf.require_slurm_running()
# REBOOT_REQUESTED/REBOOT_ISSUED only parse as of 26.05 (ticket 25499); share
# the gate between both params so the version boundary lives in one place.
reboot_name_skip = pytest.mark.skipif(
atf.get_version("bin/sinfo") < (26, 5),
reason="Ticket 25499: REBOOT_REQUESTED/REBOOT_ISSUED were not "
"accepted by --states",
)
@pytest.mark.skipif(
atf.get_version("bin/sinfo") < (25, 11),
reason="Ticket 23752: sinfo prints an error and exits non-zero on an "
"invalid --states value",
)
# npc/perfctrs are the removed PERFCTRS state: rejected on every supported
# version, so this pins the removal against a future re-add.
@pytest.mark.parametrize("state", ["NOTASTATE", "npc", "perfctrs"])
def test_states_invalid_rejected(state):
"""Verify sinfo rejects unknown and removed --states values"""
error = atf.run_command_error(f"sinfo --states={state}", fatal=True, xfail=True)
assert (
"Bad state string" in error
), f"sinfo should report a 'Bad state string' error for --states={state}"
def test_states_all_accepted():
"""Verify sinfo --states=all is accepted"""
exit_code = atf.run_command_exit("sinfo --states=all")
assert exit_code == 0, "sinfo should accept --states=all"
@pytest.mark.parametrize(
"state",
[
# Compact aliases users filtered with before the fix; these parse on
# every supported version, so they guard against a refactor dropping
# the hand-maintained special cases that live outside the state table.
"reboot",
"BOOT",
pytest.param("REBOOT_REQUESTED", marks=reboot_name_skip),
pytest.param("REBOOT_ISSUED", marks=reboot_name_skip),
],
)
def test_states_reboot_names(state):
"""Verify the compact and documented reboot --states names parse"""
exit_code = atf.run_command_exit(f"sinfo --states={state}")
assert exit_code == 0, f"sinfo should accept --states={state}"
@pytest.mark.skipif(
atf.get_version("bin/sinfo") < (26, 11),
reason="Ticket 25499: --helpstate and --states are table-driven (kept in "
"sync) as of 26.11",
)
def test_states_helpstate_roundtrip():
"""Verify every node state sinfo --helpstate advertises is accepted by --states.
--helpstate lists only the canonical names (the compact aliases are omitted
by design), so this guards the advertised canonical names and the parser
against drifting apart; it does not cover the compact aliases.
The list and parser are driven from the same table as of 26.11.
"""
states = atf.run_command_output("sinfo --helpstate", fatal=True).split()
assert states, "sinfo --helpstate should list node states"
for state in states:
exit_code = atf.run_command_exit(f"sinfo --states={state}")
assert exit_code == 0, f"sinfo should accept --states={state}"