Only 21 of 86 test_*.c group functions called their own nested UNITY_BEGIN()/UNITY_END(). Each nested call reset Unity's global NumberOfTests/TestFailures counters, so controller_test.c's final `return UNITY_END();` -- the value meson test actually gates on -- only ever reflected whichever small window of tests ran since the LAST nested reset, silently discarding pass/fail evidence for everything before it (measured: 16 of 972 total tests in one run). The same nested-BEGIN calls also caused PASS/FAIL banners to show the wrong source file for tests in files that don't reset it themselves (Unity.TestFile just carries over from whichever group last called UNITY_BEGIN()). Fix: replace every nested UNITY_BEGIN() with UnitySetTestFile(__FILE__) (sets file attribution only, no counter reset) and drop the matching UNITY_END(); add the same UnitySetTestFile(__FILE__) as the first statement to the other group functions that had neither. The 2 genuinely standalone binaries (test_job_array_sched_push.c, test_job_array_apiserver_push.c -- each has its own int main(), not registered via controller_test.c's TEST() macro) are untouched. Verified: single consolidated summary now reads "972 Tests 0 Failures 0 Ignored OK", exactly matching the ground-truth RUN_TEST call-site count across all 83 registered group files (976 total minus 4 belonging to the 2 standalone binaries). Every PASS/FAIL banner now names its own true source file. Full xce-build.sh all regression pass clean (Ok: 9, Fail: 0). No production code touched -- test-harness plumbing only.
131 lines
5.2 KiB
C
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 make test-integration.
|
|
*
|
|
* 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);
|
|
}
|