def check_easyconfigs_style(easyconfigs, verbose=False): """ Check the given list of easyconfigs for style :param: easyconfigs list of file paths to easyconfigs :param: verbose print our statistics and be verbose about the errors and warning :return: the number of warnings and errors """ # importing autopep8 changes some pep8 functions. # We reload it to be sure to get the real pep8 functions. if 'pycodestyle' in sys.modules: reload(pycodestyle) else: reload(pep8) # register the extra checks before using pep8: # any function in this module starting with `_eb_check_` will be used. cands = globals() for check_function in sorted([ cands[f] for f in cands if callable(cands[f]) and f.startswith(EB_CHECK) ]): _log.debug("Adding custom style check %s", check_function) register_check(check_function) styleguide = StyleGuide(quiet=False, config_file=None) options = styleguide.options # we deviate from standard pep8 and allow 120 chars # on a line: the default of 79 is too narrow. options.max_line_length = MAX_LINE_LENGTH # we ignore some tests # note that W291 has been replaced by our custom W299 options.ignore = ( 'W291', # replaced by W299 ) options.verbose = int(verbose) result = styleguide.check_files(easyconfigs) if verbose: result.print_statistics() return result.total_errors
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) self.allow_deprecated_behaviour() # 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 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 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() 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')) # 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, 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 '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) # 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()
def setUp(self): """Prepare for running a config test.""" reload(eboptions) super(EasyBuildConfigTest, self).setUp() self.tmpdir = tempfile.mkdtemp()
def test_XDG_CONFIG_env_vars(self): """Test effect of XDG_CONFIG* environment variables on default configuration.""" self.purge_environment() xdg_config_home = os.environ.get('XDG_CONFIG_HOME') xdg_config_dirs = os.environ.get('XDG_CONFIG_DIRS') cfg_template = '\n'.join([ '[config]', 'prefix=%s', ]) homedir = os.path.join(self.test_prefix, 'homedir', '.config') mkdir(os.path.join(homedir, 'easybuild'), parents=True) write_file(os.path.join(homedir, 'easybuild', 'config.cfg'), cfg_template % '/home') dir1 = os.path.join(self.test_prefix, 'dir1') mkdir(os.path.join(dir1, 'easybuild.d'), parents=True) write_file(os.path.join(dir1, 'easybuild.d', 'foo.cfg'), cfg_template % '/foo') write_file(os.path.join(dir1, 'easybuild.d', 'bar.cfg'), cfg_template % '/bar') dir2 = os.path.join(self.test_prefix, 'dir2') # empty on purpose mkdir(os.path.join(dir2, 'easybuild.d'), parents=True) dir3 = os.path.join(self.test_prefix, 'dir3') mkdir(os.path.join(dir3, 'easybuild.d'), parents=True) write_file(os.path.join(dir3, 'easybuild.d', 'foobarbaz.cfg'), cfg_template % '/foobarbaz') # set $XDG_CONFIG_DIRS to non-existing dir to isolate ourselves from possible system-wide config files os.environ[ 'XDG_CONFIG_DIRS'] = '/there/should/be/no/such/directory/we/hope' # only $XDG_CONFIG_HOME set (to existing path) os.environ['XDG_CONFIG_HOME'] = homedir cfg_files = [os.path.join(homedir, 'easybuild', 'config.cfg')] reload(eboptions) eb_go = eboptions.parse_options(args=[]) self.assertEqual(eb_go.options.configfiles, cfg_files) self.assertEqual(eb_go.options.prefix, '/home') # $XDG_CONFIG_HOME set, one directory listed in $XDG_CONFIG_DIRS os.environ['XDG_CONFIG_DIRS'] = dir1 cfg_files = [ os.path.join(dir1, 'easybuild.d', 'bar.cfg'), os.path.join(dir1, 'easybuild.d', 'foo.cfg'), os.path.join(homedir, 'easybuild', 'config.cfg'), # $XDG_CONFIG_HOME goes last ] reload(eboptions) eb_go = eboptions.parse_options(args=[]) self.assertEqual(eb_go.options.configfiles, cfg_files) self.assertEqual(eb_go.options.prefix, '/home') # last cfgfile wins # $XDG_CONFIG_HOME not set, multiple directories listed in $XDG_CONFIG_DIRS del os.environ['XDG_CONFIG_HOME'] # unset, so should become default os.environ['XDG_CONFIG_DIRS'] = os.pathsep.join([dir1, dir2, dir3]) cfg_files = [ os.path.join(dir1, 'easybuild.d', 'bar.cfg'), os.path.join(dir1, 'easybuild.d', 'foo.cfg'), os.path.join(dir3, 'easybuild.d', 'foobarbaz.cfg'), ] reload(eboptions) eb_go = eboptions.parse_options(args=[]) # note: there may be a config file in $HOME too, so don't use a strict comparison self.assertEqual(cfg_files, eb_go.options.configfiles[:3]) # $XDG_CONFIG_HOME set to non-existing directory, multiple directories listed in $XDG_CONFIG_DIRS os.environ['XDG_CONFIG_HOME'] = os.path.join(self.test_prefix, 'nosuchdir') cfg_files = [ os.path.join(dir1, 'easybuild.d', 'bar.cfg'), os.path.join(dir1, 'easybuild.d', 'foo.cfg'), os.path.join(dir3, 'easybuild.d', 'foobarbaz.cfg'), ] reload(eboptions) eb_go = eboptions.parse_options(args=[]) self.assertEqual(eb_go.options.configfiles, cfg_files) self.assertEqual(eb_go.options.prefix, '/foobarbaz') # last cfgfile wins # restore $XDG_CONFIG env vars to original state if xdg_config_home is None: del os.environ['XDG_CONFIG_HOME'] else: os.environ['XDG_CONFIG_HOME'] = xdg_config_home if xdg_config_dirs is None: del os.environ['XDG_CONFIG_DIRS'] else: os.environ['XDG_CONFIG_DIRS'] = xdg_config_dirs reload(eboptions)