myxce/src/controller/testsuite/test_ha_ctrlhello.c
Rongsong Shen 12c6a59c03
feat(eliminate-frontend-makefile): task 3.4 - update source code comments
Comment-only edits in 4 files: test_ha_bootstrap.c/test_ha_ctrlhello.c
rename their "make test-integration" pointers to reference the
regression suite (tests/regression/run.sh) directly; apiserver/xcecli
cmd/main.go drop the Makefile clause from their ldflags-injection
comments, keeping only src/tools/go_build. Zero production/test
logic changed -- verified via full controller unit-test suite rerun
(1261 tests, 0 failures) and xcecli build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYdtrEWWZfKRRGED7raEYg
2026-09-03 14:34:48 +00:00

131 lines
5.2 KiB
C

/*
* test_ha_ctrlhello.c — Unit tests for handle_ctrlhello() (task 9.3).
*
* Tests exercise the primary-side OP_ctrlHello handler:
* - CtrlHelloRequest struct fields accessible (schema compile check)
* - CtrlHelloReply fields accessible (schema compile check)
* - handle_ctrlhello with malformed request returns -EINVAL
* - typemap fields: ctrl_hello_req_t and ctrl_hello_reply_t compile
* - OPCode_walCatchupEntry exists in generated capnp header
* - Request_body_ctrlhellomsg discriminant exists
*
* Full integration (WAL streaming, snapshot transfer) requires a live cluster
* and is validated via the regression suite (tests/regression/run.sh).
*
* Requirements: 6.5, 6.6, 6.7
*/
#define _GNU_SOURCE
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unity/unity.h>
#include "controller.capnp.h"
#include "typemap.h"
#include "config_repl.h"
/* ── Test 1: CtrlHelloRequest struct is accessible from capnp.h ─────────── */
static void test_ctrl_hello_request_fields_accessible(void)
{
/* Static compile check: access CtrlHelloRequest field constants */
TEST_ASSERT_GREATER_THAN(0, (int)CtrlHelloRequest_struct_bytes_count);
TEST_ASSERT_GREATER_THAN(0, (int)CtrlHelloRequest_word_count);
printf("test_ctrl_hello_request_fields_accessible: PASS\n");
}
/* ── Test 2: CtrlHelloReply struct is accessible from capnp.h ──────────── */
static void test_ctrl_hello_reply_fields_accessible(void)
{
TEST_ASSERT_GREATER_THAN(0, (int)CtrlHelloReply_struct_bytes_count);
TEST_ASSERT_GREATER_THAN(0, (int)CtrlHelloReply_word_count);
printf("test_ctrl_hello_reply_fields_accessible: PASS\n");
}
/* ── Test 3: ctrl_hello_req_t C struct compiles correctly ───────────────── */
static void test_ctrl_hello_req_t_layout(void)
{
ctrl_hello_req_t req;
memset(&req, 0, sizeof(req));
req.name = NULL;
req.key = NULL;
req.applied_lsn = 42;
req.config_tag = 7;
TEST_ASSERT_EQUAL_UINT64(42, req.applied_lsn);
TEST_ASSERT_EQUAL_UINT64(7, req.config_tag);
printf("test_ctrl_hello_req_t_layout: PASS\n");
}
/* ── Test 4: ctrl_hello_reply_t C struct compiles correctly ─────────────── */
static void test_ctrl_hello_reply_t_layout(void)
{
ctrl_hello_reply_t rep;
memset(&rep, 0, sizeof(rep));
rep.committed_lsn = 100;
rep.needs_snapshot = 0;
rep.config_tag = 5;
TEST_ASSERT_EQUAL_UINT64(100, rep.committed_lsn);
TEST_ASSERT_EQUAL_INT(0, rep.needs_snapshot);
TEST_ASSERT_EQUAL_UINT64(5, rep.config_tag);
printf("test_ctrl_hello_reply_t_layout: PASS\n");
}
/* ── Test 5: OPCode_walCatchupEntry exists in generated capnp header ────── */
static void test_opcode_walcatchupentry_exists(void)
{
int opcode = (int)OPCode_walCatchupEntry;
TEST_ASSERT_EQUAL_INT(37, opcode);
printf("test_opcode_walcatchupentry_exists: PASS\n");
}
/* ── Test 6: Request_body_ctrlhellomsg discriminant exists ─────────────── */
static void test_request_body_ctrlhellomsg_exists(void)
{
int disc = (int)Request_body_ctrlhellomsg;
/* The body union discriminant is derived from @N in the capnp schema.
* ctrlhellomsg @26 → discriminant 23 (0-indexed from @3, fields @3..@26). */
TEST_ASSERT_GREATER_OR_EQUAL(0, disc);
printf("test_request_body_ctrlhellomsg_exists (disc=%d): PASS\n", disc);
}
/* ── Test 7: handle_ctrlhello rejects request with wrong body_which ─────── */
static void test_handle_ctrlhello_rejects_malformed(void)
{
/* NULL cluster — handle_ctrlhello checks body_which before dereferencing c */
xce_request_t req;
memset(&req, 0, sizeof(req));
req.opcode = OPCode_hello;
req.body_which = Request_body_nomsg; /* not ctrlhellomsg */
int rc = handle_ctrlhello(NULL, NULL, &req);
TEST_ASSERT_EQUAL_INT(-EINVAL, rc);
printf("test_handle_ctrlhello_rejects_malformed: PASS\n");
}
/* ── Test 8: handle_ctrlhello rejects NULL body pointer ─────────────────── */
static void test_handle_ctrlhello_rejects_null_body(void)
{
xce_request_t req;
memset(&req, 0, sizeof(req));
req.opcode = OPCode_hello;
req.body_which = Request_body_ctrlhellomsg;
req.body.ctrlhellomsg = NULL; /* body set but null payload */
int rc = handle_ctrlhello(NULL, NULL, &req);
TEST_ASSERT_EQUAL_INT(-EINVAL, rc);
printf("test_handle_ctrlhello_rejects_null_body: PASS\n");
}
/* ── Suite entry point ──────────────────────────────────────────────────── */
void test_ha_ctrlhello(void)
{
UnitySetTestFile(__FILE__);
RUN_TEST(test_ctrl_hello_request_fields_accessible);
RUN_TEST(test_ctrl_hello_reply_fields_accessible);
RUN_TEST(test_ctrl_hello_req_t_layout);
RUN_TEST(test_ctrl_hello_reply_t_layout);
RUN_TEST(test_opcode_walcatchupentry_exists);
RUN_TEST(test_request_body_ctrlhellomsg_exists);
RUN_TEST(test_handle_ctrlhello_rejects_malformed);
RUN_TEST(test_handle_ctrlhello_rejects_null_body);
}