blob: bfc2aea38027de17cc4db614ca6a712bdacb1f25 [file] [log] [blame]
############################################################################
# Copyright (C) SchedMD LLC.
############################################################################
import atf
import logging
import pytest
import re
import pexpect
@pytest.fixture(scope="module", autouse=True)
def setup():
atf.require_accounting(modify=True)
atf.require_slurm_running()
# Global variables used in the tests
cluster1 = "cluster1"
cluster2 = "cluster2"
cluster3 = "cluster3"
cluster4 = "cluster4"
cluster5 = "cluster5"
federation1 = "federation1"
federation2 = "federation2"
federation3 = "federation3"
max_fed_clusters = 64
cluster_list = []
for i in range(1, max_fed_clusters):
cluster_list.append(f"cluster{i}")
cluster_string = ",".join(cluster_list)
# Variables and functions to perform subsequent matching
pos = 0
text = ""
@pytest.fixture(scope="function")
def setup_federation1(no_federations):
atf.run_command(
f"sacctmgr -i add federation {federation1}",
user=atf.properties["slurm-user"],
fatal=True,
)
yield
atf.run_command(
f"sacctmgr -i delete federation {federation1}",
user=atf.properties["slurm-user"],
fatal=False,
)
@pytest.fixture(scope="module", autouse=True)
def clean_clusters():
yield
atf.run_command(
f"sacctmgr -i delete cluster {cluster_string}",
user=atf.properties["slurm-user"],
)
@pytest.fixture(scope="function")
def no_federations():
atf.run_command(
f"sacctmgr -i delete federation {federation1},{federation2},{federation3}",
user=atf.properties["slurm-user"],
xfail=True,
)
# Performs an initial match and prepares to do subsequent matching
def first_match(pattern, initial_string):
global pos, text
pos = 0
text = initial_string
match = re.search(pattern, text)
if match is not None:
pos = match.end()
return True
else:
return False
# Looks for matches continuing from where the previous match left off
def next_match(pattern):
global pos, text
match = re.compile(pattern).search(text, pos)
if match is not None:
pos = match.end()
return True
else:
return False
def test_add_federation_nonexistent_cluster():
"""Add federation with non-existent cluster(s)"""
error = atf.run_command_error(
f"sacctmgr -i add federation {federation1} cluster={cluster1}",
user=atf.properties["slurm-user"],
)
assert (
re.search(rf"The cluster {cluster1} doesn't exist\. Please add first\.", error)
is not None
)
error = atf.run_command_error(
f"sacctmgr -i add federation {federation1} cluster={cluster1},{cluster2}",
user=atf.properties["slurm-user"],
)
assert (
re.search(rf"The cluster {cluster1} doesn't exist\. Please add first\.", error)
is not None
)
assert (
re.search(rf"The cluster {cluster2} doesn't exist\. Please add first\.", error)
is not None
)
def test_add_cluster_nonexistent_federation():
"""Add cluster to non-existent federation"""
error = atf.run_command_error(
f"sacctmgr -i add cluster {cluster1} federation={federation1}",
user=atf.properties["slurm-user"],
)
assert (
re.search(rf"The federation {federation1} doesn't exist\.", error) is not None
)
def test_add_federation():
"""Add new federation"""
output = atf.run_command_output(
f"sacctmgr -i add federation {federation1}", user=atf.properties["slurm-user"]
)
assert first_match(r"Adding Federation\(s\)", output)
assert next_match(rf"(?m)^ +{federation1}")
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation", output)
assert next_match(rf"(?m)^ +{federation1}")
def test_add_existing_federation():
"""Add new federation - already exists"""
output = atf.run_command_output(
f"sacctmgr -i add federation {federation1}", user=atf.properties["slurm-user"]
)
assert (
re.search(
rf"This federation {federation1} already exists\. +Not adding\.", output
)
is not None
)
def test_add_second_federation():
"""Add second federation and make sure that you can select only one federation"""
output = atf.run_command_output(
f"sacctmgr -i add federation {federation2}", user=atf.properties["slurm-user"]
)
assert first_match(r"Adding Federation\(s\)", output)
assert next_match(rf"(?m)^ +{federation2}")
output = atf.run_command_output(
"sacctmgr show federation format=federation%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation", output)
assert next_match(rf"(?m)^ +{federation1}")
assert next_match(rf"(?m)^ +{federation2}")
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation", output)
assert next_match(rf"(?m)^ +{federation1}")
assert not next_match(rf"(?m)^ +{federation2}")
def test_add_cluster_state_federation():
"""Add new cluster with state to existing federation"""
output = atf.run_command_output(
f"sacctmgr -i add cluster {cluster1} federation={federation1} fedstate=drain",
user=atf.properties["slurm-user"],
)
assert first_match(r"Adding Cluster\(s\)", output)
assert next_match(rf"(?m)^ +Name += +{cluster1}")
assert next_match(r"Setting")
assert next_match(rf"(?m)^ +Federation += +{federation1}")
assert next_match(r"(?m)^ +FedState += +DRAIN")
def test_add_multiple_clusters_federation():
"""Add multiple new clusters to single federation"""
output = atf.run_command_output(
f"sacctmgr -i add cluster {cluster2} {cluster3} federation={federation2}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Adding Cluster\(s\)", output)
assert next_match(rf"(?m)^ +Name += +{cluster2}")
assert next_match(rf"(?m)^ +Name += +{cluster3}")
assert next_match(r"Setting")
assert next_match(rf"Federation += +{federation2}")
output = atf.run_command_output(
f"sacctmgr show cluster {cluster1} {cluster2} {cluster3} format=cluster%20,federation%20,fedstate%20,id",
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster1} +{federation1} +DRAIN +1")
assert next_match(rf"(?m)^ +{cluster2} +{federation2} +ACTIVE +1")
assert next_match(rf"(?m)^ +{cluster3} +{federation2} +ACTIVE +2")
def test_show_cluster_WithFed():
"""Show cluster WithFed"""
output = atf.run_command_output(
f"sacctmgr show cluster {cluster1} {cluster2} {cluster3} WithFed",
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster.*?Federation +ID +Features +FedState", output)
assert next_match(rf"(?m)^ +{cluster1}.*?federatio.{{1,2}} +1 +DRAIN")
assert next_match(rf"(?m)^ +{cluster2}.*?federatio.{{1,2}} +1 +ACTIVE")
assert next_match(rf"(?m)^ +{cluster3}.*?federatio.{{1,2}} +2 +ACTIVE")
output = atf.run_command_output(
f'sacctmgr show federation {federation1} {federation2} format="federation%20,cluster%20"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster", output)
assert next_match(rf"(?m)^ +{federation1} +{cluster1}")
assert next_match(rf"(?m)^ +{federation2} +{cluster2}")
assert next_match(rf"(?m)^ +{federation2} +{cluster3}")
def test_show_federation_tree():
"""Test tree option - shows one federation line per federation"""
output = atf.run_command_output(
f'sacctmgr show federation {federation1} {federation2} format="federation%20,cluster%20" tree',
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster", output)
assert next_match(rf"{federation1} *\n +{cluster1}")
assert next_match(rf"{federation2} *\n +{cluster2} *\n +{cluster3}")
def test_clusters_multiple_federations():
"""Attempt to set clusters to multiple federations"""
error = atf.run_command_error(
f"sacctmgr -i modify federation {federation1} {federation2} set clusters={cluster1}",
user=atf.properties["slurm-user"],
)
assert (
re.search(r"Can't assign clusters to multiple federations", error) is not None
)
def test_add_cluster_no_federation():
"""Attempt to set clusters with no where clause"""
error = atf.run_command_error(
f"sacctmgr -i modify federation set clusters={cluster1}",
user=atf.properties["slurm-user"],
)
assert (
re.search(r"Can't assign clusters to multiple federations", error) is not None
)
error = atf.run_command_error(
f"sacctmgr -i modify federation set clusters={cluster1} where cluster={cluster1}",
user=atf.properties["slurm-user"],
)
assert (
re.search(r"Can't assign clusters to multiple federations", error) is not None
)
def test_modify_cluster_fedstate():
"""Modify clusters with fed options"""
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster1} {cluster3} set fedstate=DRAIN",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(r"(?m)^ +FedState += +DRAIN")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster1}")
assert next_match(rf"(?m)^ +{cluster3}")
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster2} set fedstate=DRAIN+REMOVE",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(r"(?m)^ +FedState += +DRAIN\+REMOVE")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster2}")
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster1} set fedstate=ACTIVE",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(r"(?m)^ +FedState += +ACTIVE")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster1}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster1} {cluster2} {cluster3} format="cluster%20,federation%20,fedstate%20"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState", output)
assert next_match(rf"(?m)^ +{cluster1} +{federation1} +ACTIVE")
assert next_match(rf"(?m)^ +{cluster2} +{federation2} +DRAIN\+REMOVE")
assert next_match(rf"(?m)^ +{cluster3} +{federation2} +DRAIN")
def test_modify_cluster_federation():
"""Modify cluster to federation. Check ids. Create hole in fed2 ids"""
results = atf.run_command(
f"sacctmgr -i modify cluster {cluster2} set federation={federation1}",
user=atf.properties["slurm-user"],
)
assert first_match(
rf"The cluster {cluster2} is assigned to federation {federation2}",
results["stderr"],
)
assert first_match(r"Setting", results["stdout"])
assert next_match(rf"(?m)^ +Federation += +{federation1}")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster2}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster1} {cluster2} {cluster3} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster1} +{federation1} +ACTIVE +1")
assert next_match(rf"(?m)^ +{cluster2} +{federation1} +ACTIVE +2")
assert next_match(rf"(?m)^ +{cluster3} +{federation2} +DRAIN +2")
# Move cluster1 into whole
results = atf.run_command(
f"sacctmgr -i modify cluster {cluster1} set federation={federation2}",
user=atf.properties["slurm-user"],
)
assert first_match(
rf"The cluster {cluster1} is assigned to federation {federation1}",
results["stderr"],
)
assert first_match(r"Setting", results["stdout"])
assert next_match(rf"(?m)^ +Federation += +{federation2}")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster1}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster1} {cluster2} {cluster3} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster1} +{federation2} +ACTIVE +1")
assert next_match(rf"(?m)^ +{cluster2} +{federation1} +ACTIVE +2")
assert next_match(rf"(?m)^ +{cluster3} +{federation2} +DRAIN +2")
# Move cluster2 back to federation2 and get new id -- 3
results = atf.run_command(
f"sacctmgr -i modify cluster {cluster2} set federation={federation2}",
user=atf.properties["slurm-user"],
)
assert first_match(
rf"The cluster {cluster2} is assigned to federation {federation1}",
results["stderr"],
)
assert first_match(r"Setting", results["stdout"])
assert next_match(rf"(?m)^ +Federation += +{federation2}")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster2}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster1} {cluster2} {cluster3} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster1} +{federation2} +ACTIVE +1")
assert next_match(rf"(?m)^ +{cluster2} +{federation2} +ACTIVE +3")
assert next_match(rf"(?m)^ +{cluster3} +{federation2} +DRAIN +2")
def test_add_federation_existing_cluster():
"""Add federation with existing clusters"""
command = f"sacctmgr add federation {federation3} clusters={cluster1},{cluster2}"
logging.log(
logging.NOTE,
f"Running command {command} as user {atf.properties['slurm-user']}",
)
child = pexpect.spawn(
"sudo",
[
"--preserve-env=PATH",
"-nu",
atf.properties["slurm-user"],
"/bin/bash",
"-lc",
command,
],
encoding="utf-8",
)
assert (
child.expect(f"The cluster {cluster1} is assigned to federation {federation2}")
== 0
)
assert (
child.expect(f"The cluster {cluster2} is assigned to federation {federation2}")
== 0
)
assert child.expect("Are you sure") == 0
assert child.expect(r"\(N/y\):") == 0
child.send("y")
assert child.expect(r"Adding Federation\(s\)") == 0
assert child.expect(f"(?m)^ +{federation3}") == 0
assert child.expect("Setting") == 0
assert child.expect(f"(?m)^ +Cluster += +{cluster1}") == 0
assert child.expect(f"(?m)^ +Cluster += +{cluster2}") == 0
assert child.expect("Would you like") == 0
assert child.expect(r"\(N/y\):") == 0
child.send("y")
assert child.expect(pexpect.EOF) == 0
output = atf.run_command_output(
f"sacctmgr show federation {federation1} {federation2} {federation3} format=federation%20,cluster%20,fedstate%20,id",
user=atf.properties["slurm-user"],
)
assert first_match("Federation +Cluster +FedState +ID", output)
assert next_match(rf"(?m)^ +{federation1}")
assert next_match(rf"(?m)^ +{federation2} +{cluster3} +DRAIN +2")
assert next_match(rf"(?m)^ +{federation3} +{cluster1} +ACTIVE +1")
assert next_match(rf"(?m)^ +{federation3} +{cluster2} +ACTIVE +2")
def test_modify_cluster_clear_federation():
"""Modify cluster. Clear federation"""
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster3} set federation=",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(r"(?m)^ +Federation += +$")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster3}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster3} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster3} +NA +0")
def test_select_clusters_by_federation():
"""Test selecting clusters by federations"""
output = atf.run_command_output(
f'sacctmgr show cluster where fed={federation3} format="cluster%20,federation%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +ID", output)
assert next_match(rf"(?m)^ +{cluster1} +{federation3} +1")
assert next_match(rf"(?m)^ +{cluster2} +{federation3} +2")
def test_add_cluster_verify_state():
"""Test selecting clusters by federations"""
output = atf.run_command_output(
f"sacctmgr -i add cluster {cluster4}", user=atf.properties["slurm-user"]
)
assert first_match(r"Adding Cluster\(s\)", output)
assert next_match(rf"(?m)^ +Name += +{cluster4}")
# New clusters should have fed_id=0, federation="", fed_state=NA
output = atf.run_command_output(
f'sacctmgr show cluster {cluster4} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster4} +NA +0")
def test_add_cluster_federation_activates():
"""Test adding cluster to federation sets state to ACTIVE"""
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster4} set federation={federation3}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(rf"(?m)^ +Federation += +{federation3}")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster4}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster4} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster4} +{federation3} +ACTIVE +3")
def test_modify_cluster_same_federation():
"""Modifying cluster to same federation shouldln't change fed_id or fed_state"""
# set state to something other than ACTIVE, it should stay the same
assert (
atf.run_command_exit(
f"sacctmgr -i modify cluster {cluster4} set fedstate=DRAIN",
user=atf.properties["slurm-user"],
)
== 0
)
results = atf.run_command(
f"sacctmgr -i modify cluster {cluster4} set federation={federation3}",
user=atf.properties["slurm-user"],
)
assert first_match(
rf"The cluster {cluster4} is already assigned to federation {federation3}",
results["stderr"],
)
assert first_match(r"Nothing to change", results["stdout"])
output = atf.run_command_output(
f'sacctmgr show cluster {cluster4} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster4} +{federation3} +DRAIN +3")
def test_modify_federation_same_cluster():
"""Modifying federation to same cluster shouldln't change anything"""
error = atf.run_command_error(
f"sacctmgr -i modify federation {federation3} set clusters+={cluster4}",
user=atf.properties["slurm-user"],
)
assert (
re.search(
rf"The cluster {cluster4} is already assigned to federation {federation3}",
error,
)
is not None
)
output = atf.run_command_output(
f'sacctmgr show cluster {cluster4} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster4} +{federation3} +DRAIN +3")
def test_move_cluster_federation_activates():
"""Changing from one federation to another should set the state to active"""
results = atf.run_command(
f"sacctmgr -i modify cluster {cluster4} set federation={federation2}",
user=atf.properties["slurm-user"],
)
assert first_match(
rf"The cluster {cluster4} is assigned to federation {federation3}",
results["stderr"],
)
assert first_match(r"Setting", results["stdout"])
assert next_match(rf"(?m)^ +Federation += +{federation2}")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster4}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster4} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster4} +{federation2} +ACTIVE +1")
def test_move_federation_cluster_activates():
"""Same thing for modifying federation - state should go to active"""
assert (
atf.run_command_exit(
f"sacctmgr -i modify cluster {cluster4} set fedstate=DRAIN",
user=atf.properties["slurm-user"],
)
== 0
)
results = atf.run_command(
f"sacctmgr -i modify federation {federation3} set clusters+={cluster4}",
user=atf.properties["slurm-user"],
)
assert first_match(
rf"The cluster {cluster4} is assigned to federation {federation2}",
results["stderr"],
)
assert first_match(r"Setting", results["stdout"])
assert next_match(rf"(?m)^ +Cluster +\+= +{cluster4}")
assert next_match(r"Modified federation\.\.\.")
assert next_match(rf"(?m)^ +{federation3}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster4} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster4} +{federation3} +ACTIVE +3")
def test_set_state_inactive():
"""Test setting state to INACTIVE"""
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster4} set fedstate=INACTIVE",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(r"(?m)^ +FedState += +INACTIVE")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster4}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster4} format="cluster%20,federation%20,fedstate%20,id"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster4} +{federation3} +INACTIVE +3")
def test_invalid_state():
"""Test invalid state"""
error = atf.run_command_error(
f"sacctmgr -i modify cluster {cluster4} set fedstate=abcdefg",
user=atf.properties["slurm-user"],
)
assert first_match(r"Invalid FedState abcdefg", error)
def test_modify_federation_change_clusters():
"""Modify federation change clusters - must remove others"""
atf.run_command(
f"sacctmgr -i modify cluster {cluster1} {cluster2} {cluster3} set federation=",
user=atf.properties["slurm-user"],
fatal=True,
)
output = atf.run_command_output(
f"sacctmgr -i modify federation {federation1} set clusters={cluster1},{cluster2}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(rf"(?m)^ +Cluster +\+= +{cluster1}")
assert next_match(rf"(?m)^ +Cluster +\+= +{cluster2}")
assert next_match(r"Modified federation\.\.\.")
assert next_match(rf"(?m)^ +{federation1}")
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20,cluster%20,fedstate%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster +FedState", output)
assert next_match(rf"(?m)^ +{federation1} +{cluster1} +ACTIVE")
assert next_match(rf"(?m)^ +{federation1} +{cluster2} +ACTIVE")
results = atf.run_command(
f"sacctmgr -i modify federation {federation1} set clusters={cluster1},{cluster3}",
user=atf.properties["slurm-user"],
)
assert first_match(
rf"The cluster {cluster1} is already assigned to federation {federation1}",
results["stderr"],
)
assert first_match(r"Setting", results["stdout"])
assert next_match(rf"(?m)^ +Cluster +\+= +{cluster3}")
assert next_match(rf"(?m)^ +Cluster +-= +{cluster2}")
assert next_match(r"Modified federation\.\.\.")
assert next_match(rf"(?m)^ +{federation1}")
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20,cluster%20,fedstate%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster +FedState", output)
assert next_match(rf"(?m)^ +{federation1} +{cluster1} +ACTIVE")
assert next_match(rf"(?m)^ +{federation1} +{cluster3} +ACTIVE")
output = atf.run_command_output(
f"sacctmgr -i modify federation {federation1} set clusters+={cluster2}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(rf"(?m)^ +Cluster +\+= +{cluster2}")
assert next_match(r"Modified federation\.\.\.")
assert next_match(rf"(?m)^ +{federation1}")
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20,cluster%20,fedstate%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster +FedState", output)
assert next_match(rf"(?m)^ +{federation1} +{cluster1} +ACTIVE")
assert next_match(rf"(?m)^ +{federation1} +{cluster2} +ACTIVE")
assert next_match(rf"(?m)^ +{federation1} +{cluster3} +ACTIVE")
output = atf.run_command_output(
f"sacctmgr -i modify federation {federation1} set clusters-={cluster1},{cluster2}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(rf"(?m)^ +Cluster +-= +{cluster1}")
assert next_match(rf"(?m)^ +Cluster +-= +{cluster2}")
assert next_match(r"Modified federation\.\.\.")
assert next_match(rf"(?m)^ +{federation1}")
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20,cluster%20,fedstate%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster +FedState", output)
assert next_match(rf"(?m)^ +{federation1} +{cluster3} +ACTIVE")
results = atf.run_command(
f"sacctmgr -i modify federation {federation1} set clusters-={cluster1},{cluster3}",
user=atf.properties["slurm-user"],
)
assert first_match(
rf"The cluster {cluster1} isn't assigned to federation {federation1}",
results["stderr"],
)
assert first_match(r"Setting", results["stdout"])
assert next_match(rf"(?m)^ +Cluster +-= +{cluster3}")
assert next_match(r"Modified federation\.\.\.")
assert next_match(rf"(?m)^ +{federation1}")
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20,cluster%20,fedstate%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster +FedState", output)
assert next_match(rf"(?m)^ +{federation1} +$")
def test_operators():
"""Error checking on using +, - and ="""
error = atf.run_command_error(
f"sacctmgr -i modify federation {federation1} set cluster={cluster1},+{cluster2}",
user=atf.properties["slurm-user"],
)
assert first_match(r"You can't use '=' and '\+' or '-' in the same line", error)
error = atf.run_command_error(
f"sacctmgr -i modify federation {federation1} set cluster={cluster1},-{cluster2}",
user=atf.properties["slurm-user"],
)
assert first_match(r"You can't use '=' and '\+' or '-' in the same line", error)
def test_modify_federation_clear_clusters():
"""Modify federation, clear clusters"""
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster1} {cluster2} {cluster3} set federation={federation1}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(rf"(?m)^ +Federation += +{federation1}")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster1}")
assert next_match(rf"(?m)^ +{cluster2}")
assert next_match(rf"(?m)^ +{cluster3}")
output = atf.run_command_output(
f"sacctmgr -i modify federation {federation1} set clusters=",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(rf"(?m)^ +Cluster +-= +{cluster1}")
assert next_match(rf"(?m)^ +Cluster +-= +{cluster2}")
assert next_match(rf"(?m)^ +Cluster +-= +{cluster3}")
assert next_match(r"Modified federation\.\.\.")
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20,cluster%20,fedstate%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster +FedState", output)
assert next_match(rf"(?m)^ +{federation1} +$")
# Verify clusters fed_id=0, federation="", fed_state=NA after being removed from federation
output = atf.run_command_output(
f"sacctmgr show cluster {cluster1} {cluster2} {cluster3} format=cluster%20,federation%20,fedstate%20,id",
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
assert next_match(rf"(?m)^ +{cluster1} +NA +0")
assert next_match(rf"(?m)^ +{cluster2} +NA +0")
assert next_match(rf"(?m)^ +{cluster3} +NA +0")
def test_delete_cluster_by_federation():
"""Test deleting cluster with where federation= clause"""
atf.run_command(
f"sacctmgr -i delete federation {federation2} {federation3}",
user=atf.properties["slurm-user"],
fatal=True,
)
output = atf.run_command_output(
f"sacctmgr -i add federation {federation2} clusters={cluster1},{cluster2}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Adding Federation\(s\)", output)
assert next_match(rf"(?m)^ +{federation2}")
assert next_match(r"Setting")
assert next_match(rf"(?m)^ +Cluster += +{cluster1}")
assert next_match(rf"(?m)^ +Cluster += +{cluster2}")
# Add second cluster to make sure selection only on federation
output = atf.run_command_output(
f"sacctmgr -i add federation {federation3} clusters={cluster3},{cluster4}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Adding Federation\(s\)", output)
assert next_match(rf"(?m)^ +{federation3}")
assert next_match(r"Setting")
assert next_match(rf"(?m)^ +Cluster += +{cluster3}")
assert next_match(rf"(?m)^ +Cluster += +{cluster4}")
output = atf.run_command_output(
f"sacctmgr -i delete cluster where federation={federation2}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Deleting clusters\.\.\.", output)
assert next_match(rf"(?m)^ +{cluster1}")
assert next_match(rf"(?m)^ +{cluster2}")
# Add back clusters back to federation to verify both federation clusters are selected
output = atf.run_command_output(
f"sacctmgr -i add cluster {cluster1},{cluster2} federation={federation2}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Adding Cluster\(s\)", output)
assert next_match(rf"(?m)^ +Name += +{cluster1}")
assert next_match(rf"(?m)^ +Name += +{cluster2}")
assert next_match(r"Setting")
assert next_match(rf"(?m)^ +Federation += +{federation2}")
output = atf.run_command_output(
f"sacctmgr -i delete cluster where federation={federation2},{federation3}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Deleting clusters\.\.\.", output)
assert next_match(rf"(?m)^ +{cluster1}")
assert next_match(rf"(?m)^ +{cluster2}")
assert next_match(rf"(?m)^ +{cluster3}")
assert next_match(rf"(?m)^ +{cluster4}")
def test_max_clusters_federation(setup_federation1):
"""Test adding more than 63 clusters to a federation"""
atf.run_command(
f"sacctmgr -i modify federation {federation1} set clusters=",
user=atf.properties["slurm-user"],
)
output = atf.run_command_output(
f"sacctmgr -i add cluster {cluster_string} federation={federation1}",
user=atf.properties["slurm-user"],
timeout=300,
)
assert first_match(r"Adding Cluster\(s\)", output)
for cluster in cluster_list:
assert next_match(rf"(?m)^ +Name += +{cluster}")
assert next_match(r"Setting")
assert next_match(rf"(?m)^ +Federation += +{federation1}")
results = atf.run_command(
f"sacctmgr -i add cluster cluster{max_fed_clusters} federation={federation1}",
user=atf.properties["slurm-user"],
)
assert first_match(
r"Problem adding clusters: Too many clusters in federation", results["stderr"]
)
assert first_match(r"Adding Cluster\(s\)", results["stdout"])
assert next_match(rf"(?m)^ +Name += +cluster{max_fed_clusters}")
assert next_match(r"Setting")
assert next_match(rf"(?m)^ +Federation += +{federation1}")
# Modify cluster to exceed max clusters in federation
output = atf.run_command_output(
f"sacctmgr -i add cluster cluster{max_fed_clusters}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Adding Cluster\(s\)", output)
assert next_match(rf"(?m)^ +Name += +cluster{max_fed_clusters}")
results = atf.run_command(
f"sacctmgr -i modify cluster cluster{max_fed_clusters} set federation={federation1}",
user=atf.properties["slurm-user"],
)
assert first_match(r"Too many clusters in federation", results["stderr"])
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20,cluster%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster", output)
for cluster in cluster_list:
assert re.search(rf"(?m)^ +{federation1} +{cluster} *$", output) is not None
def test_delete_cluster():
"""Delete cluster - should delete it from federation"""
output = atf.run_command_output(
f"sacctmgr -i delete cluster {cluster1}", user=atf.properties["slurm-user"]
)
assert first_match(r"Deleting clusters\.\.\.", output)
assert next_match(rf"(?m)^ +{cluster1}")
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20,cluster%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster", output)
assert re.search(rf"(?m)^ +{federation1} +{cluster1} *$", output) is None
def test_delete_federation(setup_federation1):
"""Delete federation - should clean clusters from federation"""
output = atf.run_command_output(
f"sacctmgr -i delete federation {federation1}",
user=atf.properties["slurm-user"],
fatal=True,
)
assert first_match(r"Deleting federations\.\.\.", output)
assert next_match(rf"(?m)^ +{federation1}")
output = atf.run_command_output(
f"sacctmgr show federation {federation1} format=federation%20,cluster%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Federation +Cluster", output)
assert re.search(rf"(?m)^ +{federation1} +$", output) is None
output = atf.run_command_output(
"sacctmgr show cluster format=cluster%20,federation%20",
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation", output)
assert re.search(rf"(?m)^ +{federation1}", output) is None
# Verify clusters fed_id=0, federation="", fed_state=NA after federation is deleted
output = atf.run_command_output(
f"sacctmgr show cluster {cluster_string} format=cluster%20,federation%20,fedstate%20,id",
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Federation +FedState +ID", output)
for cluster in cluster_list[1:]:
assert re.search(rf"(?m)^ +{cluster} +NA +0", output) is not None
def test_add_modify_cluster_features():
"""Add/modify cluster features"""
output = atf.run_command_output(
f"sacctmgr -i add cluster {cluster1} features=a,b",
user=atf.properties["slurm-user"],
)
assert first_match(r"Adding Cluster\(s\)", output)
assert next_match(rf"(?m)^ +Name += +{cluster1}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster1} format="cluster%20,features%20"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Features", output)
assert next_match(rf"(?m)^ +{cluster1} +a,b")
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster1} set features=aa,ab",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(r"(?m)^ +Feature += +aa")
assert next_match(r"(?m)^ +Feature += +ab")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster1}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster1} format="cluster%20,features%20"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Features", output)
assert next_match(rf"(?m)^ +{cluster1} +aa,ab")
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster1} set features+=fc",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(r"(?m)^ +Feature +\+= +fc")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster1}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster1} format="cluster%20,features%20"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Features", output)
assert next_match(rf"(?m)^ +{cluster1} +aa,ab,fc")
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster1} set features-=ab",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(r"(?m)^ +Feature +-= +ab")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster1}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster1} format="cluster%20,features%20"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Features", output)
assert next_match(rf"(?m)^ +{cluster1} +aa,fc")
output = atf.run_command_output(
f"sacctmgr -i modify cluster {cluster1} set features-=aa,fc",
user=atf.properties["slurm-user"],
)
assert first_match(r"Setting", output)
assert next_match(r"(?m)^ +Feature +-= +aa")
assert next_match(r"(?m)^ +Feature +-= +fc")
assert next_match(r"Modified cluster\.\.\.")
assert next_match(rf"(?m)^ +{cluster1}")
output = atf.run_command_output(
f'sacctmgr show cluster {cluster1} format="cluster%20,features%20"',
user=atf.properties["slurm-user"],
)
assert first_match(r"Cluster +Features", output)
assert next_match(rf"(?m)^ +{cluster1} +$")