def test_log_levels(self): """Test whether log levels are respected""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s [%(levelname)s] :: %(message)s") # test basic log methods logToFile(tmplog, enable=True) log = getLogger('test_easybuildlog') self.mock_stderr(True) # avoid that some log statement spit out stuff to stderr while tests are running for level in ['ERROR', 'WARNING', 'INFO', 'DEBUG', 'DEVEL']: log.setLevelName(level) log.raiseError = False log.error('kaput') log.deprecated('almost kaput', '10000000000000') log.raiseError = True log.warn('this is a warning') log.info('fyi') log.debug('gdb') log.devel('tmi') self.mock_stderr(False) logToFile(tmplog, enable=False) logtxt = read_file(tmplog) prefix = 'fancyroot.test_easybuildlog' devel_msg = r"%s \[DEVEL\] :: tmi" % prefix debug_msg = r"%s \[DEBUG\] :: gdb" % prefix info_msg = r"%s \[INFO\] :: fyi" % prefix warning_msg = r"%s \[WARNING\] :: this is a warning" % prefix deprecated_msg = r"%s \[WARNING\] :: Deprecated functionality, .*: almost kaput; see .*" % prefix error_msg = r"%s \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): kaput" % prefix expected_logtxt = '\n'.join([ error_msg, error_msg, deprecated_msg, warning_msg, error_msg, deprecated_msg, warning_msg, info_msg, error_msg, deprecated_msg, warning_msg, info_msg, debug_msg, error_msg, deprecated_msg, warning_msg, info_msg, debug_msg, devel_msg, ]) logtxt_regex = re.compile(r'^%s' % expected_logtxt, re.M) self.assertTrue(logtxt_regex.search(logtxt), "Pattern '%s' found in %s" % (logtxt_regex.pattern, logtxt))
def test_module_mismatch(self): """Test whether mismatch detection between modules tool and 'module' function works.""" # redefine 'module' function (deliberate mismatch with used module command in MockModulesTool) os.environ[ 'module'] = "() { eval `/tmp/Modules/$MODULE_VERSION/bin/modulecmd bash $*`\n}" error_regex = ".*pattern .* not found in defined 'module' function" self.assertErrorRegex(EasyBuildError, error_regex, MockModulesTool, testing=True) # check whether escaping error by allowing mismatch via build options works build_options = { 'allow_modules_tool_mismatch': True, } init_config(build_options=build_options) fancylogger.logToFile(self.logfile) mt = MockModulesTool(testing=True) logtxt = read_file(self.logfile) warn_regex = re.compile( "WARNING .*pattern .* not found in defined 'module' function") self.assertTrue( warn_regex.search(logtxt), "Found pattern '%s' in: %s" % (warn_regex.pattern, logtxt)) # redefine 'module' function with correct module command os.environ['module'] = "() { eval `/bin/echo $*`\n}" mt = MockModulesTool(testing=True) self.assertTrue(isinstance(mt.loaded_modules(), list)) # dummy usage # a warning should be logged if the 'module' function is undefined del os.environ['module'] mt = MockModulesTool(testing=True) logtxt = read_file(self.logfile) warn_regex = re.compile( "WARNING No 'module' function defined, can't check if it matches .*" ) self.assertTrue( warn_regex.search(logtxt), "Pattern %s found in %s" % (warn_regex.pattern, logtxt)) fancylogger.logToFile(self.logfile, enable=False)
def test_easybuildlog(self): """Tests for EasyBuildLog.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # compose versions older/newer than current version depr_ver = int(os.environ['EASYBUILD_DEPRECATED']) older_ver = str(depr_ver - 1) newer_ver = str(depr_ver + 1) # set log format, for each regex searching setLogFormat("%(name)s [%(levelname)s] :: %(message)s") # test basic log methods logToFile(tmplog, enable=True) log = getLogger('test_easybuildlog') self.mock_stderr(True) log.setLevelName('DEBUG') log.debug("123 debug") log.info("foobar info") log.warning("justawarning") log.deprecated("anotherwarning", newer_ver) log.deprecated("onemorewarning", '1.0', '2.0') log.deprecated("lastwarning", '1.0', max_ver='2.0') log.deprecated("thisisnotprinted", '1.0', max_ver='2.0', silent=True) log.error("kaput") log.error("err: %s", 'msg: %s') stderr = self.get_stderr() self.mock_stderr(False) more_info = "see http://easybuild.readthedocs.org/en/latest/Deprecated-functionality.html for more information" expected_stderr = '\n\n'.join([ "\nWARNING: Deprecated functionality, will no longer work in v10000001: anotherwarning; " + more_info, "\nWARNING: Deprecated functionality, will no longer work in v2.0: onemorewarning", "\nWARNING: Deprecated functionality, will no longer work in v2.0: lastwarning", ]) + '\n\n' self.assertEqual(stderr, expected_stderr) try: log.exception("oops") except EasyBuildError: pass logToFile(tmplog, enable=False) logtxt = read_file(tmplog) expected_logtxt = '\n'.join([ r"fancyroot.test_easybuildlog \[DEBUG\] :: 123 debug", r"fancyroot.test_easybuildlog \[INFO\] :: foobar info", r"fancyroot.test_easybuildlog \[WARNING\] :: justawarning", r"fancyroot.test_easybuildlog \[WARNING\] :: Deprecated functionality.*anotherwarning.*", r"fancyroot.test_easybuildlog \[WARNING\] :: Deprecated functionality.*onemorewarning.*", r"fancyroot.test_easybuildlog \[WARNING\] :: Deprecated functionality.*lastwarning.*", r"fancyroot.test_easybuildlog \[WARNING\] :: Deprecated functionality.*thisisnotprinted.*", r"fancyroot.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): kaput", r"fancyroot.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): err: msg: %s", r"fancyroot.test_easybuildlog \[ERROR\] :: .*EasyBuild encountered an exception \(at .* in .*\): oops", '', ]) logtxt_regex = re.compile(r'^%s' % expected_logtxt, re.M) self.assertTrue(logtxt_regex.search(logtxt), "Pattern '%s' found in %s" % (logtxt_regex.pattern, logtxt)) self.assertErrorRegex(EasyBuildError, r"DEPRECATED \(since .*: kaput", log.deprecated, "kaput", older_ver) self.assertErrorRegex(EasyBuildError, r"DEPRECATED \(since .*: 2>1", log.deprecated, "2>1", '2.0', '1.0') self.assertErrorRegex(EasyBuildError, r"DEPRECATED \(since .*: 2>1", log.deprecated, "2>1", '2.0', max_ver='1.0') # wipe log so we can reuse it write_file(tmplog, '') # test formatting log messages by providing extra arguments logToFile(tmplog, enable=True) log.warning("%s", "bleh") log.info("%s+%s = %d", '4', '2', 42) args = ['this', 'is', 'just', 'a', 'test'] log.debug("%s %s %s %s %s", *args) log.error("foo %s baz", 'baz') logToFile(tmplog, enable=False) logtxt = read_file(tmplog) expected_logtxt = '\n'.join([ r"fancyroot.test_easybuildlog \[WARNING\] :: bleh", r"fancyroot.test_easybuildlog \[INFO\] :: 4\+2 = 42", r"fancyroot.test_easybuildlog \[DEBUG\] :: this is just a test", r"fancyroot.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): foo baz baz", '', ]) logtxt_regex = re.compile(r'^%s' % expected_logtxt, re.M) self.assertTrue(logtxt_regex.search(logtxt), "Pattern '%s' found in %s" % (logtxt_regex.pattern, logtxt)) write_file(tmplog, '') logToFile(tmplog, enable=True) # also test use of 'more_info' named argument for log.deprecated self.mock_stderr(True) log.deprecated("\nthis is just a test\n", newer_ver, more_info="(see URLGOESHERE for more information)") self.mock_stderr(False) logtxt = read_file(tmplog) expected_logtxt = '\n'.join([ "[WARNING] :: Deprecated functionality, will no longer work in v10000001: ", "this is just a test", "(see URLGOESHERE for more information)", ]) self.assertTrue(logtxt.strip().endswith(expected_logtxt))
import unittest from easybuild.base import fancylogger from easybuild.tools.build_log import EasyBuildError from easybuild.tools.options import set_tmpdir import test.easyblocks.general as g import test.easyblocks.init_easyblocks as i import test.easyblocks.module as m # initialize logger for all the unit tests fd, log_fn = tempfile.mkstemp(prefix='easybuild-easyblocks-tests-', suffix='.log') os.close(fd) os.remove(log_fn) fancylogger.logToFile(log_fn) log = fancylogger.getLogger() log.setLevelName('DEBUG') try: tmpdir = set_tmpdir(raise_error=True) except EasyBuildError as err: sys.stderr.write( "No execution rights on temporary files, specify another location via $TMPDIR: %s\n" % err) sys.exit(1) os.environ['EASYBUILD_TMP_LOGDIR'] = tempfile.mkdtemp( prefix='easyblocks_test_') # call suite() for each module and then run them all
def stop_logging(logfile, logtostdout=False): """Stop logging.""" if logtostdout: fancylogger.logToScreen(enable=False, stdout=True) if logfile is not None: fancylogger.logToFile(logfile, enable=False)
fancylogger.FancyLogger.exception(self, ebmsg + msg, *args) # set format for logger LOGGING_FORMAT = EB_MSG_PREFIX + ' %(asctime)s %(filename)s:%(lineno)s %(levelname)s %(message)s' fancylogger.setLogFormat(LOGGING_FORMAT) # set the default LoggerClass to EasyBuildLog fancylogger.logging.setLoggerClass(EasyBuildLog) # you can't easily set another LoggerClass before fancylogger calls getLogger on import _init_fancylog = fancylogger.getLogger(fname=False) del _init_fancylog.manager.loggerDict[_init_fancylog.name] # we need to make sure there is a handler fancylogger.logToFile(filename=os.devnull, max_bytes=0) # EasyBuildLog _init_easybuildlog = fancylogger.getLogger(fname=False) def init_logging(logfile, logtostdout=False, silent=False, colorize=fancylogger.Colorize.AUTO, tmp_logdir=None): """Initialize logging.""" if logtostdout: fancylogger.logToScreen(enable=True, stdout=True, colorize=colorize) else: if logfile is None: