feat(controller-status): add per-controller connection-status field to CtrlPeer schema (task 8.1)

Adds CtrlPeer.status (UInt8, next free ordinal @3 after port) plus the
matching xce_ctrlpeer_t.status typemap field, verified field-for-field
against the regenerated codec with a genuine encode/decode round-trip
test. No sourcing/rendering logic yet (task 8.2/8.3) -- field defaults
to 0 (unknown) until wired.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
Rongsong Shen 2026-09-16 14:12:04 +00:00
parent 8a1964d483
commit 1b278c0e9a
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
4 changed files with 122 additions and 1 deletions

View file

@ -580,7 +580,85 @@ static void test_ctrlstatus_electedatms_roundtrip(void)
printf("test_ctrlstatus_electedatms_roundtrip: PASS\n");
}
/* ── (l) codec round-trip: HeartbeatMsg.electedAtMs @4 (task 7.1, Req 12.1) ──
/* ── (l) codec round-trip: CtrlPeer.status @3 (task 8.1, Req 13.1) ──
* Design delta "Design Delta — Requirement 13", Schema delta subsection: a new
* append-only UInt8 status code on the nested CtrlPeer list element (next
* free ordinal after port @2). Schema/codec-level only -- ctrlstatus_fill
* does not source real status values yet (task 8.2, out of boundary here).
* Proves a CtrlPeer.status value set to a non-default code (2 == catching-up)
* survives a genuine CtrlStatus encode -> bytes -> decode cycle unchanged,
* and that a peer whose status is left unset defaults to 0 (unknown) on the
* wire -- mirroring the peers-list construction pattern in
* src/lib/testsuite/test_ctrlstatus.c's test_ctrlstatus_roundtrip_all_fields.
*/
static void test_ctrlpeer_status_roundtrip(void)
{
xce_ctrlpeer_t p0 = {
.name = "ctrl-a", .host = "10.0.0.1", .port = 9991, .status = 2
};
xce_ctrlpeer_t p1 = {
.name = "ctrl-b", .host = "10.0.0.2", .port = 9992
/* .status intentionally left unset -- must default to 0 (unknown) */
};
xce_ctrlpeer_t* peerlist[2] = { &p0, &p1 };
xce_ctrlstatus_t in;
memset(&in, 0, sizeof(in));
in.clusterName = "lab-cluster";
in.responderName = "ctrl-a";
in.peers.count = 2;
in.peers.list = peerlist;
in.peerCount = 2;
struct capn c;
struct capn_segment* cs;
struct CtrlStatus cap_in;
CtrlStatus_ptr sp;
capn_init_malloc(&c);
cs = capn_root(&c).seg;
memset(&cap_in, 0, sizeof(cap_in));
encode_CtrlStatus(cs, &cap_in, &in);
sp = new_CtrlStatus(cs);
write_CtrlStatus(&cap_in, sp);
capn_setp(capn_root(&c), 0, sp.p);
size_t sz = capn_size(&c);
uint8_t* buf = (uint8_t*)malloc(sz);
TEST_ASSERT_NOT_NULL(buf);
TEST_ASSERT_EQUAL_size_t(sz, capn_write_mem(&c, buf, sz, 0));
capn_free(&c);
struct capn dc;
struct CtrlStatus cap_out;
CtrlStatus_ptr dp;
xce_ctrlstatus_t out;
capn_init_mem(&dc, buf, sz, 0);
dp.p = capn_getp(capn_root(&dc), 0, 1);
read_CtrlStatus(&cap_out, dp);
memset(&out, 0, sizeof(out));
decode_CtrlStatus(&out, &cap_out);
TEST_ASSERT_EQUAL_INT(2, out.peers.count);
TEST_ASSERT_NOT_NULL(out.peers.list);
TEST_ASSERT_NOT_NULL(out.peers.list[0]);
TEST_ASSERT_EQUAL_STRING("ctrl-a", out.peers.list[0]->name);
TEST_ASSERT_EQUAL_UINT8(2, out.peers.list[0]->status);
TEST_ASSERT_NOT_NULL(out.peers.list[1]);
TEST_ASSERT_EQUAL_STRING("ctrl-b", out.peers.list[1]->name);
TEST_ASSERT_EQUAL_UINT8(0, out.peers.list[1]->status);
free_CtrlStatus(&out);
capn_free(&dc);
free(buf);
printf("test_ctrlpeer_status_roundtrip: PASS\n");
}
/* ── (m) codec round-trip: HeartbeatMsg.electedAtMs @4 (task 7.1, Req 12.1) ──
* Same design-delta schema addition on the heartbeat message the primary
* already sends to standbys, next free ordinal after committedConfigTag @3.
* Direct struct construction + encode/decode -- no heartbeat send/receive
@ -721,6 +799,7 @@ void test_ctrlstatus(void)
RUN_TEST(test_ctrlstatus_primary_reports_own_committed);
RUN_TEST(test_ctrlstatus_responder_time_ms);
RUN_TEST(test_ctrlstatus_electedatms_roundtrip);
RUN_TEST(test_ctrlpeer_status_roundtrip);
RUN_TEST(test_heartbeatmsg_electedatms_roundtrip);
RUN_TEST(test_ctrlstatus_primary_reports_own_elected_at_ms);
RUN_TEST(test_ctrlstatus_standby_reports_learned_elected_at_ms);