blob: 5b9d98c895c6b47965b104ecdb98092f4d7ff6c9 [file] [edit]
############################################################################
# Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
############################################################################
"""Test reservation KV is not stored without AccountingStoreFlags=resv_kv."""
import time
import pytest
import atf
RESV_NAME = "resv_kv_not_stored"
@pytest.fixture(scope="module", autouse=True)
def setup():
atf.require_accounting()
atf.require_config_parameter_excludes("AccountingStoreFlags", "resv_kv")
atf.require_version(
(26, 11), "bin/sacctmgr", reason="Issue 51034: KV was added in 26.11"
)
atf.require_slurm_running()
@pytest.fixture
def reservation():
"""A started reservation created with KV, deleted after."""
admin = atf.properties["slurm-user"]
atf.run_command(
f"scontrol create reservation reservationname={RESV_NAME} "
f"starttime=now duration=10 nodecnt=1 users={admin} KV='{{\"a\":1}}'",
user=admin,
fatal=True,
)
yield RESV_NAME
atf.run_command(f"scontrol delete reservation={RESV_NAME}", user=admin, fatal=True)
def sacctmgr_periods(name):
"""Return the WithKV output of each accounting period of a reservation."""
window = "start=now-1hours end=now+1hours"
output = atf.run_command_output(
f"sacctmgr show reservation names={name} {window} WithKV", fatal=True
)
lines = output.splitlines()
# Each period is a header naming it, a rule, then the document
return [lines[i + 2] for i in range(0, len(lines) - 2, 3)]
def test_kv_not_stored(reservation):
"""Verify sacctmgr reports NONE, and a KV change opens no new period."""
for _ in atf.timer(fatal=True):
if sacctmgr_periods(reservation):
break
assert sacctmgr_periods(reservation) == [
"NONE"
], "sacctmgr should report no KV for the reservation"
# Accounting periods are keyed on whole seconds, so let the start second
# pass, or a wrongly opened period would replace the first one unseen
time.sleep(2)
admin = atf.properties["slurm-user"]
atf.run_command(
f"scontrol update reservationname={reservation} KV='{{\"a\":2}}'",
user=admin,
fatal=True,
)
# A new period would follow the update in the same message, so give it
# time to show up. Nothing should, so keep that well under the default
# timeout.
for _ in atf.timer(timeout=10, xfail=True):
periods = sacctmgr_periods(reservation)
if periods != ["NONE"]:
break
assert periods == [
"NONE"
], "A KV change should not open a new accounting period without resv_kv"