#include "test_framework.h" #include "../src/types.h" #include "../src/rate_limit.h" #include void test_rate_limit_disabled(void) { TEST_SUITE_BEGIN("Rate Limit Disabled"); rate_limit_cleanup(); TEST_ASSERT_EQ(1, rate_limit_check("192.168.1.1"), "Rate limit check passes when disabled"); TEST_ASSERT_EQ(1, rate_limit_check("10.0.0.1"), "Any IP passes when disabled"); TEST_ASSERT_EQ(1, rate_limit_check(NULL), "NULL IP passes when disabled"); TEST_SUITE_END(); } void test_rate_limit_init(void) { TEST_SUITE_BEGIN("Rate Limit Init"); rate_limit_cleanup(); rate_limit_init(100, 60); TEST_ASSERT_EQ(1, rate_limit_check("192.168.1.100"), "First request passes"); rate_limit_cleanup(); TEST_SUITE_END(); } void test_rate_limit_within_limit(void) { TEST_SUITE_BEGIN("Rate Limit Within Limit"); rate_limit_cleanup(); rate_limit_init(10, 60); const char *ip = "192.168.1.50"; int all_passed = 1; for (int i = 0; i < 10; i++) { if (rate_limit_check(ip) != 1) { all_passed = 0; break; } } TEST_ASSERT_EQ(1, all_passed, "All requests within limit pass"); rate_limit_cleanup(); TEST_SUITE_END(); } void test_rate_limit_exceeded(void) { TEST_SUITE_BEGIN("Rate Limit Exceeded"); rate_limit_cleanup(); rate_limit_init(5, 60); const char *ip = "192.168.1.200"; for (int i = 0; i < 5; i++) { rate_limit_check(ip); } int exceeded = rate_limit_check(ip); TEST_ASSERT_EQ(0, exceeded, "Request exceeding limit is blocked"); rate_limit_cleanup(); TEST_SUITE_END(); } void test_rate_limit_different_ips(void) { TEST_SUITE_BEGIN("Rate Limit Different IPs"); rate_limit_cleanup(); rate_limit_init(3, 60); for (int i = 0; i < 3; i++) { rate_limit_check("10.0.0.1"); } TEST_ASSERT_EQ(0, rate_limit_check("10.0.0.1"), "First IP blocked after limit"); TEST_ASSERT_EQ(1, rate_limit_check("10.0.0.2"), "Second IP still allowed"); TEST_ASSERT_EQ(1, rate_limit_check("10.0.0.3"), "Third IP still allowed"); rate_limit_cleanup(); TEST_SUITE_END(); } void test_rate_limit_null_ip(void) { TEST_SUITE_BEGIN("Rate Limit NULL IP"); rate_limit_cleanup(); rate_limit_init(5, 60); TEST_ASSERT_EQ(1, rate_limit_check(NULL), "NULL IP passes (fail-open)"); rate_limit_cleanup(); TEST_SUITE_END(); } void test_rate_limit_purge_expired(void) { TEST_SUITE_BEGIN("Rate Limit Purge Expired"); rate_limit_cleanup(); rate_limit_init(100, 60); rate_limit_check("192.168.1.1"); rate_limit_check("192.168.1.2"); rate_limit_check("192.168.1.3"); rate_limit_purge_expired(); TEST_ASSERT_EQ(1, rate_limit_check("192.168.1.1"), "Entry still valid after purge"); rate_limit_cleanup(); TEST_SUITE_END(); } void test_rate_limit_cleanup(void) { TEST_SUITE_BEGIN("Rate Limit Cleanup"); rate_limit_init(10, 60); for (int i = 0; i < 100; i++) { char ip[32]; snprintf(ip, sizeof(ip), "192.168.%d.%d", i / 256, i % 256); rate_limit_check(ip); } rate_limit_cleanup(); TEST_ASSERT_EQ(1, rate_limit_check("192.168.1.1"), "After cleanup, rate limit disabled"); TEST_SUITE_END(); } void run_rate_limit_tests(void) { test_rate_limit_disabled(); test_rate_limit_init(); test_rate_limit_within_limit(); test_rate_limit_exceeded(); test_rate_limit_different_ips(); test_rate_limit_null_ip(); test_rate_limit_purge_expired(); test_rate_limit_cleanup(); }