fix(scheduler): snapshots save a job's resreq text, not its debug dump (bug-1888)
build_wire_job() filled the saved job's submit->resreq with
format_resreq()'s human-readable dump ("Primary:\n Tasks: ..."). The
loader's parser accepted that as a primary with neither select nor
rusage, so every job restored from a snapshot (a replay's start snapshot,
REPL snapshots) lost both.
A scheduler job now keeps the text its resreq was parsed from
(xce_sched_job_t.resreq_str, set at ingest, JOB_UPDATE and snapshot load,
freed at teardown) and the snapshot saves that; a job without it restores
as the loader's "type == any" default.
Test: test_snapshot_round_trip_keeps_job_resreq_text RED before (saved
text was the dump), GREEN after.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3e873f0a66
commit
077b1213d3
7 changed files with 83 additions and 9 deletions
|
|
@ -2601,9 +2601,67 @@ test_snapshot_load_leaves_running_job_without_allocation_at_zero_resinuse(void)
|
|||
TEST_ASSERT_EQUAL_FLOAT(0.0f, resinuse_slots);
|
||||
}
|
||||
|
||||
/*
|
||||
* bug-1888: a snapshot saves the text a job's resreq was parsed from, so
|
||||
* the restored job gets the same request back. It saved format_resreq()'s
|
||||
* human-readable dump instead, which the loader parsed as a primary with
|
||||
* neither select nor rusage.
|
||||
*/
|
||||
static void test_snapshot_round_trip_keeps_job_resreq_text(void)
|
||||
{
|
||||
xce_sched_core_t core_a;
|
||||
xce_sched_core_t core_b;
|
||||
xce_queue_t wire_queue;
|
||||
xce_job_t* wire_job;
|
||||
xce_core_event_t events[2];
|
||||
sched_snapshot_data_t snap;
|
||||
xce_sched_job_t* restored;
|
||||
int rc;
|
||||
|
||||
memset(&g_stub_state_a, 0, sizeof(g_stub_state_a));
|
||||
memset(&g_stub_state_b, 0, sizeof(g_stub_state_b));
|
||||
fixture_init(&core_a, &g_stub_plugin_a);
|
||||
fixture_init(&core_b, &g_stub_plugin_b);
|
||||
|
||||
memset(&wire_queue, 0, sizeof(wire_queue));
|
||||
wire_queue.queue = "normal";
|
||||
wire_queue.priority = 1;
|
||||
wire_queue.status = QUEUE_STAT_OPEN;
|
||||
|
||||
wire_job = make_job_with_resreq(503, JOB_STAT_PEND, "normal", "alice",
|
||||
"proj1", "rusage[mem=2]");
|
||||
|
||||
memset(events, 0, sizeof(events));
|
||||
events[0].type = XCE_CORE_EVENT_QUEUE_UPDATE;
|
||||
events[0].u.queue_update.queue = &wire_queue;
|
||||
events[1].type = XCE_CORE_EVENT_JOBS_PUSH;
|
||||
events[1].u.jobs_push.njobs = 1;
|
||||
events[1].u.jobs_push.jobs = &wire_job;
|
||||
rc = xce_core_push_events(&core_a, events, 2);
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
|
||||
memset(&snap, 0, sizeof(snap));
|
||||
rc = xce_sched_core_save_snapshot(&core_a, &snap);
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
TEST_ASSERT_EQUAL_INT(1, snap.jobs->count);
|
||||
TEST_ASSERT_EQUAL_STRING("rusage[mem=2]",
|
||||
snap.jobs->jobs[0]->submit->resreq);
|
||||
|
||||
rc = xce_sched_core_load_snapshot(&core_b, &snap);
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
restored = sched_get_job(&core_b, 503);
|
||||
TEST_ASSERT_NOT_NULL(restored);
|
||||
TEST_ASSERT_NOT_NULL(restored->resreq);
|
||||
TEST_ASSERT_EQUAL_INT(XCE_RESREQ_PRIMARY, restored->resreq->tag);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(
|
||||
1, restored->resreq->u.primary->rusages.count,
|
||||
"the restored job must keep its rusage");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_snapshot_round_trip_keeps_job_resreq_text);
|
||||
RUN_TEST(
|
||||
test_snapshot_guards_reject_null_args_and_busy_session_without_mutating_state);
|
||||
RUN_TEST(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue