Skip to content

Commit 3d6d5ce

Browse files
committed
Do not symlink against report files in non-default locations
1 parent 6e1f162 commit 3d6d5ce

File tree

7 files changed

+127
-90
lines changed

7 files changed

+127
-90
lines changed

docs/manpage.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,11 +367,15 @@ Options controlling ReFrame output
367367
The file where ReFrame will store its report.
368368

369369
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.
370+
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.
370371

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

373374
.. versionadded:: 3.1
374375

376+
.. versionadded:: 4.2
377+
Symlink to the latest report is now created.
378+
375379
.. option:: --report-junit=FILE
376380

377381
Instruct ReFrame to generate a JUnit XML report in ``FILE``.

reframe/core/runtime.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,23 @@ def get_option(self, option, default=None):
170170
:returns: The value of the option.
171171
172172
.. versionchanged:: 3.11.0
173-
Add ``default`` named argument.
173+
Add ``default`` named argument.
174174
'''
175175
return self._site_config.get(option, default=default)
176176

177+
def get_default(self, option):
178+
'''Get the default value for the option as defined in the configuration
179+
schema.
180+
181+
:arg option: The option whose default value is requested
182+
:returns: The default value of the requested option
183+
:raises KeyError: if option does not have a default value
184+
185+
.. versionadded:: 4.2
186+
'''
187+
188+
return self._site_config.schema['defaults'][option]
189+
177190

178191
# Global resources for the current host
179192
_runtime_context = None

reframe/frontend/cli.py

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#
44
# SPDX-License-Identifier: BSD-3-Clause
55

6-
import functools
76
import inspect
87
import itertools
98
import json
@@ -1379,36 +1378,18 @@ def module_unuse(*paths):
13791378
json_report['restored_cases'].append(report.case(*c))
13801379

13811380
report_file = runreport.next_report_filename(report_file)
1381+
default_loc = os.path.dirname(
1382+
osext.expandvars(rt.get_default('general/report_file'))
1383+
)
13821384
try:
1383-
with open(report_file, 'w') as fp:
1384-
if rt.get_option('general/0/compress_report'):
1385-
jsonext.dump(json_report, fp)
1386-
else:
1387-
jsonext.dump(json_report, fp, indent=2)
1388-
fp.write('\n')
1389-
1390-
printer.info(f'Run report saved in {report_file!r}')
1385+
runreport.write_report(json_report, report_file,
1386+
rt.get_option(
1387+
'general/0/compress_report'),
1388+
os.path.dirname(report_file) == default_loc)
13911389
except OSError as e:
13921390
printer.warning(
13931391
f'failed to generate report in {report_file!r}: {e}'
13941392
)
1395-
else:
1396-
# Add a symlink to the latest report
1397-
with osext.change_dir(basedir):
1398-
link_name = 'latest.json'
1399-
create_symlink = functools.partial(
1400-
os.symlink, os.path.basename(report_file), link_name
1401-
)
1402-
if not os.path.exists(link_name):
1403-
create_symlink()
1404-
else:
1405-
if os.path.islink(link_name):
1406-
os.remove(link_name)
1407-
create_symlink()
1408-
else:
1409-
printer.warning('could not create a symlink '
1410-
'to the latest report file; '
1411-
'path exists and is not a symlink')
14121393

14131394
# Generate the junit xml report for this session
14141395
junit_report_file = rt.get_option('general/0/report_junit')

reframe/frontend/runreport.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# SPDX-License-Identifier: BSD-3-Clause
55

66
import decimal
7+
import functools
78
import json
89
import jsonschema
910
import lxml.etree as etree
@@ -13,6 +14,8 @@
1314
import reframe as rfm
1415
import reframe.core.exceptions as errors
1516
import reframe.utility.jsonext as jsonext
17+
import reframe.utility.osext as osext
18+
from reframe.core.logging import getlogger
1619
from reframe.core.warnings import suppress_deprecations
1720

1821
# The schema data version
@@ -179,6 +182,36 @@ def load_report(*filenames):
179182
return rpt
180183

181184

185+
def write_report(report, filename, compress=False, link_to_last=False):
186+
with open(filename, 'w') as fp:
187+
if compress:
188+
jsonext.dump(report, fp)
189+
else:
190+
jsonext.dump(report, fp, indent=2)
191+
fp.write('\n')
192+
193+
if not link_to_last:
194+
return
195+
196+
# Add a symlink to the latest report
197+
basedir = os.path.dirname(filename)
198+
with osext.change_dir(basedir):
199+
link_name = 'latest.json'
200+
create_symlink = functools.partial(
201+
os.symlink, os.path.basename(filename), link_name
202+
)
203+
if not os.path.exists(link_name):
204+
create_symlink()
205+
else:
206+
if os.path.islink(link_name):
207+
os.remove(link_name)
208+
create_symlink()
209+
else:
210+
getlogger().warning('could not create a symlink '
211+
'to the latest report file: '
212+
'path exists and is not a symlink')
213+
214+
182215
def junit_xml_report(json_report):
183216
'''Generate a JUnit report from a standard ReFrame JSON report.'''
184217

test_reframe.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@
3939
'--rfm-help', action='help', help='Print this help message and exit.'
4040
)
4141
options, rem_args = parser.parse_known_args()
42-
test_util.USER_CONFIG_FILE = options.rfm_user_config
42+
43+
user_config = options.rfm_user_config
44+
if user_config is not None:
45+
user_config = os.path.abspath(user_config)
46+
47+
test_util.USER_CONFIG_FILE = user_config
4348
test_util.USER_SYSTEM = options.rfm_user_system
4449
test_util.init_runtime()
4550

unittests/resources/config/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@
241241
{
242242
'name': 'unittest',
243243
'options': [
244-
'-c unittests/resources/checks/hellocheck.py',
244+
'-n ^HelloTest$',
245245
'-p builtin',
246246
'-S local=1'
247247
]

0 commit comments

Comments
 (0)