From 1a426f4283f1292eae97ee9d867f22b4d87c127a Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 29 Sep 2025 09:03:59 +0200 Subject: [PATCH 1/5] Replace `assertErrorRegex` by standard `assertRaisesRegex` --- easybuild/base/testing.py | 2 +- test/framework/build_log.py | 26 ++--- test/framework/config.py | 16 +-- test/framework/containers.py | 20 ++-- test/framework/docs.py | 8 +- test/framework/easyblock.py | 78 +++++++-------- test/framework/easyconfig.py | 142 +++++++++++++-------------- test/framework/easyconfigparser.py | 4 +- test/framework/easyconfigversion.py | 2 +- test/framework/easystack.py | 14 +-- test/framework/ebconfigobj.py | 4 +- test/framework/filetools.py | 146 ++++++++++++++-------------- test/framework/general.py | 6 +- test/framework/github.py | 12 +-- test/framework/hooks.py | 6 +- test/framework/include.py | 2 +- test/framework/lib.py | 8 +- test/framework/module_generator.py | 22 ++--- test/framework/modules.py | 32 +++--- test/framework/modulestool.py | 4 +- test/framework/options.py | 132 ++++++++++++------------- test/framework/output.py | 6 +- test/framework/package.py | 2 +- test/framework/parallelbuild.py | 2 +- test/framework/robot.py | 12 +-- test/framework/run.py | 48 ++++----- test/framework/systemtools.py | 26 ++--- test/framework/toolchain.py | 36 +++---- test/framework/toy_build.py | 74 +++++++------- test/framework/tweak.py | 6 +- test/framework/type_checking.py | 94 +++++++++--------- test/framework/utilities.py | 2 +- test/framework/utilities_test.py | 26 ++--- test/framework/variables.py | 2 +- 34 files changed, 511 insertions(+), 511 deletions(-) diff --git a/easybuild/base/testing.py b/easybuild/base/testing.py index 71700794d3..e3082d7ad5 100644 --- a/easybuild/base/testing.py +++ b/easybuild/base/testing.py @@ -66,7 +66,7 @@ def nicediff(txta, txtb, offset=5): class TestCase(OrigTestCase): - """Enhanced test case, provides extra functionality (e.g. an assertErrorRegex method).""" + """Enhanced test case, provides extra functionality (e.g. an assertRaisesRegex method).""" longMessage = True # print both standard messgae and custom message diff --git a/test/framework/build_log.py b/test/framework/build_log.py index fc7aa83529..565ce012fe 100644 --- a/test/framework/build_log.py +++ b/test/framework/build_log.py @@ -66,7 +66,7 @@ def test_easybuilderror(self): # if no logger is available, and no logger is specified, use default 'root' fancylogger logToFile(tmplog, enable=True) - self.assertErrorRegex(EasyBuildError, 'BOOM', raise_easybuilderror, 'BOOM') + self.assertRaisesRegex(EasyBuildError, 'BOOM', raise_easybuilderror, 'BOOM') logToFile(tmplog, enable=False) log_re = re.compile(r"^fancyroot ::.* BOOM \(at .*:[0-9]+ in [a-z_]+\)$", re.M) @@ -74,11 +74,11 @@ def test_easybuilderror(self): self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) # test formatting of message - self.assertErrorRegex(EasyBuildError, 'BOOMBAF', raise_easybuilderror, 'BOOM%s', 'BAF') + self.assertRaisesRegex(EasyBuildError, 'BOOMBAF', raise_easybuilderror, 'BOOM%s', 'BAF') # a '%s' in a value used to template the error message should not print a traceback! self.mock_stderr(True) - self.assertErrorRegex(EasyBuildError, 'err: msg: %s', raise_easybuilderror, "err: %s", "msg: %s") + self.assertRaisesRegex(EasyBuildError, 'err: msg: %s', raise_easybuilderror, "err: %s", "msg: %s") stderr = self.get_stderr() self.mock_stderr(False) # stderr should be *empty* (there should definitely not be a traceback) @@ -148,9 +148,9 @@ def test_easybuildlog(self): logtxt_regex = re.compile(r'^%s' % expected_logtxt, re.M) self.assertTrue(logtxt_regex.search(logtxt), "Pattern '%s' found in %s" % (logtxt_regex.pattern, logtxt)) - self.assertErrorRegex(EasyBuildError, r"DEPRECATED \(since .*: kaput", log.deprecated, "kaput", older_ver) - self.assertErrorRegex(EasyBuildError, r"DEPRECATED \(since .*: 2>1", log.deprecated, "2>1", '2.0', '1.0') - self.assertErrorRegex(EasyBuildError, r"DEPRECATED \(since .*: 2>1", log.deprecated, "2>1", '2.0', + self.assertRaisesRegex(EasyBuildError, r"DEPRECATED \(since .*: kaput", log.deprecated, "kaput", older_ver) + self.assertRaisesRegex(EasyBuildError, r"DEPRECATED \(since .*: 2>1", log.deprecated, "2>1", '2.0', '1.0') + self.assertRaisesRegex(EasyBuildError, r"DEPRECATED \(since .*: 2>1", log.deprecated, "2>1", '2.0', max_ver='1.0') # wipe log so we can reuse it @@ -257,7 +257,7 @@ def run_check(args, silent=False, expected_stderr='', **kwargs): run_check(['You have been %s.', 'warned'], silent=True) run_check(['You %s %s %s.', 'have', 'been', 'warned'], silent=True) - self.assertErrorRegex(EasyBuildError, "Unknown named arguments", print_warning, 'foo', unknown_arg='bar') + self.assertRaisesRegex(EasyBuildError, "Unknown named arguments", print_warning, 'foo', unknown_arg='bar') # test passing of logger to print_warning tmp_logfile = os.path.join(self.test_prefix, 'test.log') @@ -273,7 +273,7 @@ def run_check(args, silent=False, expected_stderr=''): """Helper function to check stdout/stderr produced via print_error.""" self.mock_stderr(True) self.mock_stdout(True) - self.assertErrorRegex(SystemExit, '1', print_error, *args, silent=silent) + self.assertRaisesRegex(SystemExit, '1', print_error, *args, silent=silent) stderr = self.get_stderr() stdout = self.get_stdout() self.mock_stdout(False) @@ -288,7 +288,7 @@ def run_check(args, silent=False, expected_stderr=''): run_check(['You have %s.', 'failed'], silent=True) run_check(['%s %s %s.', 'You', 'have', 'failed'], silent=True) - self.assertErrorRegex(EasyBuildError, "Unknown named arguments", print_error, 'foo', unknown_arg='bar') + self.assertRaisesRegex(EasyBuildError, "Unknown named arguments", print_error, 'foo', unknown_arg='bar') def test_print_msg(self): """Test print_msg""" @@ -321,7 +321,7 @@ def run_check(msg, args, expected_stdout='', expected_stderr='', **kwargs): run_check("testing, 1, 2, 3", [], silent=True, stderr=True) run_check("testing, %s, %s, 3", ['1', '2'], silent=True, stderr=True) - self.assertErrorRegex(EasyBuildError, "Unknown named arguments", print_msg, 'foo', unknown_arg='bar') + self.assertRaisesRegex(EasyBuildError, "Unknown named arguments", print_msg, 'foo', unknown_arg='bar') def test_time_str_since(self): """Test time_str_since""" @@ -356,7 +356,7 @@ def run_check(msg, args, expected_stdout='', **kwargs): run_check("test 123", [], silent=True) run_check("test %s", ['123'], silent=True) - self.assertErrorRegex(EasyBuildError, "Unknown named arguments", dry_run_msg, 'foo', unknown_arg='bar') + self.assertRaisesRegex(EasyBuildError, "Unknown named arguments", dry_run_msg, 'foo', unknown_arg='bar') def test_dry_run_warning(self): """Test dry_run_warningmsg""" @@ -377,7 +377,7 @@ def run_check(msg, args, expected_stdout='', **kwargs): run_check("test 123", [], silent=True) run_check("test %s", ['123'], silent=True) - self.assertErrorRegex(EasyBuildError, "Unknown named arguments", dry_run_warning, 'foo', unknown_arg='bar') + self.assertRaisesRegex(EasyBuildError, "Unknown named arguments", dry_run_warning, 'foo', unknown_arg='bar') def test_init_logging(self): """Test init_logging function.""" @@ -434,7 +434,7 @@ def test_init_logging(self): stop_logging(logfile, logtostdout=True) def test_raise_nosupport(self): - self.assertErrorRegex(EasyBuildError, 'NO LONGER SUPPORTED since v42: foobar;', + self.assertRaisesRegex(EasyBuildError, 'NO LONGER SUPPORTED since v42: foobar;', raise_nosupport, 'foobar', 42) diff --git a/test/framework/config.py b/test/framework/config.py index 23ccadb0bc..506e6a9638 100644 --- a/test/framework/config.py +++ b/test/framework/config.py @@ -176,7 +176,7 @@ def test_generaloption_config(self): installpath_software = tempfile.mkdtemp(prefix='installpath-software') os.environ['EASYBUILD_SUBDIR_SOFTWARE'] = installpath_software error_regex = r"Found problems validating the options.*'subdir_software' must specify a \*relative\* path" - self.assertErrorRegex(EasyBuildError, error_regex, init_config) + self.assertRaisesRegex(EasyBuildError, error_regex, init_config) del os.environ['EASYBUILD_PREFIX'] del os.environ['EASYBUILD_SUBDIR_SOFTWARE'] @@ -192,7 +192,7 @@ def test_error_env_var_typo(self): error = r"Found 2 environment variable\(s\) that are prefixed with %s " % CONFIG_ENV_VAR_PREFIX error += r"but do not match valid option\(s\): " error += r','.join(['EASYBUILD_FOO', 'EASYBUILD_THERESNOSUCHCONFIGURATIONOPTION']) - self.assertErrorRegex(EasyBuildError, error, init_config) + self.assertRaisesRegex(EasyBuildError, error, init_config) del os.environ['EASYBUILD_THERESNOSUCHCONFIGURATIONOPTION'] del os.environ['EASYBUILD_FOO'] @@ -205,7 +205,7 @@ def test_install_path(self): self.assertEqual(install_path(typ='mod'), os.path.join(self.test_installpath, 'modules')) self.assertEqual(install_path('modules'), os.path.join(self.test_installpath, 'modules')) - self.assertErrorRegex(EasyBuildError, "Unknown type specified", install_path, typ='foo') + self.assertRaisesRegex(EasyBuildError, "Unknown type specified", install_path, typ='foo') args = [ '--subdir-software', 'SOFT', @@ -365,16 +365,16 @@ def test_build_options(self): self.assertTrue(bo['force']) # updating is impossible (methods are not even available) - self.assertErrorRegex(Exception, '.*(item assignment|no attribute).*', lambda x: bo.update(x), {'debug': True}) - self.assertErrorRegex(AttributeError, '.*no attribute.*', lambda x: bo.__setitem__(*x), ('debug', True)) + self.assertRaisesRegex(Exception, '.*(item assignment|no attribute).*', lambda x: bo.update(x), {'debug': True}) + self.assertRaisesRegex(AttributeError, '.*no attribute.*', lambda x: bo.__setitem__(*x), ('debug', True)) # only valid keys can be set BuildOptions.__class__._instances.clear() msg = r"Encountered unknown keys .* \(known keys: .*" - self.assertErrorRegex(KeyError, msg, BuildOptions, {'thisisclearlynotavalidbuildoption': 'FAIL'}) + self.assertRaisesRegex(KeyError, msg, BuildOptions, {'thisisclearlynotavalidbuildoption': 'FAIL'}) # test init_build_options and build_option functions - self.assertErrorRegex(KeyError, msg, init_build_options, {'thisisclearlynotavalidbuildoption': 'FAIL'}) + self.assertRaisesRegex(KeyError, msg, init_build_options, {'thisisclearlynotavalidbuildoption': 'FAIL'}) bo = init_build_options({ 'robot_path': '/some/robot/path', 'stop': 'configure', @@ -656,7 +656,7 @@ def test_log_file_format(self): # test handling of incorrect setting for --logfile-format init_config(args=['--logfile-format=easybuild,log.txt,thisiswrong']) error_pattern = "Incorrect log file format specification, should be 2-tuple" - self.assertErrorRegex(EasyBuildError, error_pattern, log_file_format) + self.assertRaisesRegex(EasyBuildError, error_pattern, log_file_format) def test_log_path(self): """Test for log_path().""" diff --git a/test/framework/containers.py b/test/framework/containers.py index b0fa41b51e..ed61d2d991 100644 --- a/test/framework/containers.py +++ b/test/framework/containers.py @@ -110,16 +110,16 @@ def test_end2end_singularity_recipe_config(self): args.extend(['--container-config', 'osversion=7.6.1810']) error_pattern = r"Keyword 'bootstrap' is required in container base config" - self.assertErrorRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) args.extend(['--container-config', 'bootstrap=foobar']) error_pattern = r"Unknown value specified for 'bootstrap' keyword: foobar \(known: arch, busybox, debootstrap, " - self.assertErrorRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) # default mirror URL for yum bootstrap agent uses ${OSVERSION}, so 'osversion' must be specified too args.extend(['--container-config', 'bootstrap=yum']) error_pattern = "Keyword 'osversion' is required in container base config when '%{OSVERSION}' is used" - self.assertErrorRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) args[-1] = 'bootstrap=yum,osversion=7.6.1810' stdout, stderr = self.run_main(args, raise_error=True) @@ -197,7 +197,7 @@ def test_end2end_singularity_recipe_config(self): error_pattern = "Keyword 'from' is required in container base config when using bootstrap agent" for (bootstrap, from_spec) in test_cases: args[-1] = 'bootstrap=%s' % bootstrap - self.assertErrorRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) args[-1] += ',from=%s' % from_spec remove_file(test_container_recipe) @@ -281,7 +281,7 @@ def test_end2end_singularity_image(self): if which('singularity') is None: error_pattern = "singularity with version 2.4 or higher not found on your system." - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) # install mocked versions of 'sudo' and 'singularity' commands singularity = os.path.join(self.test_prefix, 'bin', 'singularity') @@ -338,7 +338,7 @@ def test_end2end_singularity_image(self): error_pattern = "Container image already exists at %s, not overwriting it without --force" % cont_img self.mock_stdout(True) - self.assertErrorRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) self.mock_stdout(False) args.append('--force') @@ -380,7 +380,7 @@ def test_end2end_dockerfile(self): ] error_pattern = "Unsupported container config 'not-supported'" - self.assertErrorRegex(EasyBuildError, + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_main, base_args + ['--container-config=not-supported'], @@ -397,7 +397,7 @@ def test_end2end_dockerfile(self): error_pattern = "Container recipe at %s/containers/Dockerfile.toy-0.0 already exists, " \ "not overwriting it without --force" % self.test_prefix - self.assertErrorRegex(EasyBuildError, + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_main, base_args + ['--container-config=centos:7'], @@ -441,7 +441,7 @@ def test_end2end_docker_image(self): if not which('docker'): error_pattern = "docker not found on your system." - self.assertErrorRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_main, args, raise_error=True) # install mocked versions of 'sudo' and 'docker' commands docker = os.path.join(self.test_prefix, 'bin', 'docker') @@ -488,7 +488,7 @@ def test_container_config_template_recipe(self): 'toy-0.0.eb', ] error_pattern = "--container-config must be specified!" - self.assertErrorRegex(EasyBuildError, error_pattern, self.run_main, args) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_main, args) args.extend(['--container-config', 'bootstrap=localimage,from=foobar']) stdout, stderr = self.run_main(args) diff --git a/test/framework/docs.py b/test/framework/docs.py index 865bdec716..15d25b8a8b 100644 --- a/test/framework/docs.py +++ b/test/framework/docs.py @@ -1288,8 +1288,8 @@ def test_mk_table(self): res = mk_rst_table(titles, table) self.assertEqual(res, expected_rst) - self.assertErrorRegex(ValueError, "Number of titles/columns should be equal", mk_md_table, titles, []) - self.assertErrorRegex(ValueError, "Number of titles/columns should be equal", mk_rst_table, titles, []) + self.assertRaisesRegex(ValueError, "Number of titles/columns should be equal", mk_md_table, titles, []) + self.assertRaisesRegex(ValueError, "Number of titles/columns should be equal", mk_rst_table, titles, []) def test_title_and_table(self): """ @@ -1329,8 +1329,8 @@ def test_title_and_table(self): self.assertEqual(res, expected_rst) error_pattern = "Number of titles/columns should be equal" - self.assertErrorRegex(ValueError, error_pattern, md_title_and_table, '', titles, []) - self.assertErrorRegex(ValueError, error_pattern, rst_title_and_table, '', titles, [('val 11', 'val 12')]) + self.assertRaisesRegex(ValueError, error_pattern, md_title_and_table, '', titles, []) + self.assertRaisesRegex(ValueError, error_pattern, rst_title_and_table, '', titles, [('val 11', 'val 12')]) def test_help(self): """ diff --git a/test/framework/easyblock.py b/test/framework/easyblock.py index 35af52cbcc..1c56ffeb4f 100644 --- a/test/framework/easyblock.py +++ b/test/framework/easyblock.py @@ -82,7 +82,7 @@ def test_empty(self): self.writeEC() """ empty files should not parse! """ self.assertRaises(EasyBuildError, EasyConfig, self.eb_file) - self.assertErrorRegex(EasyBuildError, "Value of incorrect type passed", EasyBlock, "") + self.assertRaisesRegex(EasyBuildError, "Value of incorrect type passed", EasyBlock, "") def test_easyblock(self): """ make sure easyconfigs defining extensions work""" @@ -727,7 +727,7 @@ def test_make_module_req(self): with eb.module_generator.start_module_creation(): err_regex = "Expansion of search path glob.*pointing outside of parent directory.*" - self.assertErrorRegex(EasyBuildError, err_regex, eb.make_module_req) + self.assertRaisesRegex(EasyBuildError, err_regex, eb.make_module_req) # Test modextrapaths: with absolute + empty paths, appending and custom delimiters remove_dir(eb.installdir) @@ -877,7 +877,7 @@ def test_module_search_path_headers(self): error_pattern = "Unknown value selected for option module-search-path-headers" with eb.module_generator.start_module_creation(): - self.assertErrorRegex(EasyBuildError, error_pattern, EasyBlock, ec) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyBlock, ec) # cleanup eb.close_log() @@ -1203,7 +1203,7 @@ def test_det_iter_cnt(self): self.writeEC() error_pattern = "lists for iterated build should have same length" - self.assertErrorRegex(EasyBuildError, error_pattern, EasyConfig, self.eb_file) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyConfig, self.eb_file) def test_handle_iterate_opts(self): """Test for handle_iterate_opts method.""" @@ -1290,7 +1290,7 @@ def test_post_processing_step(self): depr_msg = r"EasyBlock.post_install_step\(\) is deprecated, use EasyBlock.post_processing_step\(\) instead" expected_error = r"DEPRECATED \(since v6.0\).*" + depr_msg with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, expected_error, eb.run_all_steps, True) + self.assertRaisesRegex(EasyBuildError, expected_error, eb.run_all_steps, True) change_dir(cwd) toy_ec = EasyConfig(toy_ec_fn) @@ -1345,7 +1345,7 @@ def test_extensions_step(self): eb = EasyBlock(EasyConfig(self.eb_file)) eb.installdir = config.install_path() self.assertRaises(EasyBuildError, eb.extensions_step, fetch=True) - self.assertErrorRegex(EasyBuildError, "No default extension class set", eb.extensions_step, fetch=True) + self.assertRaisesRegex(EasyBuildError, "No default extension class set", eb.extensions_step, fetch=True) # test if everything works fine if set self.contents += "\nexts_defaultclass = 'DummyExtension'" @@ -1357,7 +1357,7 @@ def test_extensions_step(self): # test for proper error message when skip is set, but no exts_filter is set self.assertRaises(EasyBuildError, eb.skip_extensions) - self.assertErrorRegex(EasyBuildError, "no exts_filter set", eb.skip_extensions) + self.assertRaisesRegex(EasyBuildError, "no exts_filter set", eb.skip_extensions) # cleanup eb.close_log() @@ -1406,7 +1406,7 @@ def test_extensions_step_deprecations(self): self.assertEqual(ext.__class__.__name__, "DeprecatedDummyExtension") for substep in install_substeps: expected_error = rf"DEPRECATED \(since v6.0\).*use {substep}\(\) instead.*" - self.assertErrorRegex(EasyBuildError, expected_error, ext.install_extension_substep, substep) + self.assertRaisesRegex(EasyBuildError, expected_error, ext.install_extension_substep, substep) # ChildCustomDummyExtension ext = eb.ext_instances[3] self.assertEqual(ext.__class__.__name__, "ChildCustomDummyExtension") @@ -1418,7 +1418,7 @@ def test_extensions_step_deprecations(self): self.assertEqual(ext.__class__.__name__, "ChildDeprecatedDummyExtension") for substep in install_substeps: expected_error = rf"DEPRECATED \(since v6.0\).*use {substep}\(\) instead.*" - self.assertErrorRegex(EasyBuildError, expected_error, ext.install_extension_substep, substep) + self.assertRaisesRegex(EasyBuildError, expected_error, ext.install_extension_substep, substep) def test_init_extensions(self): """Test creating extension instances.""" @@ -1454,7 +1454,7 @@ def test_init_extensions(self): eb.prepare_for_extensions() error_pattern = "ConfigureMake easyblock can not be used to install extensions" - self.assertErrorRegex(EasyBuildError, error_pattern, eb.init_ext_instances) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.init_ext_instances) def test_extension_source_tmpl(self): """Test type checking for 'source_tmpl' value of an extension.""" @@ -1476,7 +1476,7 @@ def test_extension_source_tmpl(self): error_pattern = r"source_tmpl value must be a string! " error_pattern += r"\(found value of type 'list'\): \['%\(name\)s-%\(version\)s.tar.gz'\]" - self.assertErrorRegex(EasyBuildError, error_pattern, eb.fetch_step) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.fetch_step) self.contents = self.contents.replace("'source_tmpl': [SOURCE_TAR_GZ]", "'source_tmpl': SOURCE_TAR_GZ") self.writeEC() @@ -1770,7 +1770,7 @@ def test_make_module_step(self): eb.installdir = os.path.join(config.install_path(), 'pi', '3.14') eb.check_readiness_step() with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, eb.make_module_step) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.make_module_step) def test_gen_dirs(self): """Test methods that generate/set build/install directory names.""" @@ -1971,13 +1971,13 @@ def test_fetch_sources(self): # old format for specifying source with custom extract command is deprecated eb.src = [] error_msg = r"DEPRECATED \(since v4.0\).*Using a 2-element list/tuple.*" - self.assertErrorRegex(EasyBuildError, error_msg, eb.fetch_sources, + self.assertRaisesRegex(EasyBuildError, error_msg, eb.fetch_sources, [('toy-0.0_gzip.patch.gz', "gunzip %s")], checksums=[]) # unknown dict keys in sources are reported sources[0]['nosuchkey'] = 'foobar' error_pattern = "Found one or more unexpected keys in 'sources' specification: {'nosuchkey': 'foobar'}" - self.assertErrorRegex(EasyBuildError, error_pattern, eb.fetch_sources, sources, checksums=[]) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.fetch_sources, sources, checksums=[]) @requires_github_access() def test_fetch_sources_git(self): @@ -2048,7 +2048,7 @@ def test_download_instructions(self): common_error_pattern = "^Couldn't find file software_with_missing_sources-0.0.tar.gz anywhere" error_pattern = common_error_pattern + ", and downloading it didn't work either" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, eb.fetch_step) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.fetch_step) download_instructions = "download_instructions = 'Manual download from example.com required'" sources = "sources = [SOURCE_TAR_GZ]" @@ -2059,7 +2059,7 @@ def test_download_instructions(self): error_pattern = common_error_pattern + ", please follow the download instructions above" self.mock_stderr(True) self.mock_stdout(True) - self.assertErrorRegex(EasyBuildError, error_pattern, eb.fetch_step) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.fetch_step) stderr = self.get_stderr().strip() self.mock_stderr(False) self.assertIn("Download instructions:\n\n Manual download from example.com required", stderr) @@ -2073,7 +2073,7 @@ def test_download_instructions(self): error_pattern = "^Couldn't find file ext_with_missing_sources-0.0.tar.gz anywhere" self.mock_stderr(True) self.mock_stdout(True) - self.assertErrorRegex(EasyBuildError, error_pattern, eb.fetch_step) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.fetch_step) stderr = self.get_stderr().strip() self.mock_stderr(False) self.mock_stdout(False) @@ -2088,7 +2088,7 @@ def test_download_instructions(self): # no download instructions printed anymore now self.mock_stderr(True) self.mock_stdout(True) - self.assertErrorRegex(EasyBuildError, error_pattern, eb.fetch_step) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.fetch_step) stderr = self.get_stderr().strip() self.mock_stderr(False) self.mock_stdout(False) @@ -2103,7 +2103,7 @@ def test_download_instructions(self): self.mock_stderr(True) self.mock_stdout(True) - self.assertErrorRegex(EasyBuildError, error_pattern, eb.fetch_step) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.fetch_step) stderr = self.get_stderr().strip() self.mock_stderr(False) self.mock_stdout(False) @@ -2117,7 +2117,7 @@ def test_download_instructions(self): self.mock_stderr(True) self.mock_stdout(True) - self.assertErrorRegex(EasyBuildError, error_pattern, eb.fetch_step) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.fetch_step) stderr = self.get_stderr().strip() self.mock_stderr(False) self.mock_stdout(False) @@ -2211,7 +2211,7 @@ def test_obtain_file(self): urls = ['file://%s' % tmpdir_subdir] error_pattern = "Couldn't find file 'toy-0.0.tar.gz' anywhere, and downloading it is disabled" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, eb.obtain_file, + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.obtain_file, toy_tarball, urls=urls, alt_location='alt_toy', no_download=True) # 'downloading' a file to (first) alternative sourcepath works @@ -2274,14 +2274,14 @@ def test_obtain_file(self): fn = 'thisisclearlyanonexistingfile' error_regex = "Couldn't find file %s anywhere, and downloading it didn't work either" % fn with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_regex, eb.obtain_file, fn, urls=['file://%s' % tmpdir_subdir]) + self.assertRaisesRegex(EasyBuildError, error_regex, eb.obtain_file, fn, urls=['file://%s' % tmpdir_subdir]) # also test triggering error when downloading from a URL that includes URL-encoded characters # cfr. https://github.com/easybuilders/easybuild-framework/pull/4005 url = 'file://%s' % os.path.dirname(tmpdir_subdir) url += '%2F' + os.path.basename(tmpdir_subdir) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_regex, eb.obtain_file, fn, urls=[url]) + self.assertRaisesRegex(EasyBuildError, error_regex, eb.obtain_file, fn, urls=[url]) # file specifications via URL also work, are downloaded to (first) sourcepath init_config(args=["--sourcepath=%s:/no/such/dir:%s" % (tmpdir, sandbox_sources)]) @@ -2401,7 +2401,7 @@ def test_collect_exts_file_info(self): self.assertNotIn('patches', exts_file_info[3]) error_msg = "Can't verify checksums for extension files if they are not being fetched" - self.assertErrorRegex(EasyBuildError, error_msg, toy_eb.collect_exts_file_info, fetch_files=False) + self.assertRaisesRegex(EasyBuildError, error_msg, toy_eb.collect_exts_file_info, fetch_files=False) def test_obtain_file_extension(self): """Test use of obtain_file method on an extension.""" @@ -2534,7 +2534,7 @@ def test_patch_step(self): with self.mocked_stdout_stderr(): eb.fetch_step() eb.extract_step() - self.assertErrorRegex(EasyBuildError, '.*', eb.patch_step) + self.assertRaisesRegex(EasyBuildError, '.*', eb.patch_step) # test actual patching of unpacked sources ec['sources'] = orig_sources @@ -2606,7 +2606,7 @@ def test_extensions_sanity_check(self): error_pattern += r"failing sanity check for 'toy' extension: " error_pattern += r'command "thisshouldfail" failed; output:\n.* thisshouldfail: command not found' with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, eb.run_all_steps, True) + self.assertRaisesRegex(EasyBuildError, error_pattern, eb.run_all_steps, True) # purposely put sanity check command in place that breaks the build, # to check whether sanity check is only run once; @@ -2860,7 +2860,7 @@ def check_start_dir(expected_start_dir): # clean error when specified start dir does not exist ec['ec']['start_dir'] = 'thisstartdirisnotthere' err_pattern = "Specified start dir .*/toy-0.0/thisstartdirisnotthere does not exist" - self.assertErrorRegex(EasyBuildError, err_pattern, check_start_dir, 'whatever') + self.assertRaisesRegex(EasyBuildError, err_pattern, check_start_dir, 'whatever') def test_extension_set_start_dir(self): """Test start dir with extensions.""" @@ -2929,7 +2929,7 @@ def check_ext_start_dir(expected_start_dir, unpack_src=True, parent_startdir=Non ] with self.mocked_stdout_stderr(): err_pattern = r"Provided start dir \(nonexistingdir\) for extension barbar does not exist:.*" - self.assertErrorRegex(EasyBuildError, err_pattern, check_ext_start_dir, 'whatever') + self.assertRaisesRegex(EasyBuildError, err_pattern, check_ext_start_dir, 'whatever') # No error when using relative path in non-extracted source for some reason ec['ec']['exts_list'] = [ @@ -3014,14 +3014,14 @@ def run_extension_step(): with ec.disable_templating(): ec['exts_list'][0][2]['unpack_source'] = False with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, 'not extracted', run_extension_step) + self.assertRaisesRegex(EasyBuildError, 'not extracted', run_extension_step) self.assertFalse(self.get_stderr()) # Patch but no source with ec.disable_templating(): ec['exts_list'][0][2]['nosource'] = True with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, 'no sources', run_extension_step) + self.assertRaisesRegex(EasyBuildError, 'no sources', run_extension_step) self.assertFalse(self.get_stderr()) # Patch without source is possible if the start_dir is set @@ -3239,11 +3239,11 @@ def test_checksum_step(self): eb = get_easyblock_instance(ec) eb.fetch_sources() error_msg = "Checksum verification for .*/toy-0.0.tar.gz using .* failed" - self.assertErrorRegex(EasyBuildError, error_msg, eb.checksum_step) + self.assertRaisesRegex(EasyBuildError, error_msg, eb.checksum_step) # also check verification of checksums for extensions, which is part of collect_exts_file_info error_msg = "Checksum verification for extension source bar-0.0.tar.gz failed" - self.assertErrorRegex(EasyBuildError, error_msg, eb.collect_exts_file_info) + self.assertRaisesRegex(EasyBuildError, error_msg, eb.collect_exts_file_info) # create test easyconfig from which checksums have been stripped test_ec = os.path.join(self.test_prefix, 'test.eb') @@ -3290,11 +3290,11 @@ def test_checksum_step(self): init_config(build_options=build_options) eb.fetch_sources() error_msg = "Checksum verification for .*/toy-0.0.tar.gz using .* failed" - self.assertErrorRegex(EasyBuildError, error_msg, eb.checksum_step) + self.assertRaisesRegex(EasyBuildError, error_msg, eb.checksum_step) # also check verification of checksums for extensions, which is part of collect_exts_file_info error_msg = "Checksum verification for extension source bar-0.0.tar.gz failed" - self.assertErrorRegex(EasyBuildError, error_msg, eb.collect_exts_file_info) + self.assertRaisesRegex(EasyBuildError, error_msg, eb.collect_exts_file_info) # if --ignore-checksums is enabled, faulty checksums are reported but otherwise ignored (no error) build_options = { @@ -3596,7 +3596,7 @@ def run_sanity_check_step(sanity_check_paths, enhance_sanity_check): ] for test_case in test_cases: # without enhanced sanity check, these are all invalid sanity_check_paths values - self.assertErrorRegex(EasyBuildError, error_pattern, run_sanity_check_step, test_case, False) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_sanity_check_step, test_case, False) # if enhance_sanity_check is enabled, these are acceptable sanity_check_step values run_sanity_check_step(test_case, True) @@ -3609,8 +3609,8 @@ def run_sanity_check_step(sanity_check_paths, enhance_sanity_check): {'dirs': [], 'libs': ['libfoo.a']}, ] for test_case in test_cases: - self.assertErrorRegex(EasyBuildError, error_pattern, run_sanity_check_step, test_case, False) - self.assertErrorRegex(EasyBuildError, error_pattern, run_sanity_check_step, test_case, True) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_sanity_check_step, test_case, False) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_sanity_check_step, test_case, True) # non-list values yield different errors with/without enhance_sanity_check error_pattern_bis = r"Incorrect value type in sanity_check_paths, should be a list: .*" @@ -3621,8 +3621,8 @@ def run_sanity_check_step(sanity_check_paths, enhance_sanity_check): {'files': [], 'dirs': 'foo'}, ] for test_case in test_cases: - self.assertErrorRegex(EasyBuildError, error_pattern, run_sanity_check_step, test_case, False) - self.assertErrorRegex(EasyBuildError, error_pattern_bis, run_sanity_check_step, test_case, True) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_sanity_check_step, test_case, False) + self.assertRaisesRegex(EasyBuildError, error_pattern_bis, run_sanity_check_step, test_case, True) # empty sanity_check_paths is always OK, since then the fallback to default bin + lib/lib64 kicks in run_sanity_check_step({}, False) diff --git a/test/framework/easyconfig.py b/test/framework/easyconfig.py index 7a07eab449..aa10dc9ace 100644 --- a/test/framework/easyconfig.py +++ b/test/framework/easyconfig.py @@ -146,13 +146,13 @@ def tearDown(self): def test_empty(self): """ empty files should not parse! """ - self.assertErrorRegex(EasyBuildError, "expected a valid path", EasyConfig, "") + self.assertRaisesRegex(EasyBuildError, "expected a valid path", EasyConfig, "") self.contents = "# empty string" self.prep() self.assertRaises(EasyBuildError, EasyConfig, self.eb_file) self.contents = "" self.prep() - self.assertErrorRegex(EasyBuildError, "is empty", EasyConfig, self.eb_file) + self.assertRaisesRegex(EasyBuildError, "is empty", EasyConfig, self.eb_file) def test_mandatory(self): """ make sure all checking of mandatory parameters works """ @@ -162,7 +162,7 @@ def test_mandatory(self): 'version = "3.14"', ]) self.prep() - self.assertErrorRegex(EasyBuildError, "mandatory parameters not provided", EasyConfig, self.eb_file) + self.assertRaisesRegex(EasyBuildError, "mandatory parameters not provided", EasyConfig, self.eb_file) self.contents += '\n' + '\n'.join([ 'homepage = "http://example.com"', @@ -197,20 +197,20 @@ def test_validation(self): ]) self.prep() ec = EasyConfig(self.eb_file, validate=False) - self.assertErrorRegex(EasyBuildError, r"\w* provided '\w*' is not valid", ec.validate) + self.assertRaisesRegex(EasyBuildError, r"\w* provided '\w*' is not valid", ec.validate) ec['stop'] = 'patch' # this should now not crash ec.validate() ec['osdependencies'] = ['non-existent-dep'] - self.assertErrorRegex(EasyBuildError, "OS dependencies were not found", ec.validate) + self.assertRaisesRegex(EasyBuildError, "OS dependencies were not found", ec.validate) # system toolchain, installversion == version self.assertEqual(det_full_ec_version(ec), "3.14") os.chmod(self.eb_file, 0o000) - self.assertErrorRegex(EasyBuildError, "Permission denied", EasyConfig, self.eb_file) + self.assertRaisesRegex(EasyBuildError, "Permission denied", EasyConfig, self.eb_file) os.chmod(self.eb_file, 0o755) self.contents += "\nsyntax_error'" @@ -222,13 +222,13 @@ def test_validation(self): else: error_pattern = "Parsing easyconfig file failed: EOL while scanning string literal" - self.assertErrorRegex(EasyBuildError, error_pattern, EasyConfig, self.eb_file) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyConfig, self.eb_file) # introduce "TypeError: format requires mapping" issue" self.contents = self.contents.replace("syntax_error'", "foo = '%(name)s %s' % version") self.prep() error_pattern = r"Parsing easyconfig file failed: format requires a mapping \(line 8\)" - self.assertErrorRegex(EasyBuildError, error_pattern, EasyConfig, self.eb_file) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyConfig, self.eb_file) def test_system_toolchain_constant(self): """Test use of SYSTEM constant to specify toolchain.""" @@ -327,12 +327,12 @@ def test_dependency(self): self.assertEqual(det_full_ec_version(first), '1.1-GCC-4.6.3') self.assertEqual(det_full_ec_version(second), '2.2-GCC-4.6.3') - self.assertErrorRegex(EasyBuildError, "Dependency foo of unsupported type", eb._parse_dependency, "foo") - self.assertErrorRegex(EasyBuildError, "without name", eb._parse_dependency, ()) - self.assertErrorRegex(EasyBuildError, "without version", eb._parse_dependency, {'name': 'test'}) + self.assertRaisesRegex(EasyBuildError, "Dependency foo of unsupported type", eb._parse_dependency, "foo") + self.assertRaisesRegex(EasyBuildError, "without name", eb._parse_dependency, ()) + self.assertRaisesRegex(EasyBuildError, "without version", eb._parse_dependency, {'name': 'test'}) err_msg = "Incorrect external dependency specification" - self.assertErrorRegex(EasyBuildError, err_msg, eb._parse_dependency, (EXTERNAL_MODULE_MARKER,)) - self.assertErrorRegex(EasyBuildError, err_msg, eb._parse_dependency, ('foo', '1.2.3', EXTERNAL_MODULE_MARKER)) + self.assertRaisesRegex(EasyBuildError, err_msg, eb._parse_dependency, (EXTERNAL_MODULE_MARKER,)) + self.assertRaisesRegex(EasyBuildError, err_msg, eb._parse_dependency, ('foo', '1.2.3', EXTERNAL_MODULE_MARKER)) def test_false_dep_version(self): """ @@ -416,7 +416,7 @@ def test_extra_options(self): ]) self.prep() eb = EasyConfig(self.eb_file) - self.assertErrorRegex(EasyBuildError, "unknown easyconfig parameter", lambda: eb['custom_key']) + self.assertRaisesRegex(EasyBuildError, "unknown easyconfig parameter", lambda: eb['custom_key']) extra_vars = {'custom_key': ['default', "This is a default key", easyconfig.CUSTOM]} @@ -443,7 +443,7 @@ def test_extra_options(self): # test extra mandatory parameters extra_vars.update({'mandatory_key': ['default', 'another mandatory key', easyconfig.MANDATORY]}) - self.assertErrorRegex(EasyBuildError, r"mandatory parameters not provided", + self.assertRaisesRegex(EasyBuildError, r"mandatory parameters not provided", EasyConfig, self.eb_file, extra_options=extra_vars) self.contents += '\nmandatory_key = "value"' @@ -636,10 +636,10 @@ def test_suggestions(self): 'sourceURLs = ["http://example.com"]', ]) self.prep() - self.assertErrorRegex(EasyBuildError, "dependencis -> dependencies", EasyConfig, self.eb_file) - self.assertErrorRegex(EasyBuildError, "source_uls -> source_urls", EasyConfig, self.eb_file) - self.assertErrorRegex(EasyBuildError, "source_URLs -> source_urls", EasyConfig, self.eb_file) - self.assertErrorRegex(EasyBuildError, "sourceURLs -> source_urls", EasyConfig, self.eb_file) + self.assertRaisesRegex(EasyBuildError, "dependencis -> dependencies", EasyConfig, self.eb_file) + self.assertRaisesRegex(EasyBuildError, "source_uls -> source_urls", EasyConfig, self.eb_file) + self.assertRaisesRegex(EasyBuildError, "source_URLs -> source_urls", EasyConfig, self.eb_file) + self.assertRaisesRegex(EasyBuildError, "sourceURLs -> source_urls", EasyConfig, self.eb_file) # No error for known params prefixed by "local_" self.contents = '\n'.join([ @@ -892,7 +892,7 @@ def test_installversion(self): 'versionsuffix': {'name': 'system', 'version': 'system'}, } error_pattern = "versionsuffix value should be a string, found 'dict'" - self.assertErrorRegex(EasyBuildError, error_pattern, det_full_ec_version, faulty_dep_spec) + self.assertRaisesRegex(EasyBuildError, error_pattern, det_full_ec_version, faulty_dep_spec) def test_obtain_easyconfig(self): """test obtaining an easyconfig file given certain specifications""" @@ -965,7 +965,7 @@ def test_obtain_easyconfig(self): specs = {'name': 'nosuchsoftware'} error_regexp = ".*No easyconfig files found for software %s, and no templates available. I'm all out of ideas." error_regexp = error_regexp % specs['name'] - self.assertErrorRegex(EasyBuildError, error_regexp, obtain_ec_for, specs, [self.test_prefix], None) + self.assertRaisesRegex(EasyBuildError, error_regexp, obtain_ec_for, specs, [self.test_prefix], None) # should find matching easyconfig file specs = { @@ -987,7 +987,7 @@ def test_obtain_easyconfig(self): 'versionsuffix': suff }) error_regexp = ".*No toolchain name specified, and more than one available: .*" - self.assertErrorRegex(EasyBuildError, error_regexp, obtain_ec_for, specs, [self.test_prefix], None) + self.assertRaisesRegex(EasyBuildError, error_regexp, obtain_ec_for, specs, [self.test_prefix], None) # should be able to generate an easyconfig file that slightly differs ver = '3.16' @@ -1107,7 +1107,7 @@ def test_obtain_easyconfig(self): res = obtain_ec_for(specs, [self.test_prefix], None) self.assertEqual(res[0], True) error_pattern = r"Hidden deps with visible module names .* not in list of \(build\)dependencies: .*" - self.assertErrorRegex(EasyBuildError, error_pattern, EasyConfig, res[1]) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyConfig, res[1]) remove_file(res[1]) specs['dependencies'].append(('test', '3.2.1')) @@ -1339,8 +1339,8 @@ def test_ec_method_resolve_template(self): # by default unresolved template value triggers an error being raised error_pattern = "Failed to resolve all templates" - self.assertErrorRegex(EasyBuildError, error_pattern, ec.resolve_template, val) - self.assertErrorRegex(EasyBuildError, error_pattern, ec.get, 'installopts') + self.assertRaisesRegex(EasyBuildError, error_pattern, ec.resolve_template, val) + self.assertRaisesRegex(EasyBuildError, error_pattern, ec.get, 'installopts') # this can be (temporarily) disabled with ec.allow_unresolved_templates(): @@ -1350,8 +1350,8 @@ def test_ec_method_resolve_template(self): # Enforced again self.assertTrue(ec.expect_resolved_template_values) - self.assertErrorRegex(EasyBuildError, error_pattern, ec.resolve_template, val) - self.assertErrorRegex(EasyBuildError, error_pattern, ec.get, 'installopts') + self.assertRaisesRegex(EasyBuildError, error_pattern, ec.resolve_template, val) + self.assertRaisesRegex(EasyBuildError, error_pattern, ec.get, 'installopts') def test_templating_cuda_toolchain(self): """Test templates via toolchain component, like setting %(cudaver)s with fosscuda toolchain.""" @@ -1718,7 +1718,7 @@ def test_build_options(self): ]) self.prep() eb = EasyConfig(self.eb_file, validate=False) - self.assertErrorRegex(EasyBuildError, "Build option lists for iterated build should have same length", + self.assertRaisesRegex(EasyBuildError, "Build option lists for iterated build should have same length", eb.validate) # list with a single element is OK, is treated as a string @@ -1820,14 +1820,14 @@ def test_get_easyblock_class(self): self.assertEqual(get_easyblock_class(easyblock), easyblock_class) error_pattern = "No software-specific easyblock 'EB_gzip' found" - self.assertErrorRegex(EasyBuildError, error_pattern, get_easyblock_class, None, name='gzip') + self.assertRaisesRegex(EasyBuildError, error_pattern, get_easyblock_class, None, name='gzip') self.assertEqual(get_easyblock_class(None, name='gzip', error_on_missing_easyblock=False), None) self.assertEqual(get_easyblock_class(None, name='toy'), EB_toy) - self.assertErrorRegex(EasyBuildError, "Failed to import EB_TOY", get_easyblock_class, None, name='TOY') + self.assertRaisesRegex(EasyBuildError, "Failed to import EB_TOY", get_easyblock_class, None, name='TOY') self.assertEqual(get_easyblock_class(None, name='TOY', error_on_failed_import=False), None) # Test passing neither easyblock nor name - self.assertErrorRegex(EasyBuildError, "neither name nor easyblock were specified", get_easyblock_class, None) + self.assertRaisesRegex(EasyBuildError, "neither name nor easyblock were specified", get_easyblock_class, None) self.assertEqual(get_easyblock_class(None, error_on_missing_easyblock=False), None) def test_letter_dir(self): @@ -1929,7 +1929,7 @@ def test_filter_deps(self): ec_txt = ec_txt.replace('hwloc', 'deptobefiltered') write_file(ec_file, ec_txt) - self.assertErrorRegex(EasyBuildError, "Failed to determine minimal toolchain for dep .*", + self.assertRaisesRegex(EasyBuildError, "Failed to determine minimal toolchain for dep .*", EasyConfig, ec_file, validate=False) build_options.update({'filter_deps': ['deptobefiltered']}) @@ -1949,13 +1949,13 @@ def test_replaced_easyconfig_parameters(self): } for key, (newkey, ver) in replaced_parameters.items(): error_regex = "NO LONGER SUPPORTED since v%s.*'%s' is replaced by '%s'" % (ver, key, newkey) - self.assertErrorRegex(EasyBuildError, error_regex, ec.get, key) - self.assertErrorRegex(EasyBuildError, error_regex, lambda k: ec[k], key) + self.assertRaisesRegex(EasyBuildError, error_regex, ec.get, key) + self.assertRaisesRegex(EasyBuildError, error_regex, lambda k: ec[k], key) def foo(key): ec[key] = 'foo' - self.assertErrorRegex(EasyBuildError, error_regex, foo, key) + self.assertRaisesRegex(EasyBuildError, error_regex, foo, key) def test_alternative_easyconfig_parameters(self): """Test handling of alternative easyconfig parameters.""" @@ -1972,7 +1972,7 @@ def test_alternative_easyconfig_parameters(self): # post_install_cmds is not accepted unless it's registered as an alternative easyconfig parameter easyconfig.easyconfig.ALTERNATIVE_EASYCONFIG_PARAMETERS = {} - self.assertErrorRegex(EasyBuildError, "post_install_cmds -> postinstallcmds", EasyConfig, test_ec) + self.assertRaisesRegex(EasyBuildError, "post_install_cmds -> postinstallcmds", EasyConfig, test_ec) easyconfig.easyconfig.ALTERNATIVE_EASYCONFIG_PARAMETERS = { 'env_mod_class': 'moduleclass', @@ -2024,13 +2024,13 @@ def test_deprecated_easyconfig_parameters(self): if LooseVersion(depr_ver) <= easybuild.tools.build_log.CURRENT_VERSION: # deprecation error error_regex = "DEPRECATED.*since v%s.*'%s' is deprecated.*use '%s' instead" % (depr_ver, key, newkey) - self.assertErrorRegex(EasyBuildError, error_regex, ec.get, key) - self.assertErrorRegex(EasyBuildError, error_regex, lambda k: ec[k], key) + self.assertRaisesRegex(EasyBuildError, error_regex, ec.get, key) + self.assertRaisesRegex(EasyBuildError, error_regex, lambda k: ec[k], key) def foo(key): ec[key] = 'foo' - self.assertErrorRegex(EasyBuildError, error_regex, foo, key) + self.assertRaisesRegex(EasyBuildError, error_regex, foo, key) else: # only deprecation warning, but key is replaced when getting/setting with self.mocked_stdout_stderr(): @@ -2084,13 +2084,13 @@ def test_unknown_easyconfig_parameter(self): ec = EasyConfig(self.eb_file) self.assertNotIn('therenosucheasyconfigparameterlikethis', ec) error_regex = "unknown easyconfig parameter" - self.assertErrorRegex(EasyBuildError, error_regex, lambda k: ec[k], 'therenosucheasyconfigparameterlikethis') + self.assertRaisesRegex(EasyBuildError, error_regex, lambda k: ec[k], 'therenosucheasyconfigparameterlikethis') def set_ec_key(key): """Dummy function to set easyconfig parameter in 'ec' EasyConfig instance""" ec[key] = 'foobar' - self.assertErrorRegex(EasyBuildError, error_regex, set_ec_key, 'therenosucheasyconfigparameterlikethis') + self.assertRaisesRegex(EasyBuildError, error_regex, set_ec_key, 'therenosucheasyconfigparameterlikethis') def test_external_dependencies(self): """Test specifying external (build) dependencies.""" @@ -3435,7 +3435,7 @@ def test_software_license(self): ec['software_license'] = 'LicenseThatDoesNotExist' err_pat = r"Invalid license LicenseThatDoesNotExist \(known licenses:" - self.assertErrorRegex(EasyBuildError, err_pat, ec.validate_license) + self.assertRaisesRegex(EasyBuildError, err_pat, ec.validate_license) def test_param_value_type_checking(self): """Test value tupe checking of easyconfig parameters.""" @@ -3443,7 +3443,7 @@ def test_param_value_type_checking(self): ec_file = os.path.join(topdir, 'easyconfigs', 'test_ecs', 'g', 'gzip', 'gzip-1.4-broken.eb') # version parameter has values of wrong type in this broken easyconfig error_msg_pattern = "Type checking of easyconfig parameter values failed: .*'version'.*" - self.assertErrorRegex(EasyBuildError, error_msg_pattern, EasyConfig, ec_file, auto_convert_value_types=False) + self.assertRaisesRegex(EasyBuildError, error_msg_pattern, EasyConfig, ec_file, auto_convert_value_types=False) # test default behaviour: auto-converting of mismatching value types ec = EasyConfig(ec_file) @@ -3862,17 +3862,17 @@ def test_categorize_files_by_type(self): # Error cases tmpdir = tempfile.mkdtemp() non_existing = os.path.join(tmpdir, 'does_not_exist.patch') - self.assertErrorRegex(EasyBuildError, + self.assertRaisesRegex(EasyBuildError, "File %s does not exist" % non_existing, categorize_files_by_type, [non_existing]) patch_dir = os.path.join(tmpdir, 'folder.patch') os.mkdir(patch_dir) - self.assertErrorRegex(EasyBuildError, + self.assertRaisesRegex(EasyBuildError, "File %s is expected to be a regular file" % patch_dir, categorize_files_by_type, [patch_dir]) invalid_patch = os.path.join(tmpdir, 'invalid.patch') copy_file(gzip_ec, invalid_patch) - self.assertErrorRegex(EasyBuildError, + self.assertRaisesRegex(EasyBuildError, "%s is not detected as a valid patch file" % invalid_patch, categorize_files_by_type, [invalid_patch]) @@ -3948,10 +3948,10 @@ def test_det_subtoolchain_version(self): # missing gompic and double golfc should both give exceptions cands = [{'name': 'golfc', 'version': '2018a'}, {'name': 'golfc', 'version': '2018.01'}] - self.assertErrorRegex(EasyBuildError, + self.assertRaisesRegex(EasyBuildError, "No version found for subtoolchain gompic in dependencies of fosscuda", det_subtoolchain_version, current_tc, 'gompic', optional_toolchains, cands) - self.assertErrorRegex(EasyBuildError, + self.assertRaisesRegex(EasyBuildError, "Multiple versions of golfc found in dependencies of toolchain fosscuda: 2018.01, 2018a", det_subtoolchain_version, current_tc, 'golfc', optional_toolchains, cands) @@ -4013,7 +4013,7 @@ def test_verify_easyconfig_filename(self): error_pattern = "filename '%s' does not match with expected filename 'toy-0.0-gompi-2018a.eb' " % toy_ec_name error_pattern += r"\(specs: name: 'toy'; version: '0.0'; versionsuffix: ''; " error_pattern += r"toolchain name, version: 'gompi', '2018a'\)" - self.assertErrorRegex(EasyBuildError, error_pattern, verify_easyconfig_filename, toy_ec, specs) + self.assertRaisesRegex(EasyBuildError, error_pattern, verify_easyconfig_filename, toy_ec, specs) specs['versionsuffix'] = '-test' # incorrect file name @@ -4023,7 +4023,7 @@ def test_verify_easyconfig_filename(self): error_pattern = "filename 'toy.eb' does not match with expected filename 'toy-0.0-gompi-2018a-test.eb' " error_pattern += r"\(specs: name: 'toy'; version: '0.0'; versionsuffix: '-test'; " error_pattern += r"toolchain name, version: 'gompi', '2018a'\)" - self.assertErrorRegex(EasyBuildError, error_pattern, verify_easyconfig_filename, toy_ec, specs) + self.assertRaisesRegex(EasyBuildError, error_pattern, verify_easyconfig_filename, toy_ec, specs) # incorrect file contents error_pattern = r"Contents of .*/%s does not match with filename" % os.path.basename(toy_ec) @@ -4031,7 +4031,7 @@ def test_verify_easyconfig_filename(self): toy_ec = os.path.join(self.test_prefix, 'toy-0.0-gompi-2018a-test.eb') write_file(toy_ec, toy_txt) error_pattern = "Contents of .*/%s does not match with filename" % os.path.basename(toy_ec) - self.assertErrorRegex(EasyBuildError, error_pattern, verify_easyconfig_filename, toy_ec, specs) + self.assertRaisesRegex(EasyBuildError, error_pattern, verify_easyconfig_filename, toy_ec, specs) def test_get_paths_for(self): """Test for get_paths_for""" @@ -4154,7 +4154,7 @@ def test_not_an_easyconfig(self): # from Python 3.10 onwards: invalid decimal literal # older Python versions: invalid syntax error_pattern = "Parsing easyconfig file failed: invalid" - self.assertErrorRegex(EasyBuildError, error_pattern, EasyConfig, not_an_ec) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyConfig, not_an_ec) def test_check_sha256_checksums(self): """Test for check_sha256_checksums function.""" @@ -4253,7 +4253,7 @@ def test_deprecated(self): write_file(test_ec, toy_ec_txt + "\ndeprecated = 'this is just a test'") error_pattern = r"easyconfig file '.*/test.eb' is marked as deprecated:\nthis is just a test\n \(see also" - self.assertErrorRegex(EasyBuildError, error_pattern, EasyConfig, test_ec) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyConfig, test_ec) with self.mocked_stdout_stderr(): # But this can be silenced init_config(build_options={'silence_deprecation_warnings': ['easyconfig']}) @@ -4267,7 +4267,7 @@ def test_deprecated_toolchain(self): deprecated_toolchain_ec = os.path.join(topdir, 'easyconfigs', 'test_ecs', 't', 'toy', 'toy-0.0-gompi-2018a.eb') init_config(build_options={'silence_deprecation_warnings': [], 'unit_testing_mode': False}) error_pattern = r"toolchain 'gompi/2018a' is marked as deprecated \(see also" - self.assertErrorRegex(EasyBuildError, error_pattern, EasyConfig, deprecated_toolchain_ec) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyConfig, deprecated_toolchain_ec) with self.mocked_stdout_stderr(): # But this can be silenced init_config(build_options={'silence_deprecation_warnings': ['toolchain'], 'unit_testing_mode': False}) @@ -4391,14 +4391,14 @@ def test_multi_deps(self): # trying to combine multi_deps with a list of lists in builddependencies is not allowed write_file(test_ec, test_ec_txt + "\nbuilddependencies = [[('CMake', '3.12.1')], [('CMake', '3.9.1')]]") error_pattern = "Can't combine multi_deps with builddependencies specified as list of lists" - self.assertErrorRegex(EasyBuildError, error_pattern, EasyConfig, test_ec) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyConfig, test_ec) # test with different number of dependency versions in multi_deps, should result in a clean error test_ec_txt = toy_ec_txt + "\nmulti_deps = {'one': ['1.0'], 'two': ['2.0', '2.1']}" write_file(test_ec, test_ec_txt) error_pattern = "Not all the dependencies listed in multi_deps have the same number of versions!" - self.assertErrorRegex(EasyBuildError, error_pattern, EasyConfig, test_ec) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyConfig, test_ec) def test_multi_deps_templated_builddeps(self): """Test effect of multi_deps on builddependencies w.r.t. resolving templates like %(pyver)s.""" @@ -4530,7 +4530,7 @@ def test_fix_deprecated_easyconfigs(self): init_config(build_options={'local_var_naming_check': 'error', 'silent': True}) write_file(test_ec, test_ectxt) - self.assertErrorRegex(EasyBuildError, unknown_params_error_pattern, EasyConfig, test_ec) + self.assertRaisesRegex(EasyBuildError, unknown_params_error_pattern, EasyConfig, test_ec) self.mock_stderr(True) self.mock_stdout(True) @@ -4627,7 +4627,7 @@ def test_triage_easyconfig_params(self): } ec.update(local_vars) error = "Found 4 easyconfig parameters that are considered local variables: _, _foo, local_foo, x" - self.assertErrorRegex(EasyBuildError, error, triage_easyconfig_params, variables, ec) + self.assertRaisesRegex(EasyBuildError, error, triage_easyconfig_params, variables, ec) for key in local_vars: del ec[key] @@ -4649,7 +4649,7 @@ def test_local_vars_detection(self): ]) write_file(test_ec, test_ectxt) expected_error = "Use of 1 unknown easyconfig parameters detected in test.eb: foobar" - self.assertErrorRegex(EasyBuildError, expected_error, EasyConfig, test_ec, local_var_naming_check='error') + self.assertRaisesRegex(EasyBuildError, expected_error, EasyConfig, test_ec, local_var_naming_check='error') # all unknown keys are detected at once, and reported alphabetically # single-letter local variables are not a problem @@ -4666,7 +4666,7 @@ def test_local_vars_detection(self): expected_error = "Use of 4 unknown easyconfig parameters detected in test.eb: " expected_error += "an_unknown_key, foobar, test_list, zzz_test" - self.assertErrorRegex(EasyBuildError, expected_error, EasyConfig, test_ec, local_var_naming_check='error') + self.assertRaisesRegex(EasyBuildError, expected_error, EasyConfig, test_ec, local_var_naming_check='error') def test_arch_specific_dependency(self): """Tests that the correct version is chosen for this architecture""" @@ -4722,11 +4722,11 @@ def __init__(self, values): self.options = values.get('options', {}) error_msg = 'exts_filter should be a list or tuple' - self.assertErrorRegex(EasyBuildError, error_msg, resolve_exts_filter_template, + self.assertRaisesRegex(EasyBuildError, error_msg, resolve_exts_filter_template, '[ 1 == 1 ]', {}) - self.assertErrorRegex(EasyBuildError, error_msg, resolve_exts_filter_template, + self.assertRaisesRegex(EasyBuildError, error_msg, resolve_exts_filter_template, ['[ 1 == 1 ]'], {}) - self.assertErrorRegex(EasyBuildError, error_msg, resolve_exts_filter_template, + self.assertRaisesRegex(EasyBuildError, error_msg, resolve_exts_filter_template, ['[ 1 == 1 ]', 'true', 'false'], {}) test_cases = [ @@ -5084,7 +5084,7 @@ def test_easyconfig_import(self): write_file(test_ec, test_ec_txt) error_pattern = r"Failed to copy '.*' easyconfig parameter" - self.assertErrorRegex(EasyBuildError, error_pattern, EasyConfig, test_ec) + self.assertRaisesRegex(EasyBuildError, error_pattern, EasyConfig, test_ec) def test_get_cuda_cc_template_value(self): """ @@ -5102,7 +5102,7 @@ def test_get_cuda_cc_template_value(self): ec = EasyConfig(self.eb_file) error_pattern = "foobar is not a template value based on --cuda-compute-capabilities/cuda_compute_capabilities" - self.assertErrorRegex(EasyBuildError, error_pattern, ec.get_cuda_cc_template_value, 'foobar') + self.assertRaisesRegex(EasyBuildError, error_pattern, ec.get_cuda_cc_template_value, 'foobar') error_pattern = r"Template value '%s' is not defined!\n" error_pattern += r"Make sure that either the --cuda-compute-capabilities EasyBuild configuration " @@ -5118,7 +5118,7 @@ def test_get_cuda_cc_template_value(self): 'cuda_sm_space_sep': 'sm_65 sm_70', } for key in cuda_template_values: - self.assertErrorRegex(EasyBuildError, error_pattern % key, ec.get_cuda_cc_template_value, key) + self.assertRaisesRegex(EasyBuildError, error_pattern % key, ec.get_cuda_cc_template_value, key) self.assertEqual(ec.get_cuda_cc_template_value(key, required=False), '') update_build_option('cuda_compute_capabilities', ['6.5', '7.0']) @@ -5131,7 +5131,7 @@ def test_get_cuda_cc_template_value(self): ec = EasyConfig(self.eb_file) for key in cuda_template_values: - self.assertErrorRegex(EasyBuildError, error_pattern % key, ec.get_cuda_cc_template_value, key) + self.assertRaisesRegex(EasyBuildError, error_pattern % key, ec.get_cuda_cc_template_value, key) self.contents += "\ncuda_compute_capabilities = ['6.5', '7.0']" self.prep() @@ -5157,7 +5157,7 @@ def test_get_amdgcn_cc_template_value(self): error_pattern = ("foobar is not a template value based on " "--amdgcn-capabilities/amdgcn_capabilities") - self.assertErrorRegex(EasyBuildError, error_pattern, ec.get_amdgcn_cc_template_value, 'foobar') + self.assertRaisesRegex(EasyBuildError, error_pattern, ec.get_amdgcn_cc_template_value, 'foobar') error_pattern = r"Template value '%s' is not defined!\n" error_pattern += r"Make sure that either the --amdgcn-capabilities EasyBuild configuration " @@ -5168,7 +5168,7 @@ def test_get_amdgcn_cc_template_value(self): 'amdgcn_cc_semicolon_sep': 'gfx90a;gfx1100;gfx10-3-generic', } for key in amdgcn_template_values: - self.assertErrorRegex(EasyBuildError, error_pattern % key, ec.get_amdgcn_cc_template_value, key) + self.assertRaisesRegex(EasyBuildError, error_pattern % key, ec.get_amdgcn_cc_template_value, key) update_build_option('amdgcn_capabilities', ['gfx90a', 'gfx1100', 'gfx10-3-generic']) ec = EasyConfig(self.eb_file) @@ -5180,7 +5180,7 @@ def test_get_amdgcn_cc_template_value(self): ec = EasyConfig(self.eb_file) for key in amdgcn_template_values: - self.assertErrorRegex(EasyBuildError, error_pattern % key, ec.get_amdgcn_cc_template_value, key) + self.assertRaisesRegex(EasyBuildError, error_pattern % key, ec.get_amdgcn_cc_template_value, key) self.assertEqual(ec.get_amdgcn_cc_template_value(key, required=False), '') self.contents += "\namdgcn_capabilities = ['gfx90a', 'gfx1100', 'gfx10-3-generic']" @@ -5323,7 +5323,7 @@ def test_templates(self): self.assertEqual(ec.get_ref('description'), "name: %(name)s, version: %(version)s, pyshortver: %(pyshortver)s") error_pattern = r"Failed to resolve all templates in.* %\(pyshortver\)s.* using template dictionary:" - self.assertErrorRegex(EasyBuildError, error_pattern, ec.__getitem__, 'description') + self.assertRaisesRegex(EasyBuildError, error_pattern, ec.__getitem__, 'description') # EasyBuild can be configured to allow unresolved templates update_build_option('allow_unresolved_templates', True) diff --git a/test/framework/easyconfigparser.py b/test/framework/easyconfigparser.py index d04361b78f..6a82e5ba95 100644 --- a/test/framework/easyconfigparser.py +++ b/test/framework/easyconfigparser.py @@ -185,7 +185,7 @@ def test_raw(self): self.assertEqual(ec['name'], 'gzip') self.assertEqual(ec['toolchain']['name'], 'foss') - self.assertErrorRegex(EasyBuildError, "Neither filename nor rawcontent provided", EasyConfigParser) + self.assertRaisesRegex(EasyBuildError, "Neither filename nor rawcontent provided", EasyConfigParser) def test_easyconfig_constants(self): """Test available easyconfig constants.""" @@ -214,7 +214,7 @@ def test_check_value_types(self): test_ec = os.path.join(TESTDIRBASE, 'test_ecs', 'g', 'gzip', 'gzip-1.4-broken.eb') error_msg_pattern = "Type checking of easyconfig parameter values failed: .*'version'.*" ecp = EasyConfigParser(test_ec, auto_convert_value_types=False) - self.assertErrorRegex(EasyBuildError, error_msg_pattern, ecp.get_config_dict) + self.assertRaisesRegex(EasyBuildError, error_msg_pattern, ecp.get_config_dict) # test default behaviour: auto-converting of mismatched value types ecp = EasyConfigParser(test_ec) diff --git a/test/framework/easyconfigversion.py b/test/framework/easyconfigversion.py index 59cf051a42..43dce5feba 100644 --- a/test/framework/easyconfigversion.py +++ b/test/framework/easyconfigversion.py @@ -68,7 +68,7 @@ def test_boolean(self): self.assertTrue(VersionOperator('123')) error_msg = "Failed to parse '<=' as a version operator string" - self.assertErrorRegex(EasyBuildError, error_msg, VersionOperator, '<=') + self.assertRaisesRegex(EasyBuildError, error_msg, VersionOperator, '<=') def test_vop_test(self): """Test version checker""" diff --git a/test/framework/easystack.py b/test/framework/easystack.py index 46a9653296..a78e1c9f07 100644 --- a/test/framework/easystack.py +++ b/test/framework/easystack.py @@ -87,7 +87,7 @@ def test_easystack_easyconfigs_dict(self): test_easystack = os.path.join(topdir, 'easystacks', 'test_easystack_easyconfigs_dict.yaml') error_pattern = r"Found dict value for 'easyconfigs' in .* should be list.\nMake sure you use '-' to create .*" - self.assertErrorRegex(EasyBuildError, error_pattern, parse_easystack, test_easystack) + self.assertRaisesRegex(EasyBuildError, error_pattern, parse_easystack, test_easystack) def test_easystack_easyconfigs_str(self): """Test for easystack file where easyconfigs item is parsed as a dict, because easyconfig names are not @@ -96,7 +96,7 @@ def test_easystack_easyconfigs_str(self): test_easystack = os.path.join(topdir, 'easystacks', 'test_easystack_easyconfigs_str.yaml') error_pattern = r"Found str value for 'easyconfigs' in .* should be list.\nMake sure you use '-' to create .*" - self.assertErrorRegex(EasyBuildError, error_pattern, parse_easystack, test_easystack) + self.assertRaisesRegex(EasyBuildError, error_pattern, parse_easystack, test_easystack) def test_easystack_easyconfig_opts(self): """Test an easystack file using the 'easyconfigs' key, with additonal options for some easyconfigs""" @@ -118,7 +118,7 @@ def test_easystack_invalid_key(self): test_easystack = os.path.join(topdir, 'easystacks', 'test_easystack_invalid_key.yaml') error_pattern = r"Found one or more invalid keys for .* \(only 'options' supported\).*" - self.assertErrorRegex(EasyBuildError, error_pattern, parse_easystack, test_easystack) + self.assertRaisesRegex(EasyBuildError, error_pattern, parse_easystack, test_easystack) def test_easystack_invalid_key2(self): """Test easystack files with invalid key at the same level as the key that names the easyconfig""" @@ -127,7 +127,7 @@ def test_easystack_invalid_key2(self): error_pattern = r"expected a dictionary with one key \(the EasyConfig name\), " error_pattern += r"instead found keys: .*, invalid_key" - self.assertErrorRegex(EasyBuildError, error_pattern, parse_easystack, test_easystack) + self.assertRaisesRegex(EasyBuildError, error_pattern, parse_easystack, test_easystack) def test_easystack_restore_env_after_each_build(self): """Test that the build environment and tmpdir is reset for each easystack item""" @@ -182,14 +182,14 @@ def test_missing_easyconfigs_key(self): test_easystack = os.path.join(topdir, 'easystacks', 'test_missing_easyconfigs_key.yaml') error_pattern = r"Top-level key 'easyconfigs' missing in easystack file %s" % test_easystack - self.assertErrorRegex(EasyBuildError, error_pattern, parse_easystack, test_easystack) + self.assertRaisesRegex(EasyBuildError, error_pattern, parse_easystack, test_easystack) def test_parse_fail(self): """Test for clean error when easystack file fails to parse.""" test_yml = os.path.join(self.test_prefix, 'test.yml') write_file(test_yml, 'easyconfigs: %s') error_pattern = "Failed to parse .*/test.yml: while scanning for the next token" - self.assertErrorRegex(EasyBuildError, error_pattern, parse_easystack, test_yml) + self.assertRaisesRegex(EasyBuildError, error_pattern, parse_easystack, test_yml) def test_check_value(self): """Test check_value function.""" @@ -201,7 +201,7 @@ def test_check_value(self): context = "" for version in (1.2, 100, None): error_pattern = r"Value .* \(of type .*\) obtained for is not valid!" - self.assertErrorRegex(EasyBuildError, error_pattern, check_value, version, context) + self.assertRaisesRegex(EasyBuildError, error_pattern, check_value, version, context) def suite(loader=None): diff --git a/test/framework/ebconfigobj.py b/test/framework/ebconfigobj.py index 113c9e557d..1d4089fea0 100644 --- a/test/framework/ebconfigobj.py +++ b/test/framework/ebconfigobj.py @@ -85,7 +85,7 @@ def test_ebconfigobj_unusable_default(self): for val, res in data: configobj_txt = ['[SUPPORTED]', val] co = ConfigObj(configobj_txt) - self.assertErrorRegex(EasyBuildError, + self.assertRaisesRegex(EasyBuildError, r'First\s+(toolchain|version)\s.*?\scan\'t\s+be\s+used\s+as\s+default', EBConfigObj, co) @@ -160,7 +160,7 @@ def test_squash_invalid(self): for txt in [txt_wrong_versions, txt_conflict_nested_versions]: co = ConfigObj(txt) cov = EBConfigObj(co) - self.assertErrorRegex(EasyBuildError, r'conflict', cov.squash, + self.assertRaisesRegex(EasyBuildError, r'conflict', cov.squash, default_version, tc_first['name'], tc_first['version']) def test_toolchain_squash_nested(self): diff --git a/test/framework/filetools.py b/test/framework/filetools.py index 7e296803cc..7fc6bb7bae 100644 --- a/test/framework/filetools.py +++ b/test/framework/filetools.py @@ -122,7 +122,7 @@ def test_extract_cmd(self): self.assertEqual("unzip -qq -o test.zip", ft.extract_cmd('test.zip', True)) error_pattern = "test.foo has unknown file extension" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.extract_cmd, 'test.foo') + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.extract_cmd, 'test.foo') def test_find_extension(self): """Test find_extension function.""" @@ -189,9 +189,9 @@ def test_find_glob_pattern(self): self.assertEqual(ft.find_glob_pattern(os.path.join(tmpdir, 'python3.5*', 'include')), os.path.join(tmpdir, 'python3.5m', 'include')) self.assertEqual(ft.find_glob_pattern(os.path.join(tmpdir, 'python3.6*'), False), None) - self.assertErrorRegex(EasyBuildError, "Was expecting exactly", ft.find_glob_pattern, + self.assertRaisesRegex(EasyBuildError, "Was expecting exactly", ft.find_glob_pattern, os.path.join(tmpdir, 'python3.6*')) - self.assertErrorRegex(EasyBuildError, "Was expecting exactly", ft.find_glob_pattern, + self.assertRaisesRegex(EasyBuildError, "Was expecting exactly", ft.find_glob_pattern, os.path.join(tmpdir, 'python*')) def test_encode_class_name(self): @@ -240,7 +240,7 @@ def test_which(self): path = ft.which(invalid_cmd, on_error=IGNORE) self.assertIsNone(path) error_msg = "Could not find command '%s'" % invalid_cmd - self.assertErrorRegex(EasyBuildError, error_msg, ft.which, invalid_cmd, on_error=ERROR) + self.assertRaisesRegex(EasyBuildError, error_msg, ft.which, invalid_cmd, on_error=ERROR) os.environ['PATH'] = '%s:%s' % (self.test_prefix, os.environ['PATH']) # put a directory 'foo' in place (should be ignored by 'which') @@ -332,7 +332,7 @@ def test_checksums(self): # checksum of length other than 32/64 yields an error error_pattern = r"Length of checksum '.*' \(\d+\) does not match with either MD5 \(32\) or SHA256 \(64\)" for checksum in ['tooshort', 'inbetween32and64charactersisnotgoodeither', known_checksums['sha256'] + 'foo']: - self.assertErrorRegex(EasyBuildError, error_pattern, ft.verify_checksum, fp, checksum) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.verify_checksum, fp, checksum) # make sure faulty checksums are reported broken_checksums = {typ: (val[:-3] + 'foo') for typ, val in known_checksums.items()} @@ -359,7 +359,7 @@ def test_checksums(self): # None is accepted self.assertTrue(ft.verify_checksum(fp, {os.path.basename(fp): None})) faulty_dict = {'wrong-name': known_checksums['sha256']} - self.assertErrorRegex(EasyBuildError, + self.assertRaisesRegex(EasyBuildError, "Missing checksum for " + os.path.basename(fp) + " in .*wrong-name.*", ft.verify_checksum, fp, faulty_dict) @@ -369,17 +369,17 @@ def test_checksums(self): } init_config(build_options=build_options) - self.assertErrorRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, fp, None) + self.assertRaisesRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, fp, None) self.assertTrue(ft.verify_checksum(fp, known_checksums['sha256'])) # Test dictionary-type checksums - self.assertErrorRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, + self.assertRaisesRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, fp, {os.path.basename(fp): None}) for checksum in [known_checksums[x] for x in ['sha256']]: dict_checksum = {os.path.basename(fp): checksum, 'foo': 'baa'} self.assertTrue(ft.verify_checksum(fp, dict_checksum)) del dict_checksum[os.path.basename(fp)] - self.assertErrorRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, fp, dict_checksum) + self.assertRaisesRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, fp, dict_checksum) def test_deprecated_checksums(self): """Test checksum functionality.""" @@ -412,7 +412,7 @@ def test_deprecated_checksums(self): # checksum of length other than 32/64 yields an error error_pattern = r"Length of checksum '.*' \(\d+\) does not match with either MD5 \(32\) or SHA256 \(64\)" for checksum in ['tooshort', 'inbetween32and64charactersisnotgoodeither', known_checksums['md5'] + 'foo']: - self.assertErrorRegex(EasyBuildError, error_pattern, ft.verify_checksum, fp, checksum) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.verify_checksum, fp, checksum) # make sure faulty checksums are reported broken_checksums = {typ: (val[:-3] + 'foo') for typ, val in known_checksums.items()} @@ -438,7 +438,7 @@ def test_deprecated_checksums(self): } init_config(build_options=build_options) - self.assertErrorRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, fp, None) + self.assertRaisesRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, fp, None) self.assertTrue(ft.verify_checksum(fp, known_checksums['md5'])) # Test dictionary-type checksums @@ -446,7 +446,7 @@ def test_deprecated_checksums(self): dict_checksum = {os.path.basename(fp): checksum, 'foo': 'baa'} self.assertTrue(ft.verify_checksum(fp, dict_checksum)) del dict_checksum[os.path.basename(fp)] - self.assertErrorRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, fp, dict_checksum) + self.assertRaisesRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, fp, dict_checksum) self.mock_stderr(False) @@ -672,7 +672,7 @@ def fake_urllib_open(*args, **kwargs): # without requests being available, error is raised ft.HAVE_REQUESTS = False - self.assertErrorRegex(EasyBuildError, "SSL issues with urllib2", ft.download_file, fn, url, target) + self.assertRaisesRegex(EasyBuildError, "SSL issues with urllib2", ft.download_file, fn, url, target) # replaceurlopen with function that raises HTTP error 403 def fake_urllib_open(*args, **kwargs): @@ -689,7 +689,7 @@ def fake_urllib_open(*args, **kwargs): # without requests being available, error is raised ft.HAVE_REQUESTS = False - self.assertErrorRegex(EasyBuildError, "SSL issues with urllib2", ft.download_file, fn, url, target) + self.assertRaisesRegex(EasyBuildError, "SSL issues with urllib2", ft.download_file, fn, url, target) def test_download_file_insecure(self): """ @@ -783,7 +783,7 @@ def check_mkdir(path, error=None, **kwargs): ft.mkdir(path, **kwargs) self.assertTrue(os.path.exists(path) and os.path.isdir(path), "Directory %s exists" % path) else: - self.assertErrorRegex(EasyBuildError, error, ft.mkdir, path, **kwargs) + self.assertRaisesRegex(EasyBuildError, error, ft.mkdir, path, **kwargs) foodir = os.path.join(self.test_prefix, 'foo') barfoodir = os.path.join(self.test_prefix, 'bar', 'foo') @@ -880,7 +880,7 @@ def test_symlink_resolve_path(self): # test symlink when it already exists but points to a different path test_file2 = os.path.join(link_dir, 'test2.txt') ft.write_file(test_file, "test123") - self.assertErrorRegex(EasyBuildError, + self.assertRaisesRegex(EasyBuildError, "Trying to symlink %s to %s, but the symlink already exists and points to %s." % (test_file2, link, test_file), ft.symlink, test_file2, link) @@ -889,7 +889,7 @@ def test_symlink_resolve_path(self): self.assertEqual(test_dir, ft.resolve_path(link_dir)) self.assertEqual(os.path.join(os.path.realpath(self.test_prefix), 'test', 'test.txt'), ft.resolve_path(link)) self.assertEqual(ft.read_file(link), "test123") - self.assertErrorRegex(EasyBuildError, "Resolving path .* failed", ft.resolve_path, None) + self.assertRaisesRegex(EasyBuildError, "Resolving path .* failed", ft.resolve_path, None) def test_remove_symlinks(self): """Test remove valid and invalid symlinks""" @@ -982,8 +982,8 @@ def test_read_write_file(self): # blind overwriting can be disabled via 'overwrite' error = "File exists, not overwriting it without --force: %s" % fp - self.assertErrorRegex(EasyBuildError, error, ft.write_file, fp, 'blah', always_overwrite=False) - self.assertErrorRegex(EasyBuildError, error, ft.write_file, fp, 'blah', always_overwrite=False, backup=True) + self.assertRaisesRegex(EasyBuildError, error, ft.write_file, fp, 'blah', always_overwrite=False) + self.assertRaisesRegex(EasyBuildError, error, ft.write_file, fp, 'blah', always_overwrite=False, backup=True) # use of --force ensuring that file gets written regardless of whether or not it exists already build_options = {'force': True} @@ -1361,7 +1361,7 @@ def test_expand_glob_paths(self): # check behaviour if glob that has no (file) matches is passed glob_pat = os.path.join(self.test_prefix, 'test_*') - self.assertErrorRegex(EasyBuildError, "No files found using glob pattern", ft.expand_glob_paths, [glob_pat]) + self.assertRaisesRegex(EasyBuildError, "No files found using glob pattern", ft.expand_glob_paths, [glob_pat]) def test_adjust_permissions(self): """Test adjust_permissions""" @@ -1434,9 +1434,9 @@ def test_adjust_permissions(self): # check error reporting when changing permissions fails nosuchdir = os.path.join(self.test_prefix, 'nosuchdir') err_msg = "Failed to chmod/chown several paths.*No such file or directory" - self.assertErrorRegex(EasyBuildError, err_msg, ft.adjust_permissions, nosuchdir, stat.S_IWOTH) + self.assertRaisesRegex(EasyBuildError, err_msg, ft.adjust_permissions, nosuchdir, stat.S_IWOTH) nosuchfile = os.path.join(self.test_prefix, 'nosuchfile') - self.assertErrorRegex(EasyBuildError, err_msg, ft.adjust_permissions, nosuchfile, stat.S_IWUSR, recursive=False) + self.assertRaisesRegex(EasyBuildError, err_msg, ft.adjust_permissions, nosuchfile, stat.S_IWUSR, recursive=False) # try using adjust_permissions on a file not owned by current user, # using permissions that are actually already correct; @@ -1574,11 +1574,11 @@ def test_apply_regex_substitutions(self): regex_subs_no_match = [('Not there', 'Not used')] error_pat = "Nothing found to replace 'Not there' in %s" % testfile # Error - self.assertErrorRegex(EasyBuildError, error_pat, ft.apply_regex_substitutions, testfile, regex_subs_no_match, + self.assertRaisesRegex(EasyBuildError, error_pat, ft.apply_regex_substitutions, testfile, regex_subs_no_match, on_missing_match=ERROR) # First matches, but 2nd not regex_subs_part_match = [regex_subs[0], ('Not there', 'Not used')] - self.assertErrorRegex(EasyBuildError, error_pat, ft.apply_regex_substitutions, testfile, regex_subs_part_match, + self.assertRaisesRegex(EasyBuildError, error_pat, ft.apply_regex_substitutions, testfile, regex_subs_part_match, on_missing_match=ERROR, match_all=True) # First matched so OK with match_all ft.apply_regex_substitutions(testfile, regex_subs_part_match, @@ -1603,7 +1603,7 @@ def test_apply_regex_substitutions(self): # clean error on non-existing file error_pat = "Failed to patch .*/nosuchfile.txt: .*No such file or directory" path = os.path.join(self.test_prefix, 'nosuchfile.txt') - self.assertErrorRegex(EasyBuildError, error_pat, ft.apply_regex_substitutions, path, regex_subs) + self.assertRaisesRegex(EasyBuildError, error_pat, ft.apply_regex_substitutions, path, regex_subs) # Replace multi-line strings testtxt = "This si wrong\nBut mkae right\nLeave this!" @@ -1837,21 +1837,21 @@ def test_create_patch_info(self): expected_error = r"Wrong patch spec \(foo.txt\), extension type should be any of .patch, .patch.bz2, " expected_error += ".patch.gz, .patch.xz." - self.assertErrorRegex(EasyBuildError, expected_error, ft.create_patch_info, 'foo.txt') + self.assertRaisesRegex(EasyBuildError, expected_error, ft.create_patch_info, 'foo.txt') # faulty input error_msg = "Wrong patch spec" - self.assertErrorRegex(EasyBuildError, error_msg, ft.create_patch_info, None) - self.assertErrorRegex(EasyBuildError, error_msg, ft.create_patch_info, {'copy': 'subdir'}) - self.assertErrorRegex(EasyBuildError, error_msg, ft.create_patch_info, {'name': 'foo.txt'}) - self.assertErrorRegex(EasyBuildError, error_msg, ft.create_patch_info, {'name': 'foo.txt', 'random': 'key'}) - self.assertErrorRegex(EasyBuildError, error_msg, ft.create_patch_info, + self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, None) + self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, {'copy': 'subdir'}) + self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, {'name': 'foo.txt'}) + self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, {'name': 'foo.txt', 'random': 'key'}) + self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, {'name': 'foo.txt', 'copy': 'subdir', 'sourcepath': 'subdir'}) - self.assertErrorRegex(EasyBuildError, error_msg, ft.create_patch_info, + self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, {'name': 'foo.txt', 'copy': 'subdir', 'level': 1}) - self.assertErrorRegex(EasyBuildError, error_msg, ft.create_patch_info, ('foo.patch', [1, 2])) + self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, ('foo.patch', [1, 2])) error_msg = "Unknown patch specification" - self.assertErrorRegex(EasyBuildError, error_msg, ft.create_patch_info, ('foo.patch', 1, 'subdir')) + self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, ('foo.patch', 1, 'subdir')) def test_apply_patch(self): """ Test apply_patch """ @@ -1887,7 +1887,7 @@ def test_apply_patch(self): self.assertIn(pattern, patched_gz) # trying the patch again should fail - self.assertErrorRegex(EasyBuildError, "Couldn't apply patch file", ft.apply_patch, toy_patch, path) + self.assertRaisesRegex(EasyBuildError, "Couldn't apply patch file", ft.apply_patch, toy_patch, path) # Passing an option works with self.mocked_stdout_stderr(): @@ -1985,7 +1985,7 @@ def test_copy_file(self): src, target = os.path.dirname(toy_ec), os.path.join(self.test_prefix, 'toy') # error message was changed in Python 3.9.7 to "FileNotFoundError: Directory does not exist" error_pattern = "Failed to copy file.*(Is a directory|Directory does not exist)" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.copy_file, src, target) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.copy_file, src, target) # test overwriting of existing file owned by someone else, # which should make copy_file use shutil.copyfile rather than shutil.copy2 @@ -2052,7 +2052,7 @@ def test_copy_file(self): # Test that a non-existing file raises an exception update_build_option('extended_dry_run', False) src, target = os.path.join(self.test_prefix, 'this_file_does_not_exist'), os.path.join(self.test_prefix, 'toy') - self.assertErrorRegex(EasyBuildError, "Could not copy *", ft.copy_file, src, target) + self.assertRaisesRegex(EasyBuildError, "Could not copy *", ft.copy_file, src, target) # Test that copying a non-existing file in 'dry_run' mode does noting update_build_option('extended_dry_run', True) self.mock_stdout(True) @@ -2061,7 +2061,7 @@ def test_copy_file(self): self.mock_stdout(False) self.assertTrue(re.search("^copied file %s to %s" % (src, target), txt)) # However, if we add 'force_in_dry_run=True' it should throw an exception - self.assertErrorRegex(EasyBuildError, "Could not copy *", ft.copy_file, src, target, force_in_dry_run=True) + self.assertRaisesRegex(EasyBuildError, "Could not copy *", ft.copy_file, src, target, force_in_dry_run=True) def test_copy_file_xattr(self): """Test copying a file with extended attributes using copy_file.""" @@ -2140,12 +2140,12 @@ def test_copy_files(self): # copying files to an existing target that is not a directory results in an error self.assertTrue(os.path.isfile(copied_toy_ec)) error_pattern = "/toy-0.0.eb exists but is not a directory" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.copy_files, [bzip2_ec], copied_toy_ec) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.copy_files, [bzip2_ec], copied_toy_ec) # by default copy_files allows empty input list, but if allow_empty=False then an error is raised ft.copy_files([], self.test_prefix) error_pattern = 'One or more files to copy should be specified!' - self.assertErrorRegex(EasyBuildError, error_pattern, ft.copy_files, [], self.test_prefix, allow_empty=False) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.copy_files, [], self.test_prefix, allow_empty=False) # test special case: copying a single file to a file target via target_single_file=True target = os.path.join(self.test_prefix, 'target') @@ -2295,12 +2295,12 @@ def test_copy_dir(self): # clean error when trying to copy a file with copy_dir src, target = os.path.join(to_copy, 'GCC-4.6.3.eb'), os.path.join(self.test_prefix, 'GCC-4.6.3.eb') - self.assertErrorRegex(EasyBuildError, "Failed to copy directory.*Not a directory", ft.copy_dir, src, target) + self.assertRaisesRegex(EasyBuildError, "Failed to copy directory.*Not a directory", ft.copy_dir, src, target) # if directory already exists, we expect a clean error testdir = os.path.join(self.test_prefix, 'thisdirexists') ft.mkdir(testdir) - self.assertErrorRegex(EasyBuildError, "Target location .* already exists", ft.copy_dir, to_copy, testdir) + self.assertRaisesRegex(EasyBuildError, "Target location .* already exists", ft.copy_dir, to_copy, testdir) # if the directory already exists and 'dirs_exist_ok' is True, copy_dir should succeed ft.copy_dir(to_copy, testdir, dirs_exist_ok=True) @@ -2335,7 +2335,7 @@ def ignore_func(_, names): target_dir = os.path.join(self.test_prefix, 'target_to_copy_to') # trying this without symlinks=True ends in tears, because bar.txt points to a non-existing file - self.assertErrorRegex(EasyBuildError, "Failed to copy directory", ft.copy_dir, srcdir, target_dir) + self.assertRaisesRegex(EasyBuildError, "Failed to copy directory", ft.copy_dir, srcdir, target_dir) ft.remove_dir(target_dir) ft.copy_dir(srcdir, target_dir, symlinks=True) @@ -2349,7 +2349,7 @@ def ignore_func(_, names): # Detect recursive symlinks by default instead of infinite loop during copy ft.remove_dir(target_dir) os.symlink('.', os.path.join(subdir, 'recursive_link')) - self.assertErrorRegex(EasyBuildError, 'Recursive symlinks detected', ft.copy_dir, srcdir, target_dir) + self.assertRaisesRegex(EasyBuildError, 'Recursive symlinks detected', ft.copy_dir, srcdir, target_dir) self.assertNotExists(target_dir) # Ok for symlinks=True ft.copy_dir(srcdir, target_dir, symlinks=True) @@ -2442,7 +2442,7 @@ def test_get_cwd(self): self.assertTrue(os.path.samefile(ft.get_cwd(), toy_dir)) os.rmdir(toy_dir) - self.assertErrorRegex(EasyBuildError, ft.CWD_NOTFOUND_ERROR, ft.get_cwd) + self.assertRaisesRegex(EasyBuildError, ft.CWD_NOTFOUND_ERROR, ft.get_cwd) self.assertEqual(ft.get_cwd(must_exist=False), None) @@ -2469,7 +2469,7 @@ def test_change_dir(self): self.assertEqual(prev_dir, None) foo = os.path.join(self.test_prefix, 'foo') - self.assertErrorRegex(EasyBuildError, "Failed to change from .* to %s" % foo, ft.change_dir, foo) + self.assertRaisesRegex(EasyBuildError, "Failed to change from .* to %s" % foo, ft.change_dir, foo) def test_extract_file(self): """Test extract_file""" @@ -2625,10 +2625,10 @@ def test_remove(self): ft.write_file(testfile, 'bar') ft.mkdir(test_dir) ft.adjust_permissions(self.test_prefix, stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH, add=False) - self.assertErrorRegex(EasyBuildError, "Failed to remove", ft.remove_file, testfile) - self.assertErrorRegex(EasyBuildError, "Failed to remove", ft.remove, testfile) - self.assertErrorRegex(EasyBuildError, "Failed to remove", ft.remove_dir, test_dir) - self.assertErrorRegex(EasyBuildError, "Failed to remove", ft.remove, test_dir) + self.assertRaisesRegex(EasyBuildError, "Failed to remove", ft.remove_file, testfile) + self.assertRaisesRegex(EasyBuildError, "Failed to remove", ft.remove, testfile) + self.assertRaisesRegex(EasyBuildError, "Failed to remove", ft.remove_dir, test_dir) + self.assertRaisesRegex(EasyBuildError, "Failed to remove", ft.remove, test_dir) # also test behaviour under --dry-run build_options = { @@ -2683,10 +2683,10 @@ def test_index_functions(self): # create_index checks whether specified path is an existing directory doesnotexist = os.path.join(self.test_prefix, 'doesnotexist') - self.assertErrorRegex(EasyBuildError, "Specified path does not exist", ft.create_index, doesnotexist) + self.assertRaisesRegex(EasyBuildError, "Specified path does not exist", ft.create_index, doesnotexist) toy_ec = os.path.join(test_ecs, 't', 'toy', 'toy-0.0.eb') - self.assertErrorRegex(EasyBuildError, "Specified path is not a directory", ft.create_index, toy_ec) + self.assertRaisesRegex(EasyBuildError, "Specified path is not a directory", ft.create_index, toy_ec) # load_index just returns None if there is no index in specified directory self.assertEqual(ft.load_index(self.test_prefix), None) @@ -2751,7 +2751,7 @@ def test_index_functions(self): # dump_index will not overwrite existing index without force error_pattern = "File exists, not overwriting it without --force" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.dump_index, ecs_dir) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.dump_index, ecs_dir) ft.remove_file(index_fp) @@ -2890,7 +2890,7 @@ def test_search_file(self): # check how simply invalid queries are handled for pattern in ['*foo', '(foo', ')foo', 'foo)', 'foo(']: - self.assertErrorRegex(EasyBuildError, "Invalid search query", ft.search_file, [test_ecs], pattern) + self.assertRaisesRegex(EasyBuildError, "Invalid search query", ft.search_file, [test_ecs], pattern) def test_dir_contains_files(self): def makedirs_in_test(*paths): @@ -2929,7 +2929,7 @@ def test_find_eb_script(self): self.assertExists(ft.find_eb_script('rpath_args.py')) self.assertExists(ft.find_eb_script('rpath_wrapper_template.sh.in')) - self.assertErrorRegex(EasyBuildError, "Script 'no_such_script' not found", ft.find_eb_script, 'no_such_script') + self.assertRaisesRegex(EasyBuildError, "Script 'no_such_script' not found", ft.find_eb_script, 'no_such_script') # put test script in place relative to location of 'eb' fake_eb = os.path.join(self.test_prefix, 'bin', 'eb') @@ -2950,7 +2950,7 @@ def test_find_eb_script(self): # if script can't be found via either $EB_SCRIPT_PATH or location of 'eb', we get a clean error del os.environ['EB_SCRIPT_PATH'] error_pattern = "Script 'thisisjustatestscript.sh' not found at expected location" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.find_eb_script, 'thisisjustatestscript.sh') + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.find_eb_script, 'thisisjustatestscript.sh') def test_move_file(self): """Test move_file function""" @@ -3346,17 +3346,17 @@ def run_check(): error_pattern = "Neither tag nor commit found in git_config parameter" else: error_pattern = "%s not specified in git_config parameter" % key - self.assertErrorRegex(EasyBuildError, error_pattern, ft.get_source_tarball_from_git, *args) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.get_source_tarball_from_git, *args) git_config[key] = orig_value git_config['commit'] = '8456f86' error_pattern = "Tag and commit are mutually exclusive in git_config parameter" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.get_source_tarball_from_git, *args) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.get_source_tarball_from_git, *args) del git_config['commit'] git_config['unknown'] = 'foobar' error_pattern = "Found one or more unexpected keys in 'git_config' specification" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.get_source_tarball_from_git, *args) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.get_source_tarball_from_git, *args) del git_config['unknown'] def test_make_archive(self): @@ -3435,7 +3435,7 @@ def test_make_archive(self): self.assertExists(custom_tgz) os.remove(custom_tgz) - self.assertErrorRegex(EasyBuildError, "Unsupported archive format.*", ft.make_archive, tardir, "unknown.ext") + self.assertRaisesRegex(EasyBuildError, "Unsupported archive format.*", ft.make_archive, tardir, "unknown.ext") reference_checksum_txz = "ec0f91a462c2743b19b428f4c177d7109d2ccc018dcdedc12570d9d735d6fb1b" reference_checksum_tar = "6e902e77925ab2faeef8377722434d4482f1fcc74af958c984c3f22509ae5084" @@ -3576,7 +3576,7 @@ def test_copy_easyblocks(self): # easybuild/easyblocks subdirectory must exist in target directory error_pattern = "Could not find easybuild/easyblocks subdir in .*" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.copy_easyblocks, [], self.test_prefix) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.copy_easyblocks, [], self.test_prefix) easyblocks_dir = os.path.join(self.test_prefix, 'easybuild', 'easyblocks') @@ -3641,7 +3641,7 @@ def test_copy_framework_files(self): ft.write_file(foo_py, '') error_pattern = "Specified path '.*/foo.py' does not include a 'easybuild-framework' directory!" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.copy_framework_files, [foo_py], self.test_prefix) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.copy_framework_files, [foo_py], self.test_prefix) # create empty test/framework/modules.py, to check whether 'new' is set correctly in result ft.write_file(os.path.join(target_dir, 'test', 'framework', 'modules.py'), '') @@ -3725,7 +3725,7 @@ def test_locks(self): self.assertEqual(os.listdir(locks_dir), [lock_name + '.lock']) # if lock exists, then check_lock raises an error - self.assertErrorRegex(EasyBuildError, "Lock .* already exists", ft.check_lock, lock_name) + self.assertRaisesRegex(EasyBuildError, "Lock .* already exists", ft.check_lock, lock_name) # remove_lock should... remove the lock ft.remove_lock(lock_name) @@ -3778,7 +3778,7 @@ def test_locks(self): self.assertEqual(os.listdir(locks_dir), [lock_name + '.lock']) # clean_up_locks_signal_handler causes sys.exit with specified exit code - self.assertErrorRegex(SystemExit, '15', ft.clean_up_locks_signal_handler, 15, None) + self.assertRaisesRegex(SystemExit, '15', ft.clean_up_locks_signal_handler, 15, None) self.assertFalse(ft.global_lock_names) self.assertNotExists(lock_path) self.assertEqual(os.listdir(locks_dir), []) @@ -3801,7 +3801,7 @@ def test_locate_files(self): # error is raised if files could not be found error_pattern = r"One or more files not found: nosuchfile.txt \(search paths: \)" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.locate_files, ['nosuchfile.txt'], []) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.locate_files, ['nosuchfile.txt'], []) # files specified via absolute path don't have to be found res = ft.locate_files([one], []) @@ -3841,7 +3841,7 @@ def test_locate_files(self): # only some files found yields correct warning files = ['2.txt', '3.txt', '1.txt'] error_pattern = r"One or more files not found: 3\.txt, 1.txt \(search paths: .*/subdirA\)" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.locate_files, files, [os.path.dirname(two)]) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.locate_files, files, [os.path.dirname(two)]) # check that relative paths are found in current working dir ft.change_dir(self.test_prefix) @@ -3854,7 +3854,7 @@ def test_locate_files(self): # no recursive search in current working dir (which would potentially be way too expensive) error_pattern = r"One or more files not found: 2\.txt \(search paths: \)" - self.assertErrorRegex(EasyBuildError, error_pattern, ft.locate_files, ['2.txt'], []) + self.assertRaisesRegex(EasyBuildError, error_pattern, ft.locate_files, ['2.txt'], []) def test_set_gid_sticky_bits(self): """Test for set_gid_sticky_bits function.""" @@ -3973,7 +3973,7 @@ def test_create_unused_dir(self): old_perms = os.lstat(readonly_dir)[stat.ST_MODE] ft.adjust_permissions(readonly_dir, stat.S_IREAD | stat.S_IEXEC, relative=False) try: - self.assertErrorRegex(EasyBuildError, 'Failed to create directory', + self.assertRaisesRegex(EasyBuildError, 'Failed to create directory', ft.create_unused_dir, readonly_dir, 'new_folder') finally: ft.adjust_permissions(readonly_dir, old_perms, relative=False) @@ -4080,7 +4080,7 @@ def expected_suffix(n_calls_to_create_non_existing_paths): ft.adjust_permissions(readonly_dir, stat.S_IREAD | stat.S_IEXEC, relative=False) requested_path = [os.path.join(readonly_dir, 'new_folder')] try: - self.assertErrorRegex( + self.assertRaisesRegex( EasyBuildError, "Failed to create directory", ft.create_non_existing_paths, requested_path ) @@ -4097,7 +4097,7 @@ def expected_suffix(n_calls_to_create_non_existing_paths): ft.mkdir(os.path.join(test_root, 'attempt_2')) ft.mkdir(os.path.join(test_root, 'attempt_3')) max_tries = 4 - self.assertErrorRegex( + self.assertRaisesRegex( EasyBuildError, rf"Exceeded maximum number of attempts \({max_tries}\) to generate non-existing paths", ft.create_non_existing_paths, @@ -4119,7 +4119,7 @@ def expected_suffix(n_calls_to_create_non_existing_paths): os.path.join(test_root, 'foo/bar'), os.path.join(test_root, 'foo/bar/baz'), ] - self.assertErrorRegex( + self.assertRaisesRegex( EasyBuildError, "Path '.*/foo/bar' is a parent path of '.*/foo/bar/baz'", ft.create_non_existing_paths, @@ -4131,7 +4131,7 @@ def expected_suffix(n_calls_to_create_non_existing_paths): os.path.join(test_root, 'foo/bar/baz'), os.path.join(test_root, 'foo/bar'), ] - self.assertErrorRegex( + self.assertRaisesRegex( EasyBuildError, "Path '.*/foo/bar' is a parent path of '.*/foo/bar/baz'", ft.create_non_existing_paths, @@ -4143,7 +4143,7 @@ def expected_suffix(n_calls_to_create_non_existing_paths): os.path.join(test_root, 'foo/bar'), os.path.join(test_root, 'foo/bar'), ] - self.assertErrorRegex( + self.assertRaisesRegex( EasyBuildError, "Path '.*/foo/bar' is a parent path of '.*/foo/bar'", ft.create_non_existing_paths, diff --git a/test/framework/general.py b/test/framework/general.py index fe08c3a960..b9f649863f 100644 --- a/test/framework/general.py +++ b/test/framework/general.py @@ -83,14 +83,14 @@ def bar(): err_pat = r"None of the specified modules \(nosuchmoduleoutthere\) is available.*" err_pat += r"package nosuchpkg.*pypi/nosuchpkg" - self.assertErrorRegex(EasyBuildError, err_pat, bar) + self.assertRaisesRegex(EasyBuildError, err_pat, bar) @only_if_module_is_available(('nosuchmodule', 'anothernosuchmodule')) def bar2(): pass err_pat = r"ImportError: None of the specified modules \(nosuchmodule, anothernosuchmodule\) is available" - self.assertErrorRegex(EasyBuildError, err_pat, bar2) + self.assertRaisesRegex(EasyBuildError, err_pat, bar2) class Foo(): @only_if_module_is_available('thisdoesnotexist', url='http://example.com') @@ -99,7 +99,7 @@ def foobar(self): err_pat = r"None of the specified modules \(thisdoesnotexist\) is available " err_pat += r"\(available from http://example.com\)" - self.assertErrorRegex(EasyBuildError, err_pat, Foo().foobar) + self.assertRaisesRegex(EasyBuildError, err_pat, Foo().foobar) def test_docstrings(self): """Make sure tags included in docstrings are correctly formatted.""" diff --git a/test/framework/github.py b/test/framework/github.py index c80e496cf2..240c0369d6 100644 --- a/test/framework/github.py +++ b/test/framework/github.py @@ -246,7 +246,7 @@ def test_github_add_pr_labels(self): self.mock_stdout(True) error_pattern = "Adding labels to PRs for repositories other than easyconfigs hasn't been implemented yet" - self.assertErrorRegex(EasyBuildError, error_pattern, gh.add_pr_labels, 1) + self.assertRaisesRegex(EasyBuildError, error_pattern, gh.add_pr_labels, 1) self.mock_stdout(False) build_options['pr_target_repo'] = GITHUB_EASYCONFIGS_REPO @@ -545,11 +545,11 @@ def test_fetch_files_from_commit(self): # test downloading with short commit, download_repo currently enforces using long commit error_pattern = r"Specified commit SHA 7c83a55 for downloading easybuilders/easybuild-easyconfigs " error_pattern += r"is not valid, must be full SHA-1 \(40 chars\)" - self.assertErrorRegex(EasyBuildError, error_pattern, fetch_files_from_commit, '7c83a55') + self.assertRaisesRegex(EasyBuildError, error_pattern, fetch_files_from_commit, '7c83a55') # test downloading of non-existing commit error_pattern = r"Failed to download diff for easybuilders/easybuild-easyconfigs commit c0ff33c0ff33" - self.assertErrorRegex(EasyBuildError, error_pattern, fetch_files_from_commit, 'c0ff33c0ff33') + self.assertRaisesRegex(EasyBuildError, error_pattern, fetch_files_from_commit, 'c0ff33c0ff33') def test_fetch_easyconfigs_from_commit(self): """Test fetch_easyconfigs_from_commit function.""" @@ -655,10 +655,10 @@ def test_github_download_repo_commit(self): self.assertTrue("v4.9.0 (30 December 2023)" in release_notes_txt) # short commit doesn't work, must be full commit ID - self.assertErrorRegex(EasyBuildError, "Specified commit SHA bdcc586 .* is not valid", gh.download_repo, + self.assertRaisesRegex(EasyBuildError, "Specified commit SHA bdcc586 .* is not valid", gh.download_repo, path=self.test_prefix, commit='bdcc586') - self.assertErrorRegex(EasyBuildError, "Failed to download tarball .* commit", gh.download_repo, + self.assertRaisesRegex(EasyBuildError, "Failed to download tarball .* commit", gh.download_repo, path=self.test_prefix, commit='0000000000000000000000000000000000000000') def test_install_github_token(self): @@ -996,7 +996,7 @@ def test_github_det_patch_specs(self): error_pattern = "Failed to determine software name to which patch file .*/2.patch relates" self.mock_stdout(True) - self.assertErrorRegex(EasyBuildError, error_pattern, gh.det_patch_specs, patch_paths, file_info, []) + self.assertRaisesRegex(EasyBuildError, error_pattern, gh.det_patch_specs, patch_paths, file_info, []) self.mock_stdout(False) rawtxt = textwrap.dedent(""" diff --git a/test/framework/hooks.py b/test/framework/hooks.py index b460842e33..a25e8fef18 100644 --- a/test/framework/hooks.py +++ b/test/framework/hooks.py @@ -103,7 +103,7 @@ def tearDown(self): def test_load_hooks(self): """Test for load_hooks function.""" - self.assertErrorRegex(EasyBuildError, "Specified path .* does not exist.*", load_hooks, '/no/such/hooks.py') + self.assertRaisesRegex(EasyBuildError, "Specified path .* does not exist.*", load_hooks, '/no/such/hooks.py') hooks = load_hooks(self.test_hooks_pymod) @@ -141,7 +141,7 @@ def test_load_hooks(self): # clearing cached hooks results in error because hooks file is not found easybuild.tools.hooks._cached_hooks = {} - self.assertErrorRegex(EasyBuildError, "Specified path .* does not exist.*", load_hooks, self.test_hooks_pymod) + self.assertRaisesRegex(EasyBuildError, "Specified path .* does not exist.*", load_hooks, self.test_hooks_pymod) def test_find_hook(self): """Test for find_hook function.""" @@ -321,7 +321,7 @@ def install_hook(self): error_msg_pattern += r"\* stat_hook \(did you mean 'start_hook'\?\)\n" error_msg_pattern += r"\* there_is_no_such_hook\n\n" error_msg_pattern += r"Run 'eb --avail-hooks' to get an overview of known hooks" - self.assertErrorRegex(EasyBuildError, error_msg_pattern, load_hooks, test_broken_hooks_pymod) + self.assertRaisesRegex(EasyBuildError, error_msg_pattern, load_hooks, test_broken_hooks_pymod) def suite(loader=None): diff --git a/test/framework/include.py b/test/framework/include.py index c65c1e17ec..239327dd1e 100644 --- a/test/framework/include.py +++ b/test/framework/include.py @@ -246,7 +246,7 @@ def test_include_toolchains(self): def test_is_software_specific_easyblock(self): """Test is_software_specific_easyblock function.""" - self.assertErrorRegex(EasyBuildError, "No such file", is_software_specific_easyblock, '/no/such/easyblock.py') + self.assertRaisesRegex(EasyBuildError, "No such file", is_software_specific_easyblock, '/no/such/easyblock.py') testdir = os.path.dirname(os.path.abspath(__file__)) test_easyblocks = os.path.join(testdir, 'sandbox', 'easybuild', 'easyblocks') diff --git a/test/framework/lib.py b/test/framework/lib.py index 88b8264cec..dbc4e6dcf1 100644 --- a/test/framework/lib.py +++ b/test/framework/lib.py @@ -75,7 +75,7 @@ def test_run_cmd(self): error_pattern = r"Undefined build option: .*" error_pattern += r" Make sure you have set up the EasyBuild configuration using set_up_configuration\(\)" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, run_cmd, "echo hello") + self.assertRaisesRegex(EasyBuildError, error_pattern, run_cmd, "echo hello") self.configure() @@ -90,7 +90,7 @@ def test_run_shell_cmd(self): error_pattern = r"Undefined build option: .*" error_pattern += r" Make sure you have set up the EasyBuild configuration using set_up_configuration\(\)" - self.assertErrorRegex(EasyBuildError, error_pattern, run_shell_cmd, "echo hello") + self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, "echo hello") self.configure() @@ -108,7 +108,7 @@ def test_mkdir(self): error_pattern = r"Undefined build option: .*" error_pattern += r" Make sure you have set up the EasyBuild configuration using set_up_configuration\(\)" - self.assertErrorRegex(EasyBuildError, error_pattern, mkdir, test_dir) + self.assertRaisesRegex(EasyBuildError, error_pattern, mkdir, test_dir) self.configure() @@ -122,7 +122,7 @@ def test_modules_tool(self): error_pattern = r"Undefined build option: .*" error_pattern += r" Make sure you have set up the EasyBuild configuration using set_up_configuration\(\)" - self.assertErrorRegex(EasyBuildError, error_pattern, modules_tool) + self.assertRaisesRegex(EasyBuildError, error_pattern, modules_tool) self.configure() diff --git a/test/framework/module_generator.py b/test/framework/module_generator.py index 4669cf6888..eb52ef7f5f 100644 --- a/test/framework/module_generator.py +++ b/test/framework/module_generator.py @@ -315,7 +315,7 @@ def test_load(self): else: expected = "depends-on statements in generated module are not supported by modules tool" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, expected, + self.assertRaisesRegex(EasyBuildError, expected, self.modgen.load_module, "mod_name", depends_on=True) else: # default: guarded module load (which implies no recursive unloading) @@ -361,7 +361,7 @@ def test_load(self): else: expected = "depends_on statements in generated module are not supported by modules tool" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, expected, + self.assertRaisesRegex(EasyBuildError, expected, self.modgen.load_module, "mod_name", depends_on=True) def test_load_multi_deps(self): @@ -542,11 +542,11 @@ def test_load_multi_deps(self): def test_modulerc(self): """Test modulerc method.""" - self.assertErrorRegex(EasyBuildError, "Incorrect module_version value type", self.modgen.modulerc, 'foo') + self.assertRaisesRegex(EasyBuildError, "Incorrect module_version value type", self.modgen.modulerc, 'foo') arg = {'foo': 'bar'} error_pattern = "Incorrect module_version spec, expected keys" - self.assertErrorRegex(EasyBuildError, error_pattern, self.modgen.modulerc, arg) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.modgen.modulerc, arg) mod_ver_spec = {'modname': 'test/1.2.3.4.5', 'sym_version': '1.2.3', 'version': '1.2.3.4.5'} modulerc_path = os.path.join(self.test_prefix, 'test', self.modgen.DOT_MODULERC) @@ -555,7 +555,7 @@ def test_modulerc(self): if isinstance(self.modtool, Lmod) and LooseVersion(self.modtool.version) < LooseVersion('7.0'): error = "Expected module file .* not found; " error += "Lmod 6.x requires that .modulerc and wrapped module file are in same directory" - self.assertErrorRegex(EasyBuildError, error, self.modgen.modulerc, mod_ver_spec, filepath=modulerc_path) + self.assertRaisesRegex(EasyBuildError, error, self.modgen.modulerc, mod_ver_spec, filepath=modulerc_path) # if the wrapped module file is in place, everything should be fine write_file(os.path.join(self.test_prefix, 'test', '1.2.3.4.5'), '#%Module') @@ -774,7 +774,7 @@ def append_paths(*args, **kwargs): res = append_paths('key', ['1234@example.com'], expand_relpaths=False) self.assertEqual('append_path("key", "1234@example.com")\n', res) - self.assertErrorRegex(EasyBuildError, "Absolute path %s/foo passed to update_paths " + self.assertRaisesRegex(EasyBuildError, "Absolute path %s/foo passed to update_paths " "which only expects relative paths." % self.modgen.app.installdir, append_paths, "key2", ["bar", "%s/foo" % self.modgen.app.installdir]) @@ -908,7 +908,7 @@ def prepend_paths(*args, **kwargs): res = prepend_paths('key', ['1234@example.com'], expand_relpaths=False) self.assertEqual('prepend_path("key", "1234@example.com")\n', res) - self.assertErrorRegex(EasyBuildError, "Absolute path %s/foo passed to update_paths " + self.assertRaisesRegex(EasyBuildError, "Absolute path %s/foo passed to update_paths " "which only expects relative paths." % self.modgen.app.installdir, prepend_paths, "key2", ["bar", "%s/foo" % self.modgen.app.installdir]) @@ -1363,7 +1363,7 @@ def test_mns(): err_pattern = 'nosucheasyconfigparameteravailable' ec_file = os.path.join(ecs_dir, 'g', 'gzip', 'gzip-1.5-foss-2018a.eb') - self.assertErrorRegex(EasyBuildError, err_pattern, EasyConfig, ec_file) + self.assertRaisesRegex(EasyBuildError, err_pattern, EasyConfig, ec_file) # test simple custom module naming scheme os.environ['EASYBUILD_MODULE_NAMING_SCHEME'] = 'TestModuleNamingScheme' @@ -1445,7 +1445,7 @@ def test_mns(): 'versionsuffix': {'name': 'system', 'version': 'system'}, } error_pattern = "versionsuffix value should be a string, found 'dict'" - self.assertErrorRegex(EasyBuildError, error_pattern, ActiveMNS().det_full_module_name, faulty_dep_spec) + self.assertRaisesRegex(EasyBuildError, error_pattern, ActiveMNS().det_full_module_name, faulty_dep_spec) def test_mod_name_validation(self): """Test module naming validation.""" @@ -1586,7 +1586,7 @@ def test_ec(ecfile, short_modname, mod_subdir, modpath_exts, user_modpath_exts, # impi with dummy toolchain, which doesn't make sense in a hierarchical context ec = EasyConfig(os.path.join(ecs_dir, 'i', 'impi', 'impi-5.1.2.150.eb')) - self.assertErrorRegex(EasyBuildError, 'No compiler available.*MPI lib', ActiveMNS().det_modpath_extensions, ec) + self.assertRaisesRegex(EasyBuildError, 'No compiler available.*MPI lib', ActiveMNS().det_modpath_extensions, ec) os.environ['EASYBUILD_MODULE_NAMING_SCHEME'] = 'CategorizedHMNS' init_config(build_options=build_options) @@ -1623,7 +1623,7 @@ def test_ec(ecfile, short_modname, mod_subdir, modpath_exts, user_modpath_exts, # impi with dummy toolchain, which doesn't make sense in a hierarchical context ec = EasyConfig(os.path.join(ecs_dir, 'i', 'impi', 'impi-5.1.2.150.eb')) - self.assertErrorRegex(EasyBuildError, 'No compiler available.*MPI lib', ActiveMNS().det_modpath_extensions, ec) + self.assertRaisesRegex(EasyBuildError, 'No compiler available.*MPI lib', ActiveMNS().det_modpath_extensions, ec) os.environ['EASYBUILD_MODULE_NAMING_SCHEME'] = 'CategorizedModuleNamingScheme' init_config(build_options=build_options) diff --git a/test/framework/modules.py b/test/framework/modules.py index bfd21778ba..96eb0eee31 100644 --- a/test/framework/modules.py +++ b/test/framework/modules.py @@ -120,7 +120,7 @@ def test_run_module(self): # by default, exit code is checked and an error is raised if we run something that fails error_pattern = "Module command '.*thisdoesnotmakesense' failed with exit code [1-9]" - self.assertErrorRegex(EasyBuildError, error_pattern, self.modtool.run_module, 'thisdoesnotmakesense') + self.assertRaisesRegex(EasyBuildError, error_pattern, self.modtool.run_module, 'thisdoesnotmakesense') # we need to use a different error pattern here with EnvironmentModulesC and # EnvironmentModules <5.5, because a load of a non-existing module doesnt' trigger a @@ -131,7 +131,7 @@ def test_run_module(self): error_pattern = "Unable to locate a modulefile for 'nosuchmodule/1.2.3'" else: error_pattern = "Module command '.*load nosuchmodule/1.2.3' failed with exit code [1-9]" - self.assertErrorRegex(EasyBuildError, error_pattern, self.modtool.run_module, 'load', 'nosuchmodule/1.2.3') + self.assertRaisesRegex(EasyBuildError, error_pattern, self.modtool.run_module, 'load', 'nosuchmodule/1.2.3') # we can choose to blatently ignore the exit code, # and also disable the output check that serves as a fallback; @@ -444,7 +444,7 @@ def test_load(self): 'MPI/GCC/6.4.0-2.28/OpenMPI/2.1.2/ScaLAPACK/2.0.2-OpenBLAS-0.2.20', ] for modname in modnames: - self.assertErrorRegex(EasyBuildError, '.*', self.modtool.load, [modname]) + self.assertRaisesRegex(EasyBuildError, '.*', self.modtool.load, [modname]) # by default, modules are always loaded, even if they are already loaded self.modtool.load(['GCC/6.4.0-2.28', 'OpenMPI/2.1.2-GCC-6.4.0-2.28']) @@ -734,7 +734,7 @@ def check_get_software_libdir(expected, **additional_args): remove_file(os.path.join(root, 'lib64', 'libfoo.' + shlib_ext)) # check expected result of get_software_libdir with multiple lib subdirs - self.assertErrorRegex(EasyBuildError, "Multiple library subdirectories found.*", get_software_libdir, name) + self.assertRaisesRegex(EasyBuildError, "Multiple library subdirectories found.*", get_software_libdir, name) check_get_software_libdir(only_one=False, expected=['lib', 'lib64']) # only directories containing files in specified list should be retained @@ -947,7 +947,7 @@ def test_modpath_extensions_for(self): # error for non-existing modules error_pattern = "Can't get value from a non-existing module" - self.assertErrorRegex(EasyBuildError, error_pattern, self.modtool.modpath_extensions_for, ['nosuchmodule/1.2']) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.modtool.modpath_extensions_for, ['nosuchmodule/1.2']) # make sure $HOME/$USER is set to something we can easily check os.environ['HOME'] = os.path.join(self.test_prefix, 'HOME') @@ -1098,7 +1098,7 @@ def test_modules_tool_stateless(self): # GCC/4.6.3 is *not* an available Core module os.environ['LC_ALL'] = 'C' os.environ['LANG'] = 'C' - self.assertErrorRegex(EasyBuildError, load_err_msg, self.modtool.load, ['GCC/4.6.3']) + self.assertRaisesRegex(EasyBuildError, load_err_msg, self.modtool.load, ['GCC/4.6.3']) # GCC/6.4.0-2.28 is one of the available Core modules self.modtool.load(['GCC/6.4.0-2.28']) @@ -1133,7 +1133,7 @@ def test_modules_tool_stateless(self): else: load_err_msg = "Unable to locate a modulefile" - self.assertErrorRegex(EasyBuildError, load_err_msg, self.modtool.load, ['OpenMPI/2.1.2']) + self.assertRaisesRegex(EasyBuildError, load_err_msg, self.modtool.load, ['OpenMPI/2.1.2']) def test_mk_module_cache_key(self): """Test mk_module_cache_key method.""" @@ -1227,7 +1227,7 @@ def test_module_use_unuse(self): # Adding an empty modulepath is not possible modulepath = os.environ.get('MODULEPATH', '') - self.assertErrorRegex(EasyBuildError, "Cannot add empty path", self.modtool.use, '') + self.assertRaisesRegex(EasyBuildError, "Cannot add empty path", self.modtool.use, '') self.assertEqual(os.environ.get('MODULEPATH', ''), modulepath) # make sure the right test module is loaded @@ -1441,7 +1441,7 @@ def test_exit_code_check(self): else: # Environment Modules exits with 0 even when a non-existing module is loaded... error_pattern = "Unable to locate a modulefile for 'nosuchmoduleavailableanywhere'" - self.assertErrorRegex(EasyBuildError, error_pattern, self.modtool.load, ['nosuchmoduleavailableanywhere']) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.modtool.load, ['nosuchmoduleavailableanywhere']) def test_check_loaded_modules(self): """Test check_loaded_modules method.""" @@ -1497,7 +1497,7 @@ def check_loaded_modules(): # error mentioning 1 non-allowed module (OpenMPI), both GCC and hwloc loaded modules are allowed error_pattern = r"Found one or more non-allowed loaded .* module.*\n" error_pattern += r"\* OpenMPI/2.1.2-GCC-6.4.0-2.28\n\nThis is not" - self.assertErrorRegex(EasyBuildError, error_pattern, self.modtool.check_loaded_modules) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.modtool.check_loaded_modules) # check for warning message when purge is being run on loaded modules build_options.update({'detect_loaded_modules': 'purge'}) @@ -1530,7 +1530,7 @@ def check_loaded_modules(): init_config(build_options=build_options) error_msg = r"Found defined \$EBROOT\* environment variables without matching loaded module: " error_msg += r"\$EBROOTSOFTWAREWITHOUTAMATCHINGMODULE\n" - self.assertErrorRegex(EasyBuildError, error_msg, check_loaded_modules) + self.assertRaisesRegex(EasyBuildError, error_msg, check_loaded_modules) build_options.update({'check_ebroot_env_vars': 'ignore'}) init_config(build_options=build_options) @@ -1547,7 +1547,7 @@ def check_loaded_modules(): # specified action for detected loaded modules is verified early error_msg = "Unknown action specified to --detect-loaded-modules: sdvbfdgh" - self.assertErrorRegex(EasyBuildError, error_msg, init_config, args=['--detect-loaded-modules=sdvbfdgh']) + self.assertRaisesRegex(EasyBuildError, error_msg, init_config, args=['--detect-loaded-modules=sdvbfdgh']) def test_NoModulesTool(self): """Test use of NoModulesTool class.""" @@ -1921,7 +1921,7 @@ def test_module_load_environment(self): self.assertEqual(mod_load_env.TEST_VAR.contents, test_contents) error_pattern = "Name of ModuleLoadEnvironment attribute does not conform to shell naming rules.*'test_lower'" - self.assertErrorRegex(EasyBuildError, error_pattern, setattr, mod_load_env, 'test_lower', test_contents) + self.assertRaisesRegex(EasyBuildError, error_pattern, setattr, mod_load_env, 'test_lower', test_contents) mod_load_env.TEST_STR = 'some/path' self.assertTrue(hasattr(mod_load_env, 'TEST_STR')) @@ -2066,9 +2066,9 @@ def test_module_load_environment(self): self.assertEqual(alias_load_env.ALIAS_VAR32.contents, ['alias3_path', 'new_path']) error_pattern = "Wrong format for aliases defitions passed to ModuleLoadEnvironment" - self.assertErrorRegex(EasyBuildError, error_pattern, mod.ModuleLoadEnvironment, aliases=False) - self.assertErrorRegex(EasyBuildError, error_pattern, mod.ModuleLoadEnvironment, aliases='wrong') - self.assertErrorRegex(EasyBuildError, error_pattern, mod.ModuleLoadEnvironment, aliases=['some', 'list']) + self.assertRaisesRegex(EasyBuildError, error_pattern, mod.ModuleLoadEnvironment, aliases=False) + self.assertRaisesRegex(EasyBuildError, error_pattern, mod.ModuleLoadEnvironment, aliases='wrong') + self.assertRaisesRegex(EasyBuildError, error_pattern, mod.ModuleLoadEnvironment, aliases=['some', 'list']) def suite(loader=None): diff --git a/test/framework/modulestool.py b/test/framework/modulestool.py index ad89b4e3e5..1541813d3e 100644 --- a/test/framework/modulestool.py +++ b/test/framework/modulestool.py @@ -111,7 +111,7 @@ def test_module_mismatch(self): # redefine 'module' function (deliberate mismatch with used module command in MockModulesTool) os.environ['module'] = "() { eval `/tmp/Modules/$MODULE_VERSION/bin/modulecmd bash $*`\n}" error_regex = ".*pattern .* not found in defined 'module' function" - self.assertErrorRegex(EasyBuildError, error_regex, MockModulesTool, testing=True) + self.assertRaisesRegex(EasyBuildError, error_regex, MockModulesTool, testing=True) # check whether escaping error by allowing mismatch via build options works build_options = { @@ -202,7 +202,7 @@ def test_environment_modules_specific(self): os.environ['_module_raw'] = "() { eval `/usr/share/Modules/libexec/foo.tcl' bash $*`;\n}" os.environ['module'] = "() { _module_raw \"$@\" 2>&1;\n}" error_regex = ".*pattern .* not found in defined 'module' function" - self.assertErrorRegex(EasyBuildError, error_regex, EnvironmentModules, testing=True) + self.assertRaisesRegex(EasyBuildError, error_regex, EnvironmentModules, testing=True) # redefine '_module_raw' function with correct module command os.environ['_module_raw'] = "() { eval `/usr/share/Modules/libexec/modulecmd.tcl' bash $*`;\n}" diff --git a/test/framework/options.py b/test/framework/options.py index 35d70b84f1..276beae30c 100644 --- a/test/framework/options.py +++ b/test/framework/options.py @@ -345,7 +345,7 @@ def test_skip(self): '--force', ] error_pattern = "Sanity check failed: no file found at 'bin/nosuchfile'" - self.assertErrorRegex(EasyBuildError, error_pattern, self.mocked_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.mocked_main, args, do_build=True, raise_error=True) def test_module_only_param(self): """check use of module_only parameter""" @@ -390,20 +390,20 @@ def test_skipsteps(self): '--rebuild', ] error_pattern = "Sanity check failed: no file found at 'bin/nosuchfile'" - self.assertErrorRegex(EasyBuildError, error_pattern, self.mocked_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.mocked_main, args, do_build=True, raise_error=True) # Verify a wrong step name is caught test_ec_txt += "\nskipsteps = ['wrong-step-name']\n" write_file(test_ec, test_ec_txt) error_pattern = "Found one or more unknown step names in 'skipsteps' easyconfig parameter:\n" error_pattern += r"\* wrong-step-name" - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) # 'source' step was renamed to 'extract' in EasyBuild 5.0, # see https://github.com/easybuilders/easybuild-framework/pull/4629 test_ec_txt += "\nskipsteps = ['source']\n" write_file(test_ec, test_ec_txt) error_pattern = error_pattern.replace('wrong-step-name', r"source \(did you mean 'extract'\?\)") - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) # check use of skipsteps to skip sanity check test_ec_txt += "\nskipsteps = ['sanitycheck']\n" @@ -468,7 +468,7 @@ def test_ignore_test_failure(self): # Passing skip and ignore options is disallowed args.append('--skip-test-step') error_pattern = 'Found both ignore-test-failure and skip-test-step enabled' - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) def test_skip_sanity_check(self): """Test skipping of sanity check step (--skip-sanity-check).""" @@ -481,7 +481,7 @@ def test_skip_sanity_check(self): args = [test_ec, '--rebuild'] err_msg = "Sanity check failed" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, err_msg, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, err_msg, self.eb_main, args, do_build=True, raise_error=True) args.append('--skip-sanity-check') with self.mocked_stdout_stderr(): @@ -492,7 +492,7 @@ def test_skip_sanity_check(self): args.append('--sanity-check-only') error_pattern = 'Found both skip-sanity-check and sanity-check-only enabled' with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) def test_job(self): """Test submitting build as a job.""" @@ -1200,12 +1200,12 @@ def test_search(self): for pattern in ['*foo', '(foo', ')foo', 'foo)', 'foo(']: args = [opt, pattern, '--robot', test_easyconfigs_dir] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, "Invalid search query", self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, "Invalid search query", self.eb_main, args, raise_error=True) # test searching for non-existing easyconfig file (should produce non-zero exit code) # 4 corresponds with MISSING_EASYCONFIG in EasyBuildExit (see easybuild/tools/build_log.py) args = ['--search', 'nosuchsoftware-1.2.3.4.5'] - self.assertErrorRegex(SystemExit, 'MISSING_EASYCONFIG|4', self.eb_main, args, + self.assertRaisesRegex(SystemExit, 'MISSING_EASYCONFIG|4', self.eb_main, args, testing=False, raise_error=True, raise_systemexit=True) def test_ignore_index(self): @@ -1389,7 +1389,7 @@ def check_copied_files(): args = ['--copy-ec', 'toy-0.0.eb', 'bzip2-1.0.6-GCC-4.9.2.eb', target] error_pattern = ".*/test.eb exists but is not a directory" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) # test use of --copy-ec with only one argument: copy to current working directory test_working_dir = os.path.join(self.test_prefix, 'test_working_dir') @@ -1408,7 +1408,7 @@ def check_copied_files(): args = ['--copy-ec'] error_pattern = "One or more files to copy should be specified!" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) def test_github_copy_ec_from_pr(self): """Test combination of --copy-ec with --from-pr.""" @@ -1669,7 +1669,7 @@ def test_eb_with(option_flag, is_valid): "Should not fail with --buildpath='{build_dir}' and {option_flag}='{persist_path}'." ) else: - self.assertErrorRegex(EasyBuildError, pattern, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, pattern, self.eb_main, args, raise_error=True) test_eb_with(option_flag='--failed-install-logs-path', is_valid=True) test_eb_with(option_flag='--failed-install-logs-path', is_valid=False) @@ -1834,7 +1834,7 @@ def test_try_toolchain_mapping(self): # if it fails, an error is printed error_pattern = "Toolchain iccifort is not equivalent to toolchain foss in terms of capabilities." with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True, do_build=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True, do_build=True) # can continue anyway using --disable-map-toolchains args.append('--disable-map-toolchains') @@ -1884,7 +1884,7 @@ def test_try_update_deps(self): ] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, "Experimental functionality", self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, "Experimental functionality", self.eb_main, args, raise_error=True) args.append('--experimental') with self.mocked_stdout_stderr(): @@ -2763,13 +2763,13 @@ def test_try(self): for extra_arg in ['--try-software=foo', '--try-toolchain=gompi', '--try-toolchain=gomp,2018a,-a-suffix']: allargs = args + [extra_arg] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, "problems validating the options", + self.assertRaisesRegex(EasyBuildError, "problems validating the options", self.eb_main, allargs, raise_error=True) # no --try used, so no tweaked easyconfig files are generated allargs = args + ['--software-version=1.2.3', '--toolchain=gompi,2018a'] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, "version .* not available", self.eb_main, allargs, raise_error=True) + self.assertRaisesRegex(EasyBuildError, "version .* not available", self.eb_main, allargs, raise_error=True) # Try changing only name or version of toolchain args.pop(0) # Remove EC filename @@ -3192,12 +3192,12 @@ def test_parse_http_header_fields_urlpat(self): # Case H: recurse into files but hit limit args = filesub4 error_regex = r"Failed to parse_http_header_fields_urlpat \(recursion limit\)" - self.assertErrorRegex(EasyBuildError, error_regex, parse_http_header_fields_urlpat, args) + self.assertRaisesRegex(EasyBuildError, error_regex, parse_http_header_fields_urlpat, args) # Case I: argument is not a string args = list("foobar") error_regex = r"Failed to parse_http_header_fields_urlpat \(argument not a string\)" - self.assertErrorRegex(EasyBuildError, error_regex, parse_http_header_fields_urlpat, args) + self.assertRaisesRegex(EasyBuildError, error_regex, parse_http_header_fields_urlpat, args) def test_http_header_fields_urlpat(self): """Test use of --http-header-fields-urlpat.""" @@ -3387,7 +3387,7 @@ def test_robot(self): ] error_regex = r"Missing modules for dependencies .*: toy/\.0.0-deps" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_regex, self.eb_main, args, raise_error=True, do_build=True) + self.assertRaisesRegex(EasyBuildError, error_regex, self.eb_main, args, raise_error=True, do_build=True) # enable robot, but without passing path required to resolve toy dependency => FAIL # note that --dry-run is now robust against missing easyconfig, so shouldn't use it here @@ -3396,7 +3396,7 @@ def test_robot(self): '--robot', ] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, 'Missing dependencies', self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, 'Missing dependencies', self.eb_main, args, raise_error=True) # add path to test easyconfigs to robot paths, so dependencies can be resolved args.append('--dry-run') @@ -3448,7 +3448,7 @@ def test_robot_path_check(self): for robot in ['--robot=foo', '--robot=%s' % empty_file]: args = ['toy-0.0.eb', '--dry-run', robot] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) toy_mod_txt = 'module: toy/0.0' @@ -3468,7 +3468,7 @@ def test_robot_path_check(self): args = ['--dry-run', '--robot', 'no_such_easyconfig_file_in_robot_search_path.eb'] error_pattern = "One or more files not found: no_such_easyconfig_file_in_robot_search_path.eb" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) for robot in ['-r%s' % self.test_prefix, '--robot=%s' % self.test_prefix]: args = ['toy-0.0.eb', '--dry-run', robot] @@ -3487,7 +3487,7 @@ def test_robot_path_check(self): for arg in ['-DX', '-DrX', '-DXr', '-frkDX', '-XfrD']: args = ['toy-0.0.eb', arg] with self.mocked_stdout_stderr(): - self.assertErrorRegex(SystemExit, '.*', self.eb_main, args, raise_error=True, raise_systemexit=True) + self.assertRaisesRegex(SystemExit, '.*', self.eb_main, args, raise_error=True, raise_systemexit=True) stderr = self.get_stderr() self.assertIn("error: no such option: -X", stderr) @@ -3496,7 +3496,7 @@ def test_missing_cfgfile(self): args = ['--configfiles=/no/such/cfgfile.foo'] error_regex = "parseconfigfiles: configfile .* not found" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_regex, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_regex, self.eb_main, args, raise_error=True) def test_show_default_moduleclasses(self): """Test --show-default-moduleclasses.""" @@ -3782,7 +3782,7 @@ def test_xxx_include_generic_easyblocks(self): # generic easyblock FooBar is not there initially error_msg = "Failed to obtain class for FooBar easyblock" - self.assertErrorRegex(EasyBuildError, error_msg, get_easyblock_class, 'FooBar') + self.assertRaisesRegex(EasyBuildError, error_msg, get_easyblock_class, 'FooBar') # include extra test easyblocks txt = '\n'.join([ @@ -3828,7 +3828,7 @@ def test_xxx_include_generic_easyblocks(self): sys.modules[pkg].__path__.remove(path) error_msg = "Failed to obtain class for FooBar easyblock" - self.assertErrorRegex(EasyBuildError, error_msg, get_easyblock_class, 'FooBar') + self.assertRaisesRegex(EasyBuildError, error_msg, get_easyblock_class, 'FooBar') # clear log write_file(self.logfile, '') @@ -4108,7 +4108,7 @@ def test_use_included_module_naming_scheme(self): # selecting a module naming scheme that doesn't exist leads to 'invalid choice' error_regex = "Selected module naming scheme \'AnotherTestIncludedMNS\' is unknown" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_regex, self.eb_main, args, logfile=dummylogfn, + self.assertRaisesRegex(EasyBuildError, error_regex, self.eb_main, args, logfile=dummylogfn, raise_error=True, raise_systemexit=True) args.append('--include-module-naming-schemes=%s/*.py' % self.test_prefix) @@ -4291,7 +4291,7 @@ def test_set_multiple_pr_opts(self): ] for args in test_cases: error_pattern = "The following options are set but incompatible.* " + args[0] - self.assertErrorRegex(EasyBuildError, error_pattern, self._run_mock_eb, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self._run_mock_eb, args, raise_error=True) def test_set_tmpdir(self): """Test set_tmpdir config function.""" @@ -4699,7 +4699,7 @@ def test_github_new_update_pr(self): args_new_pr = args + ['--pr-commit-msg=just a test'] error_msg = r"PR commit msg \(--pr-commit-msg\) should not be used" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args_new_pr, raise_error=True, testing=False) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args_new_pr, raise_error=True, testing=False) # But commit message can still be specified when using --force args_new_pr.append('--force') @@ -4726,7 +4726,7 @@ def test_github_new_update_pr(self): error_msg = f"A meaningful commit message must be specified via --pr-commit-msg.*\nDeleted: {ec_name}" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True, testing=False) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True, testing=False) # check whether unstaged file in git working dir was copied (it shouldn't) res = glob.glob(os.path.join(self.test_prefix, 'eb-*', 'eb-*', 'git-working-dir*')) @@ -4803,7 +4803,7 @@ def test_github_new_update_pr(self): error_msg = "A meaningful commit message must be specified via --pr-commit-msg.*\n" error_msg += "Modified: " + os.path.basename(gcc_new_ec) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) # also specifying commit message is sufficient; PR title is inherited from commit message args.append('--pr-commit-msg=this is just a test') @@ -4825,7 +4825,7 @@ def test_github_new_update_pr(self): error_msg = "A meaningful commit message must be specified via --pr-commit-msg when using --update-pr" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) args.append('--pr-commit-msg=just a test') txt, _ = self._run_mock_eb(args, do_build=True, raise_error=True, testing=False) @@ -5125,7 +5125,7 @@ def test_github_merge_pr(self): ] error_msg = r"This PR is closed." with self.mocked_stdout_stderr(mock_stderr=False): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) # and also for an already merged PR args = [ @@ -5135,7 +5135,7 @@ def test_github_merge_pr(self): ] error_msg = r"This PR is already merged." with self.mocked_stdout_stderr(mock_stderr=False): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) # merged PR for EasyBuild-3.3.0.eb, is missing approved review args = [ @@ -5243,7 +5243,7 @@ def test_github_empty_pr(self): error_msg = "No changed files found when comparing to current develop branch." with self.mocked_stdout_stderr(mock_stderr=False): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, do_build=True, raise_error=True) def test_show_config(self): """"Test --show-config and --show-full-config.""" @@ -5366,7 +5366,7 @@ def test_modules_tool_vs_syntax_check(self): os.environ['EASYBUILD_MODULES_TOOL'] = 'EnvironmentModules' args = ['--show-full-config'] error_pattern = "Generating Lua module files requires Lmod as modules tool" - self.assertErrorRegex(EasyBuildError, error_pattern, self._run_mock_eb, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self._run_mock_eb, args, raise_error=True) patterns = [ r"^# Current EasyBuild configuration", @@ -5426,7 +5426,7 @@ def test_dump_env_script(self): args = ['%s.eb' % openmpi, '--dump-env-script'] error_msg = r"Script\(s\) already exists, not overwriting them \(unless --force is used\): %s.env" % openmpi with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, do_build=True, raise_error=True) os.chdir(self.test_prefix) args.append('--force') @@ -5476,7 +5476,7 @@ def test_dump_env_script_existing_module(self): error_msg = (r"Script\(s\) already exists, not overwriting them \(unless --force is used\): " + os.path.basename(env_script)) os.chdir(self.test_prefix) - self.assertErrorRegex(EasyBuildError, error_msg, self._run_mock_eb, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self._run_mock_eb, args, do_build=True, raise_error=True) self.assertExists(env_script) self.assertExists(test_module) # Unchanged module and env file @@ -5543,7 +5543,7 @@ def test_fetch(self): args = ['--sourcepath=%s:%s' % (tmpdir, self.test_sourcepath), '--fetch', 'toy-0.0.eb'] with self.mocked_stdout_stderr(): pattern = 'Checksum verification for .*/toy-0.0.tar.gz .*failed' - self.assertErrorRegex(EasyBuildError, pattern, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, pattern, self.eb_main, args, do_build=True, raise_error=True) # We can avoid that failure by ignoring the checksums args.append('--ignore-checksums') self.eb_main(args, do_build=True, raise_error=True) @@ -5602,12 +5602,12 @@ def test_parse_external_modules_metadata(self): # if both names and versions are specified, lists must have same lengths write_file(testcfg, '\n'.join(['[foo/1.2.3]', 'name = foo,bar', 'version = 1.2.3'])) err_msg = "Different length for lists of names/versions in metadata for external module" - self.assertErrorRegex(EasyBuildError, err_msg, parse_external_modules_metadata, [testcfg]) + self.assertRaisesRegex(EasyBuildError, err_msg, parse_external_modules_metadata, [testcfg]) # if path to non-existing file is used, an error is reported doesnotexist = os.path.join(self.test_prefix, 'doesnotexist') error_pattern = "Specified path for file with external modules metadata does not exist" - self.assertErrorRegex(EasyBuildError, error_pattern, parse_external_modules_metadata, [doesnotexist]) + self.assertRaisesRegex(EasyBuildError, error_pattern, parse_external_modules_metadata, [doesnotexist]) # glob pattern can be used to specify file locations to parse_external_modules_metadata cfg1 = os.path.join(self.test_prefix, 'cfg_one.ini') @@ -5647,7 +5647,7 @@ def test_parse_external_modules_metadata(self): r"\* one/1.0: foo", r"\* three/3.0: aaa, naem, vresion, zzz", ]) - self.assertErrorRegex(EasyBuildError, error_pattern, parse_external_modules_metadata, broken_cfgs) + self.assertRaisesRegex(EasyBuildError, error_pattern, parse_external_modules_metadata, broken_cfgs) def test_zip_logs(self): """Test use of --zip-logs""" @@ -5700,22 +5700,22 @@ def test_list_prs(self): args = ['--list-prs', 'foo'] error_msg = r"must be one of \['open', 'closed', 'all'\]" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) args = ['--list-prs', 'open,foo'] error_msg = r"must be one of \['created', 'updated', 'popularity', 'long-running'\]" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) args = ['--list-prs', 'open,created,foo'] error_msg = r"must be one of \['asc', 'desc'\]" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) args = ['--list-prs', 'open,created,asc,foo'] error_msg = r"must be in the format 'state\[,order\[,direction\]\]" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args, raise_error=True) args = ['--list-prs', 'closed,updated,asc'] txt, _ = self._run_mock_eb(args, testing=False) @@ -5855,17 +5855,17 @@ def test_parse_optarch(self): # Check for EasyBuildErrors error_msg = "The optarch option has an incorrect syntax" options.options.optarch = 'Intel:something;GCC' - self.assertErrorRegex(EasyBuildError, error_msg, options.postprocess) + self.assertRaisesRegex(EasyBuildError, error_msg, options.postprocess) options.options.optarch = 'Intel:something;' - self.assertErrorRegex(EasyBuildError, error_msg, options.postprocess) + self.assertRaisesRegex(EasyBuildError, error_msg, options.postprocess) options.options.optarch = 'Intel:something:somethingelse' - self.assertErrorRegex(EasyBuildError, error_msg, options.postprocess) + self.assertRaisesRegex(EasyBuildError, error_msg, options.postprocess) error_msg = "The optarch option contains duplicated entries for compiler" options.options.optarch = 'Intel:something;GCC:somethingelse;Intel:anothersomething' - self.assertErrorRegex(EasyBuildError, error_msg, options.postprocess) + self.assertRaisesRegex(EasyBuildError, error_msg, options.postprocess) # Check the parsing itself gcc_generic_flags = "march=x86-64 -mtune=generic" @@ -5903,7 +5903,7 @@ def test_check_contrib_style(self): args[0] = '--check-contrib' error_pattern = "One or more contribution checks FAILED" with self.mocked_stdout_stderr(mock_stderr=False): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) stdout = self.get_stdout().strip() self.assertRegex(stdout, regex) @@ -5925,7 +5925,7 @@ def test_check_contrib_style(self): ] error_pattern = "One or more %s checks FAILED!" % check_type with self.mocked_stdout_stderr(mock_stderr=False): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) stdout = self.get_stdout() patterns = [ "toy.eb:1:5: E223 tab before operator", @@ -5948,7 +5948,7 @@ def test_check_contrib_non_style(self): ] error_pattern = "One or more contribution checks FAILED" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, raise_error=True) stdout = self.get_stdout().strip() stderr = self.get_stderr().strip() self.assertEqual(stderr, '') @@ -5991,7 +5991,7 @@ def test_allow_use_as_root(self): # running as root is disallowed by default error_msg = "You seem to be running EasyBuild with root privileges which is not wise, so let's end this here" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self.eb_main, ['toy-0.0.eb'], raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, ['toy-0.0.eb'], raise_error=True) # running as root is allowed under --allow-use-as-root, but does result in a warning being printed to stderr args = ['toy-0.0.eb', '--allow-use-as-root-and-accept-consequences'] @@ -6032,7 +6032,7 @@ def test_verify_easyconfig_filenames(self): error_pattern += r"name: 'toy'; version: '0.0'; versionsuffix: ''; " error_pattern += r"toolchain name, version: 'system', 'system'\)" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, logfile=dummylogfn, + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, logfile=dummylogfn, raise_error=True) write_file(self.logfile, '') @@ -6160,7 +6160,7 @@ def test_inject_checksums(self): # if existing checksums are found, --force is required args = [test_ec, '--inject-checksums'] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, "Found existing checksums", self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, "Found existing checksums", self.eb_main, args, raise_error=True) stdout = self.get_stdout().strip() stderr = self.get_stderr().strip() @@ -6394,7 +6394,7 @@ def test_inject_checksums(self): # because it's not a valid type of checksum args = ['--inject-checksums', test_ec] with self.mocked_stdout_stderr(): - self.assertErrorRegex(SystemExit, '.*', self.eb_main, args, raise_error=True, raise_systemexit=True) + self.assertRaisesRegex(SystemExit, '.*', self.eb_main, args, raise_error=True, raise_systemexit=True) stdout = self.get_stdout().strip() stderr = self.get_stderr().strip() @@ -6478,7 +6478,7 @@ def test_enforce_checksums(self): copy_file(toy_ec, test_ec) error_pattern = r"Missing checksum for bar-0.0[^ ]*\.patch" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) # get rid of checksums for extensions, should result in different error message # because of missing checksum for source of 'bar' extension @@ -6488,7 +6488,7 @@ def test_enforce_checksums(self): write_file(test_ec, test_ec_txt) error_pattern = r"Missing checksum for bar-0\.0\.tar\.gz" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) # wipe both exts_list and checksums, so we can check whether missing checksum for main source is caught test_ec_txt = read_file(test_ec) @@ -6500,7 +6500,7 @@ def test_enforce_checksums(self): write_file(test_ec, test_ec_txt) error_pattern = "Missing checksum for toy-0.0.tar.gz" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) def test_show_system_info(self): """Test for --show-system-info.""" @@ -6788,7 +6788,7 @@ def test_fake_vsc_include(self): '--include-module-naming-schemes=%s' % test_mns, ] with self.mocked_stdout_stderr(): - self.assertErrorRegex(SystemExit, '1', self.eb_main, args, do_build=True, raise_error=True, verbose=True) + self.assertRaisesRegex(SystemExit, '1', self.eb_main, args, do_build=True, raise_error=True, verbose=True) stderr = self.get_stderr() regex = re.compile("ERROR: Detected import from 'vsc' namespace in .*/test_mns.py") self.assertRegex(stderr, regex) @@ -6854,7 +6854,7 @@ def test_create_index(self): # existing index is not overwritten without --force error_pattern = "File exists, not overwriting it without --force: .*/.eb-path-index" - self.assertErrorRegex(EasyBuildError, error_pattern, self._run_mock_eb, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self._run_mock_eb, args, raise_error=True) # also test creating index that's infinitely valid args.extend(['--index-max-age=0', '--force']) @@ -6888,10 +6888,10 @@ def test_sysroot(self): args = [sysroot_arg, '--show-config'] error_pattern = r"Specified sysroot '%s' does not exist!" % doesnotexist - self.assertErrorRegex(EasyBuildError, error_pattern, self._run_mock_eb, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self._run_mock_eb, args, raise_error=True) os.environ['EASYBUILD_SYSROOT'] = doesnotexist - self.assertErrorRegex(EasyBuildError, error_pattern, self._run_mock_eb, ['--show-config'], raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self._run_mock_eb, ['--show-config'], raise_error=True) def test_software_commit(self): """Test use of --software-commit option.""" @@ -6927,7 +6927,7 @@ def test_accept_eula_for(self): args = [test_ec, '--force'] error_pattern = r"The End User License Agreement \(EULA\) for toy is currently not accepted!" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, do_build=True, raise_error=True) toy_modfile = os.path.join(self.test_installpath, 'modules', 'all', 'toy', '0.0') if get_module_syntax() == 'Lua': toy_modfile += '.lua' @@ -7044,7 +7044,7 @@ def test_easystack_wrong_read(self): args = ['--easystack', toy_easystack, '--experimental'] expected_err = "No such file or directory: '%s'" % toy_easystack with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, expected_err, self.eb_main, args, raise_error=True) + self.assertRaisesRegex(EasyBuildError, expected_err, self.eb_main, args, raise_error=True) # testing basics - end-to-end # expecting successful build diff --git a/test/framework/output.py b/test/framework/output.py index c4ff0740fb..4da8ee3591 100644 --- a/test/framework/output.py +++ b/test/framework/output.py @@ -100,7 +100,7 @@ def test_get_output_style(self): if not HAVE_RICH: update_build_option('output_style', 'rich') error_pattern = "Can't use 'rich' output style, Rich Python package is not available!" - self.assertErrorRegex(EasyBuildError, error_pattern, get_output_style) + self.assertRaisesRegex(EasyBuildError, error_pattern, get_output_style) def test_use_rich_show_progress_bars(self): """Test use_rich and show_progress_bar functions.""" @@ -140,7 +140,7 @@ def test_colorize(self): self.assertEqual(colorize('test', 'red'), '\x1b[0;31mtest\x1b[0m') self.assertEqual(colorize('test', 'yellow'), '\x1b[1;33mtest\x1b[0m') - self.assertErrorRegex(EasyBuildError, "Unknown color: nosuchcolor", colorize, 'test', 'nosuchcolor') + self.assertRaisesRegex(EasyBuildError, "Unknown color: nosuchcolor", colorize, 'test', 'nosuchcolor') def test_print_error(self): """ @@ -189,7 +189,7 @@ def test_get_start_update_stop_progress_bar(self): # stopping a progress bar that never was started results in an error error_pattern = "Failed to stop extensions progress bar, since it was never started" - self.assertErrorRegex(EasyBuildError, error_pattern, stop_progress_bar, PROGRESS_BAR_EXTENSIONS) + self.assertRaisesRegex(EasyBuildError, error_pattern, stop_progress_bar, PROGRESS_BAR_EXTENSIONS) # updating a progress bar that never was started is silently ignored on purpose update_progress_bar(PROGRESS_BAR_EXTENSIONS) diff --git a/test/framework/package.py b/test/framework/package.py index c18bfc8fc5..2899ea308e 100644 --- a/test/framework/package.py +++ b/test/framework/package.py @@ -164,7 +164,7 @@ def test_check_pkg_support(self): # clear $PATH to make sure fpm/rpmbuild can not be found os.environ['PATH'] = '' - self.assertErrorRegex(EasyBuildError, "Selected packaging tool 'fpm' not found", check_pkg_support) + self.assertRaisesRegex(EasyBuildError, "Selected packaging tool 'fpm' not found", check_pkg_support) for binary in ['fpm', 'rpmbuild']: binpath = os.path.join(self.test_prefix, binary) diff --git a/test/framework/parallelbuild.py b/test/framework/parallelbuild.py index 0c821dd882..228d537f29 100644 --- a/test/framework/parallelbuild.py +++ b/test/framework/parallelbuild.py @@ -285,7 +285,7 @@ def test_build_easyconfigs_in_parallel_gc3pie(self): error = "1 jobs failed: toy-1.2.3" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error, build_easyconfigs_in_parallel, cmd, ecs, prepare_first=False) + self.assertRaisesRegex(EasyBuildError, error, build_easyconfigs_in_parallel, cmd, ecs, prepare_first=False) def test_submit_jobs(self): """Test submit_jobs""" diff --git a/test/framework/robot.py b/test/framework/robot.py index 895c92f834..d2fb2de28d 100644 --- a/test/framework/robot.py +++ b/test/framework/robot.py @@ -224,7 +224,7 @@ def test_resolve_dependencies(self): # this should not resolve (cannot find gzip-1.4.eb), both with and without robot enabled ecs = [deepcopy(easyconfig_dep)] msg = "Missing dependencies" - self.assertErrorRegex(EasyBuildError, msg, resolve_dependencies, ecs, self.modtool) + self.assertRaisesRegex(EasyBuildError, msg, resolve_dependencies, ecs, self.modtool) # test if dependencies of an automatically found file are also loaded easyconfig_dep['dependencies'] = [{ @@ -578,7 +578,7 @@ def test_resolve_dependencies_missing(self): } error = r"Missing dependencies: somedep/4.5.6 \(no easyconfig file or existing module found\)" - self.assertErrorRegex(EasyBuildError, error, resolve_dependencies, [ec], self.modtool) + self.assertRaisesRegex(EasyBuildError, error, resolve_dependencies, [ec], self.modtool) # check behaviour if only module file is available MockModule.avail_modules = ['somedep/4.5.6'] @@ -587,7 +587,7 @@ def test_resolve_dependencies_missing(self): self.assertEqual(res[0]['full_mod_name'], 'test/123') error = r"Missing dependencies: somedep/4.5.6 \(no easyconfig file found in robot search path\)" - self.assertErrorRegex(EasyBuildError, error, resolve_dependencies, [ec], self.modtool, retain_all_deps=True) + self.assertRaisesRegex(EasyBuildError, error, resolve_dependencies, [ec], self.modtool, retain_all_deps=True) res = resolve_dependencies([ec], self.modtool, retain_all_deps=True, raise_error_missing_ecs=False) self.assertEqual(len(res), 2) @@ -662,7 +662,7 @@ def test_det_easyconfig_paths(self): '--unittest-file=%s' % self.logfile, ] error_pattern = "One or more files not found: intel-2012a.eb" - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, args, logfile=dummylogfn, raise_error=True) + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, logfile=dummylogfn, raise_error=True) args.append('--consider-archived-easyconfigs') outtxt = self.eb_main(args, logfile=dummylogfn, raise_error=True) @@ -1034,7 +1034,7 @@ def test_get_toolchain_hierarchy(self): }) tc = {'name': 'gompi', 'version': '2018a'} error_msg = "Multiple versions of GCC found in dependencies of toolchain gompi: 4.6.4, 6.4.0-2.28" - self.assertErrorRegex(EasyBuildError, error_msg, get_toolchain_hierarchy, tc) + self.assertRaisesRegex(EasyBuildError, error_msg, get_toolchain_hierarchy, tc) def test_find_resolved_modules(self): """Test find_resolved_modules function.""" @@ -1536,7 +1536,7 @@ def test_robot_archived_easyconfigs(self): test_ectxt = regex.sub(tc_spec, gzip_ectxt) write_file(test_ec, test_ectxt) ecs, _ = parse_easyconfigs([(test_ec, False)]) - self.assertErrorRegex(EasyBuildError, "Missing dependencies", resolve_dependencies, + self.assertRaisesRegex(EasyBuildError, "Missing dependencies", resolve_dependencies, ecs, self.modtool, retain_all_deps=True) # --consider-archived-easyconfigs must be used to let robot pick up archived easyconfigs diff --git a/test/framework/run.py b/test/framework/run.py index c7c4e0e66b..269d23cd94 100644 --- a/test/framework/run.py +++ b/test/framework/run.py @@ -321,7 +321,7 @@ def handler(signum, _): self.assertEqual(res.output, 'foo:\nstdin: bar\n\n') error_pattern = "No matching questions found for current command output" - self.assertErrorRegex(EasyBuildError, error_pattern, run_shell_cmd, perl_script, + self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, perl_script, hidden=True, qa_patterns=[('bleh', 'blah')], qa_timeout=1) finally: # cleanup: disable the alarm + reset signal handler for SIGALRM @@ -1053,7 +1053,7 @@ def test_run_cmd_qa(self): # fails because non-question is encountered error_pattern = "Max nohits 1 reached: end of output not-a-question-but-a-statement" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, run_cmd_qa, cmd, qa, maxhits=1, trace=False) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_cmd_qa, cmd, qa, maxhits=1, trace=False) with self.mocked_stdout_stderr(): (out, ec) = run_cmd_qa(cmd, qa, no_qa=["not-a-question-but-a-statement"], maxhits=1, trace=False) @@ -1097,17 +1097,17 @@ def test_run_shell_cmd_qa(self): # check type check on qa_patterns error_pattern = "qa_patterns passed to run_shell_cmd should be a list of 2-tuples!" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns={'foo': 'bar'}) - self.assertErrorRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=('foo', 'bar')) - self.assertErrorRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=(('foo', 'bar'),)) - self.assertErrorRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns='foo:bar') - self.assertErrorRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=['foo:bar']) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns={'foo': 'bar'}) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=('foo', 'bar')) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=(('foo', 'bar'),)) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns='foo:bar') + self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=['foo:bar']) # validate use of qa_timeout to give up if there's no matching question for too long cmd = "sleep 3; echo 'question'; read a; echo $a" error_pattern = "No matching questions found for current command output, giving up after 1 seconds!" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=qa, qa_timeout=1) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=qa, qa_timeout=1) # check using answer that is completed via pattern extracted from question cmd = ';'.join([ @@ -1133,7 +1133,7 @@ def test_run_shell_cmd_qa(self): # fails because non-question is encountered error_pattern = "No matching questions found for current command output, giving up after 1 seconds!" - self.assertErrorRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=qa, qa_timeout=1, + self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=qa, qa_timeout=1, hidden=True) qa_wait_patterns = ["not-a-question-but-a-statement"] @@ -1380,7 +1380,7 @@ def test_run_cmd_qa_answers(self): self.assertEqual(ec, 0) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, "Invalid type for answer", run_cmd_qa, cmd, {'q': 1}) + self.assertRaisesRegex(EasyBuildError, "Invalid type for answer", run_cmd_qa, cmd, {'q': 1}) # test cycling of answers cmd = cmd * 2 @@ -1401,7 +1401,7 @@ def test_run_shell_cmd_qa_answers(self): self.assertEqual(res.exit_code, 0) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, "Unknown type of answers encountered", run_shell_cmd, cmd, + self.assertRaisesRegex(EasyBuildError, "Unknown type of answers encountered", run_shell_cmd, cmd, qa_patterns=[('question', 1)]) # test cycling of answers @@ -1624,7 +1624,7 @@ def test_run_cmd_list(self): cmd = ['/bin/sh', '-c', "echo hello"] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, "When passing cmd as a list then `shell` must be set explictely!", + self.assertRaisesRegex(EasyBuildError, "When passing cmd as a list then `shell` must be set explictely!", run_cmd, cmd) (out, ec) = run_cmd(cmd, shell=False) self.assertEqual(out, "hello\n") @@ -1824,7 +1824,7 @@ def test_run_cmd_async(self): time.sleep(1) error_pattern = 'cmd ".*" exited with exit code 123' with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, check_async_cmd, *cmd_info) + self.assertRaisesRegex(EasyBuildError, error_pattern, check_async_cmd, *cmd_info) with self.mocked_stdout_stderr(): cmd_info = run_cmd(error_test_cmd, asynchronous=True) @@ -1873,8 +1873,8 @@ def test_run_cmd_async(self): error_pattern = r"Number of output bytes to read should be a positive integer value \(or zero\)" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, check_async_cmd, *cmd_info, output_read_size=-1) - self.assertErrorRegex(EasyBuildError, error_pattern, check_async_cmd, *cmd_info, output_read_size='foo') + self.assertRaisesRegex(EasyBuildError, error_pattern, check_async_cmd, *cmd_info, output_read_size=-1) + self.assertRaisesRegex(EasyBuildError, error_pattern, check_async_cmd, *cmd_info, output_read_size='foo') # with output_read_size set to 0, no output is read yet, only status of command is checked with self.mocked_stdout_stderr(): @@ -1968,10 +1968,10 @@ def test_check_log_for_errors(self): os.close(fd) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, "Invalid input:", check_log_for_errors, "", [42]) - self.assertErrorRegex(EasyBuildError, "Invalid input:", check_log_for_errors, "", [(42, IGNORE)]) - self.assertErrorRegex(EasyBuildError, "Invalid input:", check_log_for_errors, "", [("42", "invalid-mode")]) - self.assertErrorRegex(EasyBuildError, "Invalid input:", check_log_for_errors, "", [("42", IGNORE, "")]) + self.assertRaisesRegex(EasyBuildError, "Invalid input:", check_log_for_errors, "", [42]) + self.assertRaisesRegex(EasyBuildError, "Invalid input:", check_log_for_errors, "", [(42, IGNORE)]) + self.assertRaisesRegex(EasyBuildError, "Invalid input:", check_log_for_errors, "", [("42", "invalid-mode")]) + self.assertRaisesRegex(EasyBuildError, "Invalid input:", check_log_for_errors, "", [("42", IGNORE, "")]) input_text = "\n".join([ "OK", @@ -1987,15 +1987,15 @@ def test_check_log_for_errors(self): # String promoted to list with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, + self.assertRaisesRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, r"\b(error|crashed)\b") # List of string(s) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, + self.assertRaisesRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, [r"\b(error|crashed)\b"]) # List of tuple(s) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, + self.assertRaisesRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, [(r"\b(error|crashed)\b", ERROR)]) expected_msg = "Found 2 potential error(s) in command output:\n"\ @@ -2013,7 +2013,7 @@ def test_check_log_for_errors(self): write_file(logfile, '') init_logging(logfile, silent=True) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, [ + self.assertRaisesRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, [ r"\berror\b", (r"\ballowed-test failed\b", IGNORE), (r"(?i)\bCRASHED\b", WARN), @@ -2263,7 +2263,7 @@ def test_run_shell_cmd_delete_cwd(self): mkdir(workdir, parents=True) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd_workdir_rm, work_dir=workdir) + self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd_workdir_rm, work_dir=workdir) def test_run_cmd_sysroot(self): """Test with_sysroot option of run_cmd function.""" diff --git a/test/framework/systemtools.py b/test/framework/systemtools.py index 73831b6bdb..66b92c70c2 100644 --- a/test/framework/systemtools.py +++ b/test/framework/systemtools.py @@ -1048,19 +1048,19 @@ def mock_python_ver(py_maj_ver, py_min_ver): # mock running with different Python versions mock_python_ver(1, 4) error_pattern = r"EasyBuild is not compatible with Python 1.4" - self.assertErrorRegex(EasyBuildError, error_pattern, check_python_version) + self.assertRaisesRegex(EasyBuildError, error_pattern, check_python_version) mock_python_ver(4, 0) error_pattern = r"EasyBuild is not compatible \(yet\) with Python 4.0" - self.assertErrorRegex(EasyBuildError, error_pattern, check_python_version) + self.assertRaisesRegex(EasyBuildError, error_pattern, check_python_version) mock_python_ver(2, 7) error_pattern = r"EasyBuild is not compatible with Python 2.7" - self.assertErrorRegex(EasyBuildError, error_pattern, check_python_version) + self.assertRaisesRegex(EasyBuildError, error_pattern, check_python_version) mock_python_ver(3, 5) error_pattern = r"Python 3.6 or higher is required, found Python 3.5" - self.assertErrorRegex(EasyBuildError, error_pattern, check_python_version) + self.assertRaisesRegex(EasyBuildError, error_pattern, check_python_version) # no problems when running with a supported Python version for pyver in [(3, 6), (3, 7), (3, 11)]: @@ -1098,7 +1098,7 @@ def test_pick_dep_version(self): self.assertEqual(pick_dep_version(dep_ver_dict), '1.2.3-ppc64le') error_pattern = "Unknown value type for version" - self.assertErrorRegex(EasyBuildError, error_pattern, pick_dep_version, ('1.2.3', '4.5.6')) + self.assertRaisesRegex(EasyBuildError, error_pattern, pick_dep_version, ('1.2.3', '4.5.6')) # check support for using 'arch=*' as fallback key dep_ver_dict = { @@ -1112,11 +1112,11 @@ def test_pick_dep_version(self): self.assertEqual(pick_dep_version(dep_ver_dict), '1.2.3') # check how faulty input is handled - self.assertErrorRegex(EasyBuildError, "Found empty dict as version!", pick_dep_version, {}) + self.assertRaisesRegex(EasyBuildError, "Found empty dict as version!", pick_dep_version, {}) error_pattern = r"Unexpected keys in version: bar,foo \(only 'arch=' keys are supported\)" - self.assertErrorRegex(EasyBuildError, error_pattern, pick_dep_version, {'foo': '1.2', 'bar': '2.3'}) + self.assertRaisesRegex(EasyBuildError, error_pattern, pick_dep_version, {'foo': '1.2', 'bar': '2.3'}) error_pattern = r"Unknown value type for version: .* \(1.23\), should be string value" - self.assertErrorRegex(EasyBuildError, error_pattern, pick_dep_version, 1.23) + self.assertRaisesRegex(EasyBuildError, error_pattern, pick_dep_version, 1.23) def test_det_pypkg_version(self): """Test det_pypkg_version function.""" @@ -1149,13 +1149,13 @@ def test_pick_system_specific_value(self): self.assertEqual(pick_system_specific_value('test-desc', option_dict), '1.2.3-other') error_pattern = "Found empty dict as test-desc" - self.assertErrorRegex(EasyBuildError, error_pattern, pick_system_specific_value, 'test-desc', {}) + self.assertRaisesRegex(EasyBuildError, error_pattern, pick_system_specific_value, 'test-desc', {}) error_pattern = r"Unexpected keys in test-desc: foo \(only 'arch=' keys are supported\)" - self.assertErrorRegex(EasyBuildError, error_pattern, pick_system_specific_value, 'test-desc', + self.assertRaisesRegex(EasyBuildError, error_pattern, pick_system_specific_value, 'test-desc', {'foo': '1'}) error_pattern = r"Unexpected keys in test-desc: foo \(only 'arch=' keys are supported\)" - self.assertErrorRegex(EasyBuildError, error_pattern, pick_system_specific_value, 'test-desc', + self.assertRaisesRegex(EasyBuildError, error_pattern, pick_system_specific_value, 'test-desc', {'foo': '1', 'arch=POWER': '2'}) def test_check_os_dependency(self): @@ -1331,7 +1331,7 @@ def test_get_cuda_object_dump_raw(self): # Test case 1: there's no cuobjdump on the path yet error_pattern = r"cuobjdump command not found" - self.assertErrorRegex(EasyBuildError, error_pattern, get_cuda_object_dump_raw, path='mock_cuda_bin') + self.assertRaisesRegex(EasyBuildError, error_pattern, get_cuda_object_dump_raw, path='mock_cuda_bin') # Put a cuobjdump on the path, doesn't matter what. It will be mocked anyway cuobjdump_dir = os.path.join(self.test_prefix, 'cuobjdump_dir') @@ -1364,7 +1364,7 @@ def test_get_cuda_object_dump_raw(self): # Test case 5: call on a file where cuobjdump produces really unexpected output error_pattern = r"Dumping CUDA binary file information for .* via .* failed!" - self.assertErrorRegex(EasyBuildError, error_pattern, get_cuda_object_dump_raw, + self.assertRaisesRegex(EasyBuildError, error_pattern, get_cuda_object_dump_raw, path='mock_non_cuda_sharedlib_unexpected') # Test case 6: call on CUDA shared lib, which only contains PTX code diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index 11f5b5b0e3..d0826aa323 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -340,27 +340,27 @@ def test_toolchain_compiler_env_vars(self): init_config(build_options={'minimal_build_env': 'CC=gcc'}) error_pattern = "Incorrect mapping in --minimal-build-env value: 'CC=gcc'" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, tc.prepare) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.prepare) init_config(build_options={'minimal_build_env': 'foo:bar:baz'}) error_pattern = "Incorrect mapping in --minimal-build-env value: 'foo:bar:baz'" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, tc.prepare) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.prepare) init_config(build_options={'minimal_build_env': 'CC:gcc,foo'}) error_pattern = "Incorrect mapping in --minimal-build-env value: 'foo'" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, tc.prepare) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.prepare) init_config(build_options={'minimal_build_env': 'foo:bar:baz,CC:gcc'}) error_pattern = "Incorrect mapping in --minimal-build-env value: 'foo:bar:baz'" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, tc.prepare) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.prepare) init_config(build_options={'minimal_build_env': 'CC:gcc,'}) error_pattern = "Incorrect mapping in --minimal-build-env value: ''" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, tc.prepare) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.prepare) # for a full toolchain, a more extensive build environment is set up (incl. $CFLAGS & co), # and the specs in --minimal-build-env are ignored @@ -884,7 +884,7 @@ def test_easyconfig_optarch_flags(self): write_file(test_ec, toy_txt + "\ntoolchainopts = {'optarch': 'GCC:-march=sandrybridge;Intel:-xAVX'}") msg = "syntax is not allowed" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, msg, self.eb_main, [test_ec], raise_error=True, do_build=True) + self.assertRaisesRegex(EasyBuildError, msg, self.eb_main, [test_ec], raise_error=True, do_build=True) # check that setting optarch flags work write_file(test_ec, toy_txt + "\ntoolchainopts = {'optarch': '-march=sandybridge'}") @@ -995,7 +995,7 @@ def test_search_path_cpp_headers(self): tc.set_options({"search-path-cpp-headers": "WRONG_MODE"}) with self.mocked_stdout_stderr(): error_pattern = "Unknown value selected for toolchain option search-path-cpp-headers" - self.assertErrorRegex(EasyBuildError, error_pattern, tc.prepare) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.prepare) self.modtool.purge() def test_search_path_linker(self): @@ -1037,7 +1037,7 @@ def test_search_path_linker(self): tc.set_options({"search-path-linker": "WRONG_MODE"}) with self.mocked_stdout_stderr(): error_pattern = "Unknown value selected for toolchain option search-path-linker" - self.assertErrorRegex(EasyBuildError, error_pattern, tc.prepare) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.prepare) self.modtool.purge() def test_cgoolf_toolchain(self): @@ -1709,7 +1709,7 @@ def test_toolchain_verification(self): error_msg = "List of toolchain dependency modules and toolchain definition do not match" tc = self.get_toolchain('foss', version='2018a-brokenFFTW') with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, tc.prepare) + self.assertRaisesRegex(EasyBuildError, error_msg, tc.prepare) self.modtool.purge() # missing optional toolchain elements are fine @@ -1723,7 +1723,7 @@ def test_nosuchtoolchain(self): """Test preparing for a toolchain for which no module is available.""" tc = self.get_toolchain('intel', version='1970.01') with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, "No module found for toolchain", tc.prepare) + self.assertRaisesRegex(EasyBuildError, "No module found for toolchain", tc.prepare) def test_mpi_cmd_prefix(self): """Test mpi_exec_nranks function.""" @@ -1824,11 +1824,11 @@ def test_mpi_cmd_for(self): init_config(build_options={'mpi_cmd_template': "mpiexec -np %(ranks)s -- %(cmd)s", 'silent': True}) error_pattern = \ r"Missing templates in mpi-cmd-template value 'mpiexec -np %\(ranks\)s -- %\(cmd\)s': %\(nr_ranks\)s" - self.assertErrorRegex(EasyBuildError, error_pattern, tc.mpi_cmd_for, 'test', 1) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.mpi_cmd_for, 'test', 1) init_config(build_options={'mpi_cmd_template': "mpirun %(foo)s -np %(nr_ranks)s %(cmd)s", 'silent': True}) error_pattern = "Failed to complete MPI cmd template .* with .*: KeyError 'foo'" - self.assertErrorRegex(EasyBuildError, error_pattern, tc.mpi_cmd_for, 'test', 1) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.mpi_cmd_for, 'test', 1) def test_get_mpi_cmd_template(self): """Test get_mpi_cmd_template function.""" @@ -1846,7 +1846,7 @@ def test_get_mpi_cmd_template(self): # Intel MPI is a special case, also requires MPI version to be known impi = toolchain.INTELMPI error_pattern = "Intel MPI version unknown, can't determine MPI command template!" - self.assertErrorRegex(EasyBuildError, error_pattern, get_mpi_cmd_template, impi, {}) + self.assertRaisesRegex(EasyBuildError, error_pattern, get_mpi_cmd_template, impi, {}) mpi_cmd_tmpl, params = get_mpi_cmd_template(toolchain.INTELMPI, input_params, mpi_version='1.0') self.assertEqual(mpi_cmd_tmpl, "mpirun %(mpdbf)s %(nodesfile)s -np %(nr_ranks)s %(cmd)s") @@ -1951,9 +1951,9 @@ def test_get_software_version(self): self.assertEqual(tc.get_software_version(['toy']), ['1.2.3']) self.assertEqual(tc.get_software_version(['toy', 'foobar']), ['1.2.3', '4.5']) # Non existing modules raise an error - self.assertErrorRegex(EasyBuildError, 'non-existing was not found', + self.assertRaisesRegex(EasyBuildError, 'non-existing was not found', tc.get_software_version, 'non-existing') - self.assertErrorRegex(EasyBuildError, 'non-existing was not found', + self.assertRaisesRegex(EasyBuildError, 'non-existing was not found', tc.get_software_version, ['toy', 'non-existing', 'foobar']) # Can use required=False to avoid self.assertEqual(tc.get_software_version('non-existing', required=False), [None]) @@ -2221,7 +2221,7 @@ def test_standalone_iccifort(self): # and corresponding environment variables are not set error_pattern = "List of toolchain dependency modules and toolchain definition do not match" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, tc.prepare) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.prepare) self.modtool.purge() # make iccifort module set $EBROOT* and $EBVERSION* to pass toolchain verification @@ -2260,7 +2260,7 @@ def test_standalone_iccifortcuda(self): # and corresponding environment variables are not set error_pattern = "List of toolchain dependency modules and toolchain definition do not match" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, tc.prepare) + self.assertRaisesRegex(EasyBuildError, error_pattern, tc.prepare) self.modtool.purge() # Verify that it works loading a module that contains a combined iccifort module @@ -2409,7 +2409,7 @@ def test_compiler_cache(self): if ccache is None: msg = r"ccache binary not found in \$PATH, required by --use-ccache" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, msg, self.eb_main, args, raise_error=True, do_build=True) + self.assertRaisesRegex(EasyBuildError, msg, self.eb_main, args, raise_error=True, do_build=True) # generate shell script to mock ccache/f90cache for cache_tool in ['ccache', 'f90cache']: diff --git a/test/framework/toy_build.py b/test/framework/toy_build.py index 9045494bc7..699afdcba4 100644 --- a/test/framework/toy_build.py +++ b/test/framework/toy_build.py @@ -263,7 +263,7 @@ def test_toy_broken(self): broken_toy_ec_txt += "checksums = ['clearywrongSHA256checksumoflength64-0123456789012345678901234567']" write_file(broken_toy_ec, broken_toy_ec_txt) error_regex = "Checksum verification .* failed" - self.assertErrorRegex(EasyBuildError, error_regex, self.run_test_toy_build_with_output, ec_file=broken_toy_ec, + self.assertRaisesRegex(EasyBuildError, error_regex, self.run_test_toy_build_with_output, ec_file=broken_toy_ec, tmpdir=tmpdir, verify=False, fails=True, verbose=False, raise_error=True) # make sure log file is retained, also for failed build @@ -470,7 +470,7 @@ def test_toy_buggy_easyblock(self): 'verbose': False, } err_regex = r"name 'run_shell_cmd' is not defined" - self.assertErrorRegex(NameError, err_regex, self.run_test_toy_build_with_output, **kwargs) + self.assertRaisesRegex(NameError, err_regex, self.run_test_toy_build_with_output, **kwargs) def test_toy_build_formatv2(self): """Perform a toy build (format v2).""" @@ -895,7 +895,7 @@ def test_toy_group_check(self): self.fail("Unknown module syntax: %s" % get_module_syntax()) write_file(test_ec, read_file(toy_ec) + "\ngroup = ('%s', 'custom message', 'extra item')\n" % group_name) - self.assertErrorRegex(SystemExit, '.*', self.eb_main, args, do_build=True, + self.assertRaisesRegex(SystemExit, '.*', self.eb_main, args, do_build=True, raise_error=True, raise_systemexit=True) def test_allow_system_deps(self): @@ -1484,7 +1484,7 @@ def test_toy_extension_sources(self): error_pattern = r"Checksum verification for extension source bar-0.0-local.tar.gz failed" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, raise_error=True, verbose=False) # test again with correct checksum for bar-0.0.tar.gz, but faulty checksum for patch file @@ -1508,7 +1508,7 @@ def test_toy_extension_sources(self): error_pattern = r"Checksum verification for extension patch bar-0.0_fix-local.patch failed" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, raise_error=True, verbose=False) # test again with correct checksums @@ -1557,7 +1557,7 @@ def test_toy_extension_extract_cmd(self): with self.mocked_stdout_stderr(): # for now, we expect subprocess.CalledProcessError, but eventually 'run' function will # do proper error reporting - self.assertErrorRegex(EasyBuildError, error_pattern, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, raise_error=True, verbose=False) def test_toy_extension_sources_git_config(self): @@ -1783,7 +1783,7 @@ def test_external_dependencies(self): err_msg = r"Unable to locate a modulefile for 'nosuchbuilddep/0.0.0'" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, err_msg, self._test_toy_build, ec_file=toy_ec, + self.assertRaisesRegex(EasyBuildError, err_msg, self._test_toy_build, ec_file=toy_ec, raise_error=True, verbose=False) extraectxt = "\ndependencies += [('nosuchmodule/1.2.3', EXTERNAL_MODULE)]" @@ -1796,7 +1796,7 @@ def test_external_dependencies(self): err_msg = r"Unable to locate a modulefile for 'nosuchmodule/1.2.3'" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, err_msg, self._test_toy_build, ec_file=toy_ec, + self.assertRaisesRegex(EasyBuildError, err_msg, self._test_toy_build, ec_file=toy_ec, raise_error=True, verbose=False) # --dry-run still works when external modules are missing; external modules are treated as if they were there @@ -1825,7 +1825,7 @@ def test_module_only(self): args = common_args + ['--module-only'] err_msg = "Sanity check failed" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, err_msg, self.eb_main, args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, err_msg, self.eb_main, args, do_build=True, raise_error=True) self.assertNotExists(toy_mod) with self.mocked_stdout_stderr(): @@ -1845,7 +1845,7 @@ def test_module_only(self): rebuild_args = args + ['--rebuild'] err_msg = "Sanity check failed" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, err_msg, self.eb_main, rebuild_args, do_build=True, raise_error=True) + self.assertRaisesRegex(EasyBuildError, err_msg, self.eb_main, rebuild_args, do_build=True, raise_error=True) self.assertNotExists(toy_mod) # installing another module under a different naming scheme and using Lua module syntax works fine @@ -1986,7 +1986,7 @@ def test_module_only_extensions(self): error_pattern = 'Sanity check failed: command "ls -l lib/libbarbar.a" failed' for extra_args in (['--module-only'], ['--module-only', '--rebuild']): with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self.eb_main, [test_ec] + extra_args, + self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, [test_ec] + extra_args, do_build=True, raise_error=True) self.assertNotExists(toy_mod) @@ -2574,7 +2574,7 @@ def test_sanity_check_paths_lib64(self): # sanity check fails if lib64 fallback in sanity check is disabled error_pattern = r"Sanity check failed: no file found at 'lib/libtoy.a' or 'lib/libfoo.a' in " with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], raise_error=True, verbose=False) @@ -2589,7 +2589,7 @@ def test_sanity_check_paths_lib64(self): error_pattern = r"Sanity check failed: no \(non-empty\) directory found at 'lib' in " with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], raise_error=True, verbose=False) @@ -2604,7 +2604,7 @@ def test_sanity_check_paths_lib64(self): # sanity check fails if lib64 fallback in sanity check is disabled, since lib64/libtoy.a is not there error_pattern = r"Sanity check failed: no file found at 'lib64/libtoy.a' in " with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], raise_error=True, verbose=False) @@ -2619,7 +2619,7 @@ def test_sanity_check_paths_lib64(self): error_pattern = r"Sanity check failed: no \(non-empty\) directory found at 'lib64' in " with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], raise_error=True, verbose=False) @@ -2795,7 +2795,7 @@ def test_toy_build_enhanced_sanity_check(self): error_pattern = r"Missing mandatory key 'dirs' in sanity_check_paths." with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, extra_args=eb_args, raise_error=True, verbose=False) del sys.modules['easybuild.easyblocks.toy'] @@ -3026,7 +3026,7 @@ def grab_gcc_rpath_wrapper_args(): eb_args = ['--rpath', '--rpath-override-dirs=/opt/eessi/2021.03/lib:eessi/lib'] error_pattern = r"Path used in rpath_override_dirs is not an absolute path: eessi/lib" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, extra_args=eb_args, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, extra_args=eb_args, raise_error=True, verbose=False) # also test use of --rpath-filter @@ -3093,7 +3093,7 @@ def test_toy_filter_rpath_sanity_libs(self): args = rpath_args + ['--rpath-filter=.*libtoy.*'] error_pattern = r"Sanity check failed\: Library libtoy\.so not found" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec, extra_args=args, name='toy-app', raise_error=True, verbose=False) # test use of --filter-rpath-sanity-libs option. In this test, we use --rpath-filter to make sure libtoy.so is @@ -3142,7 +3142,7 @@ def test_toy_filter_rpath_sanity_libs(self): args = ['libtoy-0.0.eb', '--rebuild', '--rpath', '--rpath-filter=.*libtoy.*', '--filter-env-vars=LD_LIBRARY_PATH'] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec, extra_args=args, name='toy-app', raise_error=True, verbose=False) def test_toy_cuda_sanity_check(self): @@ -3361,7 +3361,7 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None, # We expect this to fail, so first check error, then run again to check output error_pattern = r"Files missing CUDA device code: 3." with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda, extra_args=args, raise_error=True) outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=False, verify=False) stdout = self.get_stdout() @@ -3394,7 +3394,7 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None, # We expect this to fail, so first check error, then run again to check output error_pattern = r"Files missing CUDA PTX code: 3" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda, extra_args=args, raise_error=True) outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=False, verify=False) stdout = self.get_stdout() @@ -3428,7 +3428,7 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None, # We expect this to fail, so first check error, then run again to check output error_pattern = r"Files with additional CUDA device code: 3" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda, extra_args=args, raise_error=True) outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=False, verify=False) stdout = self.get_stdout() @@ -4277,14 +4277,14 @@ def test_toy_build_lock(self): error_pattern = "Lock .*_software_toy_0.0.lock already exists, aborting!" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, raise_error=True, verbose=False) + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, raise_error=True, verbose=False) # lock should still be there after it was hit self.assertExists(toy_lock_path) # trying again should give same result with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, raise_error=True, verbose=False) + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, raise_error=True, verbose=False) self.assertExists(toy_lock_path) locks_dir = os.path.join(self.test_prefix, 'locks') @@ -4298,7 +4298,7 @@ def test_toy_build_lock(self): toy_lock_path = os.path.join(locks_dir, toy_lock_fn) mkdir(toy_lock_path, parents=True) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, extra_args=extra_args, raise_error=True, verbose=False) # also test use of --ignore-locks @@ -4367,7 +4367,7 @@ def __exit__(self, type, value, traceback): self.mock_stderr(True) self.mock_stdout(True) error_pattern = r"Maximum wait time for lock /.*toy_0.0.lock to be released reached: [0-9]+ sec >= 3 sec" - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, extra_args=all_args, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, extra_args=all_args, verify=False, raise_error=True, testing=False) stderr, stdout = self.get_stderr(), self.get_stdout() self.mock_stderr(False) @@ -4397,7 +4397,7 @@ def __exit__(self, type, value, traceback): error_pattern = r"Failed to create lock /.*_software_toy_0.0.lock:.* " error_pattern += r"(Read-only file system|Permission denied)" with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_pattern, self._test_toy_build, + self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, extra_args=extra_args, raise_error=True, verbose=False) def test_toy_lock_cleanup_signals(self): @@ -4455,7 +4455,7 @@ def __exit__(self, type, value, traceback): self.mock_stderr(True) self.mock_stdout(True) - self.assertErrorRegex(exc, '.*', self._test_toy_build, ec_file=test_ec, verify=False, + self.assertRaisesRegex(exc, '.*', self._test_toy_build, ec_file=test_ec, verify=False, extra_args=extra_args, raise_error=True, testing=False, raise_systemexit=True) stderr = self.get_stderr().strip() @@ -4594,13 +4594,13 @@ def test_toy_build_sanity_check_linked_libs(self): # we can make the check fail by defining environment variables picked up by the EB_libtoy easyblock os.environ['EB_LIBTOY_BANNED_SHARED_LIBS'] = 'libtoy' with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, + self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, ec_file=libtoy_ec, extra_args=['--module-only'], raise_error=True, verbose=False) del os.environ['EB_LIBTOY_BANNED_SHARED_LIBS'] os.environ['EB_LIBTOY_REQUIRED_SHARED_LIBS'] = 'thisisnottheremostlikely' with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, + self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, ec_file=libtoy_ec, extra_args=['--module-only'], raise_error=True, verbose=False) del os.environ['EB_LIBTOY_REQUIRED_SHARED_LIBS'] @@ -4613,12 +4613,12 @@ def test_toy_build_sanity_check_linked_libs(self): # check specifying banned/required libraries via EasyBuild configuration option args = ['--banned-linked-shared-libs=%s,foobarbaz' % libtoy_fn, '--module-only'] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, + self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, ec_file=libtoy_ec, extra_args=args, raise_error=True, verbose=False) args = ['--required-linked-shared=libs=foobarbazisnotthereforsure', '--module-only'] with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, + self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, ec_file=libtoy_ec, extra_args=args, raise_error=True, verbose=False) # check specifying banned/required libraries via easyconfig parameter @@ -4626,14 +4626,14 @@ def test_toy_build_sanity_check_linked_libs(self): test_ec_txt += "\nbanned_linked_shared_libs = ['toy']" write_file(test_ec, test_ec_txt) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, + self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, ec_file=test_ec, extra_args=['--module-only'], raise_error=True, verbose=False) test_ec_txt = read_file(libtoy_ec) test_ec_txt += "\nrequired_linked_shared_libs = ['thereisnosuchlibraryyoudummy']" write_file(test_ec, test_ec_txt) with self.mocked_stdout_stderr(): - self.assertErrorRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, + self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, ec_file=test_ec, extra_args=['--module-only'], raise_error=True, verbose=False) # check behaviour when alternative subdirectories are specified @@ -4688,7 +4688,7 @@ def test_toy_mod_files(self): args += ['--fail-on-mod-files-gcccore'] pattern = r"Sanity check failed: One or more \.mod files found in .*/toy/0.0-GCCcore-6.2.0: .*/lib/file.mod" - self.assertErrorRegex(EasyBuildError, pattern, self.run_test_toy_build_with_output, ec_file=test_ec, + self.assertRaisesRegex(EasyBuildError, pattern, self.run_test_toy_build_with_output, ec_file=test_ec, extra_args=args, verify=False, fails=True, verbose=False, raise_error=True) test_ec_txt += "\nskip_mod_files_sanity_check = True" @@ -4827,7 +4827,7 @@ def test_toy_failing_test_step(self): write_file(test_ec, test_ec_txt) error_pattern = r"shell command 'false \.\.\.' failed in test step" - self.assertErrorRegex(EasyBuildError, error_pattern, self.run_test_toy_build_with_output, + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_test_toy_build_with_output, ec_file=test_ec, raise_error=True) self.assertNotExists(toy_mod_path) @@ -4843,7 +4843,7 @@ def test_toy_failing_test_step(self): write_file(test_ec, test_ec_txt) error_pattern = r"An error was raised during test step: 'TOY_TEST_FAIL'" - self.assertErrorRegex(EasyBuildError, error_pattern, self.run_test_toy_build_with_output, + self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_test_toy_build_with_output, ec_file=test_ec, raise_error=True) # make sure that option to ignore test failures works diff --git a/test/framework/tweak.py b/test/framework/tweak.py index 71d73dde8a..f70d9557d5 100644 --- a/test/framework/tweak.py +++ b/test/framework/tweak.py @@ -163,7 +163,7 @@ def test_tweak_one_version(self): # check behaviour if target file already exists error_pattern = "File exists, not overwriting it without --force" - self.assertErrorRegex(EasyBuildError, error_pattern, tweak_one, toy_ec, tweaked_toy_ec, {'version': '1.2.3'}) + self.assertRaisesRegex(EasyBuildError, error_pattern, tweak_one, toy_ec, tweaked_toy_ec, {'version': '1.2.3'}) # existing file does get overwritten when --force is used init_config(build_options={'force': True, 'silent': True}) @@ -239,7 +239,7 @@ def test_match_minimum_tc_specs(self): {'name': 'golf', 'version': '2018a'}) # Make sure there's an error when we can't do the mapping error_msg = "No possible mapping from source toolchain spec .*" - self.assertErrorRegex(EasyBuildError, error_msg, match_minimum_tc_specs, + self.assertRaisesRegex(EasyBuildError, error_msg, match_minimum_tc_specs, foss_hierarchy[3], iimpi_hierarchy) def test_dep_tree_of_toolchain(self): @@ -295,7 +295,7 @@ def test_map_toolchain_hierarchies(self): # Expect an error when there is no possible mapping error_msg = "No possible mapping from source toolchain spec .*" - self.assertErrorRegex(EasyBuildError, error_msg, map_toolchain_hierarchies, + self.assertRaisesRegex(EasyBuildError, error_msg, map_toolchain_hierarchies, foss_tc, iimpi_tc, self.modtool) # Test that we correctly include GCCcore binutils when it is there diff --git a/test/framework/type_checking.py b/test/framework/type_checking.py index 7fe44e1ee8..a0708eaeb4 100644 --- a/test/framework/type_checking.py +++ b/test/framework/type_checking.py @@ -281,9 +281,9 @@ def test_convert_value_type(self): self.assertEqual(convert_value_type('-123', int), -123) self.assertEqual(convert_value_type('1.6', float), 1.6) self.assertEqual(convert_value_type('5', float), 5.0) - self.assertErrorRegex(EasyBuildError, "Converting type of .* failed", convert_value_type, '', int) + self.assertRaisesRegex(EasyBuildError, "Converting type of .* failed", convert_value_type, '', int) # 1.6 can't be parsed as an int (yields "invalid literal for int() with base 10" error) - self.assertErrorRegex(EasyBuildError, "Converting type of .* failed", convert_value_type, '1.6', int) + self.assertRaisesRegex(EasyBuildError, "Converting type of .* failed", convert_value_type, '1.6', int) # to list of strings self.assertEqual(convert_value_type('foo', LIST_OF_STRINGS), ['foo']) @@ -306,7 +306,7 @@ def test_convert_value_type(self): # no conversion function available for specific type class Foo(): pass - self.assertErrorRegex(EasyBuildError, "No conversion function available", convert_value_type, None, Foo) + self.assertRaisesRegex(EasyBuildError, "No conversion function available", convert_value_type, None, Foo) def test_to_toolchain_dict(self): """ Test toolchain string to dict conversion """ @@ -330,22 +330,22 @@ def test_to_toolchain_dict(self): self.assertEqual(to_toolchain_dict(tc), tc) # wrong type - self.assertErrorRegex(EasyBuildError, r"Conversion of .* \(type .*\) to toolchain dict is not supported", + self.assertRaisesRegex(EasyBuildError, r"Conversion of .* \(type .*\) to toolchain dict is not supported", to_toolchain_dict, 1000) # wrong number of elements errstr = "Can not convert .* to toolchain dict. Expected 2 or 3 elements" - self.assertErrorRegex(EasyBuildError, errstr, to_toolchain_dict, "intel, 2015, True, a") - self.assertErrorRegex(EasyBuildError, errstr, to_toolchain_dict, "intel") - self.assertErrorRegex(EasyBuildError, errstr, to_toolchain_dict, ['gcc', '4', 'False', '7']) + self.assertRaisesRegex(EasyBuildError, errstr, to_toolchain_dict, "intel, 2015, True, a") + self.assertRaisesRegex(EasyBuildError, errstr, to_toolchain_dict, "intel") + self.assertRaisesRegex(EasyBuildError, errstr, to_toolchain_dict, ['gcc', '4', 'False', '7']) # invalid truth value errstr = "Invalid truth value .*" - self.assertErrorRegex(EasyBuildError, errstr, to_toolchain_dict, "intel, 2015, foo") - self.assertErrorRegex(EasyBuildError, errstr, to_toolchain_dict, ['gcc', '4', '7']) + self.assertRaisesRegex(EasyBuildError, errstr, to_toolchain_dict, "intel, 2015, foo") + self.assertRaisesRegex(EasyBuildError, errstr, to_toolchain_dict, ['gcc', '4', '7']) # missing keys - self.assertErrorRegex(EasyBuildError, "Incorrect set of keys", to_toolchain_dict, {'name': 'intel'}) + self.assertRaisesRegex(EasyBuildError, "Incorrect set of keys", to_toolchain_dict, {'name': 'intel'}) def test_to_dependency(self): """ Test dependency dict to tuple conversion """ @@ -398,14 +398,14 @@ def test_to_dependency(self): # extra keys ruin it foo_dict.update({'extra_key': 'bogus'}) - self.assertErrorRegex(EasyBuildError, r"Found unexpected \(key, value\) pair: .*", to_dependency, foo_dict) + self.assertRaisesRegex(EasyBuildError, r"Found unexpected \(key, value\) pair: .*", to_dependency, foo_dict) # no name/version - self.assertErrorRegex(EasyBuildError, "Can not parse dependency without name and version: .*", + self.assertRaisesRegex(EasyBuildError, "Can not parse dependency without name and version: .*", to_dependency, {'toolchain': 'lib, 1.2.8', 'versionsuffix': 'suff'}) # too many values dep_spec = {'lib': '1.2.8', 'foo': '1.3', 'toolchain': 'lib, 1.2.8', 'versionsuffix': 'suff'} - self.assertErrorRegex(EasyBuildError, r"Found unexpected \(key, value\) pair: .*", to_dependency, dep_spec) + self.assertRaisesRegex(EasyBuildError, r"Found unexpected \(key, value\) pair: .*", to_dependency, dep_spec) def test_to_dependencies(self): """Test to_dependencies function.""" @@ -614,7 +614,7 @@ def test_check_element_types(self): self.assertFalse(check_element_types({'one': 1}, {'two': int})) # errors - self.assertErrorRegex(EasyBuildError, "Don't know how to check element types .*", check_element_types, 1, []) + self.assertRaisesRegex(EasyBuildError, "Don't know how to check element types .*", check_element_types, 1, []) def test_to_list_of_strings(self): """Test to_list_of_strings function.""" @@ -634,9 +634,9 @@ def test_to_list_of_strings(self): # proper error reporting for other values error_pattern = r"Don't know how to convert provided value to a list of strings: " - self.assertErrorRegex(EasyBuildError, error_pattern + '123', to_list_of_strings, 123) - self.assertErrorRegex(EasyBuildError, error_pattern + 'True', to_list_of_strings, True) - self.assertErrorRegex(EasyBuildError, error_pattern, to_list_of_strings, [('foo', 'bar')]) + self.assertRaisesRegex(EasyBuildError, error_pattern + '123', to_list_of_strings, 123) + self.assertRaisesRegex(EasyBuildError, error_pattern + 'True', to_list_of_strings, True) + self.assertRaisesRegex(EasyBuildError, error_pattern, to_list_of_strings, [('foo', 'bar')]) def test_to_list_of_strings_and_tuples(self): """Test to_list_of_strings_and_tuples function.""" @@ -657,12 +657,12 @@ def test_to_list_of_strings_and_tuples(self): # conversion failures error_regex = "Expected value to be a list" - self.assertErrorRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples, 'foo') - self.assertErrorRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples, 1) - self.assertErrorRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples, {'foo': 'bar'}) + self.assertRaisesRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples, 'foo') + self.assertRaisesRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples, 1) + self.assertRaisesRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples, {'foo': 'bar'}) error_msg = "Expected elements to be of type string, tuple or list" - self.assertErrorRegex(EasyBuildError, error_msg, to_list_of_strings_and_tuples, ['foo', 1]) - self.assertErrorRegex(EasyBuildError, error_msg, to_list_of_strings_and_tuples, (1,)) + self.assertRaisesRegex(EasyBuildError, error_msg, to_list_of_strings_and_tuples, ['foo', 1]) + self.assertRaisesRegex(EasyBuildError, error_msg, to_list_of_strings_and_tuples, (1,)) def test_to_list_of_strings_and_tuples_and_dicts(self): """Test to_list_of_strings_and_tuples_and_dicts function.""" @@ -689,13 +689,13 @@ def test_to_list_of_strings_and_tuples_and_dicts(self): # conversion failures error_regex = "Expected value to be a list" - self.assertErrorRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples_and_dicts, 'foo') - self.assertErrorRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples_and_dicts, 1) - self.assertErrorRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples_and_dicts, {'foo': 'bar'}) + self.assertRaisesRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples_and_dicts, 'foo') + self.assertRaisesRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples_and_dicts, 1) + self.assertRaisesRegex(EasyBuildError, error_regex, to_list_of_strings_and_tuples_and_dicts, {'foo': 'bar'}) error_msg = "Expected elements to be of type string, tuple, dict or list" - self.assertErrorRegex(EasyBuildError, error_msg, to_list_of_strings_and_tuples_and_dicts, ['foo', 1]) - self.assertErrorRegex(EasyBuildError, error_msg, to_list_of_strings_and_tuples_and_dicts, (1,)) - self.assertErrorRegex(EasyBuildError, error_msg, to_list_of_strings_and_tuples_and_dicts, (1, {'foo': 'bar'})) + self.assertRaisesRegex(EasyBuildError, error_msg, to_list_of_strings_and_tuples_and_dicts, ['foo', 1]) + self.assertRaisesRegex(EasyBuildError, error_msg, to_list_of_strings_and_tuples_and_dicts, (1,)) + self.assertRaisesRegex(EasyBuildError, error_msg, to_list_of_strings_and_tuples_and_dicts, (1, {'foo': 'bar'})) def test_to_sanity_check_paths_dict(self): """Test to_sanity_check_paths_dict function.""" @@ -720,11 +720,11 @@ def test_to_sanity_check_paths_dict(self): self.assertEqual(to_sanity_check_paths_dict(inp), out) # conversion failures - self.assertErrorRegex(EasyBuildError, "Expected value to be a dict", to_sanity_check_paths_dict, []) + self.assertRaisesRegex(EasyBuildError, "Expected value to be a dict", to_sanity_check_paths_dict, []) error_msg = "Expected value to be a list" - self.assertErrorRegex(EasyBuildError, error_msg, to_sanity_check_paths_dict, {'files': 'foo', 'dirs': []}) + self.assertRaisesRegex(EasyBuildError, error_msg, to_sanity_check_paths_dict, {'files': 'foo', 'dirs': []}) error_msg = "Expected elements to be of type string, tuple/list or dict" - self.assertErrorRegex(EasyBuildError, error_msg, to_sanity_check_paths_dict, {'files': [], 'dirs': [1]}) + self.assertRaisesRegex(EasyBuildError, error_msg, to_sanity_check_paths_dict, {'files': [], 'dirs': [1]}) def test_to_checksums(self): """Test to_checksums function.""" @@ -786,7 +786,7 @@ def test_to_checksums(self): # Error detection wrong_nesting = [('1stchecksum', ('md5', ('md5sum', 'altmd5sum')))] - self.assertErrorRegex(EasyBuildError, 'Unexpected type.*md5', to_checksums, wrong_nesting) + self.assertRaisesRegex(EasyBuildError, 'Unexpected type.*md5', to_checksums, wrong_nesting) correct_nesting = [('1stchecksum', ('md5', 'md5sum'), ('md5', 'altmd5sum'))] self.assertEqual(to_checksums(correct_nesting), correct_nesting) # YEB (YAML EC) doesn't has tuples so it uses lists instead which need to get converted @@ -796,9 +796,9 @@ def test_to_checksums(self): self.assertEqual(to_checksums(correct_nesting_yeb_conv), correct_nesting_yeb_conv) unexpected_set = [('1stchecksum', {'md5', 'md5sum'})] - self.assertErrorRegex(EasyBuildError, 'Unexpected type.*md5', to_checksums, unexpected_set) + self.assertRaisesRegex(EasyBuildError, 'Unexpected type.*md5', to_checksums, unexpected_set) unexpected_dict = [{'src': ('md5sum', {'src': 'shasum'})}] - self.assertErrorRegex(EasyBuildError, 'Unexpected type.*shasum', to_checksums, unexpected_dict) + self.assertRaisesRegex(EasyBuildError, 'Unexpected type.*shasum', to_checksums, unexpected_dict) correct_dict = [{'src': ('md5sum', 'shasum')}] self.assertEqual(to_checksums(correct_dict), correct_dict) correct_dict_1 = [{'src': [['md5', 'md5sum'], ['sha', 'shasum']]}] @@ -812,10 +812,10 @@ def test_to_checksums(self): [{'src': ('md5sum', None)}], [{'src': ['md5sum', None]}], ] - self.assertErrorRegex(EasyBuildError, 'Unexpected None', to_checksums, unexpected_Nones[0]) - self.assertErrorRegex(EasyBuildError, 'Unexpected None', to_checksums, unexpected_Nones[1]) - self.assertErrorRegex(EasyBuildError, 'Unexpected None', to_checksums, unexpected_Nones[2]) - self.assertErrorRegex(EasyBuildError, 'Unexpected None', to_checksums, unexpected_Nones[3]) + self.assertRaisesRegex(EasyBuildError, 'Unexpected None', to_checksums, unexpected_Nones[0]) + self.assertRaisesRegex(EasyBuildError, 'Unexpected None', to_checksums, unexpected_Nones[1]) + self.assertRaisesRegex(EasyBuildError, 'Unexpected None', to_checksums, unexpected_Nones[2]) + self.assertRaisesRegex(EasyBuildError, 'Unexpected None', to_checksums, unexpected_Nones[3]) def test_ensure_iterable_license_specs(self): """Test ensure_iterable_license_specs function.""" @@ -829,15 +829,15 @@ def test_ensure_iterable_license_specs(self): # Test unacceptable inputs error_msg = "Unsupported type .* for easyconfig parameter 'license_file'!" - self.assertErrorRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, 42) - self.assertErrorRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, {'1': 'foo'}) - self.assertErrorRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, [None]) - self.assertErrorRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, [42]) - self.assertErrorRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, [42, 'foo']) - self.assertErrorRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, [['foo']]) - self.assertErrorRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, [(42, 'foo')]) - self.assertErrorRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, (42,)) - self.assertErrorRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, (42, 'foo')) + self.assertRaisesRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, 42) + self.assertRaisesRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, {'1': 'foo'}) + self.assertRaisesRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, [None]) + self.assertRaisesRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, [42]) + self.assertRaisesRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, [42, 'foo']) + self.assertRaisesRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, [['foo']]) + self.assertRaisesRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, [(42, 'foo')]) + self.assertRaisesRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, (42,)) + self.assertRaisesRegex(EasyBuildError, error_msg, ensure_iterable_license_specs, (42, 'foo')) def suite(loader=None): diff --git a/test/framework/utilities.py b/test/framework/utilities.py index eb93170c87..ea06e872e0 100644 --- a/test/framework/utilities.py +++ b/test/framework/utilities.py @@ -82,7 +82,7 @@ class EnhancedTestCase(TestCase): - """Enhanced test case, provides extra functionality (e.g. an assertErrorRegex method).""" + """Enhanced test case, provides extra functionality (e.g. an assertRaisesRegex method).""" def setUp(self): """Set up testcase.""" diff --git a/test/framework/utilities_test.py b/test/framework/utilities_test.py index ce92e1176f..a08cf34df1 100644 --- a/test/framework/utilities_test.py +++ b/test/framework/utilities_test.py @@ -80,7 +80,7 @@ def test_time2str(self): self.assertEqual(tu.time2str(end - start), expected) error_pattern = "Incorrect value type provided to time2str, should be datetime.timedelta: <.* 'int'>" - self.assertErrorRegex(EasyBuildError, error_pattern, tu.time2str, 123) + self.assertRaisesRegex(EasyBuildError, error_pattern, tu.time2str, 123) def test_natural_keys(self): """Test the natural_keys function""" @@ -191,15 +191,15 @@ def test_LooseVersion(self): # Default/None LooseVersion cannot be compared none_version = LooseVersion(None) - self.assertErrorRegex(TypeError, '', lambda c: none_version == LooseVersion('1')) - self.assertErrorRegex(TypeError, '', lambda c: none_version < LooseVersion('')) - self.assertErrorRegex(TypeError, '', lambda c: none_version < LooseVersion('0')) - self.assertErrorRegex(TypeError, '', lambda c: none_version > LooseVersion('')) - self.assertErrorRegex(TypeError, '', lambda c: none_version > LooseVersion('0')) - self.assertErrorRegex(TypeError, '', lambda c: none_version == '1') - self.assertErrorRegex(TypeError, '', lambda c: none_version != '1') - self.assertErrorRegex(TypeError, '', lambda c: none_version < '1') - self.assertErrorRegex(TypeError, '', lambda c: none_version > '1') + self.assertRaisesRegex(TypeError, '', lambda c: none_version == LooseVersion('1')) + self.assertRaisesRegex(TypeError, '', lambda c: none_version < LooseVersion('')) + self.assertRaisesRegex(TypeError, '', lambda c: none_version < LooseVersion('0')) + self.assertRaisesRegex(TypeError, '', lambda c: none_version > LooseVersion('')) + self.assertRaisesRegex(TypeError, '', lambda c: none_version > LooseVersion('0')) + self.assertRaisesRegex(TypeError, '', lambda c: none_version == '1') + self.assertRaisesRegex(TypeError, '', lambda c: none_version != '1') + self.assertRaisesRegex(TypeError, '', lambda c: none_version < '1') + self.assertRaisesRegex(TypeError, '', lambda c: none_version > '1') # You can check for None .version or .vstring self.assertIsNone(none_version.version) self.assertIsNone(none_version.vstring) @@ -222,12 +222,12 @@ def test_unique_ordered_extend(self): self.assertEqual(base, base_orig) error_pattern = "given affix list is a string" - self.assertErrorRegex(EasyBuildError, error_pattern, tu.unique_ordered_extend, base, "apple") + self.assertRaisesRegex(EasyBuildError, error_pattern, tu.unique_ordered_extend, base, "apple") error_pattern = "given affix list is not iterable" - self.assertErrorRegex(EasyBuildError, error_pattern, tu.unique_ordered_extend, base, 0) + self.assertRaisesRegex(EasyBuildError, error_pattern, tu.unique_ordered_extend, base, 0) base = "potato" error_pattern = "given base cannot be extended" - self.assertErrorRegex(EasyBuildError, error_pattern, tu.unique_ordered_extend, base, reference) + self.assertRaisesRegex(EasyBuildError, error_pattern, tu.unique_ordered_extend, base, reference) def suite(loader=None): diff --git a/test/framework/variables.py b/test/framework/variables.py index 4ca582e626..37f35745dd 100644 --- a/test/framework/variables.py +++ b/test/framework/variables.py @@ -74,7 +74,7 @@ class TestVariables(Variables): v.join('BAR2', 'FOO', 'BARINT') self.assertEqual(str(v['BAR2']), "0,1,2 0") - self.assertErrorRegex(Exception, 'not found in self', v.join, 'BAZ', 'DOESNOTEXIST') + self.assertRaisesRegex(Exception, 'not found in self', v.join, 'BAZ', 'DOESNOTEXIST') cmd = CommandFlagList(["gcc", "bar", "baz"]) self.assertEqual(str(cmd), "gcc -bar -baz") From 513c540c2647c471cc39f3e666c79500a64f4cde Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 29 Sep 2025 09:18:47 +0200 Subject: [PATCH 2/5] Fix indent --- test/framework/build_log.py | 4 +- test/framework/containers.py | 16 +++---- test/framework/easyblock.py | 4 +- test/framework/easyconfig.py | 32 ++++++------- test/framework/ebconfigobj.py | 6 +-- test/framework/filetools.py | 29 ++++++------ test/framework/github.py | 4 +- test/framework/module_generator.py | 12 ++--- test/framework/options.py | 11 ++--- test/framework/robot.py | 2 +- test/framework/run.py | 14 +++--- test/framework/systemtools.py | 6 +-- test/framework/toolchain.py | 4 +- test/framework/toy_build.py | 72 +++++++++++++++--------------- test/framework/tweak.py | 4 +- test/framework/type_checking.py | 4 +- 16 files changed, 113 insertions(+), 111 deletions(-) diff --git a/test/framework/build_log.py b/test/framework/build_log.py index 565ce012fe..7fd595f704 100644 --- a/test/framework/build_log.py +++ b/test/framework/build_log.py @@ -151,7 +151,7 @@ def test_easybuildlog(self): self.assertRaisesRegex(EasyBuildError, r"DEPRECATED \(since .*: kaput", log.deprecated, "kaput", older_ver) self.assertRaisesRegex(EasyBuildError, r"DEPRECATED \(since .*: 2>1", log.deprecated, "2>1", '2.0', '1.0') self.assertRaisesRegex(EasyBuildError, r"DEPRECATED \(since .*: 2>1", log.deprecated, "2>1", '2.0', - max_ver='1.0') + max_ver='1.0') # wipe log so we can reuse it write_file(tmplog, '') @@ -435,7 +435,7 @@ def test_init_logging(self): def test_raise_nosupport(self): self.assertRaisesRegex(EasyBuildError, 'NO LONGER SUPPORTED since v42: foobar;', - raise_nosupport, 'foobar', 42) + raise_nosupport, 'foobar', 42) def suite(loader=None): diff --git a/test/framework/containers.py b/test/framework/containers.py index ed61d2d991..37efd01135 100644 --- a/test/framework/containers.py +++ b/test/framework/containers.py @@ -381,10 +381,10 @@ def test_end2end_dockerfile(self): error_pattern = "Unsupported container config 'not-supported'" self.assertRaisesRegex(EasyBuildError, - error_pattern, - self.run_main, - base_args + ['--container-config=not-supported'], - raise_error=True) + error_pattern, + self.run_main, + base_args + ['--container-config=not-supported'], + raise_error=True) for cont_base in ['ubuntu:20.04', 'centos:7']: stdout, stderr = self.run_main(base_args + ['--container-config=%s' % cont_base]) @@ -398,10 +398,10 @@ def test_end2end_dockerfile(self): error_pattern = "Container recipe at %s/containers/Dockerfile.toy-0.0 already exists, " \ "not overwriting it without --force" % self.test_prefix self.assertRaisesRegex(EasyBuildError, - error_pattern, - self.run_main, - base_args + ['--container-config=centos:7'], - raise_error=True) + error_pattern, + self.run_main, + base_args + ['--container-config=centos:7'], + raise_error=True) remove_file(os.path.join(self.test_prefix, 'containers', 'Dockerfile.toy-0.0')) diff --git a/test/framework/easyblock.py b/test/framework/easyblock.py index 1c56ffeb4f..de06c8d8ed 100644 --- a/test/framework/easyblock.py +++ b/test/framework/easyblock.py @@ -1972,7 +1972,7 @@ def test_fetch_sources(self): eb.src = [] error_msg = r"DEPRECATED \(since v4.0\).*Using a 2-element list/tuple.*" self.assertRaisesRegex(EasyBuildError, error_msg, eb.fetch_sources, - [('toy-0.0_gzip.patch.gz', "gunzip %s")], checksums=[]) + [('toy-0.0_gzip.patch.gz', "gunzip %s")], checksums=[]) # unknown dict keys in sources are reported sources[0]['nosuchkey'] = 'foobar' @@ -2212,7 +2212,7 @@ def test_obtain_file(self): error_pattern = "Couldn't find file 'toy-0.0.tar.gz' anywhere, and downloading it is disabled" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, eb.obtain_file, - toy_tarball, urls=urls, alt_location='alt_toy', no_download=True) + toy_tarball, urls=urls, alt_location='alt_toy', no_download=True) # 'downloading' a file to (first) alternative sourcepath works with self.mocked_stdout_stderr(): diff --git a/test/framework/easyconfig.py b/test/framework/easyconfig.py index aa10dc9ace..2e93a4b5a9 100644 --- a/test/framework/easyconfig.py +++ b/test/framework/easyconfig.py @@ -444,7 +444,7 @@ def test_extra_options(self): # test extra mandatory parameters extra_vars.update({'mandatory_key': ['default', 'another mandatory key', easyconfig.MANDATORY]}) self.assertRaisesRegex(EasyBuildError, r"mandatory parameters not provided", - EasyConfig, self.eb_file, extra_options=extra_vars) + EasyConfig, self.eb_file, extra_options=extra_vars) self.contents += '\nmandatory_key = "value"' self.prep() @@ -1719,7 +1719,7 @@ def test_build_options(self): self.prep() eb = EasyConfig(self.eb_file, validate=False) self.assertRaisesRegex(EasyBuildError, "Build option lists for iterated build should have same length", - eb.validate) + eb.validate) # list with a single element is OK, is treated as a string installopts = ['FOO=foo'] @@ -1930,7 +1930,7 @@ def test_filter_deps(self): write_file(ec_file, ec_txt) self.assertRaisesRegex(EasyBuildError, "Failed to determine minimal toolchain for dep .*", - EasyConfig, ec_file, validate=False) + EasyConfig, ec_file, validate=False) build_options.update({'filter_deps': ['deptobefiltered']}) init_config(build_options=build_options) @@ -3863,18 +3863,18 @@ def test_categorize_files_by_type(self): tmpdir = tempfile.mkdtemp() non_existing = os.path.join(tmpdir, 'does_not_exist.patch') self.assertRaisesRegex(EasyBuildError, - "File %s does not exist" % non_existing, - categorize_files_by_type, [non_existing]) + "File %s does not exist" % non_existing, + categorize_files_by_type, [non_existing]) patch_dir = os.path.join(tmpdir, 'folder.patch') os.mkdir(patch_dir) self.assertRaisesRegex(EasyBuildError, - "File %s is expected to be a regular file" % patch_dir, - categorize_files_by_type, [patch_dir]) + "File %s is expected to be a regular file" % patch_dir, + categorize_files_by_type, [patch_dir]) invalid_patch = os.path.join(tmpdir, 'invalid.patch') copy_file(gzip_ec, invalid_patch) self.assertRaisesRegex(EasyBuildError, - "%s is not detected as a valid patch file" % invalid_patch, - categorize_files_by_type, [invalid_patch]) + "%s is not detected as a valid patch file" % invalid_patch, + categorize_files_by_type, [invalid_patch]) def test_resolve_template(self): """Test resolve_template function.""" @@ -3949,11 +3949,11 @@ def test_det_subtoolchain_version(self): cands = [{'name': 'golfc', 'version': '2018a'}, {'name': 'golfc', 'version': '2018.01'}] self.assertRaisesRegex(EasyBuildError, - "No version found for subtoolchain gompic in dependencies of fosscuda", - det_subtoolchain_version, current_tc, 'gompic', optional_toolchains, cands) + "No version found for subtoolchain gompic in dependencies of fosscuda", + det_subtoolchain_version, current_tc, 'gompic', optional_toolchains, cands) self.assertRaisesRegex(EasyBuildError, - "Multiple versions of golfc found in dependencies of toolchain fosscuda: 2018.01, 2018a", - det_subtoolchain_version, current_tc, 'golfc', optional_toolchains, cands) + "Multiple versions of golfc found in dependencies of toolchain fosscuda: 2018.01, 2018a", + det_subtoolchain_version, current_tc, 'golfc', optional_toolchains, cands) # missing candidate for golfc, ok for optional cands = [{'name': 'gompic', 'version': '2018a'}] @@ -4723,11 +4723,11 @@ def __init__(self, values): error_msg = 'exts_filter should be a list or tuple' self.assertRaisesRegex(EasyBuildError, error_msg, resolve_exts_filter_template, - '[ 1 == 1 ]', {}) + '[ 1 == 1 ]', {}) self.assertRaisesRegex(EasyBuildError, error_msg, resolve_exts_filter_template, - ['[ 1 == 1 ]'], {}) + ['[ 1 == 1 ]'], {}) self.assertRaisesRegex(EasyBuildError, error_msg, resolve_exts_filter_template, - ['[ 1 == 1 ]', 'true', 'false'], {}) + ['[ 1 == 1 ]', 'true', 'false'], {}) test_cases = [ # Minimal case: just name diff --git a/test/framework/ebconfigobj.py b/test/framework/ebconfigobj.py index 1d4089fea0..213cc6775d 100644 --- a/test/framework/ebconfigobj.py +++ b/test/framework/ebconfigobj.py @@ -86,8 +86,8 @@ def test_ebconfigobj_unusable_default(self): configobj_txt = ['[SUPPORTED]', val] co = ConfigObj(configobj_txt) self.assertRaisesRegex(EasyBuildError, - r'First\s+(toolchain|version)\s.*?\scan\'t\s+be\s+used\s+as\s+default', - EBConfigObj, co) + r'First\s+(toolchain|version)\s.*?\scan\'t\s+be\s+used\s+as\s+default', + EBConfigObj, co) def test_squash_simple(self): """Test toolchain filter""" @@ -161,7 +161,7 @@ def test_squash_invalid(self): co = ConfigObj(txt) cov = EBConfigObj(co) self.assertRaisesRegex(EasyBuildError, r'conflict', cov.squash, - default_version, tc_first['name'], tc_first['version']) + default_version, tc_first['name'], tc_first['version']) def test_toolchain_squash_nested(self): """Test toolchain filter on nested sections""" diff --git a/test/framework/filetools.py b/test/framework/filetools.py index 7fc6bb7bae..dbb9ce294b 100644 --- a/test/framework/filetools.py +++ b/test/framework/filetools.py @@ -190,9 +190,9 @@ def test_find_glob_pattern(self): os.path.join(tmpdir, 'python3.5m', 'include')) self.assertEqual(ft.find_glob_pattern(os.path.join(tmpdir, 'python3.6*'), False), None) self.assertRaisesRegex(EasyBuildError, "Was expecting exactly", ft.find_glob_pattern, - os.path.join(tmpdir, 'python3.6*')) + os.path.join(tmpdir, 'python3.6*')) self.assertRaisesRegex(EasyBuildError, "Was expecting exactly", ft.find_glob_pattern, - os.path.join(tmpdir, 'python*')) + os.path.join(tmpdir, 'python*')) def test_encode_class_name(self): """Test encoding of class names.""" @@ -360,8 +360,8 @@ def test_checksums(self): self.assertTrue(ft.verify_checksum(fp, {os.path.basename(fp): None})) faulty_dict = {'wrong-name': known_checksums['sha256']} self.assertRaisesRegex(EasyBuildError, - "Missing checksum for " + os.path.basename(fp) + " in .*wrong-name.*", - ft.verify_checksum, fp, faulty_dict) + "Missing checksum for " + os.path.basename(fp) + " in .*wrong-name.*", + ft.verify_checksum, fp, faulty_dict) # check whether missing checksums are enforced build_options = { @@ -374,7 +374,7 @@ def test_checksums(self): # Test dictionary-type checksums self.assertRaisesRegex(EasyBuildError, "Missing checksum for", ft.verify_checksum, - fp, {os.path.basename(fp): None}) + fp, {os.path.basename(fp): None}) for checksum in [known_checksums[x] for x in ['sha256']]: dict_checksum = {os.path.basename(fp): checksum, 'foo': 'baa'} self.assertTrue(ft.verify_checksum(fp, dict_checksum)) @@ -881,9 +881,9 @@ def test_symlink_resolve_path(self): test_file2 = os.path.join(link_dir, 'test2.txt') ft.write_file(test_file, "test123") self.assertRaisesRegex(EasyBuildError, - "Trying to symlink %s to %s, but the symlink already exists and points to %s." % - (test_file2, link, test_file), - ft.symlink, test_file2, link) + "Trying to symlink %s to %s, but the symlink already exists and points to %s." % + (test_file2, link, test_file), + ft.symlink, test_file2, link) # test resolve_path self.assertEqual(test_dir, ft.resolve_path(link_dir)) @@ -1436,7 +1436,8 @@ def test_adjust_permissions(self): err_msg = "Failed to chmod/chown several paths.*No such file or directory" self.assertRaisesRegex(EasyBuildError, err_msg, ft.adjust_permissions, nosuchdir, stat.S_IWOTH) nosuchfile = os.path.join(self.test_prefix, 'nosuchfile') - self.assertRaisesRegex(EasyBuildError, err_msg, ft.adjust_permissions, nosuchfile, stat.S_IWUSR, recursive=False) + self.assertRaisesRegex(EasyBuildError, err_msg, ft.adjust_permissions, + nosuchfile, stat.S_IWUSR, recursive=False) # try using adjust_permissions on a file not owned by current user, # using permissions that are actually already correct; @@ -1575,11 +1576,11 @@ def test_apply_regex_substitutions(self): error_pat = "Nothing found to replace 'Not there' in %s" % testfile # Error self.assertRaisesRegex(EasyBuildError, error_pat, ft.apply_regex_substitutions, testfile, regex_subs_no_match, - on_missing_match=ERROR) + on_missing_match=ERROR) # First matches, but 2nd not regex_subs_part_match = [regex_subs[0], ('Not there', 'Not used')] self.assertRaisesRegex(EasyBuildError, error_pat, ft.apply_regex_substitutions, testfile, regex_subs_part_match, - on_missing_match=ERROR, match_all=True) + on_missing_match=ERROR, match_all=True) # First matched so OK with match_all ft.apply_regex_substitutions(testfile, regex_subs_part_match, on_missing_match=ERROR, match_all=False) @@ -1846,9 +1847,9 @@ def test_create_patch_info(self): self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, {'name': 'foo.txt'}) self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, {'name': 'foo.txt', 'random': 'key'}) self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, - {'name': 'foo.txt', 'copy': 'subdir', 'sourcepath': 'subdir'}) + {'name': 'foo.txt', 'copy': 'subdir', 'sourcepath': 'subdir'}) self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, - {'name': 'foo.txt', 'copy': 'subdir', 'level': 1}) + {'name': 'foo.txt', 'copy': 'subdir', 'level': 1}) self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, ('foo.patch', [1, 2])) error_msg = "Unknown patch specification" self.assertRaisesRegex(EasyBuildError, error_msg, ft.create_patch_info, ('foo.patch', 1, 'subdir')) @@ -3974,7 +3975,7 @@ def test_create_unused_dir(self): ft.adjust_permissions(readonly_dir, stat.S_IREAD | stat.S_IEXEC, relative=False) try: self.assertRaisesRegex(EasyBuildError, 'Failed to create directory', - ft.create_unused_dir, readonly_dir, 'new_folder') + ft.create_unused_dir, readonly_dir, 'new_folder') finally: ft.adjust_permissions(readonly_dir, old_perms, relative=False) diff --git a/test/framework/github.py b/test/framework/github.py index 240c0369d6..1f4a33d1b9 100644 --- a/test/framework/github.py +++ b/test/framework/github.py @@ -656,10 +656,10 @@ def test_github_download_repo_commit(self): # short commit doesn't work, must be full commit ID self.assertRaisesRegex(EasyBuildError, "Specified commit SHA bdcc586 .* is not valid", gh.download_repo, - path=self.test_prefix, commit='bdcc586') + path=self.test_prefix, commit='bdcc586') self.assertRaisesRegex(EasyBuildError, "Failed to download tarball .* commit", gh.download_repo, - path=self.test_prefix, commit='0000000000000000000000000000000000000000') + path=self.test_prefix, commit='0000000000000000000000000000000000000000') def test_install_github_token(self): """Test for install_github_token function.""" diff --git a/test/framework/module_generator.py b/test/framework/module_generator.py index eb52ef7f5f..662788faf0 100644 --- a/test/framework/module_generator.py +++ b/test/framework/module_generator.py @@ -316,7 +316,7 @@ def test_load(self): expected = "depends-on statements in generated module are not supported by modules tool" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, expected, - self.modgen.load_module, "mod_name", depends_on=True) + self.modgen.load_module, "mod_name", depends_on=True) else: # default: guarded module load (which implies no recursive unloading) expected = '\n'.join([ @@ -362,7 +362,7 @@ def test_load(self): expected = "depends_on statements in generated module are not supported by modules tool" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, expected, - self.modgen.load_module, "mod_name", depends_on=True) + self.modgen.load_module, "mod_name", depends_on=True) def test_load_multi_deps(self): """Test generated load statement when multi_deps is involved.""" @@ -775,8 +775,8 @@ def append_paths(*args, **kwargs): self.assertEqual('append_path("key", "1234@example.com")\n', res) self.assertRaisesRegex(EasyBuildError, "Absolute path %s/foo passed to update_paths " - "which only expects relative paths." % self.modgen.app.installdir, - append_paths, "key2", ["bar", "%s/foo" % self.modgen.app.installdir]) + "which only expects relative paths." % self.modgen.app.installdir, + append_paths, "key2", ["bar", "%s/foo" % self.modgen.app.installdir]) # check for warning that is printed when same path is added multiple times with self.modgen.start_module_creation(): @@ -909,8 +909,8 @@ def prepend_paths(*args, **kwargs): self.assertEqual('prepend_path("key", "1234@example.com")\n', res) self.assertRaisesRegex(EasyBuildError, "Absolute path %s/foo passed to update_paths " - "which only expects relative paths." % self.modgen.app.installdir, - prepend_paths, "key2", ["bar", "%s/foo" % self.modgen.app.installdir]) + "which only expects relative paths." % self.modgen.app.installdir, + prepend_paths, "key2", ["bar", "%s/foo" % self.modgen.app.installdir]) # check for warning that is printed when same path is added multiple times with self.modgen.start_module_creation(): diff --git a/test/framework/options.py b/test/framework/options.py index 276beae30c..e168b0bb06 100644 --- a/test/framework/options.py +++ b/test/framework/options.py @@ -1206,7 +1206,7 @@ def test_search(self): # 4 corresponds with MISSING_EASYCONFIG in EasyBuildExit (see easybuild/tools/build_log.py) args = ['--search', 'nosuchsoftware-1.2.3.4.5'] self.assertRaisesRegex(SystemExit, 'MISSING_EASYCONFIG|4', self.eb_main, args, - testing=False, raise_error=True, raise_systemexit=True) + testing=False, raise_error=True, raise_systemexit=True) def test_ignore_index(self): """ @@ -2764,7 +2764,7 @@ def test_try(self): allargs = args + [extra_arg] with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, "problems validating the options", - self.eb_main, allargs, raise_error=True) + self.eb_main, allargs, raise_error=True) # no --try used, so no tweaked easyconfig files are generated allargs = args + ['--software-version=1.2.3', '--toolchain=gompi,2018a'] @@ -4109,7 +4109,7 @@ def test_use_included_module_naming_scheme(self): error_regex = "Selected module naming scheme \'AnotherTestIncludedMNS\' is unknown" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_regex, self.eb_main, args, logfile=dummylogfn, - raise_error=True, raise_systemexit=True) + raise_error=True, raise_systemexit=True) args.append('--include-module-naming-schemes=%s/*.py' % self.test_prefix) with self.mocked_stdout_stderr(): @@ -4699,7 +4699,8 @@ def test_github_new_update_pr(self): args_new_pr = args + ['--pr-commit-msg=just a test'] error_msg = r"PR commit msg \(--pr-commit-msg\) should not be used" with self.mocked_stdout_stderr(): - self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, args_new_pr, raise_error=True, testing=False) + self.assertRaisesRegex(EasyBuildError, error_msg, self.eb_main, + args_new_pr, raise_error=True, testing=False) # But commit message can still be specified when using --force args_new_pr.append('--force') @@ -6033,7 +6034,7 @@ def test_verify_easyconfig_filenames(self): error_pattern += r"toolchain name, version: 'system', 'system'\)" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, args, logfile=dummylogfn, - raise_error=True) + raise_error=True) write_file(self.logfile, '') diff --git a/test/framework/robot.py b/test/framework/robot.py index d2fb2de28d..0f625fca53 100644 --- a/test/framework/robot.py +++ b/test/framework/robot.py @@ -1537,7 +1537,7 @@ def test_robot_archived_easyconfigs(self): write_file(test_ec, test_ectxt) ecs, _ = parse_easyconfigs([(test_ec, False)]) self.assertRaisesRegex(EasyBuildError, "Missing dependencies", resolve_dependencies, - ecs, self.modtool, retain_all_deps=True) + ecs, self.modtool, retain_all_deps=True) # --consider-archived-easyconfigs must be used to let robot pick up archived easyconfigs init_config(build_options={ diff --git a/test/framework/run.py b/test/framework/run.py index 269d23cd94..ca7130df7b 100644 --- a/test/framework/run.py +++ b/test/framework/run.py @@ -322,7 +322,7 @@ def handler(signum, _): error_pattern = "No matching questions found for current command output" self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, perl_script, - hidden=True, qa_patterns=[('bleh', 'blah')], qa_timeout=1) + hidden=True, qa_patterns=[('bleh', 'blah')], qa_timeout=1) finally: # cleanup: disable the alarm + reset signal handler for SIGALRM signal.signal(signal.SIGALRM, orig_sigalrm_handler) @@ -1134,7 +1134,7 @@ def test_run_shell_cmd_qa(self): # fails because non-question is encountered error_pattern = "No matching questions found for current command output, giving up after 1 seconds!" self.assertRaisesRegex(EasyBuildError, error_pattern, run_shell_cmd, cmd, qa_patterns=qa, qa_timeout=1, - hidden=True) + hidden=True) qa_wait_patterns = ["not-a-question-but-a-statement"] with self.mocked_stdout_stderr(): @@ -1402,7 +1402,7 @@ def test_run_shell_cmd_qa_answers(self): with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, "Unknown type of answers encountered", run_shell_cmd, cmd, - qa_patterns=[('question', 1)]) + qa_patterns=[('question', 1)]) # test cycling of answers cmd = cmd * 2 @@ -1625,7 +1625,7 @@ def test_run_cmd_list(self): cmd = ['/bin/sh', '-c', "echo hello"] with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, "When passing cmd as a list then `shell` must be set explictely!", - run_cmd, cmd) + run_cmd, cmd) (out, ec) = run_cmd(cmd, shell=False) self.assertEqual(out, "hello\n") # no reason echo hello could fail @@ -1988,15 +1988,15 @@ def test_check_log_for_errors(self): # String promoted to list with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, - r"\b(error|crashed)\b") + r"\b(error|crashed)\b") # List of string(s) with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, - [r"\b(error|crashed)\b"]) + [r"\b(error|crashed)\b"]) # List of tuple(s) with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, expected_msg, check_log_for_errors, input_text, - [(r"\b(error|crashed)\b", ERROR)]) + [(r"\b(error|crashed)\b", ERROR)]) expected_msg = "Found 2 potential error(s) in command output:\n"\ "\terror found\n"\ diff --git a/test/framework/systemtools.py b/test/framework/systemtools.py index 66b92c70c2..e6fbaa9d12 100644 --- a/test/framework/systemtools.py +++ b/test/framework/systemtools.py @@ -1153,10 +1153,10 @@ def test_pick_system_specific_value(self): error_pattern = r"Unexpected keys in test-desc: foo \(only 'arch=' keys are supported\)" self.assertRaisesRegex(EasyBuildError, error_pattern, pick_system_specific_value, 'test-desc', - {'foo': '1'}) + {'foo': '1'}) error_pattern = r"Unexpected keys in test-desc: foo \(only 'arch=' keys are supported\)" self.assertRaisesRegex(EasyBuildError, error_pattern, pick_system_specific_value, 'test-desc', - {'foo': '1', 'arch=POWER': '2'}) + {'foo': '1', 'arch=POWER': '2'}) def test_check_os_dependency(self): """Test check_os_dependency.""" @@ -1365,7 +1365,7 @@ def test_get_cuda_object_dump_raw(self): # Test case 5: call on a file where cuobjdump produces really unexpected output error_pattern = r"Dumping CUDA binary file information for .* via .* failed!" self.assertRaisesRegex(EasyBuildError, error_pattern, get_cuda_object_dump_raw, - path='mock_non_cuda_sharedlib_unexpected') + path='mock_non_cuda_sharedlib_unexpected') # Test case 6: call on CUDA shared lib, which only contains PTX code self.assertEqual(get_cuda_object_dump_raw('mock_cuda_sharedlib'), CUOBJDUMP_PTX_ONLY) diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index d0826aa323..bbaa264d97 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -1952,9 +1952,9 @@ def test_get_software_version(self): self.assertEqual(tc.get_software_version(['toy', 'foobar']), ['1.2.3', '4.5']) # Non existing modules raise an error self.assertRaisesRegex(EasyBuildError, 'non-existing was not found', - tc.get_software_version, 'non-existing') + tc.get_software_version, 'non-existing') self.assertRaisesRegex(EasyBuildError, 'non-existing was not found', - tc.get_software_version, ['toy', 'non-existing', 'foobar']) + tc.get_software_version, ['toy', 'non-existing', 'foobar']) # Can use required=False to avoid self.assertEqual(tc.get_software_version('non-existing', required=False), [None]) self.assertEqual(tc.get_software_version(['toy', 'non-existing', 'foobar'], required=False), diff --git a/test/framework/toy_build.py b/test/framework/toy_build.py index 699afdcba4..7b64f25b46 100644 --- a/test/framework/toy_build.py +++ b/test/framework/toy_build.py @@ -264,7 +264,7 @@ def test_toy_broken(self): write_file(broken_toy_ec, broken_toy_ec_txt) error_regex = "Checksum verification .* failed" self.assertRaisesRegex(EasyBuildError, error_regex, self.run_test_toy_build_with_output, ec_file=broken_toy_ec, - tmpdir=tmpdir, verify=False, fails=True, verbose=False, raise_error=True) + tmpdir=tmpdir, verify=False, fails=True, verbose=False, raise_error=True) # make sure log file is retained, also for failed build log_path_pattern = os.path.join(tmpdir, 'eb-*', 'easybuild-toy-0.0*.log') @@ -896,7 +896,7 @@ def test_toy_group_check(self): write_file(test_ec, read_file(toy_ec) + "\ngroup = ('%s', 'custom message', 'extra item')\n" % group_name) self.assertRaisesRegex(SystemExit, '.*', self.eb_main, args, do_build=True, - raise_error=True, raise_systemexit=True) + raise_error=True, raise_systemexit=True) def test_allow_system_deps(self): """Test allow_system_deps easyconfig parameter.""" @@ -1485,7 +1485,7 @@ def test_toy_extension_sources(self): error_pattern = r"Checksum verification for extension source bar-0.0-local.tar.gz failed" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, - raise_error=True, verbose=False) + raise_error=True, verbose=False) # test again with correct checksum for bar-0.0.tar.gz, but faulty checksum for patch file test_ec_txt = '\n'.join([ @@ -1509,7 +1509,7 @@ def test_toy_extension_sources(self): error_pattern = r"Checksum verification for extension patch bar-0.0_fix-local.patch failed" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, - raise_error=True, verbose=False) + raise_error=True, verbose=False) # test again with correct checksums test_ec_txt = '\n'.join([ @@ -1558,7 +1558,7 @@ def test_toy_extension_extract_cmd(self): # for now, we expect subprocess.CalledProcessError, but eventually 'run' function will # do proper error reporting self.assertRaisesRegex(EasyBuildError, error_pattern, - self._test_toy_build, ec_file=test_ec, raise_error=True, verbose=False) + self._test_toy_build, ec_file=test_ec, raise_error=True, verbose=False) def test_toy_extension_sources_git_config(self): """Test install toy that includes extensions with 'sources' spec including 'git_config'.""" @@ -1784,7 +1784,7 @@ def test_external_dependencies(self): with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, err_msg, self._test_toy_build, ec_file=toy_ec, - raise_error=True, verbose=False) + raise_error=True, verbose=False) extraectxt = "\ndependencies += [('nosuchmodule/1.2.3', EXTERNAL_MODULE)]" extraectxt += "\nversionsuffix = '-external-deps-broken2'" @@ -1797,7 +1797,7 @@ def test_external_dependencies(self): with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, err_msg, self._test_toy_build, ec_file=toy_ec, - raise_error=True, verbose=False) + raise_error=True, verbose=False) # --dry-run still works when external modules are missing; external modules are treated as if they were there with self.mocked_stdout_stderr(): @@ -1987,7 +1987,7 @@ def test_module_only_extensions(self): for extra_args in (['--module-only'], ['--module-only', '--rebuild']): with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self.eb_main, [test_ec] + extra_args, - do_build=True, raise_error=True) + do_build=True, raise_error=True) self.assertNotExists(toy_mod) # failing sanity check for barbar extension is ignored when using --module-only --skip-extensions @@ -2575,8 +2575,8 @@ def test_sanity_check_paths_lib64(self): error_pattern = r"Sanity check failed: no file found at 'lib/libtoy.a' or 'lib/libfoo.a' in " with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, - extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], - raise_error=True, verbose=False) + extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], + raise_error=True, verbose=False) # all is fine is lib64 fallback check is enabled (which it is by default) with self.mocked_stdout_stderr(): @@ -2590,8 +2590,8 @@ def test_sanity_check_paths_lib64(self): error_pattern = r"Sanity check failed: no \(non-empty\) directory found at 'lib' in " with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, - extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], - raise_error=True, verbose=False) + extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], + raise_error=True, verbose=False) with self.mocked_stdout_stderr(): self._test_toy_build(ec_file=test_ec, extra_args=['--disable-lib64-lib-symlink'], raise_error=True) @@ -2605,8 +2605,8 @@ def test_sanity_check_paths_lib64(self): error_pattern = r"Sanity check failed: no file found at 'lib64/libtoy.a' in " with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, - extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], - raise_error=True, verbose=False) + extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], + raise_error=True, verbose=False) # sanity check passes when lib64 fallback is enabled (by default), since lib/libtoy.a is also considered with self.mocked_stdout_stderr(): @@ -2620,8 +2620,8 @@ def test_sanity_check_paths_lib64(self): error_pattern = r"Sanity check failed: no \(non-empty\) directory found at 'lib64' in " with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, - extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], - raise_error=True, verbose=False) + extra_args=['--disable-lib64-fallback-sanity-check', '--disable-lib64-lib-symlink'], + raise_error=True, verbose=False) with self.mocked_stdout_stderr(): self._test_toy_build(ec_file=test_ec, extra_args=['--disable-lib64-lib-symlink'], raise_error=True) @@ -2796,7 +2796,7 @@ def test_toy_build_enhanced_sanity_check(self): error_pattern = r"Missing mandatory key 'dirs' in sanity_check_paths." with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=test_ec, - extra_args=eb_args, raise_error=True, verbose=False) + extra_args=eb_args, raise_error=True, verbose=False) del sys.modules['easybuild.easyblocks.toy'] @@ -3027,7 +3027,7 @@ def grab_gcc_rpath_wrapper_args(): error_pattern = r"Path used in rpath_override_dirs is not an absolute path: eessi/lib" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, extra_args=eb_args, - raise_error=True, verbose=False) + raise_error=True, verbose=False) # also test use of --rpath-filter args.extend(['--rpath-filter=/test.*,/foo/bar.*', '--disable-cleanup-tmpdir']) @@ -3094,7 +3094,7 @@ def test_toy_filter_rpath_sanity_libs(self): error_pattern = r"Sanity check failed\: Library libtoy\.so not found" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec, - extra_args=args, name='toy-app', raise_error=True, verbose=False) + extra_args=args, name='toy-app', raise_error=True, verbose=False) # test use of --filter-rpath-sanity-libs option. In this test, we use --rpath-filter to make sure libtoy.so is # not rpath-ed. Then, we use --filter-rpath-sanity-libs to make sure the RPATH sanity checks ignores @@ -3143,7 +3143,7 @@ def test_toy_filter_rpath_sanity_libs(self): '--filter-env-vars=LD_LIBRARY_PATH'] with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec, - extra_args=args, name='toy-app', raise_error=True, verbose=False) + extra_args=args, name='toy-app', raise_error=True, verbose=False) def test_toy_cuda_sanity_check(self): """Test the CUDA sanity check""" @@ -3362,7 +3362,7 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None, error_pattern = r"Files missing CUDA device code: 3." with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda, - extra_args=args, raise_error=True) + extra_args=args, raise_error=True) outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=False, verify=False) stdout = self.get_stdout() msg = "Pattern '%s' not found in full build log: %s" % (device_additional_70_90_code_regex.pattern, outtxt) @@ -3395,7 +3395,7 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None, error_pattern = r"Files missing CUDA PTX code: 3" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda, - extra_args=args, raise_error=True) + extra_args=args, raise_error=True) outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=False, verify=False) stdout = self.get_stdout() msg = "Pattern '%s' not found in full build log: %s" % (device_additional_70_code_regex.pattern, outtxt) @@ -3429,7 +3429,7 @@ def assert_cuda_report(missing_cc, additional_cc, missing_ptx, log, stdout=None, error_pattern = r"Files with additional CUDA device code: 3" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, ec_file=toy_ec_cuda, - extra_args=args, raise_error=True) + extra_args=args, raise_error=True) outtxt = self._test_toy_build(ec_file=toy_ec_cuda, extra_args=args, raise_error=False, verify=False) stdout = self.get_stdout() msg = "Pattern '%s' not found in full build log: %s" % (device_additional_70_code_regex.pattern, outtxt) @@ -4299,7 +4299,7 @@ def test_toy_build_lock(self): mkdir(toy_lock_path, parents=True) with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, - extra_args=extra_args, raise_error=True, verbose=False) + extra_args=extra_args, raise_error=True, verbose=False) # also test use of --ignore-locks with self.mocked_stdout_stderr(): @@ -4368,7 +4368,7 @@ def __exit__(self, type, value, traceback): self.mock_stdout(True) error_pattern = r"Maximum wait time for lock /.*toy_0.0.lock to be released reached: [0-9]+ sec >= 3 sec" self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, extra_args=all_args, - verify=False, raise_error=True, testing=False) + verify=False, raise_error=True, testing=False) stderr, stdout = self.get_stderr(), self.get_stdout() self.mock_stderr(False) self.mock_stdout(False) @@ -4398,7 +4398,7 @@ def __exit__(self, type, value, traceback): error_pattern += r"(Read-only file system|Permission denied)" with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_pattern, self._test_toy_build, - extra_args=extra_args, raise_error=True, verbose=False) + extra_args=extra_args, raise_error=True, verbose=False) def test_toy_lock_cleanup_signals(self): """Test cleanup of locks after EasyBuild session gets a cancellation signal.""" @@ -4456,7 +4456,7 @@ def __exit__(self, type, value, traceback): self.mock_stderr(True) self.mock_stdout(True) self.assertRaisesRegex(exc, '.*', self._test_toy_build, ec_file=test_ec, verify=False, - extra_args=extra_args, raise_error=True, testing=False, raise_systemexit=True) + extra_args=extra_args, raise_error=True, testing=False, raise_systemexit=True) stderr = self.get_stderr().strip() self.mock_stderr(False) @@ -4595,13 +4595,13 @@ def test_toy_build_sanity_check_linked_libs(self): os.environ['EB_LIBTOY_BANNED_SHARED_LIBS'] = 'libtoy' with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, - ec_file=libtoy_ec, extra_args=['--module-only'], raise_error=True, verbose=False) + ec_file=libtoy_ec, extra_args=['--module-only'], raise_error=True, verbose=False) del os.environ['EB_LIBTOY_BANNED_SHARED_LIBS'] os.environ['EB_LIBTOY_REQUIRED_SHARED_LIBS'] = 'thisisnottheremostlikely' with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, - ec_file=libtoy_ec, extra_args=['--module-only'], raise_error=True, verbose=False) + ec_file=libtoy_ec, extra_args=['--module-only'], raise_error=True, verbose=False) del os.environ['EB_LIBTOY_REQUIRED_SHARED_LIBS'] # make sure default check passes (so we know better what triggered a failing test) @@ -4614,12 +4614,12 @@ def test_toy_build_sanity_check_linked_libs(self): args = ['--banned-linked-shared-libs=%s,foobarbaz' % libtoy_fn, '--module-only'] with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, - ec_file=libtoy_ec, extra_args=args, raise_error=True, verbose=False) + ec_file=libtoy_ec, extra_args=args, raise_error=True, verbose=False) args = ['--required-linked-shared=libs=foobarbazisnotthereforsure', '--module-only'] with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, - ec_file=libtoy_ec, extra_args=args, raise_error=True, verbose=False) + ec_file=libtoy_ec, extra_args=args, raise_error=True, verbose=False) # check specifying banned/required libraries via easyconfig parameter test_ec_txt = read_file(libtoy_ec) @@ -4627,14 +4627,14 @@ def test_toy_build_sanity_check_linked_libs(self): write_file(test_ec, test_ec_txt) with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, - ec_file=test_ec, extra_args=['--module-only'], raise_error=True, verbose=False) + ec_file=test_ec, extra_args=['--module-only'], raise_error=True, verbose=False) test_ec_txt = read_file(libtoy_ec) test_ec_txt += "\nrequired_linked_shared_libs = ['thereisnosuchlibraryyoudummy']" write_file(test_ec, test_ec_txt) with self.mocked_stdout_stderr(): self.assertRaisesRegex(EasyBuildError, error_msg, self._test_toy_build, force=False, - ec_file=test_ec, extra_args=['--module-only'], raise_error=True, verbose=False) + ec_file=test_ec, extra_args=['--module-only'], raise_error=True, verbose=False) # check behaviour when alternative subdirectories are specified test_ec_txt = read_file(libtoy_ec) @@ -4689,7 +4689,7 @@ def test_toy_mod_files(self): args += ['--fail-on-mod-files-gcccore'] pattern = r"Sanity check failed: One or more \.mod files found in .*/toy/0.0-GCCcore-6.2.0: .*/lib/file.mod" self.assertRaisesRegex(EasyBuildError, pattern, self.run_test_toy_build_with_output, ec_file=test_ec, - extra_args=args, verify=False, fails=True, verbose=False, raise_error=True) + extra_args=args, verify=False, fails=True, verbose=False, raise_error=True) test_ec_txt += "\nskip_mod_files_sanity_check = True" write_file(test_ec, test_ec_txt) @@ -4828,7 +4828,7 @@ def test_toy_failing_test_step(self): error_pattern = r"shell command 'false \.\.\.' failed in test step" self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_test_toy_build_with_output, - ec_file=test_ec, raise_error=True) + ec_file=test_ec, raise_error=True) self.assertNotExists(toy_mod_path) # make sure that option to ignore test failures works @@ -4844,7 +4844,7 @@ def test_toy_failing_test_step(self): error_pattern = r"An error was raised during test step: 'TOY_TEST_FAIL'" self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_test_toy_build_with_output, - ec_file=test_ec, raise_error=True) + ec_file=test_ec, raise_error=True) # make sure that option to ignore test failures works self.run_test_toy_build_with_output(ec_file=test_ec, extra_args=['--ignore-test-failure'], diff --git a/test/framework/tweak.py b/test/framework/tweak.py index f70d9557d5..7003a397d7 100644 --- a/test/framework/tweak.py +++ b/test/framework/tweak.py @@ -240,7 +240,7 @@ def test_match_minimum_tc_specs(self): # Make sure there's an error when we can't do the mapping error_msg = "No possible mapping from source toolchain spec .*" self.assertRaisesRegex(EasyBuildError, error_msg, match_minimum_tc_specs, - foss_hierarchy[3], iimpi_hierarchy) + foss_hierarchy[3], iimpi_hierarchy) def test_dep_tree_of_toolchain(self): """Test getting list of dependencies of a toolchain (as EasyConfig objects)""" @@ -296,7 +296,7 @@ def test_map_toolchain_hierarchies(self): # Expect an error when there is no possible mapping error_msg = "No possible mapping from source toolchain spec .*" self.assertRaisesRegex(EasyBuildError, error_msg, map_toolchain_hierarchies, - foss_tc, iimpi_tc, self.modtool) + foss_tc, iimpi_tc, self.modtool) # Test that we correctly include GCCcore binutils when it is there gcc_binutils_tc = {'name': 'GCC', 'version': '4.9.3-2.26'} diff --git a/test/framework/type_checking.py b/test/framework/type_checking.py index a0708eaeb4..3be6b68e39 100644 --- a/test/framework/type_checking.py +++ b/test/framework/type_checking.py @@ -331,7 +331,7 @@ def test_to_toolchain_dict(self): # wrong type self.assertRaisesRegex(EasyBuildError, r"Conversion of .* \(type .*\) to toolchain dict is not supported", - to_toolchain_dict, 1000) + to_toolchain_dict, 1000) # wrong number of elements errstr = "Can not convert .* to toolchain dict. Expected 2 or 3 elements" @@ -402,7 +402,7 @@ def test_to_dependency(self): # no name/version self.assertRaisesRegex(EasyBuildError, "Can not parse dependency without name and version: .*", - to_dependency, {'toolchain': 'lib, 1.2.8', 'versionsuffix': 'suff'}) + to_dependency, {'toolchain': 'lib, 1.2.8', 'versionsuffix': 'suff'}) # too many values dep_spec = {'lib': '1.2.8', 'foo': '1.3', 'toolchain': 'lib, 1.2.8', 'versionsuffix': 'suff'} self.assertRaisesRegex(EasyBuildError, r"Found unexpected \(key, value\) pair: .*", to_dependency, dep_spec) From 080cc658a00095ec9630fb17eaf425a99537c191 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 29 Sep 2025 08:57:50 +0200 Subject: [PATCH 3/5] Add alias `assertErrorRegex` for `assertRaisesRegex` --- easybuild/base/testing.py | 43 +++++-------------------------------- test/framework/toy_build.py | 2 +- 2 files changed, 6 insertions(+), 39 deletions(-) diff --git a/easybuild/base/testing.py b/easybuild/base/testing.py index e3082d7ad5..4adb087b73 100644 --- a/easybuild/base/testing.py +++ b/easybuild/base/testing.py @@ -36,12 +36,12 @@ import difflib import os import pprint -import re import sys from contextlib import contextmanager from io import StringIO from unittest import TestCase as OrigTestCase +from easybuild.base import fancylogger def nicediff(txta, txtb, offset=5): @@ -66,7 +66,7 @@ def nicediff(txta, txtb, offset=5): class TestCase(OrigTestCase): - """Enhanced test case, provides extra functionality (e.g. an assertRaisesRegex method).""" + """Enhanced test case, provides extra functionality.""" longMessage = True # print both standard messgae and custom message @@ -140,42 +140,9 @@ def setUp(self): self.orig_sys_stdout = sys.stdout self.orig_sys_stderr = sys.stderr - def convert_exception_to_str(self, err): - """Convert an Exception instance to a string.""" - msg = err - if hasattr(err, 'msg'): - msg = err.msg - elif hasattr(err, 'message'): - msg = err.message - if not msg: - # rely on str(msg) in case err.message is empty - msg = err - elif hasattr(err, 'args'): # KeyError in Python 2.4 only provides message via 'args' attribute - msg = err.args[0] - else: - msg = err - try: - res = str(msg) - except UnicodeEncodeError: - res = msg.encode('utf8', 'replace') - - return res - - def assertErrorRegex(self, error, regex, call, *args, **kwargs): - """ - Convenience method to match regex with the expected error message. - Example: self.assertErrorRegex(OSError, "No such file or directory", os.remove, '/no/such/file') - """ - try: - call(*args, **kwargs) - str_kwargs = ['='.join([k, str(v)]) for (k, v) in kwargs.items()] - str_args = ', '.join(list(map(str, args)) + str_kwargs) - self.fail("Expected errors with %s(%s) call should occur" % (call.__name__, str_args)) - except error as err: - msg = self.convert_exception_to_str(err) - if isinstance(regex, str): - regex = re.compile(regex) - self.assertTrue(regex.search(msg), "Pattern '%s' is found in '%s'" % (regex.pattern, msg)) + def assertErrorRegex(*args, **kwargs): + fancylogger.getLogger().deprecated('assertErrorRegex is deprecated, use assertRaisesRegex instead', '6.0') + return OrigTestCase.assertRaisesRegex(*args, **kwargs) def mock_stdout(self, enable): """Enable/disable mocking stdout.""" diff --git a/test/framework/toy_build.py b/test/framework/toy_build.py index 7b64f25b46..76a0362070 100644 --- a/test/framework/toy_build.py +++ b/test/framework/toy_build.py @@ -4842,7 +4842,7 @@ def test_toy_failing_test_step(self): test_ec_txt += '\nruntest = "RAISE_ERROR"' write_file(test_ec, test_ec_txt) - error_pattern = r"An error was raised during test step: 'TOY_TEST_FAIL'" + error_pattern = r"An error was raised during test step: TOY_TEST_FAIL" self.assertRaisesRegex(EasyBuildError, error_pattern, self.run_test_toy_build_with_output, ec_file=test_ec, raise_error=True) From 3058bfaee828c186137d8e54515dfd6565ff4f12 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 26 Sep 2025 17:31:42 +0200 Subject: [PATCH 4/5] Return message when converting `EasyBuildError` to string This ensures any formatting like newlines is kept. --- easybuild/tools/build_log.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/tools/build_log.py b/easybuild/tools/build_log.py index 044f53faac..712c3ea4e7 100644 --- a/easybuild/tools/build_log.py +++ b/easybuild/tools/build_log.py @@ -139,7 +139,7 @@ def __init__(self, msg, *args, exit_code=EasyBuildExit.ERROR, **kwargs): def __str__(self): """Return string representation of this EasyBuildError instance.""" - return repr(self.msg) + return self.msg def raise_easybuilderror(msg, *args): From 35125aca7d60c90b35aa36e303eae5d4ab32c323 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 29 Sep 2025 09:47:40 +0200 Subject: [PATCH 5/5] Adapt tests --- test/framework/hooks.py | 2 +- test/framework/toy_build.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/framework/hooks.py b/test/framework/hooks.py index a25e8fef18..2ba1387f8f 100644 --- a/test/framework/hooks.py +++ b/test/framework/hooks.py @@ -271,7 +271,7 @@ def run_hooks(): "== Running pre-single_extension hook...", "this is run before installing an extension", "== Running fail hook...", - "EasyBuild FAIL: 'oops'", + "EasyBuild FAIL: oops", "== Running crash hook...", "EasyBuild CRASHED, oh no! => boom!", "== Running post-easyblock hook...", diff --git a/test/framework/toy_build.py b/test/framework/toy_build.py index 76a0362070..a5b05b5b9c 100644 --- a/test/framework/toy_build.py +++ b/test/framework/toy_build.py @@ -1778,7 +1778,7 @@ def test_external_dependencies(self): write_file(toy_ec, ectxt + extraectxt) if isinstance(self.modtool, Lmod): - err_msg = r"Module command \\'.*load nosuchbuilddep/0.0.0\\' failed" + err_msg = r"Module command '.*load nosuchbuilddep/0.0.0' failed" else: err_msg = r"Unable to locate a modulefile for 'nosuchbuilddep/0.0.0'" @@ -1791,7 +1791,7 @@ def test_external_dependencies(self): write_file(toy_ec, ectxt + extraectxt) if isinstance(self.modtool, Lmod): - err_msg = r"Module command \\'.*load nosuchmodule/1.2.3\\' failed" + err_msg = r"Module command '.*load nosuchmodule/1.2.3' failed" else: err_msg = r"Unable to locate a modulefile for 'nosuchmodule/1.2.3'"