#include "test_framework.h" #include "../src/types.h" #include "../src/health_check.h" #include "../src/config.h" #include #include #include extern app_config_t *config; static void setup_test_config(int route_count) { if (config) { if (config->routes) free(config->routes); free(config); } config = calloc(1, sizeof(app_config_t)); config->port = 8080; config->route_count = route_count; if (route_count > 0) { config->routes = calloc(route_count, sizeof(route_config_t)); for (int i = 0; i < route_count; i++) { snprintf(config->routes[i].hostname, sizeof(config->routes[i].hostname), "host%d.example.com", i); snprintf(config->routes[i].upstream_host, sizeof(config->routes[i].upstream_host), "127.0.0.1"); config->routes[i].upstream_port = 3000 + i; } } } static void cleanup_test_config(void) { if (config) { if (config->routes) free(config->routes); free(config); config = NULL; } } void test_health_check_init_no_routes(void) { TEST_SUITE_BEGIN("Health Check Init No Routes"); setup_test_config(0); health_check_init(); int healthy = health_check_is_healthy("nonexistent.com"); TEST_ASSERT_EQ(1, healthy, "Nonexistent host returns healthy (fail-open)"); health_check_cleanup(); cleanup_test_config(); TEST_SUITE_END(); } void test_health_check_init_with_routes(void) { TEST_SUITE_BEGIN("Health Check Init With Routes"); setup_test_config(3); health_check_init(); int healthy0 = health_check_is_healthy("host0.example.com"); TEST_ASSERT_EQ(1, healthy0, "Host0 initially healthy"); int healthy1 = health_check_is_healthy("host1.example.com"); TEST_ASSERT_EQ(1, healthy1, "Host1 initially healthy"); int healthy2 = health_check_is_healthy("host2.example.com"); TEST_ASSERT_EQ(1, healthy2, "Host2 initially healthy"); int unknown = health_check_is_healthy("unknown.example.com"); TEST_ASSERT_EQ(1, unknown, "Unknown host returns healthy (fail-open)"); health_check_cleanup(); cleanup_test_config(); TEST_SUITE_END(); } void test_health_check_null_hostname(void) { TEST_SUITE_BEGIN("Health Check NULL Hostname"); setup_test_config(1); health_check_init(); int healthy = health_check_is_healthy(NULL); TEST_ASSERT_EQ(1, healthy, "NULL hostname returns healthy (fail-open)"); health_check_cleanup(); cleanup_test_config(); TEST_SUITE_END(); } void test_health_check_case_insensitive(void) { TEST_SUITE_BEGIN("Health Check Case Insensitive"); setup_test_config(1); health_check_init(); int lower = health_check_is_healthy("host0.example.com"); TEST_ASSERT_EQ(1, lower, "Lowercase matches"); int upper = health_check_is_healthy("HOST0.EXAMPLE.COM"); TEST_ASSERT_EQ(1, upper, "Uppercase matches"); int mixed = health_check_is_healthy("Host0.Example.COM"); TEST_ASSERT_EQ(1, mixed, "Mixed case matches"); health_check_cleanup(); cleanup_test_config(); TEST_SUITE_END(); } void test_health_check_cleanup(void) { TEST_SUITE_BEGIN("Health Check Cleanup"); setup_test_config(2); health_check_init(); health_check_cleanup(); int healthy = health_check_is_healthy("host0.example.com"); TEST_ASSERT_EQ(1, healthy, "After cleanup returns healthy (disabled)"); cleanup_test_config(); TEST_SUITE_END(); } void test_health_check_run_no_init(void) { TEST_SUITE_BEGIN("Health Check Run Without Init"); health_check_run(); TEST_ASSERT(1, "Run without init doesn't crash"); TEST_SUITE_END(); } void test_health_check_run_with_init(void) { TEST_SUITE_BEGIN("Health Check Run With Init"); setup_test_config(1); health_check_init(); health_check_run(); TEST_ASSERT(1, "Health check run completes"); int healthy = health_check_is_healthy("host0.example.com"); TEST_ASSERT(healthy == 0 || healthy == 1, "Health status is valid"); health_check_cleanup(); cleanup_test_config(); TEST_SUITE_END(); } void test_health_check_multiple_init(void) { TEST_SUITE_BEGIN("Health Check Multiple Init"); setup_test_config(2); health_check_init(); int h1 = health_check_is_healthy("host0.example.com"); TEST_ASSERT_EQ(1, h1, "First init: host0 healthy"); setup_test_config(3); health_check_init(); int h2 = health_check_is_healthy("host2.example.com"); TEST_ASSERT_EQ(1, h2, "Second init: host2 healthy"); health_check_cleanup(); cleanup_test_config(); TEST_SUITE_END(); } void test_health_check_disabled_state(void) { TEST_SUITE_BEGIN("Health Check Disabled State"); int healthy_before = health_check_is_healthy("any.host.com"); TEST_ASSERT_EQ(1, healthy_before, "Disabled: any host is healthy"); setup_test_config(1); health_check_init(); int healthy_enabled = health_check_is_healthy("host0.example.com"); TEST_ASSERT_EQ(1, healthy_enabled, "Enabled: known host is healthy"); health_check_cleanup(); int healthy_after = health_check_is_healthy("any.host.com"); TEST_ASSERT_EQ(1, healthy_after, "After cleanup: any host is healthy"); cleanup_test_config(); TEST_SUITE_END(); } void run_health_check_tests(void) { test_health_check_init_no_routes(); test_health_check_init_with_routes(); test_health_check_null_hostname(); test_health_check_case_insensitive(); test_health_check_cleanup(); test_health_check_run_no_init(); test_health_check_run_with_init(); test_health_check_multiple_init(); test_health_check_disabled_state(); }