Skip to content

Commit 519b70f

Browse files
authored
Merge branch 'master' into mg/pbs-job-status
2 parents 722bca5 + 6cdf0bb commit 519b70f

File tree

9 files changed

+82
-29
lines changed

9 files changed

+82
-29
lines changed

docs/config_reference.rst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,9 +1219,9 @@ The additional properties for the ``filelog`` handler are the following:
12191219
{basedir}/
12201220
system1/
12211221
partition1/
1222-
test_short_name.log
1222+
<test_class_name>.log
12231223
partition2/
1224-
test_short_name.log
1224+
<test_class_name>.log
12251225
...
12261226
system2/
12271227
...
@@ -1241,6 +1241,12 @@ The additional properties for the ``filelog`` handler are the following:
12411241
Examples of changes in the logged information are when the log record format changes or a new performance metric is added, deleted or has its name changed.
12421242
This behavior guarantees that each log file is consistent and it will not break existing parsers.
12431243

1244+
.. versionchanged:: 4.3
1245+
1246+
In the generated log file, the name of the test class name is used instead of the test's short name (which included the test's hash).
1247+
This allows the results of different variants of a parameterized test to be stored in the same log file facilitating post-processing.
1248+
1249+
12441250
The ``graylog`` log handler
12451251
---------------------------
12461252

reframe/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import os
77
import sys
88

9-
VERSION = '4.3.2'
9+
VERSION = '4.3.3'
1010
INSTALL_PREFIX = os.path.normpath(
1111
os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
1212
)

reframe/core/hooks.py

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66
import functools
77
import inspect
88

9-
import reframe.utility as util
9+
10+
def is_hook(func):
11+
return hasattr(func, '_rfm_attach')
12+
13+
14+
def is_dep_hook(func):
15+
return hasattr(func, '_rfm_resolve_deps')
1016

1117

1218
def attach_to(phase):
@@ -15,7 +21,7 @@ def attach_to(phase):
1521
:meta private:
1622
'''
1723
def deco(func):
18-
if hasattr(func, '_rfm_attach'):
24+
if is_hook(func):
1925
func._rfm_attach.append(phase)
2026
else:
2127
func._rfm_attach = [phase]
@@ -118,7 +124,7 @@ class Hook:
118124

119125
def __init__(self, fn):
120126
self.__fn = fn
121-
if not hasattr(fn, '_rfm_attach'):
127+
if not is_hook(fn):
122128
raise ValueError(f'{fn.__name__} is not a hook')
123129

124130
@property
@@ -152,7 +158,7 @@ class HookRegistry:
152158
'''Global hook registry.'''
153159

154160
def __init__(self, hooks=None):
155-
self.__hooks = util.OrderedSet()
161+
self.__hooks = []
156162
if hooks is not None:
157163
self.update(hooks)
158164

@@ -172,30 +178,36 @@ def add(self, v):
172178
of the pipeline where they must be attached. Dependencies will be
173179
resolved first in the post-setup phase if not assigned elsewhere.
174180
'''
175-
176-
if hasattr(v, '_rfm_attach'):
181+
if is_hook(v):
177182
# Always override hooks with the same name
178183
h = Hook(v)
179-
self.__hooks.discard(h)
180-
self.__hooks.add(h)
181-
elif hasattr(v, '_rfm_resolve_deps'):
184+
try:
185+
pos = self.__hooks.index(h)
186+
except ValueError:
187+
self.__hooks.append(h)
188+
else:
189+
self.__hooks[pos] = h
190+
elif is_dep_hook(v):
182191
v._rfm_attach = ['post_setup']
183-
self.__hooks.add(Hook(v))
184-
185-
def update(self, other, *, denied_hooks=None):
186-
'''Update the hook registry with the hooks from another hook registry.
192+
self.__hooks.append(Hook(v))
187193

188-
The optional ``denied_hooks`` argument takes a set of disallowed
189-
hook names, preventing their inclusion into the current hook registry.
190-
'''
194+
def update(self, other, *, forbidden_names=None):
195+
'''Update the hook registry with the hooks from another hook
196+
registry.'''
191197

192198
assert isinstance(other, HookRegistry)
193-
denied_hooks = denied_hooks or set()
199+
forbidden_names = forbidden_names or {}
194200
for h in other:
195-
if h.__name__ not in denied_hooks:
196-
# Hooks in `other` override ours
197-
self.__hooks.discard(h)
198-
self.__hooks.add(h)
201+
if (h.__name__ in forbidden_names and
202+
not is_hook(forbidden_names[h.__name__])):
203+
continue
204+
205+
try:
206+
pos = self.__hooks.index(h)
207+
except ValueError:
208+
self.__hooks.append(h)
209+
else:
210+
self.__hooks[pos] = h
199211

200212
def __repr__(self):
201213
return repr(self.__hooks)

reframe/core/meta.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,8 @@ def __init__(cls, name, bases, namespace, **kwargs):
348348
# parent classes in reverse MRO order
349349
for c in list(reversed(cls.mro()))[:-1]:
350350
if hasattr(c, '_rfm_local_hook_registry'):
351-
cls._rfm_hook_registry.update(
352-
c._rfm_local_hook_registry, denied_hooks=namespace
353-
)
351+
cls._rfm_hook_registry.update(c._rfm_local_hook_registry,
352+
forbidden_names=namespace)
354353

355354
cls._rfm_hook_registry.update(cls._rfm_local_hook_registry)
356355

reframe/frontend/autodetect.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ def __enter__(self):
5959
shutil.copy2(src, self._workdir)
6060
except FileNotFoundError:
6161
use_pip = True
62+
except Exception as err:
63+
osext.rmtree(self._workdir)
64+
raise err
6265

6366
return self._workdir, use_pip
6467

reframe/utility/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,9 @@ def __delitem__(self, key):
12751275
def __missing__(self, key):
12761276
raise KeyError(str(key))
12771277

1278+
def __rfm_json_encode__(self):
1279+
return self.data
1280+
12781281

12791282
@functools.total_ordering
12801283
class OrderedSet(collections.abc.MutableSet):

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ install_requires =
3434
semver
3535

3636
[options.packages.find]
37-
include = reframe,reframe.*
37+
include = reframe,reframe.*,hpctestlib.*
3838

3939
[options.package_data]
4040
reframe = schemas/*

unittests/test_pipeline.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,26 @@ def foo(self):
11621162
assert test.pipeline_hooks() == {'post_setup': [MyTest.foo]}
11631163

11641164

1165+
def test_overriden_hook_exec_order():
1166+
@test_util.custom_prefix('unittests/resources/checks')
1167+
class X(rfm.RunOnlyRegressionTest):
1168+
@run_before('run')
1169+
def foo(self):
1170+
pass
1171+
1172+
@run_before('run')
1173+
def bar(self):
1174+
pass
1175+
1176+
class Y(X):
1177+
@run_before('run')
1178+
def foo(self):
1179+
pass
1180+
1181+
test = Y()
1182+
assert test.pipeline_hooks() == {'pre_run': [Y.foo, X.bar]}
1183+
1184+
11651185
def test_disabled_hooks(HelloTest, local_exec_ctx):
11661186
@test_util.custom_prefix('unittests/resources/checks')
11671187
class BaseTest(HelloTest):

unittests/test_utility.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,6 @@ def test_scoped_dict_construction():
799799
'a': {'k1': 3, 'k2': 4},
800800
'b': {'k3': 5}
801801
}
802-
namespace_dict = reframe.utility.ScopedDict()
803802
namespace_dict = reframe.utility.ScopedDict(d)
804803

805804
# Change local dict and verify that the stored values are not affected
@@ -1088,6 +1087,17 @@ def test_scoped_dict_update():
10881087
assert scoped_dict == scoped_dict_alt
10891088

10901089

1090+
def test_scoped_dict_json_enc():
1091+
import json
1092+
1093+
d = {
1094+
'a': {'k1': 3, 'k2': 4},
1095+
'b': {'k3': 5}
1096+
}
1097+
ns_dict = reframe.utility.ScopedDict(d)
1098+
assert d == json.loads(jsonext.dumps(ns_dict))
1099+
1100+
10911101
def test_sequence_view():
10921102
l = util.SequenceView([1, 2, 2])
10931103
assert 1 == l[0]

0 commit comments

Comments
 (0)