feat(job-array-single-wal-record): add compact array push capnp variant

Adds Data union variant jobArray@6, reusing JobSubmit's existing
(jobid, arraySize, submit) shape verbatim -- no new struct, no
existing variant renumbered. Not yet wired into any push path
(tasks 5.1/5.2 own that).

Task 1.2 of job-array-single-wal-record.
This commit is contained in:
Rongsong Shen 2026-07-14 07:11:51 +00:00
parent 2e62e73d84
commit bc4e70b790
4 changed files with 96 additions and 2 deletions

View file

@ -8,7 +8,7 @@
- _Requirements: 1.1, 1.2, 1.3_
- _Boundary: WAL Array Submission_
- [ ] 1.2 (P) Add the compact array push wire variant
- [x] 1.2 (P) Add the compact array push wire variant
- Add one new additive variant to the existing controller-to-scheduler/apiserver push message, reusing the client submit request's existing (base jobid, array size, one spec) shape verbatim — no new struct
- Observable: the schema compiles and generates encode/decode functions for the new variant without touching any existing variant's wire layout
- _Requirements: 6.1, 6.2_

View file

@ -243,6 +243,94 @@ static void test_wal_catchup_append_term_fields_round_trip(void)
printf("test_wal_catchup_append_term_fields_round_trip: PASS\n");
}
/* ------------------------------------------------------------------ */
/* Test 6: Data union's new jobArray variant (job-array-single-wal-record */
/* task 1.2, Req 6.1/6.2) round-trips the compact (base jobid, array size, */
/* one shared spec) push descriptor through the wire -- reusing the client */
/* submit request's existing JobSubmit shape verbatim (no new struct). */
/* This only proves the additive schema variant exists and round-trips; */
/* nothing calls it yet (wiring into sched/apiserver push is task 5.1/5.2). */
/* ------------------------------------------------------------------ */
static void test_data_job_array_variant_round_trip(void)
{
job_submit_data_t submit;
memset(&submit, 0, sizeof(submit));
submit.queue = "batch";
submit.user = "rshen";
submit.mintasks = 1u;
submit.maxtasks = 4u;
submit.start_info = NULL;
submit.job_name = "array-job";
submit.project_name = "proj";
submit.user_group = "grp";
submit.job_description = "job-array-single-wal-record round-trip test";
submit.resreq = "select=1";
xce_job_submit_t src;
memset(&src, 0, sizeof(src));
src.jobid = 5000ULL; /* base jobid */
src.array_size = 250ULL;
src.submit = &submit;
xce_data_t data;
memset(&data, 0, sizeof(data));
data.table = Data_data_jobArray;
data.data.job_array = &src;
/* Encode -> flat wire buffer -> decode, exercising both the schema
* field (jobArray @6) and the typemap.h mirror mapping (xce_data_t's
* new job_array union member), the same pattern Test 4/5 use. */
struct capn c;
capn_init_malloc(&c);
struct capn_segment *cs = capn_root(&c).seg;
Data_ptr p;
encode_Data_ptr(cs, &p, &data);
capn_setp(capn_root(&c), 0, p.p);
int64_t sz = capn_size(&c);
TEST_ASSERT_TRUE(sz > 0);
uint8_t *buf = (uint8_t *)malloc((size_t)sz);
TEST_ASSERT_NOT_NULL(buf);
capn_write_mem(&c, buf, (size_t)sz, 0);
capn_free(&c);
struct capn d;
TEST_ASSERT_EQUAL_INT(0, capn_init_mem(&d, buf, (size_t)sz, 0));
Data_ptr dp;
dp.p = capn_getp(capn_root(&d), 0, 1);
struct Data wire;
read_Data(&wire, dp);
xce_data_t dst;
memset(&dst, 0, sizeof(dst));
decode_Data(&dst, &wire);
TEST_ASSERT_EQUAL_INT(Data_data_jobArray, dst.table);
TEST_ASSERT_NOT_NULL(dst.data.job_array);
TEST_ASSERT_EQUAL_UINT64(5000ULL, dst.data.job_array->jobid);
TEST_ASSERT_EQUAL_UINT64(250ULL, dst.data.job_array->array_size);
TEST_ASSERT_NOT_NULL(dst.data.job_array->submit);
TEST_ASSERT_EQUAL_STRING("batch", dst.data.job_array->submit->queue);
TEST_ASSERT_EQUAL_STRING("rshen", dst.data.job_array->submit->user);
TEST_ASSERT_EQUAL_UINT32(1u, dst.data.job_array->submit->mintasks);
TEST_ASSERT_EQUAL_UINT32(4u, dst.data.job_array->submit->maxtasks);
TEST_ASSERT_EQUAL_STRING("array-job", dst.data.job_array->submit->job_name);
/* Untouched: the existing schedjobs/jobs/etc. wire layout is unaffected --
* spot-check the enum values these variants relied on before this change
* did not shift underneath them. */
TEST_ASSERT_EQUAL_INT(0, (int)Data_data_schedjobs);
TEST_ASSERT_EQUAL_INT(2, (int)Data_data_jobs);
TEST_ASSERT_EQUAL_INT(5, (int)Data_data_resvals);
TEST_ASSERT_EQUAL_INT(6, (int)Data_data_jobArray);
free_Data(&dst);
capn_free(&d);
free(buf);
printf("test_data_job_array_variant_round_trip: PASS\n");
}
/* ------------------------------------------------------------------ */
/* Suite entry point */
/* ------------------------------------------------------------------ */
@ -256,4 +344,5 @@ void test_e2e_capnp(void)
RUN_TEST(test_repl_envelope_capnp_fields);
RUN_TEST(test_request_vote_last_log_tuple_round_trip);
RUN_TEST(test_wal_catchup_append_term_fields_round_trip);
RUN_TEST(test_data_job_array_variant_round_trip);
}

View file

@ -133,6 +133,10 @@ typedef struct {
xce_workers_data_t* workers;
xce_resource_data_t* resources;
xce_resval_data_t* resvals;
xce_job_submit_t* job_array; /* job-array-single-wal-record 1.2: compact
* (base jobid, array size, one spec) push
* descriptor -- same JobSubmit shape as the
* client submit request and WAL payload. */
} data;
} xce_data_t;

View file

@ -359,7 +359,8 @@ struct Data $C.mapname("xce_data_t"){
jobs @2: JobData $C.mapname("jobs");
workers @3: WorkerData $C.mapname("workers");
resources @4: ResourceData $C.mapname("resources");
resvals @5: ResourceVals $C.mapname("resvals");
resvals @5: ResourceVals $C.mapname("resvals");
jobArray @6: JobSubmit $C.mapname("job_array");
}
}