Skip to content

Commit

Permalink
Expand functionality of find_modules so that it can be passed a regul…
Browse files Browse the repository at this point in the history
…ar expression. It can also ommit the version (i.e. anything after the last slash) from the match, if required.
  • Loading branch information
Caspar van Leeuwen committed Aug 25, 2023
1 parent 012e74c commit 4de1bf1
Showing 1 changed file with 51 additions and 8 deletions.
59 changes: 51 additions & 8 deletions eessi/testsuite/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import re
import sys
from typing import Iterator
from typing import Iterator, List

import reframe as rfm
import reframe.core.runtime as rt
Expand Down Expand Up @@ -57,15 +57,58 @@ def is_cuda_required_module(module_name: str) -> bool:
return requires_cuda


def find_modules(substr: str) -> Iterator[str]:
"""Return all modules in the current system that contain ``substr`` in their name."""
if not isinstance(substr, str):
def find_modules(regex: str, name_only = True) -> Iterator[str]:
"""
Return all modules matching the regular expression regex. Note that since we use re.search,
a module matches if the regex matches the module name at any place. I.e. the match does
not have to be at the start of the smodule name
Arguments:
- regex: a regular expresion
- name_only: regular expressions will only be matched on the module name, not the version (default: True).
Note: the name_only feature assumes anything after the last forward '/' is the version,
and strips that before doing a match.
Example
Suppose we have the following modules on a system:
gompic/2022a
gompi/2022a
CGAL/4.14.3-gompi-2022a
The following calls would return the following respective modules
find_modules('gompi') => [gompic/2022a, gompi/2022a]
find_modules('gompi$') => [gompi/2022a]
find_modules('gompi', name_only = False) => [gompic/2022a, gompi/2022a, CGAL/4.14.3-gompi-2022a]
find_modules('^gompi', name_only = False) => [gompic/2022a, gompi/2022a]
find_modules('^gompi\/', name_only = False) => [gompi/2022a]
find_modules('-gompi-2022a', name_only = False) => [CGAL/4.14.3-gompi-2022a]
"""

if not isinstance(regex, str):
raise TypeError("'substr' argument must be a string")

ms = rt.runtime().modules_system
modules = OrderedSet(ms.available_modules(substr))
for m in modules:
yield m
# Returns e.g. ['Bison/', 'Bison/3.7.6-GCCcore-10.3.0', 'BLIS/', 'BLIS/0.8.1-GCC-10.3.0']
modules = ms.available_modules('')
for mod in modules:
# Exclude anything without version, i.e. ending with / (e.g. Bison/)
if re.search('.*\/$', mod):
continue
# The thing we yield should always be the original module name (orig_mod), including version
orig_mod = mod
if name_only:
# Remove part after the last forward slash, as we assume this is the version
mod = re.sub('\/[^\/]*$', '', mod)
# Match the actual regular expression
log(f"Matching module {mod} with regex {regex}")
if re.search(regex, mod):
log(f"Match!")
yield orig_mod

def check_proc_attribute_defined(test: rfm.RegressionTest, attribute) -> bool:
"""
Expand Down Expand Up @@ -104,4 +147,4 @@ def check_proc_attribute_defined(test: rfm.RegressionTest, attribute) -> bool:
"This is a programming error, please report this issue."
)
raise AttributeError(msg)


0 comments on commit 4de1bf1

Please sign in to comment.