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
4 changes: 4 additions & 0 deletions docs/manpage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -367,11 +367,15 @@ Options controlling ReFrame output
The file where ReFrame will store its report.

The ``FILE`` argument may contain the special placeholder ``{sessionid}``, in which case ReFrame will generate a new report each time it is run by appending a counter to the report file.
If the report is generated in the default location (see the :attr:`~config.general.report_file` configuration option), a symlink to the latest report named ``latest.json`` will also be created.

This option can also be set using the :envvar:`RFM_REPORT_FILE` environment variable or the :attr:`~config.general.report_file` general configuration parameter.

.. versionadded:: 3.1

.. versionadded:: 4.2
Symlink to the latest report is now created.

.. option:: --report-junit=FILE

Instruct ReFrame to generate a JUnit XML report in ``FILE``.
Expand Down
15 changes: 14 additions & 1 deletion reframe/core/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,23 @@ def get_option(self, option, default=None):
:returns: The value of the option.
.. versionchanged:: 3.11.0
Add ``default`` named argument.
Add ``default`` named argument.
'''
return self._site_config.get(option, default=default)

def get_default(self, option):
'''Get the default value for the option as defined in the configuration
schema.
:arg option: The option whose default value is requested
:returns: The default value of the requested option
:raises KeyError: if option does not have a default value
.. versionadded:: 4.2
'''

return self._site_config.schema['defaults'][option]


# Global resources for the current host
_runtime_context = None
Expand Down
33 changes: 7 additions & 26 deletions reframe/frontend/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#
# SPDX-License-Identifier: BSD-3-Clause

import functools
import inspect
import itertools
import json
Expand Down Expand Up @@ -1379,36 +1378,18 @@ def module_unuse(*paths):
json_report['restored_cases'].append(report.case(*c))

report_file = runreport.next_report_filename(report_file)
default_loc = os.path.dirname(
osext.expandvars(rt.get_default('general/report_file'))
)
try:
with open(report_file, 'w') as fp:
if rt.get_option('general/0/compress_report'):
jsonext.dump(json_report, fp)
else:
jsonext.dump(json_report, fp, indent=2)
fp.write('\n')

printer.info(f'Run report saved in {report_file!r}')
runreport.write_report(json_report, report_file,
rt.get_option(
'general/0/compress_report'),
os.path.dirname(report_file) == default_loc)
except OSError as e:
printer.warning(
f'failed to generate report in {report_file!r}: {e}'
)
else:
# Add a symlink to the latest report
with osext.change_dir(basedir):
link_name = 'latest.json'
create_symlink = functools.partial(
os.symlink, os.path.basename(report_file), link_name
)
if not os.path.exists(link_name):
create_symlink()
else:
if os.path.islink(link_name):
os.remove(link_name)
create_symlink()
else:
printer.warning('could not create a symlink '
'to the latest report file; '
'path exists and is not a symlink')

# Generate the junit xml report for this session
junit_report_file = rt.get_option('general/0/report_junit')
Expand Down
33 changes: 33 additions & 0 deletions reframe/frontend/runreport.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# SPDX-License-Identifier: BSD-3-Clause

import decimal
import functools
import json
import jsonschema
import lxml.etree as etree
Expand All @@ -13,6 +14,8 @@
import reframe as rfm
import reframe.core.exceptions as errors
import reframe.utility.jsonext as jsonext
import reframe.utility.osext as osext
from reframe.core.logging import getlogger
from reframe.core.warnings import suppress_deprecations

# The schema data version
Expand Down Expand Up @@ -179,6 +182,36 @@ def load_report(*filenames):
return rpt


def write_report(report, filename, compress=False, link_to_last=False):
with open(filename, 'w') as fp:
if compress:
jsonext.dump(report, fp)
else:
jsonext.dump(report, fp, indent=2)
fp.write('\n')

if not link_to_last:
return

# Add a symlink to the latest report
basedir = os.path.dirname(filename)
with osext.change_dir(basedir):
link_name = 'latest.json'
create_symlink = functools.partial(
os.symlink, os.path.basename(filename), link_name
)
if not os.path.exists(link_name):
create_symlink()
else:
if os.path.islink(link_name):
os.remove(link_name)
create_symlink()
else:
getlogger().warning('could not create a symlink '
'to the latest report file: '
'path exists and is not a symlink')


def junit_xml_report(json_report):
'''Generate a JUnit report from a standard ReFrame JSON report.'''

Expand Down
7 changes: 6 additions & 1 deletion test_reframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@
'--rfm-help', action='help', help='Print this help message and exit.'
)
options, rem_args = parser.parse_known_args()
test_util.USER_CONFIG_FILE = options.rfm_user_config

user_config = options.rfm_user_config
if user_config is not None:
user_config = os.path.abspath(user_config)

test_util.USER_CONFIG_FILE = user_config
test_util.USER_SYSTEM = options.rfm_user_system
test_util.init_runtime()

Expand Down
2 changes: 1 addition & 1 deletion unittests/resources/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@
{
'name': 'unittest',
'options': [
'-c unittests/resources/checks/hellocheck.py',
'-n ^HelloTest$',
'-p builtin',
'-S local=1'
]
Expand Down
Loading