fix(apiserver): reject a malformed rusage[] at job submit (bug-1744)
Gitea #47: `xcecli jobs submit -R "rusage[mem=100000000a0]"` was accepted with a normal "Job <...> is submitted" reply. The apiserver only length-checked resreq; the real PEG grammar ran later, asynchronously, in the scheduler's core_build_job(), which logged a server-side WARN and dropped the job -- it then sat PEND forever with no sign of why. - libxce: xce_check_rusage_syntax(resreq, &errmsg) runs parse_rusage() on every rusage[...] clause (extracted the way section.peg does: up to the first ']'), so primary, compound and alternative requests are all covered. No resource manager needed, so select[]/order[] resource names are still only checked by the scheduler (the documented scope). - apiserver/backend: ValidateResreqSyntax() cgo wrapper (resreq_check.go); the !cgo stub returns nil (no job can be submitted without CGO anyway). - controllers/jobs.go preCheckJobRequest(): calls it after the length check via a package var, so a malformed request is refused up front. Tests: lib test_check_rusage_syntax (RED before: the reported input was accepted) and backend TestValidateResreqSyntax (RED before) through the real grammar; controllers TestPreCheckJobRequest_RejectsMalformedResreq checks the call site with an injected validator (written with the call site, so no separate RED). libxce, apiserver backend (cgo) and controllers tests pass. apiserver/middleware TestLoadJobs fails here and on the baseline alike: it needs a live apiserver on :8080. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ac20b2441f
commit
b970ab75b1
8 changed files with 209 additions and 0 deletions
|
|
@ -1,3 +1,4 @@
|
|||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -481,11 +482,49 @@ void test_parse_section_span_not_in_select(void)
|
|||
FREEUP(errmsg);
|
||||
}
|
||||
|
||||
/* bug-1744: the apiserver's pre-submit check. Valid rusage clauses (and
|
||||
* requests with none) pass; a malformed one -- the reported
|
||||
* "rusage[mem=100000000a0]" -- is rejected with a message. */
|
||||
void test_check_rusage_syntax(void)
|
||||
{
|
||||
const char* good[] = {
|
||||
"rusage[mem=100]",
|
||||
"select[type==any] rusage[mem=100, swp=2]",
|
||||
"select[type==any] order[r15m]",
|
||||
"",
|
||||
"{rusage[mem=1]} || {rusage[mem=2]}",
|
||||
};
|
||||
const char* bad[] = {
|
||||
"rusage[mem=100000000a0]",
|
||||
"select[type==any] rusage[mem=]",
|
||||
"{rusage[mem=1]} || {rusage[mem=x]}",
|
||||
"rusage[mem=1",
|
||||
};
|
||||
char* errmsg;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(good) / sizeof(good[0]); i++) {
|
||||
errmsg = NULL;
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(1, xce_check_rusage_syntax(good[i], &errmsg),
|
||||
good[i]);
|
||||
TEST_ASSERT_NULL(errmsg);
|
||||
}
|
||||
for (i = 0; i < sizeof(bad) / sizeof(bad[0]); i++) {
|
||||
errmsg = NULL;
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(-EINVAL,
|
||||
xce_check_rusage_syntax(bad[i], &errmsg),
|
||||
bad[i]);
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(errmsg, bad[i]);
|
||||
free(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
void test_resreq(void)
|
||||
{
|
||||
printf("\n>> resreq test\n\n");
|
||||
|
||||
RUN_TEST(test_parse_section1);
|
||||
RUN_TEST(test_check_rusage_syntax);
|
||||
RUN_TEST(test_parse_section2);
|
||||
RUN_TEST(test_parse_section_fail);
|
||||
RUN_TEST(test_parse_section3);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue