Skip to content

Commit 9d716d9

Browse files
committed
add test that cover EasyBuild crashing
1 parent ce34aae commit 9d716d9

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

easybuild/main.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,11 +748,11 @@ def prepare_main(args=None, logfile=None, testing=None):
748748
return init_session_state, eb_go, cfg_settings
749749

750750

751-
if __name__ == "__main__":
752-
init_session_state, eb_go, cfg_settings = prepare_main()
751+
def main_with_hooks(args=None):
752+
init_session_state, eb_go, cfg_settings = prepare_main(args=args)
753753
hooks = load_hooks(eb_go.options.hooks)
754754
try:
755-
main(prepared_cfg_data=(init_session_state, eb_go, cfg_settings))
755+
main(args=args, prepared_cfg_data=(init_session_state, eb_go, cfg_settings))
756756
except EasyBuildError as err:
757757
run_hook(FAIL, hooks, args=[err])
758758
sys.exit(1)
@@ -763,3 +763,7 @@ def prepare_main(args=None, logfile=None, testing=None):
763763
run_hook(CRASH, hooks, args=[err])
764764
sys.stderr.write("EasyBuild crashed! Please consider reporting a bug, this should not happen...\n\n")
765765
raise
766+
767+
768+
if __name__ == "__main__":
769+
main_with_hooks()

test/framework/toy_build.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,23 @@
4242
import textwrap
4343
from easybuild.tools import LooseVersion
4444
from importlib import reload
45-
from test.framework.utilities import EnhancedTestCase, TestLoaderFiltered
45+
from test.framework.utilities import EnhancedTestCase, TestLoaderFiltered, cleanup
4646
from test.framework.package import mock_fpm
4747
from unittest import TextTestRunner
4848

4949
import easybuild.tools.hooks # so we can reset cached hooks
5050
import easybuild.tools.module_naming_scheme # required to dynamically load test module naming scheme(s)
5151
from easybuild.framework.easyconfig.easyconfig import EasyConfig
5252
from easybuild.framework.easyconfig.parser import EasyConfigParser
53+
from easybuild.main import main_with_hooks
5354
from easybuild.tools.build_log import EasyBuildError
5455
from easybuild.tools.config import get_module_syntax, get_repositorypath
5556
from easybuild.tools.environment import modify_env
5657
from easybuild.tools.filetools import adjust_permissions, change_dir, copy_file, mkdir, move_file
5758
from easybuild.tools.filetools import read_file, remove_dir, remove_file, which, write_file
5859
from easybuild.tools.module_generator import ModuleGeneratorTcl
5960
from easybuild.tools.modules import Lmod
60-
from easybuild.tools.run import run_cmd
61+
from easybuild.tools.run import RunShellCmdError, run_cmd, run_shell_cmd
6162
from easybuild.tools.utilities import nub
6263
from easybuild.tools.systemtools import get_shared_lib_ext
6364
from easybuild.tools.version import VERSION as EASYBUILD_VERSION
@@ -4068,6 +4069,41 @@ def test_toy_build_info_msg(self):
40684069
regex = re.compile(pattern, re.M)
40694070
self.assertTrue(regex.search(stdout), "Pattern '%s' should be found in: %s" % (regex.pattern, stdout))
40704071

4072+
def test_eb_crash(self):
4073+
"""
4074+
Test behaviour when EasyBuild crashes, for example due to a buggy hook
4075+
"""
4076+
hooks_file = os.path.join(self.test_prefix, 'my_hooks.py')
4077+
hooks_file_txt = textwrap.dedent("""
4078+
def pre_configure_hook(self, *args, **kwargs):
4079+
no_such_thing
4080+
""")
4081+
write_file(hooks_file, hooks_file_txt)
4082+
4083+
topdir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
4084+
toy_eb = os.path.join(topdir, 'test', 'framework', 'sandbox', 'easybuild', 'easyblocks', 't', 'toy.py')
4085+
toy_ec = os.path.join(topdir, 'test', 'framework', 'easyconfigs', 'test_ecs', 't', 'toy', 'toy-0.0.eb')
4086+
4087+
args = [
4088+
toy_ec,
4089+
f'--hooks={hooks_file}',
4090+
f'--force',
4091+
f'--installpath={self.test_prefix}',
4092+
f'--include-easyblocks={toy_eb}',
4093+
]
4094+
4095+
with self.mocked_stdout_stderr() as (_, stderr):
4096+
cleanup()
4097+
try:
4098+
main_with_hooks(args=args)
4099+
self.assertFalse("This should never be reached, main function should have crashed!")
4100+
except NameError as err:
4101+
self.assertEqual(str(err), "name 'no_such_thing' is not defined")
4102+
4103+
regex = re.compile(r"EasyBuild crashed! Please consider reporting a bug, this should not happen")
4104+
stderr = stderr.getvalue()
4105+
self.assertTrue(regex.search(stderr), f"Pattern '{regex.pattern}' should be found in {stderr}")
4106+
40714107

40724108
def suite():
40734109
""" return all the tests in this file """

0 commit comments

Comments
 (0)