/* test_ctrl_metrics.c — P3-7: Metrics infrastructure unit tests * * TDD: these tests are written FIRST to drive the implementation. * They verify: * - ctrl_metrics_init() zeroes all 7 counters/gauges * - CTRL_METRIC_INC increments atomically * - CTRL_METRIC_SET writes and overwrites a gauge * - The descriptor table has exactly 7 entries + NULL sentinel * - ctrl_transient_jobs_stuck counter accumulates correctly */ #define _GNU_SOURCE #include #include #include #include #include "ctrl_metrics.h" /* ------------------------------------------------------------------ */ /* Tests */ /* ------------------------------------------------------------------ */ static void test_metrics_init_zeros_all_counters(void) { ctrl_metrics_init(); TEST_ASSERT_EQUAL_UINT64(0, atomic_load(&ctrl_repl_degraded_count)); TEST_ASSERT_EQUAL_UINT64(0, atomic_load(&ctrl_split_brain_detected)); TEST_ASSERT_EQUAL_UINT64(0, atomic_load(&ctrl_async_events_lost)); TEST_ASSERT_EQUAL_UINT64(0, atomic_load(&ctrl_transient_jobs_stuck)); TEST_ASSERT_EQUAL_UINT64(0, atomic_load(&ctrl_wal_bytes)); TEST_ASSERT_EQUAL_UINT64(0, atomic_load(&ctrl_checkpoint_duration_ms)); TEST_ASSERT_EQUAL_UINT64(0, atomic_load(&ctrl_repl_lag_lsn)); printf("test_metrics_init_zeros_all_counters: PASS\n"); } static void test_metrics_increment_repl_degraded(void) { ctrl_metrics_init(); CTRL_METRIC_INC(ctrl_repl_degraded_count); CTRL_METRIC_INC(ctrl_repl_degraded_count); TEST_ASSERT_EQUAL_UINT64(2, atomic_load(&ctrl_repl_degraded_count)); printf("test_metrics_increment_repl_degraded: PASS\n"); } static void test_metrics_set_gauge(void) { ctrl_metrics_init(); CTRL_METRIC_SET(ctrl_wal_bytes, 1024 * 1024); TEST_ASSERT_EQUAL_UINT64(1024 * 1024, atomic_load(&ctrl_wal_bytes)); CTRL_METRIC_SET(ctrl_wal_bytes, 0); TEST_ASSERT_EQUAL_UINT64(0, atomic_load(&ctrl_wal_bytes)); printf("test_metrics_set_gauge: PASS\n"); } static void test_metrics_descriptor_table_has_sentinel(void) { /* The descriptor table must end with a NULL-name sentinel * and contain exactly 7 real entries. */ int i = 0; while (ctrl_metric_descriptors[i].name != NULL) i++; TEST_ASSERT_EQUAL_INT(7, i); printf("test_metrics_descriptor_table_has_sentinel: PASS\n"); } static void test_transient_jobs_stuck_counter(void) { ctrl_metrics_init(); /* Simulate 3 stuck transient jobs */ for (int j = 0; j < 3; j++) CTRL_METRIC_INC(ctrl_transient_jobs_stuck); TEST_ASSERT_EQUAL_UINT64(3, atomic_load(&ctrl_transient_jobs_stuck)); printf("test_transient_jobs_stuck_counter: PASS\n"); } /* ------------------------------------------------------------------ */ /* Suite entry point (called from controller_test.c) */ /* ------------------------------------------------------------------ */ void test_ctrl_metrics(void) { RUN_TEST(test_metrics_init_zeros_all_counters); RUN_TEST(test_metrics_increment_repl_degraded); RUN_TEST(test_metrics_set_gauge); RUN_TEST(test_metrics_descriptor_table_has_sentinel); RUN_TEST(test_transient_jobs_stuck_counter); }