Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions reframe/core/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,10 @@ def error(self, msg, *args, **kwargs):
return self.log(ERROR, msg, *args, **kwargs)

def warning(self, msg, *args, **kwargs):
return self.log(WARNING, msg, *args, **kwargs)
self.log(WARNING, msg, *args, **kwargs)

def info(self, msg, *args, **kwargs):
return self.log(INFO, msg, *args, **kwargs)
self.log(INFO, msg, *args, **kwargs)

def verbose(self, message, *args, **kwargs):
self.log(VERBOSE, message, *args, **kwargs)
Expand All @@ -423,6 +423,10 @@ def debug2(self, message, *args, **kwargs):
self.log(DEBUG2, message, *args, **kwargs)


# This is a cache for warnings that we don't want to repeat
_WARN_ONCE = set()


class LoggerAdapter(logging.LoggerAdapter):
def __init__(self, logger=None, check=None):
super().__init__(
Expand Down Expand Up @@ -550,7 +554,13 @@ def debug2(self, message, *args, **kwargs):
def verbose(self, message, *args, **kwargs):
self.log(VERBOSE, message, *args, **kwargs)

def warning(self, message, *args, **kwargs):
def warning(self, message, *args, cache=False, **kwargs):
if cache:
if message in _WARN_ONCE:
return

_WARN_ONCE.add(message)

message = '%s: %s' % (sys.argv[0], message)
if self.colorize:
message = color.colorize(message, color.YELLOW)
Expand Down Expand Up @@ -594,6 +604,7 @@ def __init__(self, check=None, level=DEBUG):
self._orig_logger = _context_logger
if check is not None:
_context_logger = LoggerAdapter(_logger, check)
_context_logger.colorize = self._orig_logger.colorize

def __enter__(self):
return _context_logger
Expand Down
20 changes: 15 additions & 5 deletions reframe/core/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,14 @@ def unload_all(self):
class NoModImpl(ModulesSystemImpl):
'''A convenience class that implements a no-op a modules system.'''

def _warn(self, msg):
getlogger().warning(
f"no modules system is set: {msg}: "
f"check the 'modules_system' configuration "
f"parameter for your system",
cache=True
)

def available_modules(self, substr):
return []

Expand All @@ -1021,10 +1029,10 @@ def _execute(self, cmd, *args):
return ''

def load_module(self, module):
pass
self._warn(f'module {module.name!r} will not be loaded')

def unload_module(self, module):
pass
self._warn(f'module {module.name!r} will not be unloaded')

def is_module_loaded(self, module):
#
Expand All @@ -1043,21 +1051,23 @@ def modulecmd(self, *args):
return ''

def unload_all(self):
pass
self._warn('no module will be purged')

def searchpath(self):
return []

def searchpath_add(self, *dirs):
pass
self._warn('MODULEPATH will not be modified')

def searchpath_remove(self, *dirs):
pass
self._warn('MODULEPATH will not be modified')

def emit_load_instr(self, module):
self._warn(f'module {module.name!r} will not be loaded')
return []

def emit_unload_instr(self, module):
self._warn(f'module {module.name!r} will not be unloaded')
return []


Expand Down
12 changes: 12 additions & 0 deletions unittests/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,18 @@ def test_handler_noappend(make_exec_ctx, config_file, logfile):
assert _found_in_logfile('bar', logfile)


def test_warn_once(default_exec_ctx, logfile):
rlog.configure_logging(rt.runtime().site_config)
rlog.getlogger().warning('foo', cache=True)
rlog.getlogger().warning('foo', cache=True)
rlog.getlogger().warning('foo', cache=True)
_flush_handlers()
_close_handlers()

with open(logfile, 'rt') as fp:
assert len(re.findall('foo', fp.read())) == 1


def test_date_format(default_exec_ctx, logfile):
rlog.configure_logging(rt.runtime().site_config)
rlog.getlogger().warning('foo')
Expand Down