def load(self, modules, mod_paths=None, purge=False, orig_env=None):
        """
        Load all requested modules.

        @param modules: list of modules to load
        @param mod_paths: list of module paths to activate before loading
        @param purge: whether or not a 'module purge' should be run before loading
        @param orig_env: original environment to restore after running 'module purge'
        """
        if mod_paths is None:
            mod_paths = []

        # purge all loaded modules if desired
        if purge:
            self.purge()
            # restore original environment if provided
            if orig_env is not None:
                modify_env(os.environ, orig_env)

        # make sure $MODULEPATH is set correctly after purging
        self.check_module_path()
        # extend $MODULEPATH if needed
        for mod_path in mod_paths:
            full_mod_path = os.path.join(install_path('mod'), build_option('suffix_modules_path'), mod_path)
            self.prepend_module_path(full_mod_path)

        for mod in modules:
            self.run_module('load', mod)
Example #2
0
def build_and_install_software(module, options, orig_environ, exitOnFailure=True, silent=False):
    """
    Build the software
    """
    spec = module['spec']

    print_msg("processing EasyBuild easyconfig %s" % spec, log=_log, silent=silent)

    # restore original environment
    _log.info("Resetting environment")
    filetools.errorsFoundInLog = 0
    modify_env(os.environ, orig_environ)

    cwd = os.getcwd()

    # load easyblock
    easyblock = options.easyblock
    if not easyblock:
        # try to look in .eb file
        reg = re.compile(r"^\s*easyblock\s*=(.*)$")
        txt = read_file(spec)
        for line in txt.split('\n'):
            match = reg.search(line)
            if match:
                easyblock = eval(match.group(1))
                break

    name = module['ec']['name']
    try:
        app_class = get_class(easyblock, name=name)
        app = app_class(spec, debug=options.debug, robot_path=options.robot, silent=silent)
        _log.info("Obtained application instance of for %s (easyblock: %s)" % (name, easyblock))
    except EasyBuildError, err:
        print_error("Failed to get application instance for %s (easyblock: %s): %s" % (name, easyblock, err.msg), silent=silent)
Example #3
0
 def tearDown(self):
     """cleanup"""
     os.chdir(self.cwd)
     os.environ['MODULEPATH'] = os.pathsep.join(self.orig_modulepaths)
     # reinitialize a modules tool, to trigger 'module use' on module paths
     modules_tool()
     modify_env(os.environ, self.orig_environ)
Example #4
0
    def tearDown(self):
        """Clean up after running testcase."""
        super(EnhancedTestCase, self).tearDown()

        # go back to where we were before
        os.chdir(self.cwd)

        # restore original environment
        modify_env(os.environ, self.orig_environ)

        # restore original Python search path
        sys.path = self.orig_sys_path

        # remove any log handlers that were added (so that log files can be effectively removed)
        log = fancylogger.getLogger(fname=False)
        new_log_handlers = [
            h for h in log.handlers if h not in self.orig_log_handlers
        ]
        for log_handler in new_log_handlers:
            log_handler.close()
            log.removeHandler(log_handler)

        # cleanup test tmp dir
        try:
            shutil.rmtree(self.test_prefix)
        except (OSError, IOError):
            pass

        # restore original 'parent' tmpdir
        for var in ['TMPDIR', 'TEMP', 'TMP']:
            os.environ[var] = self.orig_tmpdir

        # reset to make sure tempfile picks up new temporary directory to use
        tempfile.tempdir = None
    def test_job(self):
        """Test submitting build as a job."""

        # use gzip-1.4.eb easyconfig file that comes with the tests
        eb_file = os.path.join(os.path.dirname(__file__), 'easyconfigs',
                               'gzip-1.4.eb')

        # check log message with --job
        for job_args in [  # options passed are reordered, so order here matters to make tests pass
            ['--debug'],
            ['--debug', '--stop=configure', '--try-software-name=foo'],
        ]:

            # clear log file
            write_file(self.logfile, '')

            args = [
                eb_file,
                '--job',
            ] + job_args
            outtxt = self.eb_main(args)

            job_msg = "INFO.* Command template for jobs: .* && eb %%\(spec\)s.* %s.*\n" % ' .*'.join(
                job_args)
            assertmsg = "Info log message with job command template when using --job (job_msg: %s, outtxt: %s)" % (
                job_msg, outtxt)
            self.assertTrue(re.search(job_msg, outtxt), assertmsg)

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
    def test_avail_lists(self):
        """Test listing available values of certain types."""

        fd, dummylogfn = tempfile.mkstemp(prefix='easybuild-dummy', suffix='.log')
        os.close(fd)

        name_items = {
            'modules-tools': ['EnvironmentModulesC', 'Lmod'],
            'module-naming-schemes': ['EasyBuildModuleNamingScheme'],
        }
        for (name, items) in name_items.items():
            args = [
                    '--avail-%s' % name,
                    '--unittest-file=%s' % self.logfile,
                   ]
            outtxt = self.eb_main(args, logfile=dummylogfn)

            words = name.replace('-', ' ')
            info_msg = r"INFO List of supported %s:" % words
            self.assertTrue(re.search(info_msg, outtxt), "Info message with list of available %s" % words)
            for item in items:
                res = re.findall("^\s*%s" % item, outtxt, re.M)
                self.assertTrue(res, "%s is included in list of available %s" % (item, words))
                # every item should only be mentioned once
                n = len(res)
                self.assertEqual(n, 1, "%s is only mentioned once (count: %d)" % (item, n))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None

        if os.path.exists(dummylogfn):
            os.remove(dummylogfn)
    def test_job(self):
        """Test submitting build as a job."""

        # use gzip-1.4.eb easyconfig file that comes with the tests
        eb_file = os.path.join(os.path.dirname(__file__), "easyconfigs", "gzip-1.4.eb")

        # check log message with --job
        for job_args in [  # options passed are reordered, so order here matters to make tests pass
            ["--debug"],
            ["--debug", "--stop=configure", "--try-software-name=foo"],
        ]:

            # clear log file
            outtxt = write_file(self.logfile, "")

            args = [eb_file, "--job"] + job_args
            try:
                main((args, self.logfile, False))
            except (SystemExit, Exception), err:
                pass
            outtxt = read_file(self.logfile)

            job_msg = "INFO.* Command template for jobs: .* && eb %%\(spec\)s %s.*\n" % " .*".join(job_args)
            assertmsg = "Info log message with job command template when using --job (job_msg: %s, outtxt: %s)" % (
                job_msg,
                outtxt,
            )
            self.assertTrue(re.search(job_msg, outtxt), assertmsg)

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
    def test_quiet(self):
        """Test enabling quiet logging (errors only)."""

        for quiet_arg in ["--quiet"]:
            args = ["--software-name=somethingrandom", quiet_arg]
            try:
                main((args, self.logfile, False))
            except (SystemExit, Exception), err:
                pass
            outtxt = read_file(self.logfile)

            for log_msg_type in ["ERROR"]:
                res = re.search(" %s " % log_msg_type, outtxt)
                self.assertTrue(
                    res, "%s log messages are included when using %s (outtxt: %s)" % (log_msg_type, quiet_arg, outtxt)
                )

            for log_msg_type in ["DEBUG", "INFO"]:
                res = re.search(" %s " % log_msg_type, outtxt)
                self.assertTrue(
                    not res,
                    "%s log messages are *not* included when using %s (outtxt: %s)" % (log_msg_type, quiet_arg, outtxt),
                )

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
    def test_info(self):
        """Test enabling info logging."""

        for info_arg in ["--info"]:
            args = ["--software-name=somethingrandom", info_arg]
            myerr = None
            try:
                main((args, self.logfile, False))
            except (SystemExit, Exception), err:
                myerr = err
            outtxt = read_file(self.logfile)

            for log_msg_type in ["INFO", "ERROR"]:
                res = re.search(" %s " % log_msg_type, outtxt)
                self.assertTrue(
                    res,
                    "%s log messages are included when using %s (err: %s, out: %s)"
                    % (log_msg_type, info_arg, myerr, outtxt),
                )

            for log_msg_type in ["DEBUG"]:
                res = re.search(" %s " % log_msg_type, outtxt)
                self.assertTrue(not res, "%s log messages are *not* included when using %s" % (log_msg_type, info_arg))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
    def test_avail_lists(self):
        """Test listing available values of certain types."""

        fd, dummylogfn = tempfile.mkstemp(prefix="easybuild-dummy", suffix=".log")
        os.close(fd)

        name_items = {
            "modules-tools": ["EnvironmentModulesC", "Lmod"],
            "module-naming-schemes": ["EasyBuildModuleNamingScheme"],
        }
        for (name, items) in name_items.items():
            args = ["--avail-%s" % name, "--unittest-file=%s" % self.logfile]
            try:
                main((args, dummylogfn, False))
            except (SystemExit, Exception), err:
                pass
            outtxt = read_file(self.logfile)

            words = name.replace("-", " ")
            info_msg = r"INFO List of supported %s:" % words
            self.assertTrue(re.search(info_msg, outtxt), "Info message with list of available %s" % words)
            for item in items:
                res = re.findall("^\s*%s" % item, outtxt, re.M)
                self.assertTrue(res, "%s is included in list of available %s" % (item, words))
                # every item should only be mentioned once
                n = len(res)
                self.assertEqual(n, 1, "%s is only mentioned once (count: %d)" % (item, n))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #11
0
    def test_info(self):
        """Test enabling info logging."""

        for info_arg in ['--info']:
            args = [
                '--software-name=somethingrandom',
                info_arg,
            ]
            outtxt = self.eb_main(args)

            for log_msg_type in ['INFO', 'ERROR']:
                res = re.search(' %s ' % log_msg_type, outtxt)
                self.assertTrue(
                    res,
                    "%s log messages are included when using %s ( out: %s)" %
                    (log_msg_type, info_arg, outtxt))

            for log_msg_type in ['DEBUG']:
                res = re.search(' %s ' % log_msg_type, outtxt)
                self.assertTrue(
                    not res,
                    "%s log messages are *not* included when using %s" %
                    (log_msg_type, info_arg))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #12
0
    def test_job(self):
        """Test submitting build as a job."""

        # use gzip-1.4.eb easyconfig file that comes with the tests
        eb_file = os.path.join(os.path.dirname(__file__), 'easyconfigs', 'gzip-1.4.eb')

        # check log message with --job
        for job_args in [  # options passed are reordered, so order here matters to make tests pass
                         ['--debug'],
                         ['--debug', '--stop=configure', '--try-software-name=foo'],
                        ]:

            # clear log file
            write_file(self.logfile, '')

            args = [
                    eb_file,
                    '--job',
                   ] + job_args
            outtxt = self.eb_main(args)

            job_msg = "INFO.* Command template for jobs: .* && eb %%\(spec\)s.* %s.*\n" % ' .*'.join(job_args)
            assertmsg = "Info log message with job command template when using --job (job_msg: %s, outtxt: %s)" % (job_msg, outtxt)
            self.assertTrue(re.search(job_msg, outtxt), assertmsg)

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #13
0
    def test_force(self):
        """Test forcing installation even if the module is already available."""

        # use GCC-4.6.3.eb easyconfig file that comes with the tests
        eb_file = os.path.join(os.path.dirname(__file__), 'easyconfigs', 'GCC-4.6.3.eb')

        # check log message without --force
        args = [
                eb_file,
                '--debug',
               ]
        outtxt, error_thrown = self.eb_main(args, return_error=True)

        self.assertTrue(not error_thrown, "No error is thrown if software is already installed (error_thrown: %s)" % error_thrown)

        already_msg = "GCC/4.6.3 is already installed"
        self.assertTrue(re.search(already_msg, outtxt), "Already installed message without --force, outtxt: %s" % outtxt)

        # clear log file, clean up environment
        write_file(self.logfile, '')
        modify_env(os.environ, self.orig_environ)
        tempfile.tempdir = None

        # check that --force works
        args = [
                eb_file,
                '--force',
                '--debug',
               ]
        outtxt = self.eb_main(args)

        self.assertTrue(not re.search(already_msg, outtxt), "Already installed message not there with --force")
Example #14
0
    def test_set_tmpdir(self):
        """Test set_tmpdir config function."""
        self.purge_environment()
        for tmpdir in [None, os.path.join(tempfile.gettempdir(), 'foo')]:
            parent = tmpdir
            if parent is None:
                parent = tempfile.gettempdir()

            mytmpdir = set_tmpdir(tmpdir=tmpdir)

            for var in ['TMPDIR', 'TEMP', 'TMP']:
                self.assertTrue(os.environ[var].startswith(
                    os.path.join(parent, 'easybuild-')))
                self.assertEqual(os.environ[var], mytmpdir)
            self.assertTrue(tempfile.gettempdir().startswith(
                os.path.join(parent, 'easybuild-')))
            tempfile_tmpdir = tempfile.mkdtemp()
            self.assertTrue(
                tempfile_tmpdir.startswith(os.path.join(parent, 'easybuild-')))
            fd, tempfile_tmpfile = tempfile.mkstemp()
            self.assertTrue(
                tempfile_tmpfile.startswith(os.path.join(parent,
                                                         'easybuild-')))

            # cleanup
            os.close(fd)
            shutil.rmtree(mytmpdir)
            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
    def load(self, modules, mod_paths=None, purge=False, orig_env=None):
        """
        Load all requested modules.

        @param modules: list of modules to load
        @param mod_paths: list of module paths to activate before loading
        @param purge: whether or not a 'module purge' should be run before loading
        @param orig_env: original environment to restore after running 'module purge'
        """
        if mod_paths is None:
            mod_paths = []

        # purge all loaded modules if desired
        if purge:
            self.purge()
            # restore original environment if provided
            if orig_env is not None:
                modify_env(os.environ, orig_env)

        # make sure $MODULEPATH is set correctly after purging
        self.check_module_path()
        # extend $MODULEPATH if needed
        for mod_path in mod_paths:
            full_mod_path = os.path.join(install_path('mod'),
                                         build_option('suffix_modules_path'),
                                         mod_path)
            self.prepend_module_path(full_mod_path)

        for mod in modules:
            self.run_module('load', mod)
Example #16
0
    def test_quiet(self):
        """Test enabling quiet logging (errors only)."""

        for quiet_arg in ['--quiet']:
            args = [
                '--software-name=somethingrandom',
                quiet_arg,
            ]
            outtxt = self.eb_main(args)

            for log_msg_type in ['ERROR']:
                res = re.search(' %s ' % log_msg_type, outtxt)
                self.assertTrue(
                    res,
                    "%s log messages are included when using %s (outtxt: %s)" %
                    (log_msg_type, quiet_arg, outtxt))

            for log_msg_type in ['DEBUG', 'INFO']:
                res = re.search(' %s ' % log_msg_type, outtxt)
                self.assertTrue(
                    not res,
                    "%s log messages are *not* included when using %s (outtxt: %s)"
                    % (log_msg_type, quiet_arg, outtxt))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
    def tearDown(self):
        """Clean up after running testcase."""
        super(EnhancedTestCase, self).tearDown()

        self.log.info("Cleaning up for test %s", self.id())

        # go back to where we were before
        os.chdir(self.cwd)

        # restore original environment
        modify_env(os.environ, self.orig_environ, verbose=False)

        # restore original Python search path
        sys.path = self.orig_sys_path

        # remove any log handlers that were added (so that log files can be effectively removed)
        log = fancylogger.getLogger(fname=False)
        new_log_handlers = [h for h in log.handlers if h not in self.orig_log_handlers]
        for log_handler in new_log_handlers:
            log_handler.close()
            log.removeHandler(log_handler)

        # cleanup test tmp dir
        try:
            shutil.rmtree(self.test_prefix)
        except (OSError, IOError):
            pass

        # restore original 'parent' tmpdir
        for var in ['TMPDIR', 'TEMP', 'TMP']:
            os.environ[var] = self.orig_tmpdir

        # reset to make sure tempfile picks up new temporary directory to use
        tempfile.tempdir = None
Example #18
0
 def tearDown(self):
     """cleanup"""
     os.chdir(self.cwd)
     os.environ['MODULEPATH'] = os.pathsep.join(self.orig_modulepaths)
     # reinitialize a modules tool, to trigger 'module use' on module paths
     modules_tool()
     modify_env(os.environ, self.orig_environ)
    def test_set_tmpdir(self):
        """Test set_tmpdir config function."""
        self.purge_environment()

        for tmpdir in [None, os.path.join(tempfile.gettempdir(), 'foo')]:
            parent = tmpdir
            if parent is None:
                parent = tempfile.gettempdir()

            mytmpdir = set_tmpdir(tmpdir=tmpdir)

            for var in ['TMPDIR', 'TEMP', 'TMP']:
                self.assertTrue(os.environ[var].startswith(os.path.join(parent, 'easybuild-')))
                self.assertEqual(os.environ[var], mytmpdir)
            self.assertTrue(tempfile.gettempdir().startswith(os.path.join(parent, 'easybuild-')))
            tempfile_tmpdir = tempfile.mkdtemp()
            self.assertTrue(tempfile_tmpdir.startswith(os.path.join(parent, 'easybuild-')))
            fd, tempfile_tmpfile = tempfile.mkstemp()
            self.assertTrue(tempfile_tmpfile.startswith(os.path.join(parent, 'easybuild-')))

            # cleanup
            os.close(fd)
            shutil.rmtree(mytmpdir)
            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #20
0
    def tearDown(self):
        """cleanup"""
        os.environ['MODULEPATH'] = os.pathsep.join(self.orig_modulepaths)
        # reinitialize a modules tool, to trigger 'module use' on module paths
        modules_tool()

        # restore (full) original environment
        modify_env(os.environ, self.orig_environ)
Example #21
0
        def run_test(custom=None, extra_params=[]):
            """Inner function to run actual test in current setting."""

            fd, dummylogfn = tempfile.mkstemp(prefix='easybuild-dummy',
                                              suffix='.log')
            os.close(fd)

            for avail_arg in [
                    '-a',
                    '--avail-easyconfig-params',
            ]:

                # clear log
                write_file(self.logfile, '')

                args = [
                    avail_arg,
                    '--unittest-file=%s' % self.logfile,
                ]
                if custom is not None:
                    args.extend(['-e', custom])

                outtxt = self.eb_main(args, logfile=dummylogfn, verbose=True)

                # check whether all parameter types are listed
                par_types = [
                    BUILD, DEPENDENCIES, EXTENSIONS, FILEMANAGEMENT, LICENSE,
                    MANDATORY, MODULES, OTHER, TOOLCHAIN
                ]
                if custom is not None:
                    par_types.append(CUSTOM)

                for param_type in [x[1] for x in par_types]:
                    self.assertTrue(
                        re.search(
                            "%s\n%s" %
                            (param_type.upper(), '-' * len(param_type)),
                            outtxt),
                        "Parameter type %s is featured in output of eb %s (args: %s): %s"
                        % (param_type, avail_arg, args, outtxt))

                # check a couple of easyconfig parameters
                for param in [
                        "name", "version", "toolchain", "versionsuffix",
                        "buildopts", "sources", "start_dir", "dependencies",
                        "group", "exts_list", "moduleclass", "buildstats"
                ] + extra_params:
                    self.assertTrue(
                        re.search("%s(?:\(\*\))?:\s*\w.*" % param, outtxt),
                        "Parameter %s is listed with help in output of eb %s (args: %s): %s"
                        % (param, avail_arg, args, outtxt))

                modify_env(os.environ, self.orig_environ)
                tempfile.tempdir = None

            if os.path.exists(dummylogfn):
                os.remove(dummylogfn)
    def tearDown(self):
        """Post-test cleanup."""
        os.remove(self.logfile)
        os.chdir(self.pwd)
        modify_env(os.environ, self.orig_environ)
        tempfile.tempdir = None

        # restore original Python search path
        sys.path = self.orig_sys_path
Example #23
0
 def tearDown(self):
     """Clean up after a config test."""
     self.cleanup()
     try:
         shutil.rmtree(self.tmpdir)
     except OSError:
         pass
     modify_env(os.environ, self.orig_environ)
     tempfile.tempdir = None
    def eb_main(self, args, do_build=False, return_error=False, logfile=None, verbose=False, raise_error=False,
                reset_env=True, raise_systemexit=False, testing=True, redo_init_config=True):
        """Helper method to call EasyBuild main function."""
        cleanup()

        myerr = False
        if logfile is None:
            logfile = self.logfile
        # clear log file
        if logfile:
            with open(logfile, 'w') as fh:
                fh.write('')

        env_before = copy.deepcopy(os.environ)

        try:
            if '--fetch' in args:
                # The config sets modules_tool to None if --fetch is specified,
                # so do the same here to keep the behavior consistent
                modtool = None
            else:
                modtool = self.modtool
            main(args=args, logfile=logfile, do_build=do_build, testing=testing, modtool=modtool)
        except SystemExit as err:
            if raise_systemexit:
                raise err
        except Exception as err:
            myerr = err
            if verbose:
                print("err: %s" % err)

        if logfile and os.path.exists(logfile):
            logtxt = read_file(logfile)
        else:
            logtxt = None

        os.chdir(self.cwd)

        if redo_init_config:
            # make sure config is reinitialized
            init_config(with_include=False)

        # restore environment to what it was before running main,
        # changes may have been made by eb_main (e.g. $TMPDIR & co)
        if reset_env:
            modify_env(os.environ, env_before, verbose=False)
            tempfile.tempdir = None

        if myerr and raise_error:
            raise myerr

        if return_error:
            return logtxt, myerr
        else:
            return logtxt
    def tearDown(self):
        """Test cleanup."""
        remove_dir(self.tmpdir)

        sys.stdout = self.orig_sys_stdout
        sys.stderr = self.orig_sys_stderr

        # restore original environment
        modify_env(os.environ, self.orig_environ, verbose=False)

        super(EasyBlockSpecificTest, self).tearDown()
Example #26
0
    def tearDown(self):
        """Clean up after running testcase."""
        os.chdir(self.cwd)
        modify_env(os.environ, self.orig_environ)
        tempfile.tempdir = None

        # restore original Python search path
        sys.path = self.orig_sys_path

        for path in [self.test_buildpath, self.test_installpath]:
            try:
                shutil.rmtree(path)
            except OSError, err:
                pass
    def tearDown(self):
        """Clean up after running testcase."""
        os.chdir(self.cwd)
        modify_env(os.environ, self.orig_environ)
        tempfile.tempdir = None

        # restore original Python search path
        sys.path = self.orig_sys_path

        for path in [self.test_buildpath, self.test_installpath, self.test_prefix]:
            try:
                shutil.rmtree(path)
            except OSError, err:
                pass
Example #28
0
    def eb_main(self, args, do_build=False, return_error=False, logfile=None, verbose=False, raise_error=False,
                reset_env=True, raise_systemexit=False, testing=True):
        """Helper method to call EasyBuild main function."""
        cleanup()

        myerr = False
        if logfile is None:
            logfile = self.logfile
        # clear log file
        if logfile:
            f = open(logfile, 'w')
            f.write('')
            f.close()

        env_before = copy.deepcopy(os.environ)

        try:
            main(args=args, logfile=logfile, do_build=do_build, testing=testing, modtool=self.modtool)
        except SystemExit as err:
            if raise_systemexit:
                raise err
        except Exception as err:
            myerr = err
            if verbose:
                print "err: %s" % err

        if logfile and os.path.exists(logfile):
            logtxt = read_file(logfile)
        else:
            logtxt = None

        os.chdir(self.cwd)

        # make sure config is reinitialized
        init_config(with_include=False)

        # restore environment to what it was before running main,
        # changes may have been made by eb_main (e.g. $TMPDIR & co)
        if reset_env:
            modify_env(os.environ, env_before, verbose=False)
            tempfile.tempdir = None

        if myerr and raise_error:
            raise myerr

        if return_error:
            return logtxt, myerr
        else:
            return logtxt
Example #29
0
    def tearDown(self):
        """Cleanup."""
        # remove logs
        os.remove(self.logfile)

        if os.path.exists(self.dummylogfn):
            os.remove(self.dummylogfn)
        shutil.rmtree(self.buildpath)
        shutil.rmtree(self.installpath)

        # restore original Python search path
        sys.path = self.orig_sys_path

        modify_env(os.environ, self.orig_environ)
        tempfile.tempdir = None
Example #30
0
        def run_test(custom=None, extra_params=[]):
            """Inner function to run actual test in current setting."""

            fd, dummylogfn = tempfile.mkstemp(prefix='easybuild-dummy', suffix='.log')
            os.close(fd)

            for avail_arg in [
                              '-a',
                              '--avail-easyconfig-params',
                             ]:

                # clear log
                write_file(self.logfile, '')

                args = [
                        avail_arg,
                        '--unittest-file=%s' % self.logfile,
                       ]
                if custom is not None:
                    args.extend(['-e', custom])

                try:
                    main((args, dummylogfn, False))
                except (SystemExit, Exception), err:
                    pass
                outtxt = read_file(self.logfile)

                # check whether all parameter types are listed
                par_types = [BUILD, DEPENDENCIES, EXTENSIONS, FILEMANAGEMENT,
                             LICENSE, MANDATORY, MODULES, OTHER, TOOLCHAIN]
                if custom is not None:
                    par_types.append(CUSTOM)

                for param_type in [x[1] for x in par_types]:
                    self.assertTrue(re.search("%s\n%s" % (param_type.upper(), '-' * len(param_type)), outtxt),
                                    "Parameter type %s is featured in output of eb %s (args: %s): %s" %
                                    (param_type, avail_arg, args, outtxt))

                # check a couple of easyconfig parameters
                for param in ["name", "version", "toolchain", "versionsuffix", "makeopts", "sources", "start_dir",
                              "dependencies", "group", "exts_list", "moduleclass", "buildstats"] + extra_params:
                    self.assertTrue(re.search("%s(?:\(\*\))?:\s*\w.*" % param, outtxt),
                                    "Parameter %s is listed with help in output of eb %s (args: %s): %s" %
                                    (param, avail_arg, args, outtxt)
                                    )

                modify_env(os.environ, self.orig_environ)
                tempfile.tempdir = None
Example #31
0
    def test_debug(self):
        """Test enabling debug logging."""

        for debug_arg in ['-d', '--debug']:
            args = [
                    '--software-name=somethingrandom',
                    debug_arg,
                   ]
            outtxt = self.eb_main(args)

            for log_msg_type in ['DEBUG', 'INFO', 'ERROR']:
                res = re.search(' %s ' % log_msg_type, outtxt)
                self.assertTrue(res, "%s log messages are included when using %s: %s" % (log_msg_type, debug_arg, outtxt))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #32
0
    def test_debug(self):
        """Test enabling debug logging."""

        for debug_arg in ['-d', '--debug']:
            args = [
                '--software-name=somethingrandom',
                debug_arg,
            ]
            outtxt = self.eb_main(args)

            for log_msg_type in ['DEBUG', 'INFO', 'ERROR']:
                res = re.search(' %s ' % log_msg_type, outtxt)
                self.assertTrue(
                    res, "%s log messages are included when using %s: %s" %
                    (log_msg_type, debug_arg, outtxt))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #33
0
    def test_zzz_logtostdout(self):
        """Testing redirecting log to stdout."""

        fd, dummylogfn = tempfile.mkstemp(prefix='easybuild-dummy',
                                          suffix='.log')
        os.close(fd)

        for stdout_arg in ['--logtostdout', '-l']:

            _stdout = sys.stdout

            fd, fn = tempfile.mkstemp()
            fh = os.fdopen(fd, 'w')
            sys.stdout = fh

            args = [
                '--software-name=somethingrandom',
                '--robot',
                '.',
                '--debug',
                stdout_arg,
            ]
            self.eb_main(args, logfile=dummylogfn)

            # make sure we restore
            sys.stdout.flush()
            sys.stdout = _stdout
            fancylogger.logToScreen(enable=False, stdout=True)

            outtxt = read_file(fn)

            self.assertTrue(
                len(outtxt) > 100,
                "Log messages are printed to stdout when %s is used (outtxt: %s)"
                % (stdout_arg, outtxt))

            # cleanup
            os.remove(fn)
            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None

        if os.path.exists(dummylogfn):
            os.remove(dummylogfn)
        fancylogger.logToFile(self.logfile)
    def tearDown(self):
        """Clean up after running testcase."""
        super(EnhancedTestCase, self).tearDown()
        os.chdir(self.cwd)
        modify_env(os.environ, self.orig_environ)
        tempfile.tempdir = None

        # restore original Python search path
        sys.path = self.orig_sys_path

        # cleanup
        for path in [self.logfile, self.test_buildpath, self.test_installpath, self.test_prefix]:
            try:
                if os.path.isdir(path):
                    shutil.rmtree(path)
                else:
                    os.remove(path)
            except OSError, err:
                pass
    def test_debug(self):
        """Test enabling debug logging."""

        for debug_arg in ["-d", "--debug"]:
            args = ["--software-name=somethingrandom", debug_arg]
            try:
                main((args, self.logfile, False))
            except (SystemExit, Exception), err:
                myerr = err
            outtxt = read_file(self.logfile)

            for log_msg_type in ["DEBUG", "INFO", "ERROR"]:
                res = re.search(" %s " % log_msg_type, outtxt)
                self.assertTrue(
                    res, "%s log messages are included when using %s: %s" % (log_msg_type, debug_arg, outtxt)
                )

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #36
0
    def test_list_easyblocks(self):
        """Test listing easyblock hierarchy."""

        fd, dummylogfn = tempfile.mkstemp(prefix='easybuild-dummy', suffix='.log')
        os.close(fd)

        # adjust PYTHONPATH such that test easyblocks are found
        orig_sys_path = sys.path[:]

        import easybuild
        sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), 'sandbox')))
        easybuild = reload(easybuild)
        import easybuild.easyblocks
        reload(easybuild.easyblocks)
        reload(easybuild.tools.module_naming_scheme)  # required to run options unit tests stand-alone

        # simple view
        for list_arg in ['--list-easyblocks', '--list-easyblocks=simple']:

            # clear log
            write_file(self.logfile, '')

            args = [
                    list_arg,
                    '--unittest-file=%s' % self.logfile,
                   ]
            try:
                main((args, dummylogfn, False))
            except (SystemExit, Exception), err:
                pass
            outtxt = read_file(self.logfile)

            for pat in [
                        r"EasyBlock\n",
                        r"|--\s+EB_foo\n|\s+|--\s+EB_foofoo\n",
                        r"|--\s+bar\n",
                       ]:

                self.assertTrue(re.search(pat, outtxt), "Pattern '%s' is found in output of --list-easyblocks: %s" % (pat, outtxt))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #37
0
    def test_quiet(self):
        """Test enabling quiet logging (errors only)."""

        for quiet_arg in ['--quiet']:
            args = [
                    '--software-name=somethingrandom',
                    quiet_arg,
                   ]
            outtxt = self.eb_main(args)

            for log_msg_type in ['ERROR']:
                res = re.search(' %s ' % log_msg_type, outtxt)
                self.assertTrue(res, "%s log messages are included when using %s (outtxt: %s)" % (log_msg_type, quiet_arg, outtxt))

            for log_msg_type in ['DEBUG', 'INFO']:
                res = re.search(' %s ' % log_msg_type, outtxt)
                self.assertTrue(not res, "%s log messages are *not* included when using %s (outtxt: %s)" % (log_msg_type, quiet_arg, outtxt))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #38
0
    def test_info(self):
        """Test enabling info logging."""

        for info_arg in ['--info']:
            args = [
                    '--software-name=somethingrandom',
                    info_arg,
                   ]
            outtxt = self.eb_main(args)

            for log_msg_type in ['INFO', 'ERROR']:
                res = re.search(' %s ' % log_msg_type, outtxt)
                self.assertTrue(res, "%s log messages are included when using %s ( out: %s)" % (log_msg_type, info_arg, outtxt))

            for log_msg_type in ['DEBUG']:
                res = re.search(' %s ' % log_msg_type, outtxt)
                self.assertTrue(not res, "%s log messages are *not* included when using %s" % (log_msg_type, info_arg))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #39
0
    def test_force(self):
        """Test forcing installation even if the module is already available."""

        # use GCC-4.6.3.eb easyconfig file that comes with the tests
        eb_file = os.path.join(os.path.dirname(__file__), 'easyconfigs',
                               'GCC-4.6.3.eb')

        # check log message without --force
        args = [
            eb_file,
            '--debug',
        ]
        outtxt, error_thrown = self.eb_main(args, return_error=True)

        self.assertTrue(
            not error_thrown,
            "No error is thrown if software is already installed (error_thrown: %s)"
            % error_thrown)

        already_msg = "GCC/4.6.3 is already installed"
        self.assertTrue(
            re.search(already_msg, outtxt),
            "Already installed message without --force, outtxt: %s" % outtxt)

        # clear log file, clean up environment
        write_file(self.logfile, '')
        modify_env(os.environ, self.orig_environ)
        tempfile.tempdir = None

        # check that --force works
        args = [
            eb_file,
            '--force',
            '--debug',
        ]
        outtxt = self.eb_main(args)

        self.assertTrue(not re.search(already_msg, outtxt),
                        "Already installed message not there with --force")
Example #40
0
    def test_zzz_logtostdout(self):
        """Testing redirecting log to stdout."""

        fd, dummylogfn = tempfile.mkstemp(prefix='easybuild-dummy', suffix='.log')
        os.close(fd)

        for stdout_arg in ['--logtostdout', '-l']:

            _stdout = sys.stdout

            fd, fn = tempfile.mkstemp()
            fh = os.fdopen(fd, 'w')
            sys.stdout = fh

            args = [
                    '--software-name=somethingrandom',
                    '--robot', '.',
                    '--debug',
                    stdout_arg,
                   ]
            self.eb_main(args, logfile=dummylogfn)

            # make sure we restore
            sys.stdout.flush()
            sys.stdout = _stdout
            fancylogger.logToScreen(enable=False, stdout=True)

            outtxt = read_file(fn)

            self.assertTrue(len(outtxt) > 100, "Log messages are printed to stdout when %s is used (outtxt: %s)" % (stdout_arg, outtxt))

            # cleanup
            os.remove(fn)
            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None

        if os.path.exists(dummylogfn):
            os.remove(dummylogfn)
        fancylogger.logToFile(self.logfile)
    def tearDown(self):
        """Clean up after running testcase."""
        super(EnhancedTestCase, self).tearDown()
        os.chdir(self.cwd)
        modify_env(os.environ, self.orig_environ)
        tempfile.tempdir = None

        # restore original Python search path
        sys.path = self.orig_sys_path

        # cleanup
        for path in [
                self.logfile, self.test_buildpath, self.test_installpath,
                self.test_prefix
        ]:
            try:
                if os.path.isdir(path):
                    shutil.rmtree(path)
                else:
                    os.remove(path)
            except OSError, err:
                pass
    def test_modify_env(self):
        """Test for modify_env function."""

        old_env_vars = {
            'TEST_ENV_VAR_TO_UNSET1': 'foobar',
            'TEST_ENV_VAR_TO_UNSET2': 'value does not matter',
            'TEST_COMMON_ENV_VAR_CHANGED': 'old_value',
            'TEST_COMMON_ENV_VAR_SAME_VALUE': 'this_value_stays',
        }
        new_env_vars = {
            'TEST_COMMON_ENV_VAR_CHANGED': 'new_value',
            'TEST_NEW_ENV_VAR1': '1',
            'TEST_NEW_ENV_VAR2': 'two 2 two',
            'TEST_COMMON_ENV_VAR_SAME_VALUE': 'this_value_stays',
        }

        # prepare test environment first:
        # keys in new_env should not be set yet, keys in old_env are expected to be set
        for key in new_env_vars:
            if key in os.environ:
                del os.environ[key]
        for key in old_env_vars:
            os.environ[key] = old_env_vars[key]

        env.modify_env(os.environ, new_env_vars)

        self.assertEqual(os.environ.get('TEST_ENV_VAR_TO_UNSET1'), None)
        self.assertEqual(os.environ.get('TEST_ENV_VAR_TO_UNSET2'), None)
        self.assertEqual(os.environ.get('TEST_COMMON_ENV_VAR_CHANGED'),
                         'new_value')
        self.assertEqual(os.environ.get('TEST_COMMON_ENV_VAR_SAME_VALUE'),
                         'this_value_stays')
        self.assertEqual(os.environ.get('TEST_NEW_ENV_VAR1'), '1')
        self.assertEqual(os.environ.get('TEST_NEW_ENV_VAR2'), 'two 2 two')

        # extreme test case: empty entire environment (original env is restored for next tests)
        env.modify_env(os.environ, {})
Example #43
0
    def test_avail_lists(self):
        """Test listing available values of certain types."""

        fd, dummylogfn = tempfile.mkstemp(prefix='easybuild-dummy',
                                          suffix='.log')
        os.close(fd)

        name_items = {
            'modules-tools': ['EnvironmentModulesC', 'Lmod'],
            'module-naming-schemes': ['EasyBuildModuleNamingScheme'],
        }
        for (name, items) in name_items.items():
            args = [
                '--avail-%s' % name,
                '--unittest-file=%s' % self.logfile,
            ]
            outtxt = self.eb_main(args, logfile=dummylogfn)

            words = name.replace('-', ' ')
            info_msg = r"INFO List of supported %s:" % words
            self.assertTrue(re.search(info_msg, outtxt),
                            "Info message with list of available %s" % words)
            for item in items:
                res = re.findall("^\s*%s" % item, outtxt, re.M)
                self.assertTrue(
                    res,
                    "%s is included in list of available %s" % (item, words))
                # every item should only be mentioned once
                n = len(res)
                self.assertEqual(
                    n, 1, "%s is only mentioned once (count: %d)" % (item, n))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None

        if os.path.exists(dummylogfn):
            os.remove(dummylogfn)
    def test_zzz_logtostdout(self):
        """Testing redirecting log to stdout."""

        fd, dummylogfn = tempfile.mkstemp(prefix="easybuild-dummy", suffix=".log")
        os.close(fd)

        for stdout_arg in ["--logtostdout", "-l"]:

            _stdout = sys.stdout

            myerr = None
            fd, fn = tempfile.mkstemp()
            fh = os.fdopen(fd, "w")
            sys.stdout = fh

            args = ["--software-name=somethingrandom", "--robot", ".", "--debug", stdout_arg]
            try:
                main((args, dummylogfn, False))
            except (SystemExit, Exception), err:
                myerr = err

            # make sure we restore
            sys.stdout.flush()
            sys.stdout = _stdout
            fancylogger.logToScreen(enable=False, stdout=True)

            outtxt = read_file(fn)

            self.assertTrue(
                len(outtxt) > 100,
                "Log messages are printed to stdout when %s is used (outtxt: %s)" % (stdout_arg, outtxt),
            )

            # cleanup
            os.remove(fn)
            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None
Example #45
0
    def eb_main(self,
                args,
                do_build=False,
                return_error=False,
                logfile=None,
                verbose=False,
                raise_error=False,
                reset_env=True,
                raise_systemexit=False,
                testing=True):
        """Helper method to call EasyBuild main function."""
        cleanup()

        myerr = False
        if logfile is None:
            logfile = self.logfile
        # clear log file
        if logfile:
            f = open(logfile, 'w')
            f.write('')
            f.close()

        env_before = copy.deepcopy(os.environ)

        try:
            main(args=args,
                 logfile=logfile,
                 do_build=do_build,
                 testing=testing,
                 modtool=self.modtool)
        except SystemExit as err:
            if raise_systemexit:
                raise err
        except Exception as err:
            myerr = err
            if verbose:
                print "err: %s" % err

        if logfile and os.path.exists(logfile):
            logtxt = read_file(logfile)
        else:
            logtxt = None

        os.chdir(self.cwd)

        # make sure config is reinitialized
        init_config(with_include=False)

        # restore environment to what it was before running main,
        # changes may have been made by eb_main (e.g. $TMPDIR & co)
        if reset_env:
            modify_env(os.environ, env_before, verbose=False)
            tempfile.tempdir = None

        if myerr and raise_error:
            raise myerr

        if return_error:
            return logtxt, myerr
        else:
            return logtxt
Example #46
0
class EnhancedTestCase(_EnhancedTestCase):
    """Enhanced test case, provides extra functionality (e.g. an assertErrorRegex method)."""
    def setUp(self):
        """Set up testcase."""
        super(EnhancedTestCase, self).setUp()

        # make sure option parser doesn't pick up any cmdline arguments/options
        while len(sys.argv) > 1:
            sys.argv.pop()

        # keep track of log handlers
        log = fancylogger.getLogger(fname=False)
        self.orig_log_handlers = log.handlers[:]

        log.info("setting up test %s" % self.id())

        self.orig_tmpdir = tempfile.gettempdir()
        # use a subdirectory for this test (which we can clean up easily after the test completes)
        self.test_prefix = set_tmpdir()

        self.log = fancylogger.getLogger(self.__class__.__name__, fname=False)
        fd, self.logfile = tempfile.mkstemp(suffix='.log', prefix='eb-test-')
        os.close(fd)
        self.cwd = os.getcwd()

        # keep track of original environment to restore
        self.orig_environ = copy.deepcopy(os.environ)

        # keep track of original environment/Python search path to restore
        self.orig_sys_path = sys.path[:]

        testdir = os.path.dirname(os.path.abspath(__file__))

        self.test_sourcepath = os.path.join(testdir, 'sandbox', 'sources')
        os.environ['EASYBUILD_SOURCEPATH'] = self.test_sourcepath
        os.environ['EASYBUILD_PREFIX'] = self.test_prefix
        self.test_buildpath = tempfile.mkdtemp()
        os.environ['EASYBUILD_BUILDPATH'] = self.test_buildpath
        self.test_installpath = tempfile.mkdtemp()
        os.environ['EASYBUILD_INSTALLPATH'] = self.test_installpath

        # make sure that the tests only pick up easyconfigs provided with the tests
        os.environ['EASYBUILD_ROBOT_PATHS'] = os.path.join(
            testdir, 'easyconfigs')

        # make sure no deprecated behaviour is being triggered (unless intended by the test)
        # trip *all* log.deprecated statements by setting deprecation version ridiculously high
        self.orig_current_version = eb_build_log.CURRENT_VERSION
        os.environ['EASYBUILD_DEPRECATED'] = '10000000'

        init_config()

        import easybuild
        # try to import easybuild.easyblocks(.generic) packages
        # it's OK if it fails here, but important to import first before fiddling with sys.path
        try:
            import easybuild.easyblocks
            import easybuild.easyblocks.generic
        except ImportError:
            pass

        # add sandbox to Python search path, update namespace packages
        sys.path.append(os.path.join(testdir, 'sandbox'))

        # workaround for bug in recent setuptools version (19.4 and newer, atleast until 20.3.1)
        # injecting <prefix>/easybuild is required to avoid a ValueError being thrown by fixup_namespace_packages
        # cfr. https://bitbucket.org/pypa/setuptools/issues/520/fixup_namespace_packages-may-trigger
        for path in sys.path[:]:
            if os.path.exists(
                    os.path.join(path, 'easybuild', 'easyblocks',
                                 '__init__.py')):
                # keep track of 'easybuild' paths to inject into sys.path later
                sys.path.append(os.path.join(path, 'easybuild'))

        # required to make sure the 'easybuild' dir in the sandbox is picked up;
        # this relates to the other 'reload' statements below
        reload(easybuild)

        # this is strictly required to make the test modules in the sandbox available, due to declare_namespace
        fixup_namespace_packages(os.path.join(testdir, 'sandbox'))

        # remove any entries in Python search path that seem to provide easyblocks (except the sandbox)
        for path in sys.path[:]:
            if os.path.exists(
                    os.path.join(path, 'easybuild', 'easyblocks',
                                 '__init__.py')):
                if not os.path.samefile(path, os.path.join(testdir,
                                                           'sandbox')):
                    sys.path.remove(path)

        # hard inject location to (generic) test easyblocks into Python search path
        # only prepending to sys.path is not enough due to 'declare_namespace' in easybuild/easyblocks/__init__.py
        import easybuild.easyblocks
        reload(easybuild.easyblocks)
        test_easyblocks_path = os.path.join(testdir, 'sandbox', 'easybuild',
                                            'easyblocks')
        easybuild.easyblocks.__path__.insert(0, test_easyblocks_path)
        import easybuild.easyblocks.generic
        reload(easybuild.easyblocks.generic)
        test_easyblocks_path = os.path.join(test_easyblocks_path, 'generic')
        easybuild.easyblocks.generic.__path__.insert(0, test_easyblocks_path)

        # save values of $PATH & $PYTHONPATH, so they can be restored later
        # this is important in case EasyBuild was installed as a module, since that module may be unloaded,
        # for example due to changes to $MODULEPATH in case EasyBuild was installed in a module hierarchy
        # cfr. https://github.com/hpcugent/easybuild-framework/issues/1685
        self.env_path = os.environ['PATH']
        self.env_pythonpath = os.environ['PYTHONPATH']

        self.modtool = modules_tool()
        self.reset_modulepath([os.path.join(testdir, 'modules')])
        reset_module_caches()

    def tearDown(self):
        """Clean up after running testcase."""
        super(EnhancedTestCase, self).tearDown()

        self.log.info("Cleaning up for test %s", self.id())

        # go back to where we were before
        os.chdir(self.cwd)

        # restore original environment
        modify_env(os.environ, self.orig_environ, verbose=False)

        # restore original Python search path
        sys.path = self.orig_sys_path
        import easybuild.easyblocks
        reload(easybuild.easyblocks)
        import easybuild.easyblocks.generic
        reload(easybuild.easyblocks.generic)

        # remove any log handlers that were added (so that log files can be effectively removed)
        log = fancylogger.getLogger(fname=False)
        new_log_handlers = [
            h for h in log.handlers if h not in self.orig_log_handlers
        ]
        for log_handler in new_log_handlers:
            log_handler.close()
            log.removeHandler(log_handler)

        # cleanup test tmp dir
        try:
            shutil.rmtree(self.test_prefix)
        except (OSError, IOError):
            pass

        # restore original 'parent' tmpdir
        for var in ['TMPDIR', 'TEMP', 'TMP']:
            os.environ[var] = self.orig_tmpdir

        # reset to make sure tempfile picks up new temporary directory to use
        tempfile.tempdir = None

    def restore_env_path_pythonpath(self):
        """
        Restore $PATH & $PYTHONPATH in environment using saved values.
        """
        os.environ['PATH'] = self.env_path
        os.environ['PYTHONPATH'] = self.env_pythonpath

    def reset_modulepath(self, modpaths):
        """Reset $MODULEPATH with specified paths."""
        for modpath in curr_module_paths():
            self.modtool.remove_module_path(modpath, set_mod_paths=False)
        # make very sure $MODULEPATH is totally empty
        # some paths may be left behind, e.g. when they contain environment variables
        # example: "module unuse Modules/$MODULE_VERSION/modulefiles" may not yield the desired result
        os.environ['MODULEPATH'] = ''
        for modpath in modpaths:
            self.modtool.add_module_path(modpath, set_mod_paths=False)
        self.modtool.set_mod_paths()

    def eb_main(self,
                args,
                do_build=False,
                return_error=False,
                logfile=None,
                verbose=False,
                raise_error=False,
                reset_env=True,
                raise_systemexit=False,
                testing=True):
        """Helper method to call EasyBuild main function."""
        cleanup()

        myerr = False
        if logfile is None:
            logfile = self.logfile
        # clear log file
        if logfile:
            f = open(logfile, 'w')
            f.write('')
            f.close()

        env_before = copy.deepcopy(os.environ)

        try:
            main(args=args,
                 logfile=logfile,
                 do_build=do_build,
                 testing=testing,
                 modtool=self.modtool)
        except SystemExit:
            if raise_systemexit:
                raise err
        except Exception, err:
            myerr = err
            if verbose:
                print "err: %s" % err

        if logfile and os.path.exists(logfile):
            logtxt = read_file(logfile)
        else:
            logtxt = None

        os.chdir(self.cwd)

        # make sure config is reinitialized
        init_config(with_include=False)

        # restore environment to what it was before running main,
        # changes may have been made by eb_main (e.g. $TMPDIR & co)
        if reset_env:
            modify_env(os.environ, env_before, verbose=False)
            tempfile.tempdir = None

        if myerr and raise_error:
            raise myerr

        if return_error:
            return logtxt, myerr
        else:
            return logtxt
Example #47
0
        not_found = re.search(not_found_msg, outtxt)
        self.assertTrue(
            not_found,
            "Module not found message there with --skip for non-existing modules: %s"
            % outtxt)

        modules_tool().purge()

        # restore original MODULEPATH
        if orig_modulepath is not None:
            os.environ['MODULEPATH'] = orig_modulepath
        else:
            os.environ.pop('MODULEPATH')
        # reinitialize modules tool with original $MODULEPATH, to avoid problems with future tests
        modules_tool()
        modify_env(os.environ, orig_environ)

        # cleanup
        shutil.rmtree(buildpath)
        shutil.rmtree(installpath)

    def test_job(self):
        """Test submitting build as a job."""

        # set MODULEPATH to included modules
        orig_modulepath = os.getenv('MODULEPATH', None)
        os.environ['MODULEPATH'] = os.path.join(os.path.dirname(__file__),
                                                'modules')

        # use gzip-1.4.eb easyconfig file that comes with the tests
        eb_file = os.path.join(os.path.dirname(__file__), 'easyconfigs',
Example #48
0
    def test_skip(self):
        """Test skipping installation of module (--skip, -k)."""

        # use temporary paths for build/install paths, make sure sources can be found
        buildpath = tempfile.mkdtemp()
        installpath = tempfile.mkdtemp()
        sourcepath = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                  'sandbox', 'sources')

        # use toy-0.0.eb easyconfig file that comes with the tests
        eb_file = os.path.join(os.path.dirname(__file__), 'easyconfigs',
                               'toy-0.0.eb')

        # check log message with --skip for existing module
        args = [
            eb_file,
            '--sourcepath=%s' % sourcepath,
            '--buildpath=%s' % buildpath,
            '--installpath=%s' % installpath,
            '--force',
            '--debug',
        ]
        self.eb_main(args, do_build=True)
        modules_tool().purge()

        args.append('--skip')
        outtxt = self.eb_main(args, do_build=True, verbose=True)

        found_msg = "Module toy/0.0 found.\n[^\n]+Going to skip actual main build"
        found = re.search(found_msg, outtxt, re.M)
        self.assertTrue(
            found,
            "Module found message present with --skip, outtxt: %s" % outtxt)

        # cleanup for next test
        write_file(self.logfile, '')
        os.chdir(self.cwd)
        modules_tool().purge()
        # reinitialize modules tool with original $MODULEPATH, to avoid problems with future tests
        modify_env(os.environ, self.orig_environ)
        os.environ['MODULEPATH'] = ''
        modules_tool()
        tempfile.tempdir = None

        # check log message with --skip for non-existing module
        args = [
            eb_file,
            '--sourcepath=%s' % sourcepath,
            '--buildpath=%s' % buildpath,
            '--installpath=%s' % installpath,
            '--try-software-version=1.2.3.4.5.6.7.8.9',
            '--try-amend=sources=toy-0.0.tar.gz,toy-0.0.tar.gz',  # hackish, but fine
            '--force',
            '--debug',
            '--skip',
        ]
        outtxt = self.eb_main(args, do_build=True, verbose=True)

        found_msg = "Module toy/1.2.3.4.5.6.7.8.9 found."
        found = re.search(found_msg, outtxt)
        self.assertTrue(
            not found,
            "Module found message not there with --skip for non-existing modules: %s"
            % outtxt)

        not_found_msg = "No module toy/1.2.3.4.5.6.7.8.9 found. Not skipping anything."
        not_found = re.search(not_found_msg, outtxt)
        self.assertTrue(
            not_found,
            "Module not found message there with --skip for non-existing modules: %s"
            % outtxt)

        modules_tool().purge()
        # reinitialize modules tool with original $MODULEPATH, to avoid problems with future tests
        modify_env(os.environ, self.orig_environ)
        modules_tool()

        # cleanup
        shutil.rmtree(buildpath)
        shutil.rmtree(installpath)
Example #49
0
class EnhancedTestCase(_EnhancedTestCase):
    """Enhanced test case, provides extra functionality (e.g. an assertErrorRegex method)."""
    def setUp(self):
        """Set up testcase."""
        super(EnhancedTestCase, self).setUp()

        # keep track of log handlers
        log = fancylogger.getLogger(fname=False)
        self.orig_log_handlers = log.handlers[:]

        log.info("setting up test %s" % self.id())

        self.orig_tmpdir = tempfile.gettempdir()
        # use a subdirectory for this test (which we can clean up easily after the test completes)
        self.test_prefix = set_tmpdir()

        self.log = fancylogger.getLogger(self.__class__.__name__, fname=False)
        fd, self.logfile = tempfile.mkstemp(suffix='.log', prefix='eb-test-')
        os.close(fd)
        self.cwd = os.getcwd()

        # keep track of original environment to restore
        self.orig_environ = copy.deepcopy(os.environ)

        # keep track of original environment/Python search path to restore
        self.orig_sys_path = sys.path[:]

        testdir = os.path.dirname(os.path.abspath(__file__))

        self.test_sourcepath = os.path.join(testdir, 'sandbox', 'sources')
        os.environ['EASYBUILD_SOURCEPATH'] = self.test_sourcepath
        os.environ['EASYBUILD_PREFIX'] = self.test_prefix
        self.test_buildpath = tempfile.mkdtemp()
        os.environ['EASYBUILD_BUILDPATH'] = self.test_buildpath
        self.test_installpath = tempfile.mkdtemp()
        os.environ['EASYBUILD_INSTALLPATH'] = self.test_installpath

        # make sure that the tests only pick up easyconfigs provided with the tests
        os.environ['EASYBUILD_ROBOT_PATHS'] = os.path.join(
            testdir, 'easyconfigs')

        # make sure no deprecated behaviour is being triggered (unless intended by the test)
        # trip *all* log.deprecated statements by setting deprecation version ridiculously high
        self.orig_current_version = eb_build_log.CURRENT_VERSION
        os.environ['EASYBUILD_DEPRECATED'] = '10000000'

        init_config()

        # remove any entries in Python search path that seem to provide easyblocks
        for path in sys.path[:]:
            if os.path.exists(
                    os.path.join(path, 'easybuild', 'easyblocks',
                                 '__init__.py')):
                sys.path.remove(path)

        # add test easyblocks to Python search path and (re)import and reload easybuild modules
        import easybuild
        sys.path.append(os.path.join(testdir, 'sandbox'))
        reload(easybuild)
        import easybuild.easyblocks
        reload(easybuild.easyblocks)
        import easybuild.easyblocks.generic
        reload(easybuild.easyblocks.generic)
        reload(easybuild.tools.module_naming_scheme
               )  # required to run options unit tests stand-alone

        modtool = modules_tool()
        # purge out any loaded modules with original $MODULEPATH before running each test
        modtool.purge()
        self.reset_modulepath([os.path.join(testdir, 'modules')])

    def tearDown(self):
        """Clean up after running testcase."""
        super(EnhancedTestCase, self).tearDown()

        self.log.info("Cleaning up for test %s", self.id())

        # go back to where we were before
        os.chdir(self.cwd)

        # restore original environment
        modify_env(os.environ, self.orig_environ, verbose=False)

        # restore original Python search path
        sys.path = self.orig_sys_path

        # remove any log handlers that were added (so that log files can be effectively removed)
        log = fancylogger.getLogger(fname=False)
        new_log_handlers = [
            h for h in log.handlers if h not in self.orig_log_handlers
        ]
        for log_handler in new_log_handlers:
            log_handler.close()
            log.removeHandler(log_handler)

        # cleanup test tmp dir
        try:
            shutil.rmtree(self.test_prefix)
        except (OSError, IOError):
            pass

        # restore original 'parent' tmpdir
        for var in ['TMPDIR', 'TEMP', 'TMP']:
            os.environ[var] = self.orig_tmpdir

        # reset to make sure tempfile picks up new temporary directory to use
        tempfile.tempdir = None

    def reset_modulepath(self, modpaths):
        """Reset $MODULEPATH with specified paths."""
        modtool = modules_tool()
        for modpath in os.environ.get('MODULEPATH', '').split(os.pathsep):
            modtool.remove_module_path(modpath)
        # make very sure $MODULEPATH is totally empty
        # some paths may be left behind, e.g. when they contain environment variables
        # example: "module unuse Modules/$MODULE_VERSION/modulefiles" may not yield the desired result
        os.environ['MODULEPATH'] = ''
        for modpath in modpaths:
            modtool.add_module_path(modpath)

    def eb_main(self,
                args,
                do_build=False,
                return_error=False,
                logfile=None,
                verbose=False,
                raise_error=False,
                reset_env=True,
                raise_systemexit=False,
                testing=True):
        """Helper method to call EasyBuild main function."""
        cleanup()

        myerr = False
        if logfile is None:
            logfile = self.logfile
        # clear log file
        if logfile:
            f = open(logfile, 'w')
            f.write('')
            f.close()

        env_before = copy.deepcopy(os.environ)

        try:
            main(args=args,
                 logfile=logfile,
                 do_build=do_build,
                 testing=testing)
        except SystemExit:
            if raise_systemexit:
                raise err
        except Exception, err:
            myerr = err
            if verbose:
                print "err: %s" % err

        if logfile and os.path.exists(logfile):
            logtxt = read_file(logfile)
        else:
            logtxt = None

        os.chdir(self.cwd)

        # make sure config is reinitialized
        init_config()

        # restore environment to what it was before running main,
        # changes may have been made by eb_main (e.g. $TMPDIR & co)
        if reset_env:
            modify_env(os.environ, env_before)
            tempfile.tempdir = None

        if myerr and raise_error:
            raise myerr

        if return_error:
            return logtxt, myerr
        else:
            return logtxt
Example #50
0
    def test_skip(self):
        """Test skipping installation of module (--skip, -k)."""

        # use temporary paths for build/install paths, make sure sources can be found
        buildpath = tempfile.mkdtemp()
        installpath = tempfile.mkdtemp()
        sourcepath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'sandbox', 'sources')

        # use toy-0.0.eb easyconfig file that comes with the tests
        eb_file = os.path.join(os.path.dirname(__file__), 'easyconfigs', 'toy-0.0.eb')

        # check log message with --skip for existing module
        args = [
            eb_file,
            '--sourcepath=%s' % sourcepath,
            '--buildpath=%s' % buildpath,
            '--installpath=%s' % installpath,
            '--force',
            '--debug',
        ]
        self.eb_main(args, do_build=True)
        modules_tool().purge()

        args.append('--skip')
        outtxt = self.eb_main(args, do_build=True, verbose=True)

        found_msg = "Module toy/0.0 found.\n[^\n]+Going to skip actual main build"
        found = re.search(found_msg, outtxt, re.M)
        self.assertTrue(found, "Module found message present with --skip, outtxt: %s" % outtxt)

        # cleanup for next test
        write_file(self.logfile, '')
        os.chdir(self.cwd)
        modules_tool().purge()
        # reinitialize modules tool with original $MODULEPATH, to avoid problems with future tests
        modify_env(os.environ, self.orig_environ)
        os.environ['MODULEPATH'] = ''
        modules_tool()
        tempfile.tempdir = None

        # check log message with --skip for non-existing module
        args = [
            eb_file,
            '--sourcepath=%s' % sourcepath,
            '--buildpath=%s' % buildpath,
            '--installpath=%s' % installpath,
            '--try-software-version=1.2.3.4.5.6.7.8.9',
            '--try-amend=sources=toy-0.0.tar.gz,toy-0.0.tar.gz',  # hackish, but fine
            '--force',
            '--debug',
            '--skip',
        ]
        outtxt = self.eb_main(args, do_build=True, verbose=True)

        found_msg = "Module toy/1.2.3.4.5.6.7.8.9 found."
        found = re.search(found_msg, outtxt)
        self.assertTrue(not found, "Module found message not there with --skip for non-existing modules: %s" % outtxt)

        not_found_msg = "No module toy/1.2.3.4.5.6.7.8.9 found. Not skipping anything."
        not_found = re.search(not_found_msg, outtxt)
        self.assertTrue(not_found, "Module not found message there with --skip for non-existing modules: %s" % outtxt)

        modules_tool().purge()
        # reinitialize modules tool with original $MODULEPATH, to avoid problems with future tests
        modify_env(os.environ, self.orig_environ)
        modules_tool()

        # cleanup
        shutil.rmtree(buildpath)
        shutil.rmtree(installpath)
Example #51
0
def modify_env(old, new):
    """
    Compares 2 os.environ dumps. Adapts final environment.
    """
    _log.deprecated("moved modify_env to tools.environment", "2.0")
    return env.modify_env(old, new)
def modify_env(old, new):
    """
    Compares 2 os.environ dumps. Adapts final environment.
    """
    _log.deprecated("moved modify_env to tools.environment", "2.0")
    return env.modify_env(old, new)
Example #53
0
    def test_list_easyblocks(self):
        """Test listing easyblock hierarchy."""

        fd, dummylogfn = tempfile.mkstemp(prefix='easybuild-dummy', suffix='.log')
        os.close(fd)

        # adjust PYTHONPATH such that test easyblocks are found

        import easybuild
        eb_blocks_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'sandbox'))
        if not eb_blocks_path in sys.path:
            sys.path.append(eb_blocks_path)
            easybuild = reload(easybuild)

        import easybuild.easyblocks
        reload(easybuild.easyblocks)
        reload(easybuild.tools.module_naming_scheme)  # required to run options unit tests stand-alone

        # simple view
        for list_arg in ['--list-easyblocks', '--list-easyblocks=simple']:

            # clear log
            write_file(self.logfile, '')

            args = [
                    list_arg,
                    '--unittest-file=%s' % self.logfile,
                   ]
            outtxt = self.eb_main(args, logfile=dummylogfn)

            for pat in [
                        r"EasyBlock\n",
                        r"|--\s+EB_foo\n|\s+|--\s+EB_foofoo\n",
                        r"|--\s+bar\n",
                       ]:

                self.assertTrue(re.search(pat, outtxt), "Pattern '%s' is found in output of --list-easyblocks: %s" % (pat, outtxt))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None

        # clear log
        write_file(self.logfile, '')

        # detailed view
        args = [
                '--list-easyblocks=detailed',
                '--unittest-file=%s' % self.logfile,
               ]
        outtxt = self.eb_main(args, logfile=dummylogfn)

        for pat in [
                    r"EasyBlock\s+\(easybuild.framework.easyblock\)\n",
                    r"|--\s+EB_foo\s+\(easybuild.easyblocks.foo\)\n|\s+|--\s+EB_foofoo\s+\(easybuild.easyblocks.foofoo\)\n",
                    r"|--\s+bar\s+\(easybuild.easyblocks.generic.bar\)\n",
                   ]:

            self.assertTrue(re.search(pat, outtxt), "Pattern '%s' is found in output of --list-easyblocks: %s" % (pat, outtxt))

        if os.path.exists(dummylogfn):
            os.remove(dummylogfn)
Example #54
0
    def test_list_easyblocks(self):
        """Test listing easyblock hierarchy."""

        fd, dummylogfn = tempfile.mkstemp(prefix='easybuild-dummy',
                                          suffix='.log')
        os.close(fd)

        # adjust PYTHONPATH such that test easyblocks are found

        import easybuild
        eb_blocks_path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), 'sandbox'))
        if not eb_blocks_path in sys.path:
            sys.path.append(eb_blocks_path)
            easybuild = reload(easybuild)

        import easybuild.easyblocks
        reload(easybuild.easyblocks)
        reload(easybuild.tools.module_naming_scheme
               )  # required to run options unit tests stand-alone

        # simple view
        for list_arg in ['--list-easyblocks', '--list-easyblocks=simple']:

            # clear log
            write_file(self.logfile, '')

            args = [
                list_arg,
                '--unittest-file=%s' % self.logfile,
            ]
            outtxt = self.eb_main(args, logfile=dummylogfn)

            for pat in [
                    r"EasyBlock\n",
                    r"|--\s+EB_foo\n|\s+|--\s+EB_foofoo\n",
                    r"|--\s+bar\n",
            ]:

                self.assertTrue(
                    re.search(pat, outtxt),
                    "Pattern '%s' is found in output of --list-easyblocks: %s"
                    % (pat, outtxt))

            modify_env(os.environ, self.orig_environ)
            tempfile.tempdir = None

        # clear log
        write_file(self.logfile, '')

        # detailed view
        args = [
            '--list-easyblocks=detailed',
            '--unittest-file=%s' % self.logfile,
        ]
        outtxt = self.eb_main(args, logfile=dummylogfn)

        for pat in [
                r"EasyBlock\s+\(easybuild.framework.easyblock\)\n",
                r"|--\s+EB_foo\s+\(easybuild.easyblocks.foo\)\n|\s+|--\s+EB_foofoo\s+\(easybuild.easyblocks.foofoo\)\n",
                r"|--\s+bar\s+\(easybuild.easyblocks.generic.bar\)\n",
        ]:

            self.assertTrue(
                re.search(pat, outtxt),
                "Pattern '%s' is found in output of --list-easyblocks: %s" %
                (pat, outtxt))

        if os.path.exists(dummylogfn):
            os.remove(dummylogfn)