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
11 changes: 11 additions & 0 deletions docs/manpage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ This happens recursively so that if test ``T1`` depends on ``T2`` and ``T2`` dep
These are all tests with :attr:`num_gpus_per_node` greater than zero.
This option and :option:`--cpu-only` are mutually exclusive.

.. option:: --maintainer=MAINTAINER

Filter tests by maintainer.
``MAINTAINER`` is interpreted as a `Python Regular Expression <https://docs.python.org/3/library/re.html>`__; all tests that have at least a matching maintainer will be selected.
``MAINTAINER`` being a regular expression has the implication that ``--maintainer 'foo'`` will select also tests that define ``'foobar'`` as a maintainer.
To restrict the selection to tests defining only ``'foo'``, you should use ``--maintainer 'foo$'``.

This option may be specified multiple times, in which case only tests defining or matching *all* maintainers will be selected.

.. versionadded:: 3.9.1

.. option:: -n, --name=NAME

Filter tests by name.
Expand Down
9 changes: 9 additions & 0 deletions reframe/frontend/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ def main():
'--gpu-only', action='store_true',
help='Select only GPU checks'
)
select_options.add_argument(
'--maintainer', action='append', dest='maintainers', default=[],
metavar='PATTERN',
help='Select checks with at least one maintainer matching PATTERN'
)
select_options.add_argument(
'-n', '--name', action='append', dest='names', default=[],
metavar='PATTERN', help='Select checks whose name matches PATTERN'
Expand Down Expand Up @@ -842,6 +847,10 @@ def print_infoline(param, value):
f'Filtering test cases(s) by tags: {len(testcases)} remaining'
)

# Filter test cases by maintainers
for maint in options.maintainers:
testcases = filter(filters.have_maintainer(maint), testcases)

# Filter test cases further
if options.gpu_only and options.cpu_only:
printer.error("options `--gpu-only' and `--cpu-only' "
Expand Down
9 changes: 9 additions & 0 deletions reframe/frontend/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ def _fn(case):
return _fn


def have_maintainer(patt):
regex = re_compile(patt)

def _fn(case):
return any(regex.match(p) for p in case.check.maintainers)

return _fn


def have_gpu_only():
def _fn(case):
return case.check.num_gpus_per_node > 0
Expand Down
15 changes: 12 additions & 3 deletions unittests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,20 @@ def sample_cases():
make_case({
'name': 'check1',
'tags': {'a', 'b', 'c', 'd'},
'num_gpus_per_node': 1
'num_gpus_per_node': 1,
'maintainers': {'A', 'B', 'C', 'D'}
}),
make_case({
'name': 'check2',
'tags': {'x', 'y', 'z'},
'num_gpus_per_node': 0
'num_gpus_per_node': 0,
'maintainers': {'X', 'Y', 'Z'}
}),
make_case({
'name': 'check3',
'tags': {'a', 'z'},
'num_gpus_per_node': 1
'num_gpus_per_node': 1,
'maintainers': {'A', 'Z'}
})
]

Expand Down Expand Up @@ -82,6 +85,12 @@ def test_have_not_tags(sample_cases):
assert 1 == count_checks(filters.have_not_tag('z'), sample_cases)


def test_have_maintainers(sample_cases):
assert 2 == count_checks(filters.have_maintainer('A|C'), sample_cases)
assert 0 == count_checks(filters.have_maintainer('P|Q'), sample_cases)
assert 2 == count_checks(filters.have_maintainer('Z'), sample_cases)


def test_have_gpu_only(sample_cases):
assert 2 == count_checks(filters.have_gpu_only(), sample_cases)

Expand Down