Skip to content

Commit 8f22223

Browse files
authored
Merge branch 'master' into bugfix/slurm-lazy-eval-nodelist
2 parents db60948 + 3e3f4c5 commit 8f22223

File tree

6 files changed

+41
-18
lines changed

6 files changed

+41
-18
lines changed

docs/config_reference.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,7 @@ All logging handlers share the following set of common attributes:
10791079
``%(check_prebuild_cmds)s``, The value of the :attr:`~reframe.core.pipeline.RegressionTest.prebuild_cmds` attribute.
10801080
``%(check_prefix)s``, The value of the :attr:`~reframe.core.pipeline.RegressionTest.prefix` attribute.
10811081
``%(check_prerun_cmds)s``, The value of the :attr:`~reframe.core.pipeline.RegressionTest.prerun_cmds` attribute.
1082+
``%(check_result)s``, The result of the test (``pass`` or ``fail``).
10821083
``%(check_readonly_files)s``, The value of the :attr:`~reframe.core.pipeline.RegressionTest.readonly_files` attribute.
10831084
``%(check_short_name)s``, The value of the :attr:`~reframe.core.pipeline.RegressionTest.short_name` attribute.
10841085
``%(check_sourcepath)s``, The value of the :attr:`~reframe.core.pipeline.RegressionTest.sourcepath` attribute.
@@ -1116,6 +1117,9 @@ All logging handlers share the following set of common attributes:
11161117
.. versionchanged:: 3.11.0
11171118
Limit the number of attributes that can be logged. User attributes or properties must be explicitly marked as "loggable" in order to be selectable for logging.
11181119

1120+
.. versionadded:: 4.0
1121+
The ``%(check_result)s`` specifier is added.
1122+
11191123
.. versionadded:: 4.3
11201124
The ``%(check_#ALL)s`` special specifier is added.
11211125

@@ -1188,7 +1192,7 @@ The additional properties for the ``file`` handler are the following:
11881192

11891193
.. py:attribute:: logging.handlers..file..append
11901194
1191-
.. py:attribute:: logging.handlers_perflog..file..ppend
1195+
.. py:attribute:: logging.handlers_perflog..file..append
11921196
11931197
:required: No
11941198
:default: ``false``

docs/manpage.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,11 @@ Options controlling ReFrame execution
582582
the :option:`-P` option can only parameterize the leaf test:
583583
it cannot be used to parameterize a fixture of the test.
584584

585+
.. note::
586+
587+
The :option:`-P` option supports only tests that use fixtures.
588+
Tests that use raw dependencies are not supported.
589+
585590
.. versionadded:: 4.3
586591

587592
.. option:: --repeat=N

reframe/core/logging.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -789,13 +789,9 @@ def __init__(self, logger=None, check=None):
789789
'__rfm_check__': check,
790790
'__rfm_loggable_attrs__': [],
791791
'check_name': 'reframe',
792-
'check_jobid': None,
793792
'check_job_completion_time': None,
794793
'check_job_completion_time_unix': None,
795794
'check_info': 'reframe',
796-
'check_system': None,
797-
'check_partition': None,
798-
'check_environ': None,
799795
'check_perf_var': None,
800796
'check_perf_value': None,
801797
'check_perf_ref': None,

reframe/frontend/autodetect.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ def _emit_script_for_pip(job, env):
142142
commands = [
143143
'python3 -m venv venv.reframe',
144144
'source venv.reframe/bin/activate',
145+
'pip install --upgrade pip',
145146
f'pip install reframe-hpc=={rfm.VERSION}',
146147
'reframe --detect-host-topology=topo.json',
147148
'deactivate'

reframe/utility/__init__.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -829,11 +829,12 @@ def _rl_encode(seq):
829829

830830

831831
def _parse_node(nodename):
832-
m = re.search(r'(.*\D)(\d+)', nodename)
832+
m = re.search(r'(.*\D)(\d+)(\D*)', nodename)
833833
if m is None:
834834
basename = nodename
835835
width = 0
836836
nodeid = None
837+
suffix = None
837838
else:
838839
basename = m.group(1)
839840
_id = m.group(2).lstrip('0')
@@ -843,8 +844,9 @@ def _parse_node(nodename):
843844

844845
nodeid = int(_id)
845846
width = len(m.group(2))
847+
suffix = m.group(3)
846848

847-
return basename, width, nodeid
849+
return basename, width, nodeid, suffix
848850

849851

850852
def count_digits(n):
@@ -873,15 +875,20 @@ def _common_prefix(s1, s2):
873875

874876

875877
class _NodeGroup:
876-
def __init__(self, name, width):
878+
def __init__(self, name, width, suffix):
877879
self.__name = name
880+
self.__suffix = suffix
878881
self.__width = width
879882
self.__nodes = []
880883

881884
@property
882885
def name(self):
883886
return self.__name
884887

888+
@property
889+
def suffix(self):
890+
return self.__suffix
891+
885892
@property
886893
def width(self):
887894
return self.__width
@@ -903,12 +910,12 @@ def __str__(self):
903910
start, delta, size = unit
904911
if size == 1:
905912
s_start = str(start).zfill(self.width)
906-
abbrev.append(f'{self.name}{s_start}')
913+
abbrev.append(f'{self.name}{s_start}{self.suffix}')
907914
elif delta != 1:
908915
# We simply unpack node lists with delta != 1
909916
for i in range(size):
910917
s_start = str(start + i*delta).zfill(self.width)
911-
abbrev.append(f'{self.name}{s_start}')
918+
abbrev.append(f'{self.name}{s_start}{self.suffix}')
912919
else:
913920
last = start + delta*(size-1)
914921
digits_last = count_digits(last)
@@ -921,19 +928,21 @@ def __str__(self):
921928
s_first = str(start).zfill(digits_last)
922929
s_last = str(last)
923930
prefix, s_first, s_last = _common_prefix(s_first, s_last)
924-
nd_range += f'{prefix}[{s_first}-{s_last}]'
931+
nd_range += f'{prefix}[{s_first}-{s_last}]{self.suffix}'
925932
abbrev.append(nd_range)
926933

927934
return ','.join(abbrev)
928935

929936
def __hash__(self):
930-
return hash(self.name) ^ hash(self.width)
937+
return hash(self.name) ^ hash(self.suffix) ^ hash(self.width)
931938

932939
def __eq__(self, other):
933940
if not isinstance(other, _NodeGroup):
934941
return NotImplemented
935942

936-
return self.name == other.name and self.width == other.width
943+
return (self.name == other.name and
944+
self.suffix == other.suffix and
945+
self.width == other.width)
937946

938947

939948
def nodelist_abbrev(nodes):
@@ -978,8 +987,8 @@ def nodelist_abbrev(nodes):
978987

979988
node_groups = {}
980989
for n in sorted(nodes):
981-
basename, width, nid = _parse_node(n)
982-
ng = _NodeGroup(basename, width)
990+
basename, width, nid, suffix = _parse_node(n)
991+
ng = _NodeGroup(basename, width, suffix)
983992
node_groups.setdefault(ng, ng)
984993
if nid is not None:
985994
node_groups[ng].add(nid)
@@ -1004,7 +1013,9 @@ def nodelist_expand(nodespec):
10041013
return []
10051014

10061015
nodespec_parts = nodespec.split(',')
1007-
node_patt = re.compile(r'(?P<prefix>.+)\[(?P<l>\d+)-(?P<u>\d+)\]')
1016+
node_patt = re.compile(
1017+
r'(?P<prefix>.+)\[(?P<l>\d+)-(?P<u>\d+)\](?P<suffix>.*)'
1018+
)
10081019
nodes = []
10091020
for ns in nodespec_parts:
10101021
if '[' not in ns and ']' not in ns:
@@ -1015,11 +1026,11 @@ def nodelist_expand(nodespec):
10151026
if not match:
10161027
raise ValueError(f'invalid nodespec: {nodespec}')
10171028

1018-
prefix = match.group('prefix')
1029+
prefix, suffix = match.group('prefix'), match.group('suffix')
10191030
low, upper = int(match.group('l')), int(match.group('u'))
10201031
width = count_digits(upper)
10211032
for nid in range(low, upper+1):
1022-
nodes.append(f'{prefix}{nid:0{width}}')
1033+
nodes.append(f'{prefix}{nid:0{width}}{suffix}')
10231034

10241035
return nodes
10251036

unittests/test_utility.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,6 +2052,12 @@ def test_nodelist_utilities():
20522052
# Test the reverse operation
20532053
assert expand('c2-01-[00-99]') == nodes
20542054

2055+
# Test host names with suffixes (see GH #3021)
2056+
nodes = [f'nid{n:03}-x' for n in range(100)]
2057+
nodes.append('nid100-y')
2058+
assert nodelist(nodes) == 'nid0[00-99]-x,nid100-y'
2059+
assert expand('nid0[00-99]-x,nid100-y') == nodes
2060+
20552061
# Test node duplicates
20562062
assert nodelist(['nid001', 'nid001', 'nid002']) == 'nid001,nid00[1-2]'
20572063
assert expand('nid001,nid00[1-2]') == ['nid001', 'nid001', 'nid002']

0 commit comments

Comments
 (0)