Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow templates in custom_paths & custom_commands sanity-check arguments #4679

Merged
merged 5 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -3368,7 +3368,7 @@ def _sanity_check_step_common(self, custom_paths, custom_commands):
# if no sanity_check_paths are specified in easyconfig,
# we fall back to the ones provided by the easyblock via custom_paths
if custom_paths:
paths = custom_paths
paths = self.cfg.resolve_template(custom_paths)
self.log.info("Using customized sanity check paths: %s", paths)
# if custom_paths is empty, we fall back to a generic set of paths:
# non-empty bin/ + /lib or /lib64 directories
Expand Down Expand Up @@ -3418,7 +3418,7 @@ def _sanity_check_step_common(self, custom_paths, custom_commands):
self.log.info("Using (only) sanity check commands specified by easyconfig file: %s", commands)
else:
if custom_commands:
commands = custom_commands
commands = self.cfg.resolve_template(custom_commands)
self.log.info("Using customised sanity check commands: %s", commands)
else:
commands = []
Expand Down
23 changes: 23 additions & 0 deletions test/framework/easyconfigs/test_ecs/p/Python/Python-2.7.15.eb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
easyblock = 'ConfigureMake'

name = 'Python'
version = '2.7.15'

homepage = 'http://python.org/'
description = """Python is a programming language that lets you work more quickly and integrate your systems
more effectively."""

toolchain = SYSTEM

source_urls = ['http://www.python.org/ftp/%(namelower)s/%(version)s/']
sources = [SOURCE_TGZ]

# This just serves to have a Python as a dependency to test e.g. the Python version templates
# So all dependencies and extensions are removed
dependencies = []

osdependencies = []

exts_list = []

moduleclass = 'lang'
23 changes: 23 additions & 0 deletions test/framework/easyconfigs/test_ecs/p/Python/Python-3.7.2.eb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
easyblock = 'ConfigureMake'

name = 'Python'
version = '3.7.2'

homepage = 'http://python.org/'
description = """Python is a programming language that lets you work more quickly and integrate your systems
more effectively."""

toolchain = SYSTEM

source_urls = ['http://www.python.org/ftp/%(namelower)s/%(version)s/']
sources = [SOURCE_TGZ]

# This just serves to have a Python as a dependency to test e.g. the Python version templates
# So all dependencies and extensions are removed
dependencies = []

osdependencies = []

exts_list = []

moduleclass = 'lang'
2 changes: 1 addition & 1 deletion test/framework/filetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2474,7 +2474,7 @@ def test_index_functions(self):
# test with specified path with and without trailing '/'s
for path in [test_ecs, test_ecs + '/', test_ecs + '//']:
index = ft.create_index(path)
self.assertEqual(len(index), 92)
self.assertEqual(len(index), 94)

expected = [
os.path.join('b', 'bzip2', 'bzip2-1.0.6-GCC-4.9.2.eb'),
Expand Down
Binary file not shown.
93 changes: 93 additions & 0 deletions test/framework/toy_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -2593,6 +2593,99 @@ def test_toy_build_enhanced_sanity_check(self):

del sys.modules['easybuild.easyblocks.toy']

def test_toy_build_enhanced_sanity_check_templated_multi_dep(self):
"""Test enhancing of sanity check by easyblocks with templates and in the presence of multi_deps."""

# if toy easyblock was imported, get rid of corresponding entry in sys.modules,
# to avoid that it messes up the use of --include-easyblocks=toy.py below...
if 'easybuild.easyblocks.toy' in sys.modules:
del sys.modules['easybuild.easyblocks.toy']

test_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)))
toy_ec = os.path.join(test_dir, 'easyconfigs', 'test_ecs', 't', 'toy', 'toy-0.0.eb')
toy_ec_txt = read_file(toy_ec)

test_ec = os.path.join(self.test_prefix, 'test.eb')

# get rid of custom sanity check paths in test easyconfig
regex = re.compile(r'^sanity_check_paths\s*=\s*{[^}]+}', re.M)
test_ec_txt = regex.sub('', toy_ec_txt)
self.assertNotIn('sanity_check_', test_ec_txt)

test_ec_txt += "\nmulti_deps = {'Python': ['3.7.2', '2.7.15']}"
write_file(test_ec, test_ec_txt)

# create custom easyblock for toy that has a custom sanity_check_step
toy_easyblock = os.path.join(test_dir, 'sandbox', 'easybuild', 'easyblocks', 't', 'toy.py')

toy_easyblock_txt = read_file(toy_easyblock)

toy_custom_sanity_check_step = textwrap.dedent("""
# Add to class to indent
def sanity_check_step(self):
paths = {
'files': ['bin/python%(pyshortver)s'],
'dirs': ['lib/py-%(pyshortver)s'],
}
cmds = ['python%(pyshortver)s']
return super(EB_toy, self).sanity_check_step(custom_paths=paths, custom_commands=cmds)
""")
test_toy_easyblock = os.path.join(self.test_prefix, 'toy.py')
write_file(test_toy_easyblock, toy_easyblock_txt + toy_custom_sanity_check_step)

eb_args = [
'--extended-dry-run',
'--include-easyblocks=%s' % test_toy_easyblock,
]

# by default, sanity check commands & paths specified by easyblock are used
with self.mocked_stdout_stderr():
self.test_toy_build(ec_file=test_ec, extra_args=eb_args, verify=False, testing=False, raise_error=True)
stdout = self.get_stdout()
# Cut output to start of the toy-ec, after the Python installations
stdout = stdout[stdout.index(test_ec):]

pattern_template = textwrap.dedent(r"""
Sanity check paths - file.*
\s*\* bin/python{pyshortver}
Sanity check paths - \(non-empty\) directory.*
\s*\* lib/py-{pyshortver}
Sanity check commands
\s*\* python{pyshortver}
""")
for pyshortver in ('2.7', '3.7'):
regex = re.compile(pattern_template.format(pyshortver=pyshortver), re.M)
self.assertTrue(regex.search(stdout), "Pattern '%s' should be found in: %s" % (regex.pattern, stdout))

# Enhance sanity check by extra paths to check for, the ones from the easyblock should be kept
test_ec_txt += textwrap.dedent("""
enhance_sanity_check = True
sanity_check_paths = {
'files': ['bin/pip%(pyshortver)s'],
'dirs': ['bin'],
}
""")
write_file(test_ec, test_ec_txt)
with self.mocked_stdout_stderr():
self.test_toy_build(ec_file=test_ec, extra_args=eb_args, verify=False, testing=False, raise_error=True)
stdout = self.get_stdout()
# Cut output to start of the toy-ec, after the Python installations
stdout = stdout[stdout.index(test_ec):]

pattern_template = textwrap.dedent(r"""
Sanity check paths - file.*
\s*\* bin/pip{pyshortver}
\s*\* bin/python{pyshortver}
Sanity check paths - \(non-empty\) directory.*
\s*\* bin
\s*\* lib/py-{pyshortver}
Sanity check commands
\s*\* python{pyshortver}
""")
for pyshortver in ('2.7', '3.7'):
regex = re.compile(pattern_template.format(pyshortver=pyshortver), re.M)
self.assertTrue(regex.search(stdout), "Pattern '%s' should be found in: %s" % (regex.pattern, stdout))

def test_toy_dumped_easyconfig(self):
""" Test dumping of file in eb_filerepo in both .eb and .yeb format """
filename = 'toy-0.0'
Expand Down
Loading