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

add support for enabling fallback in sanity check to consider lib64 equivalent for seemingly missing libraries #2477

Merged
merged 4 commits into from
May 18, 2018
Merged
Show file tree
Hide file tree
Changes from 2 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
33 changes: 24 additions & 9 deletions easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -2147,6 +2147,21 @@ def _sanity_check_step(self, custom_paths=None, custom_commands=None, extension=
"""Real version of sanity_check_step method."""
paths, path_keys_and_check, commands = self._sanity_check_step_common(custom_paths, custom_commands)

# helper function to sanity check (alternatives for) one particular path
def check_path(xs, typ, check_fn):
"""Sanity check for one particular path."""
found = False
for name in xs:
path = os.path.join(self.installdir, name)
if check_fn(path):
self.log.debug("Sanity check: found %s %s in %s" % (typ, name, self.installdir))
found = True
break
else:
self.log.debug("Could not find %s %s in %s" % (typ, name, self.installdir))

return found

# check sanity check paths
for key, (typ, check_fn) in path_keys_and_check.items():

Expand All @@ -2156,15 +2171,15 @@ def _sanity_check_step(self, custom_paths=None, custom_commands=None, extension=
elif not isinstance(xs, tuple):
raise EasyBuildError("Unsupported type '%s' encountered in %s, not a string or tuple",
key, type(xs))
found = False
for name in xs:
path = os.path.join(self.installdir, name)
if check_fn(path):
self.log.debug("Sanity check: found %s %s in %s" % (typ, name, self.installdir))
found = True
break
else:
self.log.debug("Could not find %s %s in %s" % (typ, name, self.installdir))

found = check_path(xs, typ, check_fn)

# for library files in lib/, also consider fallback to lib64/ equivalent
if not found and build_option('lib64_fallback_sanity_check'):
if all(x.startswith('lib/') for x in xs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this all? why do all paths have to start with lib/?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a wait, xs is a tuple which we do OR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, xs is one entry from e.g. the files list from sanity_check_paths can be a tuple (and if it's just a string, we make it a tuple with a single element higher up).

xs_lib64 = [os.path.join('lib64', *os.path.split(x)[1:]) for x in xs]
found = check_path(xs_lib64, typ, check_fn)

if not found:
self.sanity_check_fail_msgs.append("no %s of %s in %s" % (typ, xs, self.installdir))
self.log.warning("Sanity check: %s" % self.sanity_check_fail_msgs[-1])
Expand Down
1 change: 1 addition & 0 deletions easybuild/tools/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ def mk_full_default_path(name, prefix=DEFAULT_PREFIX):
'hidden',
'ignore_checksums',
'install_latest_eb_release',
'lib64_fallback_sanity_check',
'logtostdout',
'minimal_toolchains',
'module_only',
Expand Down
2 changes: 2 additions & 0 deletions easybuild/tools/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ def override_options(self):
'ignore-checksums': ("Ignore failing checksum verification", None, 'store_true', False),
'ignore-osdeps': ("Ignore any listed OS dependencies", None, 'store_true', False),
'install-latest-eb-release': ("Install latest known version of easybuild", None, 'store_true', False),
'lib64-fallback-sanity-check': ("Fallback in sanity check to lib64/ equivalent for missing libraries",
None, 'store_true', False),
'max-fail-ratio-adjust-permissions': ("Maximum ratio for failures to allow when adjusting permissions",
'float', 'store', DEFAULT_MAX_FAIL_RATIO_PERMS),
'minimal-toolchains': ("Use minimal toolchain when resolving dependencies", None, 'store_true', False),
Expand Down
22 changes: 22 additions & 0 deletions test/framework/toy_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,28 @@ def test_toy_sanity_check_commands(self):

self.assertTrue(os.path.exists(toy_modfile))

def test_sanity_check_paths_lib64(self):
"""Test whether fallback in sanity check for lib64/ equivalents of library files works."""
test_ecs_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'easyconfigs')
ec_file = os.path.join(test_ecs_dir, 'test_ecs', 't', 'toy', 'toy-0.0.eb')
ectxt = read_file(ec_file)

# modify test easyconfig: move lib/libtoy.a to lib64/libtoy.a
ectxt = re.sub("\s*'files'.*", "'files': ['bin/toy', 'lib/libtoy.a'],", ectxt)
postinstallcmd = "mkdir %(installdir)s/lib64 && mv %(installdir)s/lib/libtoy.a %(installdir)s/lib64/libtoy.a"
ectxt = re.sub("postinstallcmds.*", "postinstallcmds = ['%s']" % postinstallcmd, ectxt)

test_ec = os.path.join(self.test_prefix, 'toy-0.0.eb')
write_file(test_ec, ectxt)

# sanity check fails by default
error_pattern = r"Sanity check failed: no file of \('lib/libtoy.a',\)"
self.assertErrorRegex(EasyBuildError, error_pattern, self.test_toy_build, ec_file=test_ec,
raise_error=True, verbose=False)

# all is fine is lib64 fallback check is enabled
self.test_toy_build(ec_file=test_ec, extra_args=['--lib64-fallback-sanity-check'], raise_error=True)

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