myxce/src/lib/testsuite/test_request.c
Rongsong Shen 646aa69aa8 fix(controller): set c->running in cluster_run so HA primary streams joblist/workerlist
cluster_start (which set c->running) is orphaned on the HA myapp_run path, so
the running flag was never set on HA nodes — check_controller() treated the
primary as shutting down and zeroed joblist/workerlist reply chunks. Own the
flag lifecycle in cluster_run, symmetric with the c->running=0 on shutdown.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 03:38:55 +00:00

108 lines
3.7 KiB
C

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unity/unity.h>
#include "request.h"
#include "xce/types.h"
/* Tests for xce_hostctrl_req() validation paths.
* We test only early-return paths (before xce_request() is called)
* since a live endpoint is not available in unit tests. */
static void test_hostctrl_req_null_ep(void)
{
xce_hostctrl_t ctrl = { .action = HOST_OPEN, .hostname = "host1" };
int rc = xce_hostctrl_req(NULL, &ctrl);
TEST_ASSERT_EQUAL_INT(-EINVAL, rc);
}
static void test_hostctrl_req_null_ctrl(void)
{
/* non-NULL dummy ep is enough; the NULL ctrl check fires first */
int rc = xce_hostctrl_req((endpoint_t*)0x1, NULL);
TEST_ASSERT_EQUAL_INT(-EINVAL, rc);
}
static void test_hostctrl_req_null_hostname(void)
{
xce_hostctrl_t ctrl = { .action = HOST_OPEN, .hostname = NULL };
int rc = xce_hostctrl_req((endpoint_t*)0x1, &ctrl);
TEST_ASSERT_EQUAL_INT(-EINVAL, rc);
}
static void test_hostctrl_req_empty_hostname(void)
{
xce_hostctrl_t ctrl = { .action = HOST_OPEN, .hostname = "" };
int rc = xce_hostctrl_req((endpoint_t*)0x1, &ctrl);
TEST_ASSERT_EQUAL_INT(-EINVAL, rc);
}
static void test_hostctrl_req_noop(void)
{
xce_hostctrl_t ctrl = { .action = HOST_DO_NONE, .hostname = "host1" };
int rc = xce_hostctrl_req((endpoint_t*)0x1, &ctrl);
TEST_ASSERT_EQUAL_INT(0, rc);
}
static void test_hostctrl_req_reject_tag(void)
{
xce_hostctrl_t ctrl = { .action = HOST_TAG, .hostname = "host1" };
int rc = xce_hostctrl_req((endpoint_t*)0x1, &ctrl);
TEST_ASSERT_EQUAL_INT(-EINVAL, rc);
}
static void test_hostctrl_req_reject_untag(void)
{
xce_hostctrl_t ctrl = { .action = HOST_UNTAG, .hostname = "host1" };
int rc = xce_hostctrl_req((endpoint_t*)0x1, &ctrl);
TEST_ASSERT_EQUAL_INT(-EINVAL, rc);
}
static void test_hostctrl_req_reject_negative_action(void)
{
xce_hostctrl_t ctrl = { .action = -1, .hostname = "host1" };
int rc = xce_hostctrl_req((endpoint_t*)0x1, &ctrl);
TEST_ASSERT_EQUAL_INT(-EINVAL, rc);
}
/* init_reply_by_req must fully zero the reply so the generated
* encode_RequestReply never reads a stale `redirect_host` pointer (and the
* other common trailer fields) off an uninitialized stack reply. Regression
* guard for the heap-use-after-free in encode_RequestReply / strlen seen on a
* NOP/state-report reply whose redirect_host was stack garbage. */
static void test_init_reply_by_req_zeroes_reply(void)
{
/* Poison the whole reply with non-zero bytes — mirrors an uninitialized
* stack reply whose redirect_host happens to be a (dangling) non-NULL. */
xce_reply_t reply;
xce_request_t req = { .seq = 42, .opcode = OPCode_nop };
memset(&reply, 0xFF, sizeof(reply));
init_reply_by_req(&reply, &req);
/* seq/opcode carried from the request */
TEST_ASSERT_EQUAL_UINT64(42, reply.seq);
TEST_ASSERT_EQUAL_INT(OPCode_nop, reply.opcode);
/* Trailer/common fields the encoder always reads must be cleared so a
* handler that only sets data_which/data cannot leak garbage onto the wire
* (or dereference a dangling redirect_host). */
TEST_ASSERT_NULL(reply.redirect_host);
TEST_ASSERT_EQUAL_UINT(0, reply.redirect_port);
TEST_ASSERT_EQUAL_INT(0, reply.status);
TEST_ASSERT_EQUAL_INT(0, reply.data_which);
}
void test_request(void)
{
printf("\n>> host control request validation tests\n\n");
RUN_TEST(test_hostctrl_req_null_ep);
RUN_TEST(test_hostctrl_req_null_ctrl);
RUN_TEST(test_hostctrl_req_null_hostname);
RUN_TEST(test_hostctrl_req_empty_hostname);
RUN_TEST(test_hostctrl_req_noop);
RUN_TEST(test_hostctrl_req_reject_tag);
RUN_TEST(test_hostctrl_req_reject_untag);
RUN_TEST(test_hostctrl_req_reject_negative_action);
RUN_TEST(test_init_reply_by_req_zeroes_reply);
}