Skip to content

Commit

Permalink
tests(editors): use pyfakefs instead of creating temp file
Browse files Browse the repository at this point in the history
Use `pyfakefs` to create a mock Slurm configuration file where we would
expect it to be located on a node. Also helps for testing file permissions
as we don't need to mess with privileges on the host filesystem.

Signed-off-by: Jason C. Nucciarone <[email protected]>
  • Loading branch information
NucciTheBoss committed Oct 7, 2024
1 parent 4db793e commit 3ea2755
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 135 deletions.
32 changes: 11 additions & 21 deletions tests/unit/editors/test_cgroupconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,55 +15,45 @@

"""Unit tests for the cgroup.conf editor."""

import unittest
from pathlib import Path

from slurmutils.editors import cgroupconfig
from constants import EXAMPLE_CGROUP_CONFIG
from pyfakefs.fake_filesystem_unittest import TestCase

EXAMPLE_CGROUP_CONF = """#
# `cgroup.conf` file generated at 2024-09-18 15:10:44.652017 by slurmutils.
#
ConstrainCores=yes
ConstrainDevices=yes
ConstrainRAMSpace=yes
ConstrainSwapSpace=yes
"""
from slurmutils.editors import cgroupconfig


class TestCgroupConfigEditor(unittest.TestCase):
class TestCgroupConfigEditor(TestCase):
"""Unit tests for cgroup.conf file editor."""

def setUp(self) -> None:
Path("cgroup.conf").write_text(EXAMPLE_CGROUP_CONF)
self.setUpPyfakefs()
self.fs.create_file("/etc/slurm/cgroup.conf", contents=EXAMPLE_CGROUP_CONFIG)

def test_loads(self) -> None:
"""Test `loads` method of the cgroupconfig module."""
config = cgroupconfig.loads(EXAMPLE_CGROUP_CONF)
config = cgroupconfig.loads(EXAMPLE_CGROUP_CONFIG)
self.assertEqual(config.constrain_cores, "yes")
self.assertEqual(config.constrain_devices, "yes")
self.assertEqual(config.constrain_ram_space, "yes")
self.assertEqual(config.constrain_swap_space, "yes")

def test_dumps(self) -> None:
"""Test `dumps` method of the cgroupconfig module."""
config = cgroupconfig.loads(EXAMPLE_CGROUP_CONF)
config = cgroupconfig.loads(EXAMPLE_CGROUP_CONFIG)
# The new config and old config should not be equal since the
# timestamps in the header will be different.
self.assertNotEqual(cgroupconfig.dumps(config), EXAMPLE_CGROUP_CONF)
self.assertNotEqual(cgroupconfig.dumps(config), EXAMPLE_CGROUP_CONFIG)

def test_edit(self) -> None:
"""Test `edit` context manager from the cgroupconfig module."""
with cgroupconfig.edit("cgroup.conf") as config:
with cgroupconfig.edit("/etc/slurm/cgroup.conf") as config:
config.constrain_cores = "no"
config.constrain_devices = "no"
config.constrain_ram_space = "no"
config.constrain_swap_space = "no"

config = cgroupconfig.load("cgroup.conf")
config = cgroupconfig.load("/etc/slurm/cgroup.conf")
self.assertEqual(config.constrain_cores, "no")
self.assertEqual(config.constrain_devices, "no")
self.assertEqual(config.constrain_ram_space, "no")
self.assertEqual(config.constrain_swap_space, "no")

def tearDown(self) -> None:
Path("cgroup.conf").unlink()
81 changes: 15 additions & 66 deletions tests/unit/editors/test_slurmconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,72 +15,24 @@

"""Unit tests for the slurm.conf editor."""

import unittest
from pathlib import Path

from constants import EXAMPLE_SLURM_CONFIG
from pyfakefs.fake_filesystem_unittest import TestCase

from slurmutils.editors import slurmconfig
from slurmutils.models import DownNodes, Node, Partition

example_slurm_conf = """#
# `slurm.conf` file generated at 2024-01-30 17:18:36.171652 by slurmutils.
#
SlurmctldHost=juju-c9fc6f-0(10.152.28.20)
SlurmctldHost=juju-c9fc6f-1(10.152.28.100)
ClusterName=charmed-hpc
AuthType=auth/munge
Epilog=/usr/local/slurm/epilog
Prolog=/usr/local/slurm/prolog
FirstJobId=65536
InactiveLimit=120
JobCompType=jobcomp/filetxt
JobCompLoc=/var/log/slurm/jobcomp
KillWait=30
MaxJobCount=10000
MinJobAge=3600
PluginDir=/usr/local/lib:/usr/local/slurm/lib
ReturnToService=0
SchedulerType=sched/backfill
SlurmctldLogFile=/var/log/slurm/slurmctld.log
SlurmdLogFile=/var/log/slurm/slurmd.log
SlurmctldPort=7002
SlurmdPort=7003
SlurmdSpoolDir=/var/spool/slurmd.spool
StateSaveLocation=/var/spool/slurm.state
SwitchType=switch/none
TmpFS=/tmp
WaitTime=30
#
# Node configurations
#
NodeName=juju-c9fc6f-2 NodeAddr=10.152.28.48 CPUs=1 RealMemory=1000 TmpDisk=10000
NodeName=juju-c9fc6f-3 NodeAddr=10.152.28.49 CPUs=1 RealMemory=1000 TmpDisk=10000
NodeName=juju-c9fc6f-4 NodeAddr=10.152.28.50 CPUs=1 RealMemory=1000 TmpDisk=10000
NodeName=juju-c9fc6f-5 NodeAddr=10.152.28.51 CPUs=1 RealMemory=1000 TmpDisk=10000
#
# Down node configurations
#
DownNodes=juju-c9fc6f-5 State=DOWN Reason="Maintenance Mode"

#
# Partition configurations
#
PartitionName=DEFAULT MaxTime=30 MaxNodes=10 State=UP
PartitionName=batch Nodes=juju-c9fc6f-2,juju-c9fc6f-3,juju-c9fc6f-4,juju-c9fc6f-5 MinNodes=4 MaxTime=120 AllowGroups=admin
"""


class TestSlurmConfigEditor(unittest.TestCase):
class TestSlurmConfigEditor(TestCase):
"""Unit tests for slurm.conf file editor."""

def setUp(self) -> None:
Path("slurm.conf").write_text(example_slurm_conf)
self.setUpPyfakefs()
self.fs.create_file("/etc/slurm/slurm.conf", contents=EXAMPLE_SLURM_CONFIG)

def test_loads(self) -> None:
"""Test `loads` method of the slurmconfig module."""
config = slurmconfig.loads(example_slurm_conf)
config = slurmconfig.loads(EXAMPLE_SLURM_CONFIG)
self.assertListEqual(
config.slurmctld_host, ["juju-c9fc6f-0(10.152.28.20)", "juju-c9fc6f-1(10.152.28.100)"]
)
Expand Down Expand Up @@ -115,15 +67,15 @@ def test_loads(self) -> None:

def test_dumps(self) -> None:
"""Test `dumps` method of the slurmconfig module."""
config = slurmconfig.loads(example_slurm_conf)
config = slurmconfig.loads(EXAMPLE_SLURM_CONFIG)
# The new config and old config should not be equal since the
# timestamps in the header will be different.
self.assertNotEqual(slurmconfig.dumps(config), example_slurm_conf)
self.assertNotEqual(slurmconfig.dumps(config), EXAMPLE_SLURM_CONFIG)

def test_edit(self) -> None:
"""Test `edit` context manager from the slurmconfig module."""
# Test descriptors for `slurm.conf` configuration options.
with slurmconfig.edit("slurm.conf") as config:
with slurmconfig.edit("/etc/slurm/slurm.conf") as config:
del config.inactive_limit
config.max_job_count = 20000
config.proctrack_type = "proctrack/linuxproc"
Expand All @@ -132,7 +84,7 @@ def test_edit(self) -> None:
del config.nodes["juju-c9fc6f-2"]
config.nodes.update(new_node.dict())

config = slurmconfig.load("slurm.conf")
config = slurmconfig.load("/etc/slurm/slurm.conf")
self.assertIsNone(config.inactive_limit)
self.assertEqual(config.max_job_count, "20000")
self.assertEqual(config.proctrack_type, "proctrack/linuxproc")
Expand All @@ -142,14 +94,14 @@ def test_edit(self) -> None:
)
self.assertEqual(config.nodes["batch-0"]["NodeAddr"], "10.152.28.48")

with slurmconfig.edit("slurm.conf") as config:
with slurmconfig.edit("/etc/slurm/slurm.conf") as config:
del config.nodes
del config.frontend_nodes
del config.down_nodes
del config.node_sets
del config.partitions

config = slurmconfig.load("slurm.conf")
config = slurmconfig.load("/etc/slurm/slurm.conf")
self.assertDictEqual(config.nodes, {})
self.assertDictEqual(config.frontend_nodes, {})
self.assertListEqual(config.down_nodes, [])
Expand Down Expand Up @@ -226,7 +178,7 @@ def test_edit(self) -> None:
),
]

with slurmconfig.edit("slurm.conf") as config:
with slurmconfig.edit("/etc/slurm/slurm.conf") as config:
for node in new_nodes:
config.nodes.update(node.dict())

Expand Down Expand Up @@ -287,7 +239,7 @@ def test_update(self):
},
}

config = slurmconfig.loads(example_slurm_conf)
config = slurmconfig.loads(EXAMPLE_SLURM_CONFIG)
updates = slurmconfig.SlurmConfig.from_dict(config_updates)
config.update(updates)

Expand Down Expand Up @@ -378,6 +330,3 @@ def test_update(self):
},
},
)

def tearDown(self):
Path("slurm.conf").unlink()
59 changes: 11 additions & 48 deletions tests/unit/editors/test_slurmdbdconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,84 +15,47 @@

"""Unit tests for the slurmdbd.conf editor."""

import unittest
from pathlib import Path

from slurmutils.editors import slurmdbdconfig
from constants import EXAMPLE_SLURMDBD_CONFIG
from pyfakefs.fake_filesystem_unittest import TestCase

example_slurmdbd_conf = """#
# `slurmdbd.conf` file generated at 2024-01-30 17:18:36.171652 by slurmutils.
#
ArchiveEvents=yes
ArchiveJobs=yes
ArchiveResvs=yes
ArchiveSteps=no
ArchiveTXN=no
ArchiveUsage=no
ArchiveScript=/usr/sbin/slurm.dbd.archive
AuthInfo=/var/run/munge/munge.socket.2
AuthType=auth/munge
AuthAltTypes=auth/jwt
AuthAltParameters=jwt_key=16549684561684@
DbdHost=slurmdbd-0
DbdBackupHost=slurmdbd-1
DebugLevel=info
PluginDir=/all/these/cool/plugins
PurgeEventAfter=1month
PurgeJobAfter=12month
PurgeResvAfter=1month
PurgeStepAfter=1month
PurgeSuspendAfter=1month
PurgeTXNAfter=12month
PurgeUsageAfter=24month
LogFile=/var/log/slurmdbd.log
PidFile=/var/run/slurmdbd.pid
SlurmUser=slurm
StoragePass=supersecretpasswd
StorageType=accounting_storage/mysql
StorageUser=slurm
StorageHost=127.0.0.1
StoragePort=3306
StorageLoc=slurm_acct_db
"""
from slurmutils.editors import slurmdbdconfig


class TestSlurmdbdConfigEditor(unittest.TestCase):
class TestSlurmdbdConfigEditor(TestCase):
"""Unit tests for the slurmdbd.conf file editor."""

def setUp(self) -> None:
Path("slurmdbd.conf").write_text(example_slurmdbd_conf)
self.setUpPyfakefs()
self.fs.create_file("/etc/slurm/slurmdbd.conf", contents=EXAMPLE_SLURMDBD_CONFIG)

def test_loads(self) -> None:
"""Test `loads` method of the slurmdbdconfig module."""
config = slurmdbdconfig.loads(example_slurmdbd_conf)
config = slurmdbdconfig.loads(EXAMPLE_SLURMDBD_CONFIG)
self.assertListEqual(config.plugin_dir, ["/all/these/cool/plugins"])
self.assertDictEqual(config.auth_alt_parameters, {"jwt_key": "16549684561684@"})
self.assertEqual(config.slurm_user, "slurm")
self.assertEqual(config.log_file, "/var/log/slurmdbd.log")

def test_dumps(self) -> None:
"""Test `dumps` method of the slurmdbdconfig module."""
config = slurmdbdconfig.loads(example_slurmdbd_conf)
config = slurmdbdconfig.loads(EXAMPLE_SLURMDBD_CONFIG)
# The new config and old config should not be equal since the
# timestamps in the header will be different.
self.assertNotEqual(slurmdbdconfig.dumps(config), example_slurmdbd_conf)
self.assertNotEqual(slurmdbdconfig.dumps(config), EXAMPLE_SLURMDBD_CONFIG)

def test_edit(self) -> None:
"""Test `edit` context manager from the slurmdbdconfig module."""
with slurmdbdconfig.edit("slurmdbd.conf") as config:
with slurmdbdconfig.edit("/etc/slurm/slurmdbd.conf") as config:
config.archive_usage = "yes"
config.log_file = "/var/spool/slurmdbd.log"
config.debug_flags = ["DB_EVENT", "DB_JOB", "DB_USAGE"]
del config.auth_alt_types
del config.auth_alt_parameters

config = slurmdbdconfig.load("slurmdbd.conf")
config = slurmdbdconfig.load("/etc/slurm/slurmdbd.conf")
self.assertEqual(config.archive_usage, "yes")
self.assertEqual(config.log_file, "/var/spool/slurmdbd.log")
self.assertListEqual(config.debug_flags, ["DB_EVENT", "DB_JOB", "DB_USAGE"])
self.assertIsNone(config.auth_alt_types)
self.assertIsNone(config.auth_alt_parameters)

def tearDown(self) -> None:
Path("slurmdbd.conf").unlink()
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ commands =
description = Run unit tests
deps =
pytest
pyfakefs
coverage[toml]
commands =
coverage run \
Expand Down

0 comments on commit 3ea2755

Please sign in to comment.