feat(controller-peers-env-fallback): add the environment-variable reader for the default candidate list (task 1.1)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ab21c1622d
commit
7328b06c53
4 changed files with 57 additions and 1 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# Implementation Plan
|
||||
|
||||
- [ ] 1. Foundation: shared libxce primitives and the regression script
|
||||
- [ ] 1.1 Add the environment-variable reader for the default candidate list
|
||||
- [x] 1.1 Add the environment-variable reader for the default candidate list
|
||||
- Write the failing libxce unit tests first: variable unset gives no value, set to an empty string gives no value, set to a non-empty string returns it unchanged
|
||||
- Add the reader to the shared cluster module and declare it next to the existing peers parser, so every C daemon and the harness can call it with no new build dependency
|
||||
- Each test restores the variable to unset afterwards, so later libxce tests are unaffected
|
||||
|
|
|
|||
|
|
@ -137,6 +137,17 @@ void xce_reconnect_fini(xce_reconnect_ctx_t* rctx);
|
|||
*/
|
||||
int xce_parse_peers(const char* peers_str, xce_cluster_config_t* cfg);
|
||||
|
||||
/**
|
||||
* xce_controller_peers_env() — default controller candidate list from the
|
||||
* XCE_CONTROLLER_PEERS environment variable.
|
||||
*
|
||||
* Returns the variable's value unchanged (same format as --peers, not parsed
|
||||
* here) when it is set and non-empty; NULL when it is unset or empty, so an
|
||||
* empty value behaves exactly like an unset one. The returned pointer is
|
||||
* owned by the process environment; do not free or modify it.
|
||||
*/
|
||||
const char* xce_controller_peers_env(void);
|
||||
|
||||
/* Test seam: set to non-NULL to override the real connect (unit tests only) */
|
||||
typedef void* (*xce_connect_fn_t)(const char* host, int port);
|
||||
void xce_cluster_set_connect_fn(xce_connect_fn_t fn);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,12 @@ int xce_parse_peers(const char* peers_str, xce_cluster_config_t* cfg)
|
|||
return cfg->candidates_count > 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
const char* xce_controller_peers_env(void)
|
||||
{
|
||||
const char* v = getenv("XCE_CONTROLLER_PEERS");
|
||||
return (v && v[0] != '\0') ? v : NULL;
|
||||
}
|
||||
|
||||
/* ── Test seam ─────────────────────────────────────────────────── */
|
||||
|
||||
static xce_connect_fn_t s_connect_fn = NULL;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unity/unity.h>
|
||||
|
||||
|
|
@ -290,6 +291,41 @@ static void test_convert_does_not_set_identity_fields(void)
|
|||
printf("test_convert_does_not_set_identity_fields: PASS\n");
|
||||
}
|
||||
|
||||
/* ── xce_controller_peers_env() ─────────────────────────────────── */
|
||||
|
||||
/* Req 1.2/1.3: an unset variable supplies no candidate list. */
|
||||
static void test_peers_env_unset_returns_null(void)
|
||||
{
|
||||
unsetenv("XCE_CONTROLLER_PEERS");
|
||||
TEST_ASSERT_NULL(xce_controller_peers_env());
|
||||
printf("test_peers_env_unset_returns_null: PASS\n");
|
||||
}
|
||||
|
||||
/* Req 1.3/1.7: an empty variable is treated exactly like an unset one. */
|
||||
static void test_peers_env_empty_returns_null(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(0, setenv("XCE_CONTROLLER_PEERS", "", 1));
|
||||
const char* v = xce_controller_peers_env();
|
||||
unsetenv("XCE_CONTROLLER_PEERS");
|
||||
TEST_ASSERT_NULL(v);
|
||||
printf("test_peers_env_empty_returns_null: PASS\n");
|
||||
}
|
||||
|
||||
/* Req 1.2: a non-empty variable is returned unchanged (no parsing here). */
|
||||
static void test_peers_env_nonempty_returned_unchanged(void)
|
||||
{
|
||||
const char* val = "c1=host1:9991,host2:9992";
|
||||
TEST_ASSERT_EQUAL_INT(0, setenv("XCE_CONTROLLER_PEERS", val, 1));
|
||||
const char* v = xce_controller_peers_env();
|
||||
char copy[64] = "";
|
||||
if (v)
|
||||
snprintf(copy, sizeof(copy), "%s", v);
|
||||
unsetenv("XCE_CONTROLLER_PEERS");
|
||||
TEST_ASSERT_NOT_NULL(v);
|
||||
TEST_ASSERT_EQUAL_STRING(val, copy);
|
||||
printf("test_peers_env_nonempty_returned_unchanged: PASS\n");
|
||||
}
|
||||
|
||||
/* ── Test group entry point ─────────────────────────────────────── */
|
||||
void test_cluster(void)
|
||||
{
|
||||
|
|
@ -310,4 +346,7 @@ void test_cluster(void)
|
|||
RUN_TEST(test_convert_rejects_zero_candidates);
|
||||
RUN_TEST(test_convert_truncates_over_max_candidates);
|
||||
RUN_TEST(test_convert_does_not_set_identity_fields);
|
||||
RUN_TEST(test_peers_env_unset_returns_null);
|
||||
RUN_TEST(test_peers_env_empty_returns_null);
|
||||
RUN_TEST(test_peers_env_nonempty_returned_unchanged);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue