Skip to content

[feat] Extend allowed syntax for system/partitions/environment names and enforce strict syntax checking for extra_resources keys - #3725

Merged
vkarak merged 1 commit into
reframe-hpc:developfrom
vkarak:feat/expand-alphanum-ext-string
Sep 23, 2026
Merged

vkarak merged 1 commit into
reframe-hpc:developfrom
vkarak:feat/expand-alphanum-ext-string

Conversation

@vkarak

@vkarak vkarak commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Broaden the alphanum_ext_string schema type so that system, partition, environment and feature names may:

  • start with a digit;
  • contain dots (.) and plus signs (+), in addition to the already-allowed dash (-) and underscore (_).

The valid_systems / valid_prog_environs mini-language is updated in lockstep so that every name accepted by the configuration schema can also be targeted precisely in a test's valid_systems / valid_prog_environs.

This PR also enforces strict syntax in the extra_resources keys as these are expanded in kwargs and if they are not valid identifiers, ReFrame will crash, e.g., here:

**self.extra_resources

Replaces #3720
Closes #3645
Closes #3723

Implementation details

Schema (reframe/schemas/config.json)

  • alphanum_ext_string pattern: ^[a-zA-Z_](?:[a-zA-Z0-9_-])*$ → ^[a-zA-Z0-9_](?:[a-zA-Z0-9_.+-])*$.
    A name still may not start with ., + or -; this invariant is what keeps the mini-language tokenizer unambiguous (a bare name can never be mistaken for a +feat / -feat / %key=val token).
  • The inline propertyNames patterns of systems.partitions.extras, environments.extras and environments.resources now reference the shared #/defs/alphanum_string def (no behavioural change — the inline patterns were already identical).
  • systems.partitions.resources[].name is now validated against alphanum_string instead of accepting an arbitrary string.

Mini-language (reframe/core/pipeline.py)

  • _N (the name production used by _VALID_SYS_SYNTAX / _VALID_ENV_SYNTAX) gains +. Leading digits and . were already accepted by _N; with this change the schema pattern and _N are equivalent for ASCII input.

Parser (reframe/core/runtime.py)

  • _is_valid_part() / _is_valid_env() now split %key=val specs with maxsplit=1, so a value containing = (e.g. %key=a=b) no longer raises an uncaught ValueError.

Docs (docs/config_reference.rst)

  • Updated the character rules for systems.name, systems.partitions.name, environments.name (the last one previously said nothing) and the two features lists.
  • Documented the deliberate two-tier model: names and features are permissive; extras keys and resource names stay plain POSIX-style identifiers (^[a-zA-Z_][a-zA-Z0-9_]*$).
  • versionchanged:: 4.11.0 markers throughout.

Grammar: before → after

Input Before After
sys.x:part.y ✅ ✅
0sys:1part ❌ (schema) ✅
g++, gcc-11.2+omp ❌ ✅
sys:gpu+mps, +gpu+mps ❌ ✅
.sys, +sys, -sys ❌ ❌
sys x, a:b:c, a@b ❌ ❌

@codecov

codecov Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.96%. Comparing base (f7880ce) to head (7f15777).
⚠️ Report is 2 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3725      +/-   ##
===========================================
+ Coverage    91.93%   91.96%   +0.03%     
===========================================
  Files           62       62              
  Lines        13818    13818              
===========================================
+ Hits         12703    12708       +5     
+ Misses        1115     1110       -5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@RiMillo

RiMillo commented Sep 10, 2026 •

Copy link
Copy Markdown

Hello @vkarak,

I'm reporting back from #3720.

First of all, thanks for taking the time, it is really appreciated.

I had some tests with my config. My original need was to allow version-like names for environments, i.e., 1.0.0, and they worked. I also tested system names with leading digits and they worked, too! Thanks!

I then tried adding +<stuff>, e.g., 1.0.0+alpha to environment names, and had some unexpected (at least to me, since I do not practice reframe that much) results. The name is validated just fine (that's an improvement wrt master). But if I provide the full name when launching reframe, e.g., --prgenv '1.0.0+alpha', no test is matched (hence, run neither), even if tests have valid_prog_environs = ["*"]. It works if I leave out the +alpha: since it is a regex pattern, the right environment is selected. To sum, with environment 1.0.0+alpha and valid_prog_environs = ["*"]:

  • reframe --prgenv=1.0.0+alpha: test is not selected ❌
  • reframe --prgenv=1.0.0: test is run ✅

Just to be clear, I'm already happy with the current status, and if this is, in fact, an expected behaviour, well, sorry for the noise, and do not hesitate to just merge 🙃

@vkarak

vkarak commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor Author

@RiMillo This is expected behaviour because the --prgenv interprets its argument as a Python regex. So you have to escape the + if you want it to be interpreted literally. Can you try --prgenv=1\.0\.0\+alpha. Note that technically you have to escape . as well: the fact that it works is because it matches any character. It could match also an environment named 1_0_0.

@RiMillo

RiMillo commented Sep 10, 2026

Copy link
Copy Markdown

Ah, you are right, of course. I did not think about that!

Indeed it works when escaping \+!

Cheers!

@victorusu

Copy link
Copy Markdown
Contributor

@boegel and @casparvl , would this change hurt you in any way?

@satishskamath

satishskamath commented Sep 18, 2026 •

Copy link
Copy Markdown

@vkarak , @victorusu , @boegel, @casparvl, @smoors

Dry run including this PR

uv run reframe -C /gpfs/home5/satishk/projects/eessi_reframe/settings_example.py -c /gpfs/home5/satishk/projects/test-suite/eessi/testsuite/tests/apps/openfoam.org/openfoamorg.py -t 1_node --dry-run
[ReFrame Setup]
  version:           4.11.0-dev3+cc696c3b
  command:           '/gpfs/home5/satishk/reframe/reframe/.venv/bin/reframe -C /gpfs/home5/satishk/projects/eessi_reframe/settings_example.py -c /gpfs/home5/satishk/projects/test-suite/eessi/testsuite/tests/apps/openfoam.org/openfoamorg.py -t 1_node --dry-run'
  launched by:       satishk@tcn3.local.snellius.surf.nl
  working directory: '/gpfs/home5/satishk/reframe/reframe'
  settings files:    '<builtin>', '/gpfs/home5/satishk/projects/eessi_reframe/settings_example.py'
  selected system:   'snellius_eessi'
  check search path: '/gpfs/home5/satishk/projects/test-suite/eessi/testsuite/tests/apps/openfoam.org/openfoamorg.py'
  stage directory:   '/projects/0/reframe5/satishk'
  output directory:  '/gpfs/home5/satishk/reframe/reframe/output'
  log files:         '/gpfs/home5/satishk/reframe/reframe/reframe.log'
  results database:  [off] '/home/satishk/.reframe/reports/results.db'

[==========] Running 4 check(s)
[==========] Started on Fri Sep 18 16:54:41 2026+0200

[----------] start processing checks
[ DRY      ] EESSI_OPENFOAMORG_LID_DRIVEN_CAVITY_1M %device_type=cpu %module_info=('snellius_eessi:cpu_rome', 'default', 'OpenFOAM/13-foss-2025a') %scale=1_node /78148531 @snellius_eessi:cpu_rome+default
[ DRY      ] EESSI_OPENFOAMORG_LID_DRIVEN_CAVITY_1M %device_type=cpu %module_info=('snellius_eessi:cpu_genoa', 'default', 'OpenFOAM/13-foss-2025a') %scale=1_node /4c32f268 @snellius_eessi:cpu_genoa+default
[     SKIP ] (1/4) EESSI_OPENFOAMORG_LID_DRIVEN_CAVITY_1M %device_type=cpu %module_info=('snellius_eessi:cpu_genoa', 'default', 'OpenFOAM/13-foss-2025a') %scale=1_node /4c32f268 @snellius_eessi:cpu_genoa+default [The maximum number of cores this test can run on is 128. Launch on a scale with lower corecount.]
[ DRY      ] EESSI_OPENFOAMORG_LID_DRIVEN_CAVITY_8M %device_type=cpu %module_info=('snellius_eessi:cpu_rome', 'default', 'OpenFOAM/13-foss-2025a') %scale=1_node /82ec9359 @snellius_eessi:cpu_rome+default
[ DRY      ] EESSI_OPENFOAMORG_LID_DRIVEN_CAVITY_8M %device_type=cpu %module_info=('snellius_eessi:cpu_genoa', 'default', 'OpenFOAM/13-foss-2025a') %scale=1_node /38a602f0 @snellius_eessi:cpu_genoa+default
[       OK ] (2/4) EESSI_OPENFOAMORG_LID_DRIVEN_CAVITY_1M %device_type=cpu %module_info=('snellius_eessi:cpu_rome', 'default', 'OpenFOAM/13-foss-2025a') %scale=1_node /78148531 @snellius_eessi:cpu_rome+default
P: perf: None s/timestep
[       OK ] (3/4) EESSI_OPENFOAMORG_LID_DRIVEN_CAVITY_8M %device_type=cpu %module_info=('snellius_eessi:cpu_rome', 'default', 'OpenFOAM/13-foss-2025a') %scale=1_node /82ec9359 @snellius_eessi:cpu_rome+default
P: perf: None s/timestep
[       OK ] (4/4) EESSI_OPENFOAMORG_LID_DRIVEN_CAVITY_8M %device_type=cpu %module_info=('snellius_eessi:cpu_genoa', 'default', 'OpenFOAM/13-foss-2025a') %scale=1_node /38a602f0 @snellius_eessi:cpu_genoa+default
P: perf: None s/timestep
[----------] all spawned checks have finished

[  PASSED  ] Ran 3/4 test case(s) from 4 check(s) (0 failure(s), 0 expected failure(s), 1 skipped, 0 aborted)
[==========] Finished on Fri Sep 18 16:54:49 2026+0200
Log file(s) saved in '/gpfs/home5/satishk/reframe/reframe/reframe.log'

Dry-run using the develop branch without this PR

uv run reframe -C /gpfs/home5/satishk/projects/eessi_reframe/settings_example.py -c /gpfs/home5/satishk/projects/test-suite/eessi/testsuite/tests/apps/openfoam.org/openfoamorg.py -t 1_node --dry-run
ERROR: failed to load configuration: could not validate configuration files: `<builtin>`, `/gpfs/home5/satishk/projects/eessi_reframe/settings_example.py`: '16_nodes' does not match '^[a-zA-Z_](?:[a-zA-Z0-9_-])*$'
Log file(s) saved in '/tmp/rfm-_1ddw88t.log'
[satishk@tcn3 reframe]$ uv run reframe -vvv -C /gpfs/home5/satishk/projects/eessi_reframe/settings_example.py -c /gpfs/home5/satishk/projects/test-suite/eessi/testsuite/tests/apps/openfoam.org/openfoamorg.py -t 1_node --dry-run
Loading user configuration
Loading the builtin configuration
Loading configuration file: '/gpfs/home5/satishk/projects/eessi_reframe/settings_example.py'
'16_nodes' does not match '^[a-zA-Z_](?:[a-zA-Z0-9_-])*$'

Failed validating 'pattern' in schema['properties']['systems']['items']['properties']['partitions']['items']['properties']['features']['items']:
    {'type': 'string', 'pattern': '^[a-zA-Z_](?:[a-zA-Z0-9_-])*$'}

On instance['systems'][0]['partitions'][3]['features'][13]:
    '16_nodes'
ERROR: failed to load configuration: could not validate configuration files: `<builtin>`, `/gpfs/home5/satishk/projects/eessi_reframe/settings_example.py`: '16_nodes' does not match '^[a-zA-Z_](?:[a-zA-Z0-9_-])*$'

@github-project-automation github-project-automation Bot moved this from Todo to In Progress in ReFrame Backlog Sep 23, 2026
Signed-off-by: Vasileios Karakasis <vkarak@gmail.com>
@vkarak
vkarak force-pushed the feat/expand-alphanum-ext-string branch from cc696c3 to 7f15777 Compare September 23, 2026 11:39
@vkarak
vkarak enabled auto-merge September 23, 2026 11:53
@vkarak
vkarak merged commit 7289d59 into reframe-hpc:develop Sep 23, 2026
54 of 58 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in ReFrame Backlog Sep 23, 2026
@vkarak
vkarak deleted the feat/expand-alphanum-ext-string branch September 23, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Allow feature names to start with a digit Relax alphanum_ext_string schema to support numeric and version-based environment names

5 participants