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.
98 lines
3.7 KiB
C
98 lines
3.7 KiB
C
#define _GNU_SOURCE
|
|
#include <stdio.h>
|
|
|
|
#include <unity/unity.h>
|
|
|
|
#include "config.h"
|
|
#include "ha.h"
|
|
|
|
/* ====================================================================
|
|
* raft-drive-async task 1.1 — drive-async configuration constants and
|
|
* the peer-scaled liveness-reservation clamp helper.
|
|
*
|
|
* Helper under test:
|
|
* int drive_async_liveness_reserved(int n_peers, int n_vcpus);
|
|
*
|
|
* Formula (design "LivenessAdmission → Sizing (peer-scaled)"):
|
|
* VTASK_LIVENESS_RESERVED = clamp(n_peers - 1, 1, n_vcpus - 1)
|
|
* = max(1, min(n_peers - 1, n_vcpus - 1))
|
|
* floor 1 -> deadlock-freedom (always >=1 guaranteed-free worker)
|
|
* ceiling n_vcpus - 1 -> keep >=1 REQ_BLOCK (commit) slot, cap never 0
|
|
* The floor is applied LAST so it always wins (the hard correctness invariant).
|
|
* ==================================================================== */
|
|
|
|
/* ── Regime 1: normal n_peers-1 (the un-clamped middle) ───────────── */
|
|
|
|
static void test_liveness_reserved_normal_three_peers(void)
|
|
{
|
|
/* 3-node cluster, 8 vcpus: n_peers-1 = 2, well under ceiling 7. */
|
|
TEST_ASSERT_EQUAL_INT(2, drive_async_liveness_reserved(3, 8));
|
|
}
|
|
|
|
static void test_liveness_reserved_normal_five_peers(void)
|
|
{
|
|
/* 5-node cluster, 8 vcpus: n_peers-1 = 4, under ceiling 7. */
|
|
TEST_ASSERT_EQUAL_INT(4, drive_async_liveness_reserved(5, 8));
|
|
}
|
|
|
|
/* ── Regime 2: floor hit (n_peers-1 would be < 1) ─────────────────── */
|
|
|
|
static void test_liveness_reserved_floor_single_node(void)
|
|
{
|
|
/* n_peers=1 -> n_peers-1 = 0 -> floor 1 must win. */
|
|
TEST_ASSERT_EQUAL_INT(1, drive_async_liveness_reserved(1, 8));
|
|
}
|
|
|
|
static void test_liveness_reserved_floor_zero_peers(void)
|
|
{
|
|
/* Degenerate n_peers=0 -> n_peers-1 = -1 -> floor 1 must win. */
|
|
TEST_ASSERT_EQUAL_INT(1, drive_async_liveness_reserved(0, 8));
|
|
}
|
|
|
|
/* ── Regime 3: ceiling / clamp hit (under-provisioned: n_vcpus < n_peers) ── */
|
|
|
|
static void test_liveness_reserved_ceiling_clamps_below_npeers(void)
|
|
{
|
|
/* n_peers=5, n_vcpus=3: n_peers-1 = 4 clamped to ceiling n_vcpus-1 = 2. */
|
|
TEST_ASSERT_EQUAL_INT(2, drive_async_liveness_reserved(5, 3));
|
|
}
|
|
|
|
static void test_liveness_reserved_ceiling_floor_wins_one_vcpu(void)
|
|
{
|
|
/* n_vcpus=1 -> ceiling n_vcpus-1 = 0, but the floor of 1 must win:
|
|
* max(1, min(n_peers-1, 0)) = max(1, 0) = 1. Never returns 0. */
|
|
TEST_ASSERT_EQUAL_INT(1, drive_async_liveness_reserved(5, 1));
|
|
}
|
|
|
|
static void test_liveness_reserved_exactly_npeers_vcpus(void)
|
|
{
|
|
/* n_vcpus == n_peers: ceiling = n_vcpus-1 = n_peers-1 -> no clamp.
|
|
* 3 peers, 3 vcpus -> min(2, 2) = 2. */
|
|
TEST_ASSERT_EQUAL_INT(2, drive_async_liveness_reserved(3, 3));
|
|
}
|
|
|
|
static void test_liveness_reserved_never_exceeds_vcpus_minus_one(void)
|
|
{
|
|
/* Invariant: result <= n_vcpus-1 keeps >=1 commit slot (cap never 0). */
|
|
for (int p = 0; p <= 8; p++) {
|
|
for (int v = 1; v <= 8; v++) {
|
|
int r = drive_async_liveness_reserved(p, v);
|
|
TEST_ASSERT_TRUE_MESSAGE(r >= 1, "reservation floor 1 violated");
|
|
TEST_ASSERT_TRUE_MESSAGE(r <= (v - 1 > 0 ? v - 1 : 1),
|
|
"reservation must keep >=1 commit slot");
|
|
}
|
|
}
|
|
}
|
|
|
|
void test_drive_async_config(void)
|
|
{
|
|
UnitySetTestFile(__FILE__);
|
|
RUN_TEST(test_liveness_reserved_normal_three_peers);
|
|
RUN_TEST(test_liveness_reserved_normal_five_peers);
|
|
RUN_TEST(test_liveness_reserved_floor_single_node);
|
|
RUN_TEST(test_liveness_reserved_floor_zero_peers);
|
|
RUN_TEST(test_liveness_reserved_ceiling_clamps_below_npeers);
|
|
RUN_TEST(test_liveness_reserved_ceiling_floor_wins_one_vcpu);
|
|
RUN_TEST(test_liveness_reserved_exactly_npeers_vcpus);
|
|
RUN_TEST(test_liveness_reserved_never_exceeds_vcpus_minus_one);
|
|
}
|