def _validate_modules(self, module_dict): """This method will validate modules by running ``module load`` test for all discovered modules specified in parameter ``discovered_modules``. This method returns a list of modules that were valid, if all tests pass we return the same list. A module test pass if we get a returncode 0. """ if self.debug: print( f"Testing all discovered modules: {list(module_dict.values())}" ) self.compiler_modules_lookup = {} # test all modules via 'module load' and add only modules that passed (ret: 0) for name, module_list in module_dict.items(): self.compiler_modules_lookup[name] = [] for module in module_list: cmd = Module(module, debug=self.debug) ret = cmd.test_modules(login=True) # if module load test passed we add entry to list if ret == 0: self.compiler_modules_lookup[name].append(module)
pass_counter = 0 fail_counter = 0 total = 0 for module in modules: # output of module tree is as follows '/path/to/tree:' so we remove trailing colon tree = module[:-1] # skip entry when it's module tree if os.path.exists(tree): print(f"Skipping tree: {tree}") continue if re.search("(\(default\))$", module): module = module.replace('(default)', '') cmd = Module(module, debug=True) ret = cmd.test_modules(login=True) total += 1 # if returncode is 0 mark as PASS if ret == 0: pass_counter += 1 else: fail_counter += 1 pass_rate = pass_counter * 100 / total fail_rate = fail_counter * 100 / total print("-------- SUMMARY ---------") print(f"Total Pass: {pass_counter}/{total}") print(f"Total Failure: {fail_counter}/{total}") print(f"PASS RATE: {pass_rate:.3f}")
def test_get_collection_type_mismatch(self): a = Module() a.get_collection(1)
def test_get_collection(self): a = Module() assert "module restore settarg" == a.get_collection("settarg") assert "module restore default" == a.get_collection()
def test_type_error_describe_collection(self): cmd = Module() cmd.describe(1)
def test_type_error_save_collection(self): cmd = Module() cmd.save(1)
def test_module(self): ret = subprocess.run( "module --version", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, ) print(ret.stdout) mod_names = ["lmod"] a = Module(mod_names, debug=True) print(a.get_command()) print(a.test_modules()) assert 0 == a.test_modules() b = Module(mod_names, force=True) assert 0 == b.test_modules() c = Module(mod_names, debug=True) assert 0 == c.test_modules() d = Module(mod_names, purge=True) d.get_command() e = Module("lmod settarg", debug=True) e.get_command()
from lmod.module import get_user_collections, Module collections = get_user_collections() for i in collections: a = Module() restore_cmd, ret_code = a.get_collection(i), a.test_collection(i) print(f"Collection Command: {restore_cmd} Return Code: {ret_code}") # test Python collection with debug enabled a = Module(debug=True) a.test_collection("Python") # test default collection with debug enabled a = Module(debug=True) a.test_collection() # This will raise an exception a.test_collection(1)
def test_avail(self): a = Module() a.avail() a.avail("lmod")
def test_version(self): a = Module() a.version()
def test_is_avail(self): a = Module() assert 0 == a.is_avail("lmod")
def test_modules_in_login(self): a = Module("lmod", debug=True) a.test_modules(login=True)
def test_type_error(self): a = Module(1)
def __init__( self, tree=None, purge=True, force=False, debug=False, count=999999999, name=[], include=[], exclude=[], login=False, ): """This is the initializer method for ModuleLoadTest class. Parameters: ----------- :param tree: specify one or more module trees to test. The module tree must be root directory where modulefiles are found. Use a colon ``:`` to define more than one module tree. :type tree: str :param purge: control whether to run ``module purge`` before loading each module :type purge: bool :param force: control whether to run ``module --force purge`` before loading each module :type purge: bool :param login: controls whether to run test in login shell when ``login=True``. By default tests are run in sub-shell. :type purge: bool :param count: control how many tests to run before exiting :type purge: int :param name: filter modules by software name to test :type name: list :param include: specify a list of modules to **include** by full canonical name for testing :type purge: list :param exclude: specify a list of modules to **exclude** by full canonical name for testing :type purge: list :return: Result of module load test :rtype: None """ # setting module tree to argument passed in or default to MODULEPATH self.tree = tree or os.getenv("MODULEPATH") self.debug = debug self.purge = purge self.force = force self.login = login self.count = count self.name = name self.include = include self.exclude = exclude filter_modules = None spider_cmd = Spider(self.tree) module_dict, modules = ( spider_cmd.get_modules(self.name), list(spider_cmd.get_modules(self.name).values()), ) if self.include: filter_modules = set(self.include).intersection(modules) # only do exclusion if include list is not specified if self.exclude and not self.include: filter_modules = set(modules).difference(self.exclude) modules = filter_modules or modules modulecount = 0 print(f"Testing the Following Module Trees: {self.tree}") print("{:_<80}".format("")) for module_name in modules: module_cmd = Module( module_name, purge=self.purge, force=self.force, debug=self.debug, ) ret = module_cmd.test_modules(self.login) # extract modulefile based on module name. This is basically getting the key from dictionary (module_dict) # This is only used for printing purposes since it helps to know which module is tested. Simply putting # the full module canonical name is not enough. modulefile = list(module_dict.keys())[list( module_dict.values()).index(module_name)] if ret == 0: print( f"PASSED - Module Name: {module_name} ( modulefile={modulefile} )" ) else: print( f"FAILED - Module Name: {module_name} ( modulefile={modulefile} )" ) modulecount += 1 # terminate module load test once we have tested up to specified count if self.count <= modulecount: return
import os, sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from lmod.module import Module mod_names = ["GCCcore", "Python"] a = Module(mod_names) module_cmds = a.get_command() rc = a.test_modules() if rc == 0: print(f"The following modules: {mod_names} were loaded successfully") print("\n") print(f"Command Executed: {module_cmds}") # passing a module name ``invalid`` this is expected to fail during test bad_names = ["GCCcore", "invalid"] b = Module(bad_names) print(f"Failed to load modules: {bad_names}") print(f"Command Executed: {b.get_command()}") print(f"return code: {b.test_modules()}") # disable purge when loading modules c = Module(mod_names, purge=False) print(c.get_command()) # force purge modules d = Module(mod_names, purge=True, force=True)
from lmod.module import Module a = Spider() names = a.get_names() print(f"Module Trees: {a.get_trees()}") print("{:_<80}".format("")) print(f"Unique Software: {names}") print("\n") parents = a.get_parents() print(f"Parent Modules: {parents}") print("\n") gcc_versions = a.get_all_versions("GCC") print(f"GCC Versions: {gcc_versions}") print("\n") b = Spider("/mxg-hpc/users/ssi29/easybuild-HMNS/modules/all/Core") mod_names = b.get_modules() print(f"Module Trees: {b.get_trees()}") print(f"Unique Software: {b.get_names()}") print(f"Module Names: {mod_names}") # testing all modules for x in mod_names: cmd = Module(x, debug=True) cmd.test_modules()
def test_collection(self): cmd = Module(["settarg"]) # save as collection name "settarg" cmd.save("settarg") # save as "default" collection cmd.save() # show "default" collection cmd.describe() # show "settarg" collection cmd.describe("settarg") assert 0 == cmd.test_collection("settarg") assert 0 == cmd.test_collection()
from lmod.module import Module a = Module("zlib", debug=True) # save module collection with name "zlib" a.save("zlib") # show module collection "zlib" a.describe("zlib") # show "default" module collection a.describe() # Passing a list will throw a type error. since collection name must be a string a.describe(["zlib"])