feat(raft-adapter-conformance): send explicit reply on every config-push outcome
handle_repl_config_push now sends a ReplConfigPushReply{accepted,term}
from every exit path instead of silently dropping on the four reject
conditions (malformed request, missing bytes/sha256, sha256 mismatch,
conf_save_config failure). Term is sourced live from c->ha.term.
-EAGAIN activation-defer still replies accepted=1, unchanged.
Adds an XCE_TESTING-only send-hook mirroring ha_wal_ack_send_hook so
tests can observe the reply payload without a live endpoint.
This commit is contained in:
parent
ee7ede03c2
commit
b7828eed4a
4 changed files with 148 additions and 13 deletions
|
|
@ -3483,6 +3483,82 @@ static void test_configpush_transport_holds_endpoint_ref_across_send(void)
|
|||
printf("test_configpush_transport_holds_endpoint_ref_across_send: PASS\n");
|
||||
}
|
||||
|
||||
/* raft-adapter-conformance task 2.1 (Req 2.2, 2.3, 2.5, 7.4): a config-push
|
||||
* reject must now send an explicit ReplConfigPushReply{accepted=0, term}
|
||||
* back to the primary instead of returning silently. This is a minimal,
|
||||
* representative proof that the new config_push_reply_send_hook actually
|
||||
* fires -- exercised here via ONE reject path (SHA-256 mismatch). Task 2.3
|
||||
* expands this into full coverage of all four reject paths plus the EAGAIN
|
||||
* accept-path and the cluster.c term-adoption wiring; this test is kept
|
||||
* deliberately minimal so it doesn't collide with that broader coverage. */
|
||||
static uint64_t g_cpr21_hook_term;
|
||||
static uint64_t g_cpr21_hook_version_tag;
|
||||
static int g_cpr21_hook_accepted;
|
||||
static int g_cpr21_hook_called;
|
||||
|
||||
static void cpr21_reply_capture(uint64_t term, uint64_t version_tag, int accepted)
|
||||
{
|
||||
g_cpr21_hook_called = 1;
|
||||
g_cpr21_hook_term = term;
|
||||
g_cpr21_hook_version_tag = version_tag;
|
||||
g_cpr21_hook_accepted = accepted;
|
||||
}
|
||||
|
||||
static void test_config_push_sha256_mismatch_sends_explicit_reject_reply(void)
|
||||
{
|
||||
char tmp[256];
|
||||
strcpy(tmp, "/tmp/xce_cr21_shamis_XXXXXX");
|
||||
TEST_ASSERT_NOT_NULL(mkdtemp(tmp));
|
||||
|
||||
cluster_t *c = t42_make_cluster(tmp);
|
||||
TEST_ASSERT_NOT_NULL(c);
|
||||
t43_attach_myconf(c, tmp);
|
||||
|
||||
atomic_store(&c->ha.role, CTRL_STANDBY);
|
||||
atomic_store(&c->ha.term, 7);
|
||||
|
||||
/* Deliberately mismatched payload: raw_sha256 does NOT hash to
|
||||
* raw_bytes -- exercises the real SHA-256-mismatch reject branch. */
|
||||
uint8_t payload[16];
|
||||
memset(payload, 0xAB, sizeof(payload));
|
||||
uint8_t wrong_sha[32];
|
||||
memset(wrong_sha, 0x00, sizeof(wrong_sha)); /* SHA256(payload) != all-zero */
|
||||
|
||||
repl_config_push_req_t rcpr;
|
||||
memset(&rcpr, 0, sizeof(rcpr));
|
||||
rcpr.version_tag = 0x1234;
|
||||
rcpr.raw_bytes = payload;
|
||||
rcpr.raw_bytes_len = sizeof(payload);
|
||||
rcpr.raw_sha256 = wrong_sha;
|
||||
|
||||
xce_request_t req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.body_which = Request_body_replconfigpushrequestmsg;
|
||||
req.body.replconfigpushrequestmsg = &rcpr;
|
||||
|
||||
g_cpr21_hook_called = 0;
|
||||
config_push_reply_send_hook = cpr21_reply_capture;
|
||||
|
||||
int rc = handle_repl_config_push(c, /*ep*/NULL, &req);
|
||||
|
||||
config_push_reply_send_hook = NULL; /* uninstall before any assertion can fail */
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(-EBADMSG, rc);
|
||||
TEST_ASSERT_TRUE_MESSAGE(g_cpr21_hook_called,
|
||||
"raft-adapter-conformance 2.1: a config-push SHA-256 mismatch must "
|
||||
"send an explicit ReplConfigPushReply, not silence it entirely");
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(0, g_cpr21_hook_accepted,
|
||||
"the reply for a rejected config push must carry accepted=0");
|
||||
TEST_ASSERT_EQUAL_UINT64(7, g_cpr21_hook_term);
|
||||
|
||||
t43_free_myconf(c);
|
||||
t42_teardown(c);
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd), "rm -rf %s", tmp);
|
||||
system(cmd);
|
||||
printf("test_config_push_sha256_mismatch_sends_explicit_reject_reply: PASS\n");
|
||||
}
|
||||
|
||||
#endif /* XCE_TESTING */
|
||||
|
||||
/* ── raw capnp shims (Task A) ───────────────────── */
|
||||
|
|
@ -6848,6 +6924,8 @@ void test_config_repl(void)
|
|||
RUN_TEST(test_wait_all_with_timeout_fast_threads);
|
||||
/* bug-1381: push_config_transport_only endpoint-lifetime regression */
|
||||
RUN_TEST(test_configpush_transport_holds_endpoint_ref_across_send);
|
||||
/* raft-adapter-conformance task 2.1: config-push reject reply integrity */
|
||||
RUN_TEST(test_config_push_sha256_mismatch_sends_explicit_reject_reply);
|
||||
/* Task 2.1: OPCode_walCatchupEntry handler */
|
||||
RUN_TEST(test_wal_catchup_entry_advances_applied_lsn);
|
||||
RUN_TEST(test_wal_catchup_entry_error_skipped_no_crash);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue