fix(lib): a malformed select in a resreq fails the parse instead of being dropped (bug-1887)

The primary_resreq action ignored parse_resreq_primary()'s result, so a
primary whose select (or rusage) clause failed to parse was accepted
without that clause: select[type==] or select[mem>] matched every host.
A malformed clause now fails the whole resreq, and parse_resreq() returns
the clause's own message.

A select naming an unregistered resource is still dropped, not an
error: parse_select() reports it as -ENOENT (new select_context_t
.unknown_resource) and the action lets it pass, because jobs rely on it
-- the scheduler's own "type == any" default among them when no "type"
resource is registered (making it fatal failed 36 scheduler suites).

Test: test_resreq_primary_select_error_fails_parse RED before (all
accepted), GREEN after.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-09-29 10:26:35 +00:00
parent 077b1213d3
commit b5712c053d
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
6 changed files with 117 additions and 9 deletions

View file

@ -1335,12 +1335,10 @@ test_snapshot_load_leaves_schedobj_null_when_resreq_fails_to_parse(void)
/* An unbalanced/unterminated compound-resreq brace: the top-level PEG
* grammar (xce_resreq.peg) requires a full input match through EOF; a
* lone unterminated '{' cannot complete as alter/compound/primary and
* leaves trailing unconsumed input, so parse_resreq() genuinely fails
* (unlike plain non-brace garbage, which the grammar's permissive
* primary_resreq rule accepts as a literal select expression and only
* fails later, silently, inside parse_resreq_primary() without
* propagating an error -- confirmed empirically while writing this
* test). */
* leaves trailing unconsumed input, so parse_resreq() genuinely fails.
* (Plain non-brace garbage is taken as a select expression; before
* bug-1887 its failure inside parse_resreq_primary() was dropped
* silently, now a malformed select fails the parse too.) */
bad_job = make_job_with_resreq(404, JOB_STAT_PEND, "normal", "alice",
"proj1", "{");