Exemple #1
0
    def test_get_start_update_stop_progress_bar(self):
        """
        Test starting/updating/stopping of progress bars.
        """
        # clear progress bar cache first, this test assumes we start with a clean slate
        easybuild.tools.output._progress_bar_cache.clear()

        # restore default configuration to show progress bars (disabled to avoid mangled test output)
        update_build_option('show_progress_bar', True)

        # 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)

        # updating a progress bar that never was started is silently ignored on purpose
        update_progress_bar(PROGRESS_BAR_EXTENSIONS)
        update_progress_bar(PROGRESS_BAR_EXTENSIONS, label="foo")
        update_progress_bar(PROGRESS_BAR_EXTENSIONS, progress_size=100)

        # also test normal cycle: start, update, stop
        start_progress_bar(PROGRESS_BAR_EXTENSIONS, 100)
        update_progress_bar(PROGRESS_BAR_EXTENSIONS)  # single step progress
        update_progress_bar(PROGRESS_BAR_EXTENSIONS, total=50)
        update_progress_bar(PROGRESS_BAR_EXTENSIONS,
                            label="test123",
                            progress_size=5)
        stop_progress_bar(PROGRESS_BAR_EXTENSIONS)
Exemple #2
0
    def test_update_build_option(self):
        """Test updating of a build option."""
        self.assertEqual(build_option('banned_linked_shared_libs'), None)

        update_build_option('banned_linked_shared_libs',
                            '/usr/lib64/libssl.so.1.1')
        self.assertEqual(build_option('banned_linked_shared_libs'),
                         '/usr/lib64/libssl.so.1.1')
Exemple #3
0
    def test_create_progress_bar(self):
        """Test create_progress_bar function."""

        # restore default (was disabled in EnhancedTestCase.setUp to avoid messing up test output)
        update_build_option('show_progress_bar', True)

        if HAVE_RICH:
            expected_progress_bar_class = rich.progress.Progress
        else:
            expected_progress_bar_class = DummyProgress

        progress_bar = create_progress_bar()
        error_msg = "%s should be instance of class %s" % (
            progress_bar, expected_progress_bar_class)
        self.assertTrue(isinstance(progress_bar, expected_progress_bar_class),
                        error_msg)

        update_build_option('output_style', 'basic')
        progress_bar = create_progress_bar()
        self.assertTrue(isinstance(progress_bar, DummyProgress))

        if HAVE_RICH:
            update_build_option('output_style', 'rich')
            progress_bar = create_progress_bar()
            error_msg = "%s should be instance of class %s" % (
                progress_bar, expected_progress_bar_class)
            self.assertTrue(
                isinstance(progress_bar, expected_progress_bar_class),
                error_msg)

        update_build_option('show_progress_bar', False)
        progress_bar = create_progress_bar()
        self.assertTrue(isinstance(progress_bar, DummyProgress))
Exemple #4
0
    def test_get_progress_bar(self):
        """
        Test get_progress_bar.
        """
        # restore default configuration to show progress bars (disabled to avoid mangled test output),
        # to ensure we'll get actual Progress instances when Rich is available
        update_build_option('show_progress_bar', True)

        for pbar_type in PROGRESS_BAR_TYPES:
            pbar = get_progress_bar(pbar_type, ignore_cache=True)
            if HAVE_RICH:
                self.assertTrue(isinstance(pbar, rich.progress.Progress))
            else:
                self.assertTrue(isinstance(pbar, DummyRich))
    def test_submit_jobs(self):
        """Test submit_jobs"""
        test_easyconfigs_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs')
        toy_ec = os.path.join(test_easyconfigs_dir, 't', 'toy', 'toy-0.0.eb')

        args = [
            '--debug',
            '--tmpdir', '/tmp',
            '--optarch="GCC:O3 -mtune=generic;Intel:O3 -xHost"',
            '--parallel=2',
            '--try-toolchain=intel,2016a',  # should be excluded in job script
            '--robot', self.test_prefix,  # should be excluded in job script
            '--job',  # should be excluded in job script
            '--job-cores=3',
        ]
        eb_go = parse_options(args=args)
        cmd = submit_jobs([toy_ec], eb_go.generate_cmd_line(), testing=True)

        # these patterns must be found
        regexs = [
            r' --debug ',
            # values got wrapped in single quotes (to avoid interpretation by shell)
            r" --tmpdir='/tmp' ",
            r" --parallel='2' ",
            # (unparsed) optarch value got wrapped in single quotes, double quotes got stripped
            r" --optarch='GCC:O3 -mtune=generic;Intel:O3 -xHost' ",
            # templates to be completed via build_easyconfigs_in_parallel -> create_job
            r' eb %\(spec\)s ',
            r' %\(add_opts\)s ',
            r' --testoutput=%\(output_dir\)s',
            r' --disable-job ',
        ]
        for regex in regexs:
            regex = re.compile(regex)
            self.assertTrue(regex.search(cmd), "Pattern '%s' found in: %s" % (regex.pattern, cmd))

        # these patterns should NOT be found, these options get filtered out
        # (self.test_prefix was argument to --robot)
        for regex in ['--job', '--job-cores', '--try-toolchain', '--robot=[ =]', self.test_prefix + ' ']:
            regex = re.compile(regex)
            self.assertFalse(regex.search(cmd), "Pattern '%s' should *not* be found in: %s" % (regex.pattern, cmd))

        # test again with custom EasyBuild command to use in jobs
        update_build_option('job_eb_cmd', "/just/testing/bin/eb --debug")
        cmd = submit_jobs([toy_ec], eb_go.generate_cmd_line(), testing=True)
        regex = re.compile(r" && /just/testing/bin/eb --debug %\(spec\)s ")
        self.assertTrue(regex.search(cmd), "Pattern '%s' found in: %s" % (regex.pattern, cmd))
Exemple #6
0
    def test_update_build_option(self):
        """Test updating of a build option."""
        self.assertEqual(build_option('banned_linked_shared_libs'), None)
        orig_banned_linked_shared_libs = update_build_option(
            'banned_linked_shared_libs', '/usr/lib64/libssl.so.1.1')
        self.assertEqual(build_option('banned_linked_shared_libs'),
                         '/usr/lib64/libssl.so.1.1')
        self.assertEqual(orig_banned_linked_shared_libs, None)

        self.assertTrue(build_option('cleanup_builddir'))
        orig_cleanup_builddir = update_build_option('cleanup_builddir', False)
        self.assertFalse(build_option('cleanup_builddir'))
        self.assertTrue(orig_cleanup_builddir)

        self.assertEqual(build_option('pr_target_account'), 'easybuilders')
        orig_pr_target_account = update_build_option('pr_target_account',
                                                     'test_pr_target_account')
        self.assertEqual(build_option('pr_target_account'),
                         'test_pr_target_account')
        self.assertEqual(orig_pr_target_account, 'easybuilders')
Exemple #7
0
    def test_get_output_style(self):
        """Test get_output_style function."""

        self.assertEqual(build_option('output_style'), 'auto')

        for style in (None, 'auto'):
            if style:
                update_build_option('output_style', style)

            if HAVE_RICH:
                self.assertEqual(get_output_style(), 'rich')
            else:
                self.assertEqual(get_output_style(), 'basic')

        test_styles = ['basic', 'no_color']
        if HAVE_RICH:
            test_styles.append('rich')

        for style in test_styles:
            update_build_option('output_style', style)
            self.assertEqual(get_output_style(), style)

        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)
Exemple #8
0
    def test_use_rich_show_progress_bars(self):
        """Test use_rich and show_progress_bar functions."""

        # restore default configuration to show progress bars (disabled to avoid mangled test output)
        update_build_option('show_progress_bar', True)

        self.assertEqual(build_option('output_style'), 'auto')

        if HAVE_RICH:
            self.assertTrue(use_rich())
            self.assertTrue(show_progress_bars())

            update_build_option('output_style', 'rich')
            self.assertTrue(use_rich())
            self.assertTrue(show_progress_bars())
        else:
            self.assertFalse(use_rich())
            self.assertFalse(show_progress_bars())

        update_build_option('output_style', 'basic')
        self.assertFalse(use_rich())
        self.assertFalse(show_progress_bars())
    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', 'test_ecs')

        # make sure that the EasyBuild installation is still known even if we purge an EB module
        if os.getenv('EB_SCRIPT_PATH') is None:
            eb_path = which('eb')
            if eb_path is not None:
                os.environ['EB_SCRIPT_PATH'] = eb_path

        # make sure no deprecated behaviour is being triggered (unless intended by the test)
        self.orig_current_version = eb_build_log.CURRENT_VERSION
        self.disallow_deprecated_behaviour()

        init_config()

        # disable progress bars when running the tests,
        # since it messes with test suite progress output when test installations are performed
        os.environ['EASYBUILD_DISABLE_SHOW_PROGRESS_BAR'] = '1'
        update_build_option('show_progress_bar', False)

        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
        testdir_sandbox = os.path.join(testdir, 'sandbox')
        sys.path.append(testdir_sandbox)

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

        # required to 'reset' easybuild.tools.module_naming_scheme namespace
        reload(easybuild.tools)
        reload(easybuild.tools.module_naming_scheme)

        # 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, 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 'pkgutil.extend_path' in easybuild/easyblocks/__init__.py
        easybuild.__path__.insert(0, os.path.join(testdir_sandbox, 'easybuild'))
        import easybuild.easyblocks
        test_easyblocks_path = os.path.join(testdir_sandbox, 'easybuild', 'easyblocks')
        easybuild.easyblocks.__path__.insert(0, test_easyblocks_path)
        reload(easybuild.easyblocks)

        import easybuild.easyblocks.generic
        test_easyblocks_path = os.path.join(test_easyblocks_path, 'generic')
        easybuild.easyblocks.generic.__path__.insert(0, test_easyblocks_path)
        reload(easybuild.easyblocks.generic)

        # kick out any paths that shouldn't be there for easybuild.easyblocks and easybuild.easyblocks.generic
        # to avoid that easyblocks picked up from other places cause trouble
        for pkg in ('easybuild.easyblocks', 'easybuild.easyblocks.generic'):
            for path in sys.modules[pkg].__path__[:]:
                if testdir_sandbox not in path:
                    sys.modules[pkg].__path__.remove(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/easybuilders/easybuild-framework/issues/1685
        self.env_path = os.environ.get('PATH')
        self.env_pythonpath = os.environ.get('PYTHONPATH')

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