Skip to content

Commit

Permalink
Merge pull request easybuilders#3761 from boegel/fix_sanity_check_only
Browse files Browse the repository at this point in the history
don't make changes to software installation directory when using --sanity-check-only
  • Loading branch information
akesandgren authored Jul 2, 2021
2 parents 8e0a02f + 7de5403 commit c32f8d9
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 37 deletions.
52 changes: 31 additions & 21 deletions easybuild/framework/easyblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -3700,6 +3700,11 @@ def build_and_install_one(ecdict, init_env):
new_log_dir = os.path.join(app.builddir, config.log_path(ec=app.cfg))
else:
new_log_dir = os.path.dirname(app.logfile)

# if we're only running the sanity check, we should not copy anything new to the installation directory
elif build_option('sanity_check_only'):
_log.info("Only running sanity check, so skipping build stats, easyconfigs archive, reprod files...")

else:
new_log_dir = os.path.join(app.installdir, config.log_path(ec=app.cfg))
if build_option('read_only_installdir'):
Expand Down Expand Up @@ -3749,30 +3754,35 @@ def build_and_install_one(ecdict, init_env):

# cleanup logs
app.close_log()
log_fn = os.path.basename(get_log_filename(app.name, app.version))
try:
application_log = os.path.join(new_log_dir, log_fn)
move_logs(app.logfile, application_log)

newspec = os.path.join(new_log_dir, app.cfg.filename())
copy_file(spec, newspec)
_log.debug("Copied easyconfig file %s to %s", spec, newspec)
if build_option('sanity_check_only'):
_log.info("Only running sanity check, so not copying anything to software install directory...")
else:
log_fn = os.path.basename(get_log_filename(app.name, app.version))
try:
application_log = os.path.join(new_log_dir, log_fn)
move_logs(app.logfile, application_log)

# copy patches
for patch in app.patches:
target = os.path.join(new_log_dir, os.path.basename(patch['path']))
copy_file(patch['path'], target)
_log.debug("Copied patch %s to %s", patch['path'], target)
newspec = os.path.join(new_log_dir, app.cfg.filename())
copy_file(spec, newspec)
_log.debug("Copied easyconfig file %s to %s", spec, newspec)

if build_option('read_only_installdir'):
# take away user write permissions (again)
adjust_permissions(new_log_dir, stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH, add=False, recursive=True)
except EasyBuildError as error:
if build_option('module_only'):
application_log = None
_log.debug("Using --module-only so can recover from error: %s", error)
else:
raise error
# copy patches
for patch in app.patches:
target = os.path.join(new_log_dir, os.path.basename(patch['path']))
copy_file(patch['path'], target)
_log.debug("Copied patch %s to %s", patch['path'], target)

if build_option('read_only_installdir'):
# take away user write permissions (again)
perms = stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH
adjust_permissions(new_log_dir, perms, add=False, recursive=True)
except EasyBuildError as error:
if build_option('module_only'):
application_log = None
_log.debug("Using --module-only so can recover from error: %s", error)
else:
raise error

end_timestamp = datetime.now()

Expand Down
40 changes: 24 additions & 16 deletions test/framework/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import os
import re
import shutil
import stat
import sys
import tempfile
from distutils.version import LooseVersion
Expand All @@ -50,9 +51,9 @@
from easybuild.tools.config import DEFAULT_MODULECLASSES
from easybuild.tools.config import find_last_log, get_build_log_path, get_module_syntax, module_classes
from easybuild.tools.environment import modify_env
from easybuild.tools.filetools import change_dir, copy_dir, copy_file, download_file, is_patch_file, mkdir
from easybuild.tools.filetools import parse_http_header_fields_urlpat, read_file, remove_dir, remove_file
from easybuild.tools.filetools import which, write_file
from easybuild.tools.filetools import adjust_permissions, change_dir, copy_dir, copy_file, download_file
from easybuild.tools.filetools import is_patch_file, mkdir, move_file, parse_http_header_fields_urlpat
from easybuild.tools.filetools import read_file, remove_dir, remove_file, which, write_file
from easybuild.tools.github import GITHUB_RAW, GITHUB_EB_MAIN, GITHUB_EASYCONFIGS_REPO
from easybuild.tools.github import URL_SEPARATOR, fetch_github_token
from easybuild.tools.modules import Lmod
Expand Down Expand Up @@ -1105,11 +1106,14 @@ def test_show_ec(self):
regex = re.compile(pattern, re.M)
self.assertTrue(regex.search(stdout), "Pattern '%s' found in: %s" % (regex.pattern, stdout))

def mocked_main(self, args):
def mocked_main(self, args, **kwargs):
"""Run eb_main with mocked stdout/stderr."""
if not kwargs:
kwargs = {'raise_error': True}

self.mock_stderr(True)
self.mock_stdout(True)
self.eb_main(args, raise_error=True)
self.eb_main(args, **kwargs)
stderr, stdout = self.get_stderr(), self.get_stdout()
self.mock_stderr(False)
self.mock_stdout(False)
Expand Down Expand Up @@ -5867,15 +5871,8 @@ def test_sanity_check_only(self):

args = [test_ec, '--sanity-check-only']

self.mock_stdout(True)
self.mock_stderr(True)
self.eb_main(args + ['--trace'], do_build=True, raise_error=True, testing=False)
stdout = self.get_stdout().strip()
stderr = self.get_stderr().strip()
self.mock_stdout(False)
self.mock_stderr(False)
stdout = self.mocked_main(args + ['--trace'], do_build=True, raise_error=True, testing=False)

self.assertFalse(stderr)
skipped = [
"fetching files",
"creating build dir, resetting environment",
Expand Down Expand Up @@ -5910,10 +5907,12 @@ def test_sanity_check_only(self):
for msg in msgs:
self.assertTrue(msg in stdout, "'%s' found in: %s" % (msg, stdout))

ebroottoy = os.path.join(self.test_installpath, 'software', 'toy', '0.0')

# check if sanity check for extension fails if a file provided by that extension,
# which is checked by the sanity check for that extension, is removed
libbarbar = os.path.join(self.test_installpath, 'software', 'toy', '0.0', 'lib', 'libbarbar.a')
remove_file(libbarbar)
# which is checked by the sanity check for that extension, is no longer there
libbarbar = os.path.join(ebroottoy, 'lib', 'libbarbar.a')
move_file(libbarbar, libbarbar + '.moved')

outtxt, error_thrown = self.eb_main(args + ['--debug'], do_build=True, return_error=True)
error_msg = str(error_thrown)
Expand All @@ -5929,6 +5928,15 @@ def test_sanity_check_only(self):
outtxt = self.eb_main(args + ['--skip-extensions'], do_build=True, raise_error=True)
self.assertTrue("Sanity check for toy successful" in outtxt)

# restore fail, we want a passing sanity check for the next check
move_file(libbarbar + '.moved', libbarbar)

# check use of --sanity-check-only when installation directory is read-only;
# cfr. https://github.com/easybuilders/easybuild-framework/issues/3757
adjust_permissions(ebroottoy, stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH, add=False, recursive=True)

stdout = self.mocked_main(args + ['--trace'], do_build=True, raise_error=True, testing=False)

def test_skip_extensions(self):
"""Test use of --skip-extensions."""
topdir = os.path.abspath(os.path.dirname(__file__))
Expand Down

0 comments on commit c32f8d9

Please sign in to comment.