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
3 changes: 3 additions & 0 deletions reframe/core/deferrable.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ def __iter__(self):
'''Evaluate the deferred expression and iterate over the result.'''
return iter(self.evaluate())

def __rfm_json_encode__(self):
return self.evaluate()

# Overload Python operators to be able to defer any expression
#
# NOTE: In the following we are not using `self` for denoting the first
Expand Down
3 changes: 2 additions & 1 deletion reframe/frontend/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import reframe.frontend.check_filters as filters
import reframe.frontend.dependency as dependency
import reframe.utility.os_ext as os_ext
import reframe.utility.json as jsonext
from reframe.core.exceptions import (
EnvironError, ConfigError, ReframeError,
ReframeDeprecationWarning, ReframeFatalError,
Expand Down Expand Up @@ -810,7 +811,7 @@ def print_infoline(param, value):
report_file = generate_report_filename(report_file)
try:
with open(report_file, 'w') as fp:
json.dump(json_report, fp, indent=2)
jsonext.dump(json_report, fp, indent=2)
except OSError as e:
printer.warning(
f'failed to generate report in {report_file!r}: {e}'
Expand Down
24 changes: 24 additions & 0 deletions reframe/utility/json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2016-2020 Swiss National Supercomputing Centre (CSCS/ETH Zurich)
# ReFrame Project Developers. See the top-level LICENSE file for details.
#
# SPDX-License-Identifier: BSD-3-Clause

import json


class _ReframeJsonEncoder(json.JSONEncoder):
def default(self, obj):
if hasattr(obj, '__rfm_json_encode__'):
return obj.__rfm_json_encode__()

return json.JSONEncoder.default(self, obj)


def dump(obj, fp, **kwargs):
kwargs['cls'] = _ReframeJsonEncoder
return json.dump(obj, fp, **kwargs)


def dumps(obj, **kwargs):
kwargs['cls'] = _ReframeJsonEncoder
return json.dumps(obj, **kwargs)
24 changes: 24 additions & 0 deletions unittests/test_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import reframe
import reframe.core.fields as fields
import reframe.utility as util
import reframe.utility.json as jsonext
import reframe.utility.os_ext as os_ext
import reframe.utility.sanity as sn
from reframe.core.exceptions import (SpawnedProcessError,
SpawnedProcessTimeout)

Expand Down Expand Up @@ -1293,3 +1295,25 @@ def test_cray_cle_info_missing_parts(tmp_path):
assert cle_info.date is None
assert cle_info.network is None
assert cle_info.patchset == '09'


def test_jsonext_dump(tmp_path):
json_dump = tmp_path / 'test.json'
with open(json_dump, 'w') as fp:
jsonext.dump({'foo': sn.defer(['bar'])}, fp)

with open(json_dump, 'r') as fp:
assert '{"foo": ["bar"]}' == fp.read()

with open(json_dump, 'w') as fp:
jsonext.dump({'foo': sn.defer(['bar'])}, fp, separators=(',', ':'))

with open(json_dump, 'r') as fp:
assert '{"foo":["bar"]}' == fp.read()


def test_jsonext_dumps():
assert '"foo"' == jsonext.dumps('foo')
assert '{"foo": ["bar"]}' == jsonext.dumps({'foo': sn.defer(['bar'])})
assert '{"foo":["bar"]}' == jsonext.dumps({'foo': sn.defer(['bar'])},
separators=(',', ':'))