diff --git a/build_single.py b/build_single.py index 31de840..f3dc1c4 100644 --- a/build_single.py +++ b/build_single.py @@ -7,11 +7,14 @@ # Regexes to strip package-relative imports and __main__ blocks REL_IMPORT_RE = re.compile(r'^\s*from\s+\.\w+\s+import\s+.*$', re.M) +COMMON_IMPORT_RE = re.compile(r'^\s*from\s+common\s+import\s+.*$', re.M) PKG_IMPORT_RE = re.compile(r'^\s*from\s+machinestate(?:\.\w+)?\s+import\s+.*$', re.M) def strip_relative_imports(text: str) -> str: # Remove "from .X import Y" text = REL_IMPORT_RE.sub('', text) + # Remove "from common import Y" + text = COMMON_IMPORT_RE.sub('', text) # Remove "from machinestate(.X)? import Y" text = PKG_IMPORT_RE.sub('', text) # Also remove "import machinestate" (rare) @@ -36,7 +39,11 @@ def collect_files(root: pathlib.Path) -> List[str]: if common_py.exists(): files.append(str(common_py)) - files.extend(sorted(glob.glob(str(pkg / "*" / "*.py")))) + allfiles = sorted(glob.glob(str(pkg / "*" / "*.py"))) + for f in allfiles: + fname = os.path.basename(str(f)) + if not fname.startswith("test_"): + files.append(str(f)) script_py = pkg / "script.py" if script_py.exists(): @@ -77,4 +84,4 @@ def main(): print(f"[ok] wrote {OUT} ({out_path.stat().st_size} bytes)") if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/machinestate_pkg/ModulesInfo/ModulesInfo.py b/machinestate_pkg/ModulesInfo/ModulesInfo.py index 52e0799..1feed1e 100644 --- a/machinestate_pkg/ModulesInfo/ModulesInfo.py +++ b/machinestate_pkg/ModulesInfo/ModulesInfo.py @@ -1,4 +1,4 @@ -from .common import InfoGroup, which, re, os +from common import InfoGroup, which, re, os ################################################################################ # Infos about loaded modules in the modules system @@ -9,8 +9,11 @@ def __init__(self, extended=False, anonymous=False, modulecmd="modulecmd"): super(ModulesInfo, self).__init__(name="ModulesInfo", extended=extended, anonymous=anonymous) + if os.getenv("MODULES_CMD"): + modulecmd = os.getenv("MODULES_CMD") if os.getenv("LMOD_CMD"): modulecmd = os.getenv("LMOD_CMD") + self.modulecmd = modulecmd parse = ModulesInfo.parsemodules cmd_opts = "sh -t list 2>&1" @@ -37,4 +40,6 @@ def parsemodules(value): slist = [ x.split("'")[1] for x in re.split("\n", value) if "echo" in x and "'" in x ] if re.match("^Currently Loaded.+$", slist[0]): slist = slist[1:] - return slist \ No newline at end of file + if re.match("^No Modulefiles Currently Loaded.+$", slist[0]): + slist = slist[1:] + return slist diff --git a/machinestate_pkg/ModulesInfo/test_ModulesInfo.py b/machinestate_pkg/ModulesInfo/test_ModulesInfo.py new file mode 100644 index 0000000..fdd7cf3 --- /dev/null +++ b/machinestate_pkg/ModulesInfo/test_ModulesInfo.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 + +import sys, os, os.path +sys.path.append("..") + +from locale import getpreferredencoding +ENCODING = getpreferredencoding() + +import unittest + +import ModulesInfo + +def readfile(filename): + data = None + if os.path.exists(filename): + with open(filename, 'rb') as filefp: + data = filefp.read().decode(ENCODING) + return data + +basedir = "./tests" + + +def runtest(self, testfolder): + os.environ["MODULES_CMD"] = os.path.join(basedir, "fakemodules.sh") + c = ModulesInfo.ModulesInfo(modulecmd=os.path.join(basedir, "fakemodules.sh")) + c.generate() + os.environ["FAKEMODULES_INPUT"] = os.path.join(testfolder, "input") + c.update() + j = c.get_json() + ref = readfile(os.path.join(testfolder, "output")) + self.assertEqual(ref.strip(), j.strip()) + if ref.strip() != j.strip(): + print(j.strip()) + + +class TestModulesInfo(unittest.TestCase): + def test_tcl_5_0_1(self): + runtest(self, os.path.join(basedir, "tcl_5.0.1")) + def test_tcl_5_5_0(self): + runtest(self, os.path.join(basedir, "tcl_5.5.0")) + def test_tcl_5_5_0_empty(self): + runtest(self, os.path.join(basedir, "tcl_5.5.0_empty")) + def test_tcl_5_6_0(self): + runtest(self, os.path.join(basedir, "tcl_5.6.0")) + +if __name__ == '__main__': + unittest.main() diff --git a/machinestate_pkg/ModulesInfo/tests/fakemodules.sh b/machinestate_pkg/ModulesInfo/tests/fakemodules.sh new file mode 100755 index 0000000..acc555d --- /dev/null +++ b/machinestate_pkg/ModulesInfo/tests/fakemodules.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +INP=${FAKEMODULES_INPUT} +if [ -z ${INP} ]; then + exit 1 +fi + +cat ${INP} diff --git a/machinestate_pkg/ModulesInfo/tests/tcl_5.0.1/input b/machinestate_pkg/ModulesInfo/tests/tcl_5.0.1/input new file mode 100644 index 0000000..382ccf4 --- /dev/null +++ b/machinestate_pkg/ModulesInfo/tests/tcl_5.0.1/input @@ -0,0 +1,5 @@ +Currently Loaded Modulefiles: +intel/2021.4.0 +intelmpi/2021.6.0 +scorep/7.1-intel-2021.4.0-intelmpi-2021.4.0 +scalasca/2.6-intel-2021.4.0-intelmpi-2021.4.0 diff --git a/machinestate_pkg/ModulesInfo/tests/tcl_5.0.1/output b/machinestate_pkg/ModulesInfo/tests/tcl_5.0.1/output new file mode 100644 index 0000000..2f8f668 --- /dev/null +++ b/machinestate_pkg/ModulesInfo/tests/tcl_5.0.1/output @@ -0,0 +1,9 @@ +{ + "Loaded": [ + "intel/2021.4.0", + "intelmpi/2021.6.0", + "scorep/7.1-intel-2021.4.0-intelmpi-2021.4.0", + "scalasca/2.6-intel-2021.4.0-intelmpi-2021.4.0" + ], + "_meta": "ModulesInfo(modulecmd='./tests/fakemodules.sh')" +} diff --git a/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0/input b/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0/input new file mode 100644 index 0000000..e1da355 --- /dev/null +++ b/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0/input @@ -0,0 +1,4 @@ +Currently Loaded Modulefiles: +openmpi/5.0.5-gcc13.3.0 +fftw/3.3.10-gcc13.3.0-openmpi +python/3.12-conda diff --git a/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0/output b/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0/output new file mode 100644 index 0000000..8b08002 --- /dev/null +++ b/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0/output @@ -0,0 +1,8 @@ +{ + "Loaded": [ + "openmpi/5.0.5-gcc13.3.0", + "fftw/3.3.10-gcc13.3.0-openmpi", + "python/3.12-conda" + ], + "_meta": "ModulesInfo(modulecmd='./tests/fakemodules.sh')" +} diff --git a/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0_empty/input b/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0_empty/input new file mode 100644 index 0000000..a0ea85e --- /dev/null +++ b/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0_empty/input @@ -0,0 +1 @@ +No Modulefiles Currently Loaded. diff --git a/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0_empty/output b/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0_empty/output new file mode 100644 index 0000000..f098182 --- /dev/null +++ b/machinestate_pkg/ModulesInfo/tests/tcl_5.5.0_empty/output @@ -0,0 +1,4 @@ +{ + "Loaded": [], + "_meta": "ModulesInfo(modulecmd='./tests/fakemodules.sh')" +} diff --git a/machinestate_pkg/ModulesInfo/tests/tcl_5.6.0/input b/machinestate_pkg/ModulesInfo/tests/tcl_5.6.0/input new file mode 100644 index 0000000..0ccaab7 --- /dev/null +++ b/machinestate_pkg/ModulesInfo/tests/tcl_5.6.0/input @@ -0,0 +1,5 @@ +Currently Loaded Modulefiles: +intel/2025.0.0 +intelmpi/2021.14.0 +cuda/12.9.0 +likwid/5.5.1-cuda diff --git a/machinestate_pkg/ModulesInfo/tests/tcl_5.6.0/output b/machinestate_pkg/ModulesInfo/tests/tcl_5.6.0/output new file mode 100644 index 0000000..083b64a --- /dev/null +++ b/machinestate_pkg/ModulesInfo/tests/tcl_5.6.0/output @@ -0,0 +1,9 @@ +{ + "Loaded": [ + "intel/2025.0.0", + "intelmpi/2021.14.0", + "cuda/12.9.0", + "likwid/5.5.1-cuda" + ], + "_meta": "ModulesInfo(modulecmd='./tests/fakemodules.sh')" +}