diff --git a/easybuild/tools/options.py b/easybuild/tools/options.py index 678363ab35..9709fb71ea 100644 --- a/easybuild/tools/options.py +++ b/easybuild/tools/options.py @@ -1756,24 +1756,38 @@ def set_tmpdir(tmpdir=None, raise_error=False): # reset to make sure tempfile picks up new temporary directory to use tempfile.tempdir = None - # test if temporary directory allows to execute files, warn if it doesn't - try: - fd, tmptest_file = tempfile.mkstemp() - os.close(fd) - os.chmod(tmptest_file, 0o700) - if not run_cmd(tmptest_file, simple=True, log_ok=False, regexp=False, force_in_dry_run=True, trace=False, - stream_output=False): - msg = "The temporary directory (%s) does not allow to execute files. " % tempfile.gettempdir() - msg += "This can cause problems in the build process, consider using --tmpdir." - if raise_error: - raise EasyBuildError(msg) + # cache for checked paths, via function attribute + executable_tmp_paths = getattr(set_tmpdir, 'executable_tmp_paths', []) + + # Skip the executable check if it already succeeded for any parent folder + # Especially important for the unit test suite, less so for actual execution + if not any(current_tmpdir.startswith(path) for path in executable_tmp_paths): + + # test if temporary directory allows to execute files, warn if it doesn't + try: + fd, tmptest_file = tempfile.mkstemp() + os.close(fd) + os.chmod(tmptest_file, 0o700) + if not run_cmd(tmptest_file, simple=True, log_ok=False, regexp=False, force_in_dry_run=True, trace=False, + stream_output=False): + msg = "The temporary directory (%s) does not allow to execute files. " % tempfile.gettempdir() + msg += "This can cause problems in the build process, consider using --tmpdir." + if raise_error: + raise EasyBuildError(msg) + else: + _log.warning(msg) else: - _log.warning(msg) - else: - _log.debug("Temporary directory %s allows to execute files, good!" % tempfile.gettempdir()) - os.remove(tmptest_file) + _log.debug("Temporary directory %s allows to execute files, good!" % tempfile.gettempdir()) - except OSError as err: - raise EasyBuildError("Failed to test whether temporary directory allows to execute files: %s", err) + # Put this folder into the cache + executable_tmp_paths.append(current_tmpdir) + + # set function attribute so we can retrieve cache later + set_tmpdir.executable_tmp_paths = executable_tmp_paths + + os.remove(tmptest_file) + + except OSError as err: + raise EasyBuildError("Failed to test whether temporary directory allows to execute files: %s", err) return current_tmpdir diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index 0bf963857c..11a6c083d0 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -752,17 +752,28 @@ def test_compiler_dependent_optarch(self): intel_options = [('intelflag', 'intelflag'), ('GENERIC', 'xSSE2'), ('', '')] gcc_options = [('gccflag', 'gccflag'), ('march=nocona', 'march=nocona'), ('', '')] gcccore_options = [('gcccoreflag', 'gcccoreflag'), ('GENERIC', 'march=x86-64 -mtune=generic'), ('', '')] - toolchains = [ - ('iccifort', '2018.1.163'), - ('GCC', '6.4.0-2.28'), - ('GCCcore', '6.2.0'), - ('PGI', '16.7-GCC-5.4.0-2.26'), - ] - enabled = [True, False] - test_cases = product(intel_options, gcc_options, gcccore_options, toolchains, enabled) + tc_intel = ('iccifort', '2018.1.163') + tc_gcc = ('GCC', '6.4.0-2.28') + tc_gcccore = ('GCCcore', '6.2.0') + tc_pgi = ('PGI', '16.7-GCC-5.4.0-2.26') + enabled = [True, False] - for intel_flags, gcc_flags, gcccore_flags, (toolchain_name, toolchain_ver), enable in test_cases: + test_cases = [] + for i, (tc, options) in enumerate(zip((tc_intel, tc_gcc, tc_gcccore), + (intel_options, gcc_options, gcccore_options))): + # Vary only the compiler specific option + for opt in options: + new_value = [intel_options[0], gcc_options[0], gcccore_options[0], tc] + new_value[i] = opt + test_cases.append(new_value) + # Add one case for PGI + test_cases.append((intel_options[0], gcc_options[0], gcccore_options[0], tc_pgi)) + + # Run each for enabled and disabled + test_cases = list(product(test_cases, enabled)) + + for (intel_flags, gcc_flags, gcccore_flags, (toolchain_name, toolchain_ver)), enable in test_cases: intel_flags, intel_flags_exp = intel_flags gcc_flags, gcc_flags_exp = gcc_flags