Skip to content

Commit b990b33

Browse files
authored
Merge branch 'master' into intel_vtune
2 parents 7fc6a06 + 0f8736e commit b990b33

File tree

7 files changed

+128
-65
lines changed

7 files changed

+128
-65
lines changed

docs/running.rst

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,10 +365,29 @@ For example the following will select all the checks that can run with both ``Pr
365365
366366
If you are going to run a set of tests selected by programming environment, they will run only for the selected programming environment(s).
367367

368+
The ``-p`` option accepts also the Python `regular expression syntax <https://docs.python.org/3.6/library/re.html#regular-expression-syntax>`__.
369+
In fact, the argument to ``-p`` option is treated as a regular expression always. This means that the ``-p PrgEnv-gnu`` will match also tests that support a ``PrgEnv-gnuXX`` environment.
370+
If you would like to stricly select tests that support ``PrgEnv-gnu`` only and not ``PrgEnv-gnuXX``, you should write ``-p PrgEnv-gnu$``.
371+
As described above multiple ``-p`` options are AND-ed.
372+
Combining that with regular expressions can be quite powerful.
373+
For example, the following will select all tests that support programming environment ``foo`` and either ``PrgEnv-gnu`` or ``PrgEnv-pgi``:
374+
375+
.. code-block:: bash
376+
377+
./bin/reframe -p foo -p 'PrgEnv-(gnu|pgi)' -l
378+
379+
380+
.. note::
381+
.. versionadded:: 2.17
382+
383+
The ``-p`` option recognizes regular expressions as arguments.
384+
385+
368386
Selecting tests by tags
369387
^^^^^^^^^^^^^^^^^^^^^^^
370388

371-
As we have seen in the `"ReFrame tutorial" <tutorial.html>`__, every regression test may be associated with a set of tags. Using the ``-t`` or ``--tag`` option you can select the regression tests associated with a specific tag.
389+
As we have seen in the `"ReFrame tutorial" <tutorial.html>`__, every regression test may be associated with a set of tags.
390+
Using the ``-t`` or ``--tag`` option you can select the regression tests associated with a specific tag.
372391
For example the following will list all the tests that have a ``maintenance`` tag and can run on the current system:
373392

374393
.. code-block:: bash
@@ -378,6 +397,11 @@ For example the following will list all the tests that have a ``maintenance`` ta
378397
Similarly to the ``-p`` option, you can chain multiple ``-t`` options together, in which case a regression test will be selected if it is associated with all the tags specified in the command line.
379398
The list of tags associated with a check can be viewed in the listing output when specifying the ``-l`` option.
380399

400+
.. note::
401+
.. versionadded:: 2.17
402+
403+
The ``-t`` option recognizes regular expressions as arguments.
404+
381405
Selecting tests by name
382406
^^^^^^^^^^^^^^^^^^^^^^^
383407

@@ -439,6 +463,18 @@ Similarly, you can exclude this test by passing the ``-x Example7Test`` option:
439463
Found 12 check(s).
440464
441465
466+
Both ``-n`` and ``-x`` options can be chained, in which case either the tests that have any of the specified names are selected or excluded from running.
467+
They may also accept regular expressions as arguments.
468+
469+
.. note::
470+
.. versionadded:: 2.17
471+
472+
The ``-n`` and ``-x`` options recognize regular expressions as arguments.
473+
Chaining these options, e.g., ``-n A -n B``, is equivalent to a regular expression that applies OR to the individual arguments, i.e., equivalent to ``-n 'A|B'``.
474+
475+
476+
477+
442478
Controlling the Execution of Regression Tests
443479
---------------------------------------------
444480

reframe/core/pipeline.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
'RunOnlyRegressionTest', 'CompileOnlyRegressionTest']
77

88

9-
import fnmatch
109
import inspect
1110
import itertools
1211
import os
@@ -67,12 +66,18 @@ class RegressionTest:
6766

6867
#: List of programming environments supported by this test.
6968
#:
69+
#: If ``*`` is in the list then all programming environments are supported
70+
#: by this test.
71+
#:
7072
#: :type: :class:`List[str]`
7173
#: :default: ``[]``
7274
#:
7375
#: .. note::
7476
#: .. versionchanged:: 2.12
7577
#: Programming environments can now be specified using wildcards.
78+
#:
79+
#: .. versionchanged:: 2.17
80+
#: Support for wildcards is dropped.
7681
valid_prog_environs = fields.TypedField('valid_prog_environs',
7782
typ.List[str])
7883

@@ -787,11 +792,10 @@ def supports_system(self, partition_name):
787792
return partition_name in self.valid_systems
788793

789794
def supports_environ(self, env_name):
790-
for env in self.valid_prog_environs:
791-
if fnmatch.fnmatch(env_name, env):
792-
return True
795+
if '*' in self.valid_prog_environs:
796+
return True
793797

794-
return False
798+
return env_name in self.valid_prog_environs
795799

796800
def is_local(self):
797801
"""Check if the test will execute locally.

reframe/frontend/check_filters.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,42 @@
1+
import re
2+
13
import reframe.core.runtime as rt
24
import reframe.utility.sanity as util
35

46

5-
def have_name(names):
7+
def have_name(patt):
8+
regex = re.compile(patt)
9+
610
def _fn(c):
7-
return c.name in names
11+
return regex.match(c.name)
812

913
return _fn
1014

1115

12-
def have_not_name(names):
16+
def have_not_name(patt):
1317
def _fn(c):
14-
return not have_name(names)(c)
18+
return not have_name(patt)(c)
1519

1620
return _fn
1721

1822

19-
def have_tag(tags):
23+
def have_tag(patt):
24+
regex = re.compile(patt)
25+
2026
def _fn(c):
21-
return (set(tags)).issubset(c.tags)
27+
return any(regex.match(p) for p in c.tags)
2228

2329
return _fn
2430

2531

26-
def have_prgenv(prgenv):
32+
def have_prgenv(patt):
33+
regex = re.compile(patt)
34+
2735
def _fn(c):
28-
if prgenv:
29-
return util.allx(c.supports_environ(e) for e in prgenv)
36+
if '*' in c.valid_prog_environs:
37+
return True
3038
else:
31-
return bool(c.valid_prog_environs)
39+
return any(regex.match(p) for p in c.valid_prog_environs)
3240

3341
return _fn
3442

reframe/frontend/cli.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import os
21
import inspect
32
import json
3+
import os
4+
import re
45
import socket
56
import sys
67
import traceback
@@ -111,7 +112,7 @@ def main():
111112
'-x', '--exclude', action='append', dest='exclude_names',
112113
metavar='NAME', default=[], help='Exclude checks with NAME')
113114
select_options.add_argument(
114-
'-p', '--prgenv', action='append', default=[],
115+
'-p', '--prgenv', action='append', default=[r'.*'],
115116
help='Select tests for PRGENV programming environment only')
116117
select_options.add_argument(
117118
'--gpu-only', action='store_true',
@@ -414,20 +415,25 @@ def main():
414415
raise ReframeError from e
415416

416417
# Filter checks by name
417-
checks_matched = filter(filters.have_not_name(options.exclude_names),
418-
checks_found)
418+
checks_matched = checks_found
419+
if options.exclude_names:
420+
for name in options.exclude_names:
421+
checks_matched = filter(filters.have_not_name(name),
422+
checks_matched)
419423

420424
if options.names:
421-
checks_matched = filter(filters.have_name(options.names),
425+
checks_matched = filter(filters.have_name('|'.join(options.names)),
422426
checks_matched)
423427

424428
# Filter checks by tags
425-
checks_matched = filter(filters.have_tag(options.tags), checks_matched)
429+
for tag in options.tags:
430+
checks_matched = filter(filters.have_tag(tag), checks_matched)
426431

427432
# Filter checks by prgenv
428433
if not options.skip_prgenv_check:
429-
checks_matched = filter(filters.have_prgenv(options.prgenv),
430-
checks_matched)
434+
for prgenv in options.prgenv:
435+
checks_matched = filter(filters.have_prgenv(prgenv),
436+
checks_matched)
431437

432438
# Filter checks by system
433439
if not options.skip_system_check:
@@ -447,6 +453,12 @@ def main():
447453

448454
checks_matched = [c for c in checks_matched]
449455

456+
# Determine the programming environments to run with
457+
run_environs = {e.name
458+
for env_patt in options.prgenv
459+
for p in rt.system.partitions
460+
for e in p.environs if re.match(env_patt, e.name)}
461+
450462
# Act on checks
451463

452464
# Unload regression's module and load user-specified modules
@@ -491,7 +503,7 @@ def main():
491503
exec_policy.skip_environ_check = options.skip_prgenv_check
492504
exec_policy.skip_sanity_check = options.skip_sanity_check
493505
exec_policy.skip_performance_check = options.skip_performance_check
494-
exec_policy.only_environs = options.prgenv
506+
exec_policy.only_environs = run_environs
495507
exec_policy.keep_stage_files = options.keep_stage_files
496508
try:
497509
errmsg = "invalid option for --flex-alloc-tasks: '{0}'"

unittests/test_check_filters.py

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -37,51 +37,56 @@ def setUp(self):
3737
'num_gpus_per_node': 1})
3838
]
3939

40+
def count_checks(self, filter_fn):
41+
return sn.count(filter(filter_fn, self.checks))
42+
4043
def test_have_name(self):
41-
self.assertEqual(1, sn.count(filter(filters.have_name('check1'),
42-
self.checks)))
43-
self.assertEqual(1, sn.count(filter(filters.have_name('check2'),
44-
self.checks)))
45-
self.assertEqual(1, sn.count(filter(filters.have_name('check3'),
46-
self.checks)))
47-
self.assertEqual(0, sn.count(filter(filters.have_name('check4'),
48-
self.checks)))
44+
self.assertEqual(1, self.count_checks(filters.have_name('check1')))
45+
self.assertEqual(3, self.count_checks(filters.have_name('check')))
46+
self.assertEqual(2, self.count_checks(filters.have_name(r'\S*1|\S*3')))
47+
self.assertEqual(0, self.count_checks(filters.have_name('Check')))
48+
self.assertEqual(3, self.count_checks(filters.have_name('(?i)Check')))
49+
self.assertEqual(
50+
2, self.count_checks(filters.have_name('check1|(?i)CHECK2'))
51+
)
4952

5053
def test_have_not_name(self):
51-
self.assertEqual(2, sn.count(filter(filters.have_not_name('check1'),
52-
self.checks)))
54+
self.assertEqual(2, self.count_checks(filters.have_not_name('check1')))
55+
self.assertEqual(
56+
1, self.count_checks(filters.have_not_name('check1|check3'))
57+
)
58+
self.assertEqual(
59+
0, self.count_checks(filters.have_not_name('check1|check2|check3'))
60+
)
61+
self.assertEqual(3, self.count_checks(filters.have_not_name('Check1')))
62+
self.assertEqual(
63+
2, self.count_checks(filters.have_not_name('(?i)Check1'))
64+
)
5365

5466
def test_have_tags(self):
55-
self.assertEqual(1, sn.count(filter(filters.have_tag(['a', 'c']),
56-
self.checks)))
57-
self.assertEqual(0, sn.count(filter(filters.have_tag(['p', 'q']),
58-
self.checks)))
59-
self.assertEqual(2, sn.count(filter(filters.have_tag(['z']),
60-
self.checks)))
67+
self.assertEqual(2, self.count_checks(filters.have_tag('a|c')))
68+
self.assertEqual(0, self.count_checks(filters.have_tag('p|q')))
69+
self.assertEqual(2, self.count_checks(filters.have_tag('z')))
6170

6271
def test_have_prgenv(self):
63-
self.assertEqual(1, sn.count(filter(
64-
filters.have_prgenv(['env1', 'env2']), self.checks)))
65-
self.assertEqual(2, sn.count(filter(filters.have_prgenv(['env3']),
66-
self.checks)))
67-
self.assertEqual(1, sn.count(filter(filters.have_prgenv(['env4']),
68-
self.checks)))
69-
self.assertEqual(0, sn.count(filter(
70-
filters.have_prgenv(['env1', 'env3']), self.checks)))
72+
self.assertEqual(
73+
1, self.count_checks(filters.have_prgenv('env1|env2'))
74+
)
75+
self.assertEqual(2, self.count_checks(filters.have_prgenv('env3')))
76+
self.assertEqual(1, self.count_checks(filters.have_prgenv('env4')))
77+
self.assertEqual(
78+
3, self.count_checks(filters.have_prgenv('env1|env3'))
79+
)
7180

7281
@rt.switch_runtime(fixtures.TEST_SITE_CONFIG, 'testsys')
7382
def test_partition(self):
7483
p = rt.runtime().system.partition('gpu')
75-
self.assertEqual(2, sn.count(filter(filters.have_partition([p]),
76-
self.checks)))
84+
self.assertEqual(2, self.count_checks(filters.have_partition([p])))
7785
p = rt.runtime().system.partition('login')
78-
self.assertEqual(0, sn.count(filter(filters.have_partition([p]),
79-
self.checks)))
86+
self.assertEqual(0, self.count_checks(filters.have_partition([p])))
8087

8188
def test_have_gpu_only(self):
82-
self.assertEqual(2, sn.count(filter(filters.have_gpu_only(),
83-
self.checks)))
89+
self.assertEqual(2, self.count_checks(filters.have_gpu_only()))
8490

8591
def test_have_cpu_only(self):
86-
self.assertEqual(1, sn.count(filter(filters.have_cpu_only(),
87-
self.checks)))
92+
self.assertEqual(1, self.count_checks(filters.have_cpu_only()))

unittests/test_cli.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,16 @@ def test_check_submit_success(self):
148148
self.local = False
149149
self.system = partition.fullname
150150

151-
# pick up the programming environment of the partition
152-
self.environs = [partition.environs[0].name]
151+
# Pick up the programming environment of the partition
152+
# Prepend ^ and append $ so as to much exactly the given name
153+
self.environs = ['^' + partition.environs[0].name + '$']
153154

154155
returncode, stdout, _ = self._run_reframe()
155156
self.assertNotIn('FAILED', stdout)
156157
self.assertIn('PASSED', stdout)
158+
159+
# Assert that we have run only one test case
160+
self.assertIn('Ran 1 test case(s)', stdout)
157161
self.assertEqual(0, returncode)
158162

159163
def test_check_failure(self):

unittests/test_pipeline.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,6 @@ def test_supports_environ(self):
253253
self.assertTrue(test.supports_environ('foo-env'))
254254
self.assertTrue(test.supports_environ('*'))
255255

256-
test.valid_prog_environs = ['PrgEnv-foo-*']
257-
self.assertTrue(test.supports_environ('PrgEnv-foo-version1'))
258-
self.assertTrue(test.supports_environ('PrgEnv-foo-version2'))
259-
self.assertFalse(test.supports_environ('PrgEnv-boo-version1'))
260-
self.assertFalse(test.supports_environ('Prgenv-foo-version1'))
261-
262256
def test_sourcesdir_none(self):
263257
test = RegressionTest('hellocheck', 'unittests/resources/checks')
264258
test.sourcesdir = None

0 commit comments

Comments
 (0)