def test_loggedexception_callerlogger(self): """Test LoggedException custom exception class.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") logger = getLogger('testlogger_local') # if no logger is specified, logger available in calling context should be used logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, 'BOOM', raise_loggedexception, 'BOOM') logToFile(tmplog, enable=False) rootlog = getRootLoggerName() log_re = re.compile( "^%s(.testlogger_local)? :: BOOM( \(at .*:[0-9]+ in raise_loggedexception\))?$" % rootlog) with open(tmplog, 'r') as f: logtxt = f.read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) os.remove(tmplog)
def test_loggedexception_specifiedlogger(self): """Test LoggedException custom exception class.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") logger1 = getLogger('testlogger_one') logger2 = getLogger('testlogger_two') # if logger is specified, it should be used logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, 'BOOM', raise_loggedexception, 'BOOM', logger=logger1) logToFile(tmplog, enable=False) rootlog = getRootLoggerName() log_re = re.compile( "^%s.testlogger_one :: BOOM( \(at .*:[0-9]+ in raise_loggedexception\))?$" % rootlog, re.M) logtxt = open(tmplog, 'r').read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) os.remove(tmplog)
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') 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') logToFile(tmplog, enable=False) logtxt = read_file(tmplog) root = getRootLoggerName() devel_msg = r"%s.test_easybuildlog \[DEVEL\] :: tmi" % root debug_msg = r"%s.test_easybuildlog \[DEBUG\] :: gdb" % root info_msg = r"%s.test_easybuildlog \[INFO\] :: fyi" % root warning_msg = r"%s.test_easybuildlog \[WARNING\] :: this is a warning" % root deprecated_msg = r"%s.test_easybuildlog \[WARNING\] :: Deprecated functionality, .*: almost kaput; see .*" % root error_msg = r"%s.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): kaput" % root 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_easybuilderror(self): """Tests for EasyBuildError.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") # if no logger is available, and no logger is specified, use default 'root' fancylogger logToFile(tmplog, enable=True) self.assertErrorRegex(EasyBuildError, 'BOOM', raise_easybuilderror, 'BOOM') logToFile(tmplog, enable=False) log_re = re.compile( "^%s ::.* BOOM \(at .*:[0-9]+ in [a-z_]+\)$" % getRootLoggerName(), re.M) logtxt = open(tmplog, 'r').read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) # test formatting of message self.assertErrorRegex(EasyBuildError, 'BOOMBAF', raise_easybuilderror, 'BOOM%s', 'BAF') # a '%s' in a value used to template the error message should not print a traceback! self.mock_stderr(True) self.assertErrorRegex(EasyBuildError, 'err: msg: %s', raise_easybuilderror, "err: %s", "msg: %s") stderr = self.get_stderr() self.mock_stderr(False) # stderr should be *empty* (there should definitely not be a traceback) self.assertEqual(stderr, '') os.remove(tmplog)
def test_loggedexception_defaultlogger(self): """Test LoggedException custom exception class.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") # if no logger is available, and no logger is specified, use default 'root' fancylogger logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, 'BOOM', raise_loggedexception, 'BOOM') logToFile(tmplog, enable=False) log_re = re.compile( "^%s :: BOOM( \(at .*:[0-9]+ in raise_loggedexception\))?$" % getRootLoggerName(), re.M) logtxt = open(tmplog, 'r').read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) # test formatting of message self.assertErrorRegex(LoggedException, 'BOOMBAF', raise_loggedexception, 'BOOM%s', 'BAF') # test log message that contains '%s' without any formatting arguments being passed # test formatting of message self.assertErrorRegex(LoggedException, "BOOM '%s'", raise_loggedexception, "BOOM '%s'") os.remove(tmplog)
def test_easybuilderror(self): """Tests for EasyBuildError.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") # if no logger is available, and no logger is specified, use default 'root' fancylogger logToFile(tmplog, enable=True) self.assertErrorRegex(EasyBuildError, 'BOOM', raise_easybuilderror, 'BOOM') logToFile(tmplog, enable=False) log_re = re.compile("^%s ::.* BOOM \(at .*:[0-9]+ in [a-z_]+\)$" % getRootLoggerName(), re.M) logtxt = open(tmplog, 'r').read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) # test formatting of message self.assertErrorRegex(EasyBuildError, 'BOOMBAF', raise_easybuilderror, 'BOOM%s', 'BAF') # a '%s' in a value used to template the error message should not print a traceback! self.mock_stderr(True) self.assertErrorRegex(EasyBuildError, 'err: msg: %s', raise_easybuilderror, "err: %s", "msg: %s") stderr = self.get_stderr() self.mock_stderr(False) # stderr should be *empty* (there should definitely not be a traceback) self.assertEqual(stderr, '') os.remove(tmplog)
def test_easybuilderror(self): """Tests for EasyBuildError.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") # if no logger is available, and no logger is specified, use default 'root' fancylogger logToFile(tmplog, enable=True) self.assertErrorRegex(EasyBuildError, 'BOOM', raise_easybuilderror, 'BOOM') logToFile(tmplog, enable=False) log_re = re.compile( "^%s :: BOOM \(at .*:[0-9]+ in [a-z_]+\)$" % getRootLoggerName(), re.M) logtxt = open(tmplog, 'r').read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) # test formatting of message self.assertErrorRegex(EasyBuildError, 'BOOMBAF', raise_easybuilderror, 'BOOM%s', 'BAF') os.remove(tmplog)
def test_loggedexception_location(self): """Test inclusion of location information in log message for LoggedException.""" class TestException(LoggedException): LOC_INFO_TOP_PKG_NAMES = None INCLUDE_LOCATION = True def raise_testexception(msg, *args, **kwargs): """Utility function: just raise a TestException.""" raise TestException(msg, *args, **kwargs) fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") # no location with default LOC_INFO_TOP_PKG_NAMES ([]) logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, 'BOOM', raise_testexception, 'BOOM') logToFile(tmplog, enable=False) rootlogname = getRootLoggerName() log_re = re.compile("^%s :: BOOM$" % rootlogname, re.M) with open(tmplog, 'r') as f: logtxt = f.read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) with open(tmplog, 'w') as f: f.write('') # location is included if LOC_INFO_TOP_PKG_NAMES is defined TestException.LOC_INFO_TOP_PKG_NAMES = ['vsc'] logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, 'BOOM', raise_testexception, 'BOOM') logToFile(tmplog, enable=False) log_re = re.compile(r"^%s :: BOOM \(at (?:.*?/)?vsc/install/testing.py:[0-9]+ in assertErrorRegex\)$" % rootlogname) with open(tmplog, 'r') as f: logtxt = f.read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) with open(tmplog, 'w') as f: f.write('') # absolute path of location is included if there's no match in LOC_INFO_TOP_PKG_NAMES TestException.LOC_INFO_TOP_PKG_NAMES = ['foobar'] logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, 'BOOM', raise_testexception, 'BOOM') logToFile(tmplog, enable=False) log_re = re.compile(r"^%s :: BOOM \(at (?:.*?/)?vsc/install/testing.py:[0-9]+ in assertErrorRegex\)$" % rootlogname) with open(tmplog, 'r') as f: logtxt = f.read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) os.remove(tmplog)
def test_loggedexception_location(self): """Test inclusion of location information in log message for LoggedException.""" class TestException(LoggedException): LOC_INFO_TOP_PKG_NAMES = None INCLUDE_LOCATION = True def raise_testexception(msg, *args, **kwargs): """Utility function: just raise a TestException.""" raise TestException(msg, *args, **kwargs) fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") # no location with default LOC_INFO_TOP_PKG_NAMES ([]) logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, "BOOM", raise_testexception, "BOOM") logToFile(tmplog, enable=False) rootlogname = getRootLoggerName() log_re = re.compile("^%s :: BOOM$" % rootlogname, re.M) logtxt = open(tmplog, "r").read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) f = open(tmplog, "w") f.write("") f.close() # location is included if LOC_INFO_TOP_PKG_NAMES is defined TestException.LOC_INFO_TOP_PKG_NAMES = ["vsc"] logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, "BOOM", raise_testexception, "BOOM") logToFile(tmplog, enable=False) log_re = re.compile(r"^%s :: BOOM \(at vsc/utils/testing.py:[0-9]+ in assertErrorRegex\)$" % rootlogname) logtxt = open(tmplog, "r").read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) f = open(tmplog, "w") f.write("") f.close() # absolute path of location is included if there's no match in LOC_INFO_TOP_PKG_NAMES TestException.LOC_INFO_TOP_PKG_NAMES = ["foobar"] logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, "BOOM", raise_testexception, "BOOM") logToFile(tmplog, enable=False) log_re = re.compile(r"^%s :: BOOM \(at .*/vsc/utils/testing.py:[0-9]+ in assertErrorRegex\)$" % rootlogname) logtxt = open(tmplog, "r").read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) os.remove(tmplog)
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') 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') logToFile(tmplog, enable=False) logtxt = read_file(tmplog) root = getRootLoggerName() devel_msg = r"%s.test_easybuildlog \[DEVEL\] :: tmi" % root debug_msg = r"%s.test_easybuildlog \[DEBUG\] :: gdb" % root info_msg = r"%s.test_easybuildlog \[INFO\] :: fyi" % root warning_msg = r"%s.test_easybuildlog \[WARNING\] :: this is a warning" % root deprecated_msg = r"%s.test_easybuildlog \[WARNING\] :: Deprecated functionality, .*: almost kaput; see .*" % root error_msg = r"%s.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): kaput" % root 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_loggedexception_callerlogger(self): """Test LoggedException custom exception class.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") logger = getLogger('testlogger_local') # if no logger is specified, logger available in calling context should be used logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, 'BOOM', raise_loggedexception, 'BOOM') logToFile(tmplog, enable=False) rootlog = getRootLoggerName() log_re = re.compile("^%s(.testlogger_local)? :: BOOM( \(at .*:[0-9]+ in raise_loggedexception\))?$" % rootlog) logtxt = open(tmplog, 'r').read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) os.remove(tmplog)
def test_easybuilderror(self): """Tests for EasyBuildError.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") # if no logger is available, and no logger is specified, use default 'root' fancylogger logToFile(tmplog, enable=True) self.assertErrorRegex(EasyBuildError, 'BOOM', raise_easybuilderror, 'BOOM') logToFile(tmplog, enable=False) log_re = re.compile("^%s :: BOOM \(at .*:[0-9]+ in [a-z_]+\)$" % getRootLoggerName(), re.M) logtxt = open(tmplog, 'r').read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) # test formatting of message self.assertErrorRegex(EasyBuildError, 'BOOMBAF', raise_easybuilderror, 'BOOM%s', 'BAF') os.remove(tmplog)
def test_loggedexception_specifiedlogger(self): """Test LoggedException custom exception class.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") logger1 = getLogger('testlogger_one') logger2 = getLogger('testlogger_two') # if logger is specified, it should be used logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, 'BOOM', raise_loggedexception, 'BOOM', logger=logger1) logToFile(tmplog, enable=False) rootlog = getRootLoggerName() log_re = re.compile("^%s.testlogger_one :: BOOM \(at .*:[0-9]+ in raise_loggedexception\)$" % rootlog, re.M) logtxt = open(tmplog, 'r').read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) os.remove(tmplog)
def test_easybuildlog(self): """Tests for EasyBuildLog.""" 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') log.setLevelName('DEBUG') log.debug("123 debug") log.info("foobar info") log.warn("justawarning") log.raiseError = False log.error("kaput") log.raiseError = True try: log.exception("oops") except EasyBuildError: pass logToFile(tmplog, enable=False) logtxt = read_file(tmplog) root = getRootLoggerName() expected_logtxt = '\n'.join([ r"%s.test_easybuildlog \[DEBUG\] :: 123 debug" % root, r"%s.test_easybuildlog \[INFO\] :: foobar info" % root, r"%s.test_easybuildlog \[WARNING\] :: justawarning" % root, r"%s.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): kaput" % root, r"%s.test_easybuildlog \[ERROR\] :: .*EasyBuild encountered an exception \(at .* in .*\): oops" % root, '', ]) 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)) # wipe log so we can reuse it write_file(tmplog, '') # test formatting log messages by providing extra arguments logToFile(tmplog, enable=True) log.warn("%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.raiseError = False log.error("foo %s baz", 'baz') log.raiseError = True logToFile(tmplog, enable=False) logtxt = read_file(tmplog) expected_logtxt = '\n'.join([ r"%s.test_easybuildlog \[WARNING\] :: bleh" % root, r"%s.test_easybuildlog \[INFO\] :: 4\+2 = 42" % root, r"%s.test_easybuildlog \[DEBUG\] :: this is just a test" % root, r"%s.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): foo baz baz" % root, '', ]) 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)) # test deprecated behaviour: raise EasyBuildError on log.error and log.exception os.environ['EASYBUILD_DEPRECATED'] = '2.1' init_config() log.warning("No raise for warnings") self.assertErrorRegex(EasyBuildError, 'EasyBuild crashed with an error', log.error, 'foo') self.assertErrorRegex(EasyBuildError, 'EasyBuild encountered an exception', log.exception, 'bar')
def test_easybuildlog(self): """Tests for EasyBuildLog.""" 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') log.setLevelName('DEBUG') log.debug("123 debug") log.info("foobar info") log.warn("justawarning") log.raiseError = False log.error("kaput") log.raiseError = True try: log.exception("oops") except EasyBuildError: pass logToFile(tmplog, enable=False) logtxt = read_file(tmplog) root = getRootLoggerName() expected_logtxt = '\n'.join([ r"%s.test_easybuildlog \[DEBUG\] :: 123 debug" % root, r"%s.test_easybuildlog \[INFO\] :: foobar info" % root, r"%s.test_easybuildlog \[WARNING\] :: justawarning" % root, r"%s.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): kaput" % root, r"%s.test_easybuildlog \[ERROR\] :: .*EasyBuild encountered an exception \(at .* in .*\): oops" % root, '', ]) 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)) # wipe log so we can reuse it write_file(tmplog, '') # test formatting log messages by providing extra arguments logToFile(tmplog, enable=True) log.warn("%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.raiseError = False log.error("foo %s baz", 'baz') log.raiseError = True logToFile(tmplog, enable=False) logtxt = read_file(tmplog) expected_logtxt = '\n'.join([ r"%s.test_easybuildlog \[WARNING\] :: bleh" % root, r"%s.test_easybuildlog \[INFO\] :: 4\+2 = 42" % root, r"%s.test_easybuildlog \[DEBUG\] :: this is just a test" % root, r"%s.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): foo baz baz" % root, '', ]) 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)) # test deprecated behaviour: raise EasyBuildError on log.error and log.exception os.environ['EASYBUILD_DEPRECATED'] = '2.1' init_config() log.warning("No raise for warnings") self.assertErrorRegex(EasyBuildError, 'EasyBuild crashed with an error', log.error, 'foo') self.assertErrorRegex(EasyBuildError, 'EasyBuild encountered an exception', log.exception, 'bar')
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.warn("justawarning") log.deprecated("anotherwarning", newer_ver) log.deprecated("onemorewarning", '1.0', '2.0') log.deprecated("lastwarning", '1.0', max_ver='2.0') log.error("kaput") log.error("err: %s", 'msg: %s') stderr = self.get_stderr() self.mock_stderr(False) # no output to stderr (should all go to log file) self.assertEqual(stderr, '') try: log.exception("oops") except EasyBuildError: pass logToFile(tmplog, enable=False) logtxt = read_file(tmplog) root = getRootLoggerName() expected_logtxt = '\n'.join([ r"%s.test_easybuildlog \[DEBUG\] :: 123 debug" % root, r"%s.test_easybuildlog \[INFO\] :: foobar info" % root, r"%s.test_easybuildlog \[WARNING\] :: justawarning" % root, r"%s.test_easybuildlog \[WARNING\] :: Deprecated functionality.*anotherwarning.*" % root, r"%s.test_easybuildlog \[WARNING\] :: Deprecated functionality.*onemorewarning.*" % root, r"%s.test_easybuildlog \[WARNING\] :: Deprecated functionality.*lastwarning.*" % root, r"%s.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): kaput" % root, root + r".test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): err: msg: %s", r"%s.test_easybuildlog \[ERROR\] :: .*EasyBuild encountered an exception \(at .* in .*\): oops" % root, '', ]) 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, "DEPRECATED \(since .*: kaput", log.deprecated, "kaput", older_ver) self.assertErrorRegex(EasyBuildError, "DEPRECATED \(since .*: 2>1", log.deprecated, "2>1", '2.0', '1.0') self.assertErrorRegex(EasyBuildError, "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.warn("%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"%s.test_easybuildlog \[WARNING\] :: bleh" % root, r"%s.test_easybuildlog \[INFO\] :: 4\+2 = 42" % root, r"%s.test_easybuildlog \[DEBUG\] :: this is just a test" % root, r"%s.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): foo baz baz" % root, '', ]) 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_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.warn("justawarning") log.deprecated("anotherwarning", newer_ver) log.deprecated("onemorewarning", '1.0', '2.0') log.deprecated("lastwarning", '1.0', max_ver='2.0') 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'.join([ "Deprecated functionality, will no longer work in v10000001: anotherwarning; " + more_info, "Deprecated functionality, will no longer work in v2.0: onemorewarning", "Deprecated functionality, will no longer work in v2.0: lastwarning", ]) + '\n' self.assertEqual(stderr, expected_stderr) try: log.exception("oops") except EasyBuildError: pass logToFile(tmplog, enable=False) logtxt = read_file(tmplog) root = getRootLoggerName() expected_logtxt = '\n'.join([ r"%s.test_easybuildlog \[DEBUG\] :: 123 debug" % root, r"%s.test_easybuildlog \[INFO\] :: foobar info" % root, r"%s.test_easybuildlog \[WARNING\] :: justawarning" % root, r"%s.test_easybuildlog \[WARNING\] :: Deprecated functionality.*anotherwarning.*" % root, r"%s.test_easybuildlog \[WARNING\] :: Deprecated functionality.*onemorewarning.*" % root, r"%s.test_easybuildlog \[WARNING\] :: Deprecated functionality.*lastwarning.*" % root, r"%s.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): kaput" % root, root + r".test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): err: msg: %s", r"%s.test_easybuildlog \[ERROR\] :: .*EasyBuild encountered an exception \(at .* in .*\): oops" % root, '', ]) 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, "DEPRECATED \(since .*: kaput", log.deprecated, "kaput", older_ver) self.assertErrorRegex(EasyBuildError, "DEPRECATED \(since .*: 2>1", log.deprecated, "2>1", '2.0', '1.0') self.assertErrorRegex(EasyBuildError, "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.warn("%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"%s.test_easybuildlog \[WARNING\] :: bleh" % root, r"%s.test_easybuildlog \[INFO\] :: 4\+2 = 42" % root, r"%s.test_easybuildlog \[DEBUG\] :: this is just a test" % root, r"%s.test_easybuildlog \[ERROR\] :: EasyBuild crashed with an error \(at .* in .*\): foo baz baz" % root, '', ]) 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_loggedexception_defaultlogger(self): """Test LoggedException custom exception class.""" fd, tmplog = tempfile.mkstemp() os.close(fd) # set log format, for each regex searching setLogFormat("%(name)s :: %(message)s") # if no logger is available, and no logger is specified, use default 'root' fancylogger logToFile(tmplog, enable=True) self.assertErrorRegex(LoggedException, 'BOOM', raise_loggedexception, 'BOOM') logToFile(tmplog, enable=False) log_re = re.compile("^%s :: BOOM( \(at .*:[0-9]+ in raise_loggedexception\))?$" % getRootLoggerName(), re.M) logtxt = open(tmplog, 'r').read() self.assertTrue(log_re.match(logtxt), "%s matches %s" % (log_re.pattern, logtxt)) # test formatting of message self.assertErrorRegex(LoggedException, 'BOOMBAF', raise_loggedexception, 'BOOM%s', 'BAF') # test log message that contains '%s' without any formatting arguments being passed # test formatting of message self.assertErrorRegex(LoggedException, "BOOM '%s'", raise_loggedexception, "BOOM '%s'") os.remove(tmplog)