Skip to content

Commit 5661bf5

Browse files
authored
Merge pull request #4679 from Flamefire/resolve-custom-cmds
Allow templates in `custom_paths` & `custom_commands` sanity-check arguments
2 parents ae40c24 + bdf35a6 commit 5661bf5

File tree

6 files changed

+142
-3
lines changed

6 files changed

+142
-3
lines changed

easybuild/framework/easyblock.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3368,7 +3368,7 @@ def _sanity_check_step_common(self, custom_paths, custom_commands):
33683368
# if no sanity_check_paths are specified in easyconfig,
33693369
# we fall back to the ones provided by the easyblock via custom_paths
33703370
if custom_paths:
3371-
paths = custom_paths
3371+
paths = self.cfg.resolve_template(custom_paths)
33723372
self.log.info("Using customized sanity check paths: %s", paths)
33733373
# if custom_paths is empty, we fall back to a generic set of paths:
33743374
# non-empty bin/ + /lib or /lib64 directories
@@ -3418,7 +3418,7 @@ def _sanity_check_step_common(self, custom_paths, custom_commands):
34183418
self.log.info("Using (only) sanity check commands specified by easyconfig file: %s", commands)
34193419
else:
34203420
if custom_commands:
3421-
commands = custom_commands
3421+
commands = self.cfg.resolve_template(custom_commands)
34223422
self.log.info("Using customised sanity check commands: %s", commands)
34233423
else:
34243424
commands = []
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
easyblock = 'ConfigureMake'
2+
3+
name = 'Python'
4+
version = '2.7.15'
5+
6+
homepage = 'http://python.org/'
7+
description = """Python is a programming language that lets you work more quickly and integrate your systems
8+
more effectively."""
9+
10+
toolchain = SYSTEM
11+
12+
source_urls = ['http://www.python.org/ftp/%(namelower)s/%(version)s/']
13+
sources = [SOURCE_TGZ]
14+
15+
# This just serves to have a Python as a dependency to test e.g. the Python version templates
16+
# So all dependencies and extensions are removed
17+
dependencies = []
18+
19+
osdependencies = []
20+
21+
exts_list = []
22+
23+
moduleclass = 'lang'
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
easyblock = 'ConfigureMake'
2+
3+
name = 'Python'
4+
version = '3.7.2'
5+
6+
homepage = 'http://python.org/'
7+
description = """Python is a programming language that lets you work more quickly and integrate your systems
8+
more effectively."""
9+
10+
toolchain = SYSTEM
11+
12+
source_urls = ['http://www.python.org/ftp/%(namelower)s/%(version)s/']
13+
sources = [SOURCE_TGZ]
14+
15+
# This just serves to have a Python as a dependency to test e.g. the Python version templates
16+
# So all dependencies and extensions are removed
17+
dependencies = []
18+
19+
osdependencies = []
20+
21+
exts_list = []
22+
23+
moduleclass = 'lang'

test/framework/filetools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2474,7 +2474,7 @@ def test_index_functions(self):
24742474
# test with specified path with and without trailing '/'s
24752475
for path in [test_ecs, test_ecs + '/', test_ecs + '//']:
24762476
index = ft.create_index(path)
2477-
self.assertEqual(len(index), 92)
2477+
self.assertEqual(len(index), 94)
24782478

24792479
expected = [
24802480
os.path.join('b', 'bzip2', 'bzip2-1.0.6-GCC-4.9.2.eb'),
Binary file not shown.

test/framework/toy_build.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,99 @@ def test_toy_build_enhanced_sanity_check(self):
25932593

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

2596+
def test_toy_build_enhanced_sanity_check_templated_multi_dep(self):
2597+
"""Test enhancing of sanity check by easyblocks with templates and in the presence of multi_deps."""
2598+
2599+
# if toy easyblock was imported, get rid of corresponding entry in sys.modules,
2600+
# to avoid that it messes up the use of --include-easyblocks=toy.py below...
2601+
if 'easybuild.easyblocks.toy' in sys.modules:
2602+
del sys.modules['easybuild.easyblocks.toy']
2603+
2604+
test_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)))
2605+
toy_ec = os.path.join(test_dir, 'easyconfigs', 'test_ecs', 't', 'toy', 'toy-0.0.eb')
2606+
toy_ec_txt = read_file(toy_ec)
2607+
2608+
test_ec = os.path.join(self.test_prefix, 'test.eb')
2609+
2610+
# get rid of custom sanity check paths in test easyconfig
2611+
regex = re.compile(r'^sanity_check_paths\s*=\s*{[^}]+}', re.M)
2612+
test_ec_txt = regex.sub('', toy_ec_txt)
2613+
self.assertNotIn('sanity_check_', test_ec_txt)
2614+
2615+
test_ec_txt += "\nmulti_deps = {'Python': ['3.7.2', '2.7.15']}"
2616+
write_file(test_ec, test_ec_txt)
2617+
2618+
# create custom easyblock for toy that has a custom sanity_check_step
2619+
toy_easyblock = os.path.join(test_dir, 'sandbox', 'easybuild', 'easyblocks', 't', 'toy.py')
2620+
2621+
toy_easyblock_txt = read_file(toy_easyblock)
2622+
2623+
toy_custom_sanity_check_step = textwrap.dedent("""
2624+
# Add to class to indent
2625+
def sanity_check_step(self):
2626+
paths = {
2627+
'files': ['bin/python%(pyshortver)s'],
2628+
'dirs': ['lib/py-%(pyshortver)s'],
2629+
}
2630+
cmds = ['python%(pyshortver)s']
2631+
return super(EB_toy, self).sanity_check_step(custom_paths=paths, custom_commands=cmds)
2632+
""")
2633+
test_toy_easyblock = os.path.join(self.test_prefix, 'toy.py')
2634+
write_file(test_toy_easyblock, toy_easyblock_txt + toy_custom_sanity_check_step)
2635+
2636+
eb_args = [
2637+
'--extended-dry-run',
2638+
'--include-easyblocks=%s' % test_toy_easyblock,
2639+
]
2640+
2641+
# by default, sanity check commands & paths specified by easyblock are used
2642+
with self.mocked_stdout_stderr():
2643+
self.test_toy_build(ec_file=test_ec, extra_args=eb_args, verify=False, testing=False, raise_error=True)
2644+
stdout = self.get_stdout()
2645+
# Cut output to start of the toy-ec, after the Python installations
2646+
stdout = stdout[stdout.index(test_ec):]
2647+
2648+
pattern_template = textwrap.dedent(r"""
2649+
Sanity check paths - file.*
2650+
\s*\* bin/python{pyshortver}
2651+
Sanity check paths - \(non-empty\) directory.*
2652+
\s*\* lib/py-{pyshortver}
2653+
Sanity check commands
2654+
\s*\* python{pyshortver}
2655+
""")
2656+
for pyshortver in ('2.7', '3.7'):
2657+
regex = re.compile(pattern_template.format(pyshortver=pyshortver), re.M)
2658+
self.assertTrue(regex.search(stdout), "Pattern '%s' should be found in: %s" % (regex.pattern, stdout))
2659+
2660+
# Enhance sanity check by extra paths to check for, the ones from the easyblock should be kept
2661+
test_ec_txt += textwrap.dedent("""
2662+
enhance_sanity_check = True
2663+
sanity_check_paths = {
2664+
'files': ['bin/pip%(pyshortver)s'],
2665+
'dirs': ['bin'],
2666+
}
2667+
""")
2668+
write_file(test_ec, test_ec_txt)
2669+
with self.mocked_stdout_stderr():
2670+
self.test_toy_build(ec_file=test_ec, extra_args=eb_args, verify=False, testing=False, raise_error=True)
2671+
stdout = self.get_stdout()
2672+
# Cut output to start of the toy-ec, after the Python installations
2673+
stdout = stdout[stdout.index(test_ec):]
2674+
2675+
pattern_template = textwrap.dedent(r"""
2676+
Sanity check paths - file.*
2677+
\s*\* bin/pip{pyshortver}
2678+
\s*\* bin/python{pyshortver}
2679+
Sanity check paths - \(non-empty\) directory.*
2680+
\s*\* bin
2681+
\s*\* lib/py-{pyshortver}
2682+
Sanity check commands
2683+
\s*\* python{pyshortver}
2684+
""")
2685+
for pyshortver in ('2.7', '3.7'):
2686+
regex = re.compile(pattern_template.format(pyshortver=pyshortver), re.M)
2687+
self.assertTrue(regex.search(stdout), "Pattern '%s' should be found in: %s" % (regex.pattern, stdout))
2688+
25962689
def test_toy_dumped_easyconfig(self):
25972690
""" Test dumping of file in eb_filerepo in both .eb and .yeb format """
25982691
filename = 'toy-0.0'

0 commit comments

Comments
 (0)