|
42 | 42 | import textwrap |
43 | 43 | from easybuild.tools import LooseVersion |
44 | 44 | from importlib import reload |
45 | | -from test.framework.utilities import EnhancedTestCase, TestLoaderFiltered |
| 45 | +from test.framework.utilities import EnhancedTestCase, TestLoaderFiltered, cleanup |
46 | 46 | from test.framework.package import mock_fpm |
47 | 47 | from unittest import TextTestRunner |
48 | 48 |
|
49 | 49 | import easybuild.tools.hooks # so we can reset cached hooks |
50 | 50 | import easybuild.tools.module_naming_scheme # required to dynamically load test module naming scheme(s) |
51 | 51 | from easybuild.framework.easyconfig.easyconfig import EasyConfig |
52 | 52 | from easybuild.framework.easyconfig.parser import EasyConfigParser |
| 53 | +from easybuild.main import main_with_hooks |
53 | 54 | from easybuild.tools.build_log import EasyBuildError |
54 | 55 | from easybuild.tools.config import get_module_syntax, get_repositorypath |
55 | 56 | from easybuild.tools.environment import modify_env |
56 | 57 | from easybuild.tools.filetools import adjust_permissions, change_dir, copy_file, mkdir, move_file |
57 | 58 | from easybuild.tools.filetools import read_file, remove_dir, remove_file, which, write_file |
58 | 59 | from easybuild.tools.module_generator import ModuleGeneratorTcl |
59 | 60 | 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 |
61 | 62 | from easybuild.tools.utilities import nub |
62 | 63 | from easybuild.tools.systemtools import get_shared_lib_ext |
63 | 64 | from easybuild.tools.version import VERSION as EASYBUILD_VERSION |
@@ -4068,6 +4069,41 @@ def test_toy_build_info_msg(self): |
4068 | 4069 | regex = re.compile(pattern, re.M) |
4069 | 4070 | self.assertTrue(regex.search(stdout), "Pattern '%s' should be found in: %s" % (regex.pattern, stdout)) |
4070 | 4071 |
|
| 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 | + |
4071 | 4107 |
|
4072 | 4108 | def suite(): |
4073 | 4109 | """ return all the tests in this file """ |
|
0 commit comments