Skip to content

Commit

Permalink
Merge pull request #4125 from boegel/sanity_check_load_module
Browse files Browse the repository at this point in the history
add sanity_check_load_module method to EasyBlock to provide control over when module is loaded during sanity check step
  • Loading branch information
akesandgren authored Dec 8, 2022
2 parents a304b66 + e282dbe commit a5a188a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 22 deletions.
61 changes: 41 additions & 20 deletions easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,11 @@ def __init__(self, ec):
# sanity check fail error messages to report (if any)
self.sanity_check_fail_msgs = []

# keep track of whether module is loaded during sanity check step (to avoid re-loading)
self.sanity_check_module_loaded = False
# info required to roll back loading of fake module during sanity check (see _sanity_check_step method)
self.fake_mod_data = None

# robot path
self.robot_path = build_option('robot_path')

Expand Down Expand Up @@ -1661,6 +1666,8 @@ def load_fake_module(self, purge=False, extra_modules=None, verbose=False):
:param purge: boolean indicating whether or not to purge currently loaded modules first
:param extra_modules: list of extra modules to load (these are loaded *before* loading the 'self' module)
"""
self.log.info("Loading fake module (%s)", self.short_mod_name)

# take a copy of the current environment before loading the fake module, so we can restore it
env = copy.deepcopy(os.environ)

Expand Down Expand Up @@ -3405,6 +3412,34 @@ def _sanity_check_step_extensions(self):
self.sanity_check_fail_msgs.append(overall_fail_msg + ', '.join(x[0] for x in failed_exts))
self.sanity_check_fail_msgs.extend(x[1] for x in failed_exts)

def sanity_check_load_module(self, extension=False, extra_modules=None):
"""
Load module to prepare environment for sanity check
"""

# skip loading of fake module when using --sanity-check-only, load real module instead
if build_option('sanity_check_only') and not extension:
self.log.info("Loading real module for %s %s: %s", self.name, self.version, self.short_mod_name)
self.load_module(extra_modules=extra_modules)
self.sanity_check_module_loaded = True

# only load fake module for non-extensions, and not during dry run
elif not (extension or self.dry_run):

if extra_modules:
self.log.info("Loading extra modules for sanity check: %s", ', '.join(extra_modules))

try:
# unload all loaded modules before loading fake module
# this ensures that loading of dependencies is tested, and avoids conflicts with build dependencies
self.fake_mod_data = self.load_fake_module(purge=True, extra_modules=extra_modules, verbose=True)
self.sanity_check_module_loaded = True
except EasyBuildError as err:
self.sanity_check_fail_msgs.append("loading fake module failed: %s" % err)
self.log.warning("Sanity check: %s" % self.sanity_check_fail_msgs[-1])

return self.fake_mod_data

def _sanity_check_step(self, custom_paths=None, custom_commands=None, extension=False, extra_modules=None):
"""
Real version of sanity_check_step method.
Expand Down Expand Up @@ -3469,24 +3504,8 @@ def xs2str(xs):

trace_msg("%s %s found: %s" % (typ, xs2str(xs), ('FAILED', 'OK')[found]))

fake_mod_data = None

# skip loading of fake module when using --sanity-check-only, load real module instead
if build_option('sanity_check_only') and not extension:
self.load_module(extra_modules=extra_modules)

# only load fake module for non-extensions, and not during dry run
elif not (extension or self.dry_run):
try:
# unload all loaded modules before loading fake module
# this ensures that loading of dependencies is tested, and avoids conflicts with build dependencies
fake_mod_data = self.load_fake_module(purge=True, extra_modules=extra_modules, verbose=True)
except EasyBuildError as err:
self.sanity_check_fail_msgs.append("loading fake module failed: %s" % err)
self.log.warning("Sanity check: %s" % self.sanity_check_fail_msgs[-1])

if extra_modules:
self.log.info("Loading extra modules for sanity check: %s", ', '.join(extra_modules))
if not self.sanity_check_module_loaded:
self.fake_mod_data = self.sanity_check_load_module(extension=extension, extra_modules=extra_modules)

# allow oversubscription of P processes on C cores (P>C) for software installed on top of Open MPI;
# this is useful to avoid failing of sanity check commands that involve MPI
Expand Down Expand Up @@ -3522,8 +3541,10 @@ def xs2str(xs):
self.sanity_check_fail_msgs.append(linked_shared_lib_fails)

# cleanup
if fake_mod_data:
self.clean_up_fake_module(fake_mod_data)
if self.fake_mod_data:
self.clean_up_fake_module(self.fake_mod_data)
self.sanity_check_module_loaded = False
self.fake_mod_data = None

if self.toolchain.use_rpath:
rpath_fails = self.sanity_check_rpath()
Expand Down
3 changes: 3 additions & 0 deletions easybuild/framework/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ def __init__(self, mself, ext, extra_params=None):
key, name, version, value)

self.sanity_check_fail_msgs = []
self.sanity_check_module_loaded = False
self.fake_mod_data = None

self.async_cmd_info = None
self.async_cmd_output = None
self.async_cmd_check_cnt = None
Expand Down
5 changes: 3 additions & 2 deletions easybuild/framework/extensioneasyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,9 @@ def sanity_check_step(self, exts_filter=None, custom_paths=None, custom_commands
fake_mod_data = None

# only load fake module + extra modules for stand-alone installations (not for extensions),
# since for extension the necessary modules should already be loaded at this point
if not (self.is_extension or self.dry_run):
# since for extension the necessary modules should already be loaded at this point;
# take into account that module may already be loaded earlier in sanity check
if not (self.sanity_check_module_loaded or self.is_extension or self.dry_run):
# load fake module
fake_mod_data = self.load_fake_module(purge=True, extra_modules=extra_modules)

Expand Down

0 comments on commit a5a188a

Please sign in to comment.