From bc4e70b79087e9137ce5ed4de91f6fde58aa182a Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Tue, 14 Jul 2026 07:11:51 +0000 Subject: [PATCH] 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. --- .../job-array-single-wal-record/tasks.md | 2 +- src/controller/testsuite/test_e2e_capnp.c | 89 +++++++++++++++++++ src/include/typemap.h | 4 + src/schema/controller.capnp | 3 +- 4 files changed, 96 insertions(+), 2 deletions(-) diff --git a/.kiro/specs/job-array-single-wal-record/tasks.md b/.kiro/specs/job-array-single-wal-record/tasks.md index 1013da81..cff35dd9 100644 --- a/.kiro/specs/job-array-single-wal-record/tasks.md +++ b/.kiro/specs/job-array-single-wal-record/tasks.md @@ -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_ diff --git a/src/controller/testsuite/test_e2e_capnp.c b/src/controller/testsuite/test_e2e_capnp.c index a9d4570e..3514a008 100644 --- a/src/controller/testsuite/test_e2e_capnp.c +++ b/src/controller/testsuite/test_e2e_capnp.c @@ -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); } diff --git a/src/include/typemap.h b/src/include/typemap.h index 79001647..520d822e 100644 --- a/src/include/typemap.h +++ b/src/include/typemap.h @@ -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; diff --git a/src/schema/controller.capnp b/src/schema/controller.capnp index 6b2d118e..95e682ae 100644 --- a/src/schema/controller.capnp +++ b/src/schema/controller.capnp @@ -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"); } }