forked from lei.chen/myxce
13 new Unity tests in test_p3_hardening.c covering:
- P3-1: promote/demote cycle verifies role+term monotonicity and
hooks_registered reset; heartbeat timeout sets failover_requested
- P3-2: ha_should_redirect/ha_no_primary_known corner cases for
PRIMARY, STANDBY-no-primary, STANDBY-with-primary
- P3-3: torn-write recovery after checkpoint (mixed WAL types, exact
offset truncation); CRC corruption stops replay in mixed-type WAL
- P3-4: 1000 async WAL writes complete in < 5 s (throughput floor)
- P3-5: GC retention predicates — running retained, expired EXIT
cleaned, TRANSIENT timeout, expired UNAVAIL worker cleaned,
recent DONE retained
No new implementation code. All called functions existed from P0-P2.
132 lines
3.3 KiB
C
132 lines
3.3 KiB
C
#include <argp.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <unity/unity.h>
|
|
|
|
extern void test_persist_types(void);
|
|
extern void test_persist_wal(void);
|
|
extern void test_persist_schema(void);
|
|
extern void test_persist_checkpoint(void);
|
|
extern void test_persist_recovery(void);
|
|
extern void test_hooks(void);
|
|
extern void test_persist_hooks(void);
|
|
extern void test_gc_retention(void);
|
|
extern void test_cluster_persist(void);
|
|
extern void test_e2e_wal(void);
|
|
extern void test_e2e_checkpoint(void);
|
|
extern void test_e2e_hooks(void);
|
|
extern void test_e2e_gc(void);
|
|
extern void test_e2e_capnp(void);
|
|
extern void test_ha_role(void);
|
|
extern void test_ha_cluster(void);
|
|
extern void test_ha_redirect(void);
|
|
extern void test_p1_integration(void);
|
|
extern void test_repl_unit(void);
|
|
extern void test_repl_apply(void);
|
|
extern void test_persist_repl(void);
|
|
extern void test_repl_catchup(void);
|
|
extern void test_p2_integration(void);
|
|
extern void test_p3_hardening(void);
|
|
|
|
void setUp(void) { return; }
|
|
|
|
void tearDown(void)
|
|
{
|
|
printf("\n-----------------------------------------------------\n");
|
|
return;
|
|
}
|
|
|
|
static char doc[] = "controller_test";
|
|
static char args_doc[] = "";
|
|
|
|
#define MAX_TESTS (256)
|
|
|
|
struct arguments {
|
|
int ntests;
|
|
char* tests[MAX_TESTS];
|
|
};
|
|
|
|
static struct argp_option options[] = {
|
|
{ "run", 't', "STR", 0, "run test" },
|
|
{ 0 }
|
|
};
|
|
|
|
static error_t parse_opt(int key, char* arg, struct argp_state* state)
|
|
{
|
|
struct arguments* arguments = state->input;
|
|
|
|
switch (key) {
|
|
case 't':
|
|
if (arguments->ntests >= MAX_TESTS) {
|
|
fprintf(stderr, "Too many tests\n");
|
|
exit(-1);
|
|
}
|
|
arguments->tests[arguments->ntests] = arg;
|
|
arguments->ntests++;
|
|
break;
|
|
default:
|
|
return ARGP_ERR_UNKNOWN;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct argp argp = { options, parse_opt, args_doc, doc };
|
|
struct arguments arguments;
|
|
|
|
static int check_test(struct arguments* args, char* x)
|
|
{
|
|
int i;
|
|
|
|
if (args->ntests == 0) {
|
|
return 1;
|
|
}
|
|
for (i = 0; i < args->ntests; i++) {
|
|
if (strcmp(x, args->tests[i]) == 0) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#define TEST(x) \
|
|
do { \
|
|
if (check_test(&arguments, #x)) { \
|
|
x(); \
|
|
} \
|
|
} while (0)
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
|
|
|
UNITY_BEGIN();
|
|
TEST(test_persist_types);
|
|
TEST(test_persist_wal);
|
|
TEST(test_persist_schema);
|
|
TEST(test_persist_checkpoint);
|
|
TEST(test_persist_recovery);
|
|
TEST(test_hooks);
|
|
TEST(test_persist_hooks);
|
|
TEST(test_gc_retention);
|
|
TEST(test_cluster_persist);
|
|
TEST(test_e2e_wal);
|
|
TEST(test_e2e_checkpoint);
|
|
TEST(test_e2e_hooks);
|
|
TEST(test_e2e_gc);
|
|
TEST(test_e2e_capnp);
|
|
TEST(test_ha_role);
|
|
TEST(test_ha_cluster);
|
|
TEST(test_ha_redirect);
|
|
TEST(test_p1_integration);
|
|
TEST(test_repl_unit);
|
|
TEST(test_repl_apply);
|
|
TEST(test_persist_repl);
|
|
TEST(test_repl_catchup);
|
|
TEST(test_p2_integration);
|
|
TEST(test_p3_hardening);
|
|
|
|
return UNITY_END();
|
|
}
|