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
2 changes: 2 additions & 0 deletions docs/running.rst
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ All handlers accept the following set of attributes (keys) in their configuratio
- ``check_stagedir``: The stage directory associated with the currently executing test.
- ``check_system``: The host system where this test is currently executing.
- ``check_tags``: The tags associated with this test.
- ``osuser``: The name of the OS user running ReFrame.
- ``osgroup``: The group name of the OS user running ReFrame.
- ``version``: The ReFrame version.

* ``datefmt`` (default: ``'%FT%T'``) The format that will be used for outputting timestamps (i.e., the ``%(asctime)s`` field).
Expand Down
5 changes: 4 additions & 1 deletion reframe/core/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import reframe
import reframe.core.debug as debug
import reframe.utility.os_ext as os_ext
from reframe.core.exceptions import ConfigError, LoggingError


Expand Down Expand Up @@ -343,6 +344,8 @@ def __init__(self, logger=None, check=None):
'check_perf_ref': None,
'check_perf_lower_thres': None,
'check_perf_upper_thres': None,
'osuser': os_ext.osuser() or '<unknown>',
'osgroup': os_ext.osgroup() or '<unknown>',
'check_tags': None,
'version': reframe.VERSION,
}
Expand Down Expand Up @@ -388,7 +391,7 @@ def log_performance(self, level, tag, value, ref,
self.extra['check_perf_lower_thres'] = low_thres
self.extra['check_perf_upper_thres'] = upper_thres
if msg is None:
msg = 'sent by ' + os.environ['USER']
msg = 'sent by ' + self.extra['osuser']

self.log(level, msg)

Expand Down
2 changes: 1 addition & 1 deletion reframe/frontend/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ def main():
# Print command line
printer.info('Command line: %s' % ' '.join(sys.argv))
printer.info('Reframe version: ' + reframe.VERSION)
printer.info('Launched by user: ' + os.environ['USER'])
printer.info('Launched by user: ' + (os_ext.osuser() or '<unknown>'))
printer.info('Launched on host: ' + socket.gethostname())

# Print important paths
Expand Down
2 changes: 1 addition & 1 deletion reframe/frontend/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def warning(self, msg):
def error(self, msg):
msg = AnsiColorizer.colorize('%s: %s' % (sys.argv[0], msg),
AnsiColorizer.red)
self._logger.error('%s: %s' % (sys.argv[0], msg))
self._logger.error(msg)

def log_config(self, options):
opt_list = [' %s=%s' % (attr, val)
Expand Down
28 changes: 27 additions & 1 deletion reframe/utility/os_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
# OS and shell utility functions
#

import getpass
import grp
import os
import re
import shlex
Expand All @@ -13,7 +15,6 @@

from reframe.core.exceptions import (ReframeError, SpawnedProcessError,
SpawnedProcessTimeout)
from reframe.core.logging import getlogger


def run_command(cmd, check=False, timeout=None, shell=False):
Expand Down Expand Up @@ -63,6 +64,9 @@ def run_command_async(cmd,
stderr=subprocess.PIPE,
shell=False,
**popen_args):
# Import logger here to avoid unnecessary circular dependencies
from reframe.core.logging import getlogger

getlogger().debug('executing OS command: ' + cmd)
if not shell:
cmd = shlex.split(cmd)
Expand All @@ -75,6 +79,28 @@ def run_command_async(cmd,
**popen_args)


def osuser():
"""Return the name of the current OS user.

If the name cannot be retrieved, :class:`None` will be returned.
"""
try:
return getpass.getuser()
except BaseException:
return None


def osgroup():
"""Return the group name of the current OS user.

If the name cannot be retrieved, :class:`None` will be returned.
"""
try:
return grp.getgrgid(os.getgid()).gr_name
except KeyError:
return None


def copytree(src, dst, symlinks=False, ignore=None, copy_function=shutil.copy2,
ignore_dangling_symlinks=False):
"""Same as shutil.copytree() but valid also if 'dst' exists.
Expand Down