diff --git a/.kiro/specs/xce-test-e2e-primitives/tasks.md b/.kiro/specs/xce-test-e2e-primitives/tasks.md index 86f04ef..206251d 100644 --- a/.kiro/specs/xce-test-e2e-primitives/tasks.md +++ b/.kiro/specs/xce-test-e2e-primitives/tasks.md @@ -53,7 +53,7 @@ - _Requirements: 5.1, 5.2_ - _Boundary: Assertions_ - _Depends: 5.1_ -- [ ] 5.3 `expect-job ` assertion +- [x] 5.3 `expect-job ` assertion - Add `cmd_expect_job`: pass when the JobId is present in the job list; otherwise print the missing id and return `<0`. Works with `$jobid` substitution. - Observable: `expect-job $jobid` passes for a submitted job; `expect-job ` fails the session and prints the missing id. - _Requirements: 5.3, 5.4_ diff --git a/src/controller/testsuite/test.c b/src/controller/testsuite/test.c index fa5cd81..3a4acef 100644 --- a/src/controller/testsuite/test.c +++ b/src/controller/testsuite/test.c @@ -118,6 +118,7 @@ extern int cmd_setpend(int, char*[]); extern int cmd_jobinfo(int, char*[]); extern int cmd_echo(int, char*[]); extern int cmd_expect_jobs(int, char*[]); +extern int cmd_expect_job(int, char*[]); static int worker_house_keeping(void*); /* Session verdict / loop state (xce-test-e2e-primitives task 1.1). @@ -203,6 +204,7 @@ static command_t client_commands[] = { { "qctrl", cmd_qctrl, "queue control" }, { "joblist", cmd_joblist, "list jobs" }, { "expect-jobs", cmd_expect_jobs, "assert current job count" }, + { "expect-job", cmd_expect_job, "assert a JobId is present" }, { "shutdown", cmd_shutdown, "shutdown xce controller" }, { "jobrun", cmd_jobrun, "run a job" }, { "jobsub", cmd_jobsub, "submit a job" }, @@ -1021,6 +1023,55 @@ int cmd_expect_jobs(int argc, char* argv[]) return 0; } +/* `expect-job ` assertion (xce-test-e2e-primitives task 5.3, Req 5.3/5.4, + * design.md cmd_expect_jobs / cmd_expect_job). + * + * Passes (returns 0) when a job whose `fmt_jobid` string equals argv[1] is + * present in the current job list; otherwise prints the missing id and returns a + * negative errno-style value so preprocess_and_run records the session as failed + * (Req 1.1). + * + * `$jobid` substitution is transparent: autovar substitution (task 3.1) replaces + * `$jobid` with the captured id string BEFORE this handler runs, so argv[1] is + * already the literal id. The membership test in joblist_query uses the SAME + * `fmt_jobid` representation that cmd_jobsub captured into `$jobid` (task 4.1), + * so `expect-job $jobid` matches the joblist entry. + * + * A missing argument is itself an assertion failure, not a no-op. A failed + * joblist query is also a failure: we cannot determine membership, so we report + * the query failure distinctly rather than silently equating it with "absent". */ +int cmd_expect_job(int argc, char* argv[]) +{ + int contains; + int rc; + + if (argc != 2) { + printf("expect-job \n"); + return -EINVAL; + } + + /* Print-free membership query via the shared helper. A negative rc means the + * query itself failed (e.g. no reachable master) — that is an assertion + * failure, distinct from "job absent". */ + rc = joblist_query(argv[1], &contains, 0); + + if (rc < 0) { + printf("expect-job: could not determine membership of '%s' (joblist " + "query failed)\n", + argv[1]); + return rc; + } + + if (!contains) { + printf("expect-job: job %s not found\n", argv[1]); + return -ENOENT; + } + + printf("expect-job: ok (%s)\n", argv[1]); + + return 0; +} + static void print_jobinfo(xce_job_t* job) { char idstring[128];