#include "test_framework.h" #include "../src/types.h" #include "../src/monitor.h" #include #include void test_history_deque_init(void) { TEST_SUITE_BEGIN("History Deque Initialization"); history_deque_t dq; history_deque_init(&dq, 10); TEST_ASSERT(dq.points != NULL, "Deque points allocated"); TEST_ASSERT_EQ(10, dq.capacity, "Capacity is 10"); TEST_ASSERT_EQ(0, dq.count, "Count is 0"); TEST_ASSERT_EQ(0, dq.head, "Head is 0"); free(dq.points); TEST_SUITE_END(); } void test_history_deque_push(void) { TEST_SUITE_BEGIN("History Deque Push"); history_deque_t dq; history_deque_init(&dq, 5); history_deque_push(&dq, 1.0, 100.0); TEST_ASSERT_EQ(1, dq.count, "Count is 1 after first push"); history_deque_push(&dq, 2.0, 200.0); history_deque_push(&dq, 3.0, 300.0); TEST_ASSERT_EQ(3, dq.count, "Count is 3 after three pushes"); history_deque_push(&dq, 4.0, 400.0); history_deque_push(&dq, 5.0, 500.0); TEST_ASSERT_EQ(5, dq.count, "Count is 5 at capacity"); history_deque_push(&dq, 6.0, 600.0); TEST_ASSERT_EQ(5, dq.count, "Count stays at capacity after overflow"); free(dq.points); TEST_SUITE_END(); } void test_network_history_deque(void) { TEST_SUITE_BEGIN("Network History Deque"); network_history_deque_t dq; network_history_deque_init(&dq, 5); TEST_ASSERT(dq.points != NULL, "Network deque points allocated"); TEST_ASSERT_EQ(5, dq.capacity, "Capacity is 5"); TEST_ASSERT_EQ(0, dq.count, "Count is 0"); network_history_deque_push(&dq, 1.0, 100.0, 50.0); TEST_ASSERT_EQ(1, dq.count, "Count is 1 after push"); network_history_deque_push(&dq, 2.0, 200.0, 100.0); network_history_deque_push(&dq, 3.0, 300.0, 150.0); TEST_ASSERT_EQ(3, dq.count, "Count is 3"); free(dq.points); TEST_SUITE_END(); } void test_disk_history_deque(void) { TEST_SUITE_BEGIN("Disk History Deque"); disk_history_deque_t dq; disk_history_deque_init(&dq, 5); TEST_ASSERT(dq.points != NULL, "Disk deque points allocated"); TEST_ASSERT_EQ(5, dq.capacity, "Capacity is 5"); disk_history_deque_push(&dq, 1.0, 10.0, 5.0); TEST_ASSERT_EQ(1, dq.count, "Count is 1 after push"); disk_history_deque_push(&dq, 2.0, 20.0, 10.0); TEST_ASSERT_EQ(2, dq.count, "Count is 2"); free(dq.points); TEST_SUITE_END(); } void test_request_time_deque(void) { TEST_SUITE_BEGIN("Request Time Deque"); request_time_deque_t dq; request_time_deque_init(&dq, 10); TEST_ASSERT(dq.times != NULL, "Request time deque allocated"); TEST_ASSERT_EQ(10, dq.capacity, "Capacity is 10"); TEST_ASSERT_EQ(0, dq.count, "Count is 0"); request_time_deque_push(&dq, 15.5); TEST_ASSERT_EQ(1, dq.count, "Count is 1 after push"); request_time_deque_push(&dq, 20.0); request_time_deque_push(&dq, 25.5); TEST_ASSERT_EQ(3, dq.count, "Count is 3"); for (int i = 0; i < 10; i++) { request_time_deque_push(&dq, (double)i); } TEST_ASSERT_EQ(10, dq.count, "Count stays at capacity"); free(dq.times); TEST_SUITE_END(); } void test_monitor_init_cleanup(void) { TEST_SUITE_BEGIN("Monitor Init and Cleanup"); monitor_init(NULL); TEST_ASSERT(monitor.cpu_history.points != NULL, "CPU history initialized"); TEST_ASSERT(monitor.memory_history.points != NULL, "Memory history initialized"); TEST_ASSERT(monitor.network_history.points != NULL, "Network history initialized"); TEST_ASSERT(monitor.disk_history.points != NULL, "Disk history initialized"); monitor_cleanup(); TEST_ASSERT(monitor.cpu_history.points == NULL, "CPU history cleaned up"); TEST_ASSERT(monitor.memory_history.points == NULL, "Memory history cleaned up"); TEST_SUITE_END(); } void test_monitor_vhost_stats(void) { TEST_SUITE_BEGIN("Monitor Vhost Stats"); monitor_init(NULL); vhost_stats_t *stats1 = monitor_get_or_create_vhost_stats("test.example.com"); TEST_ASSERT(stats1 != NULL, "First vhost stats created"); TEST_ASSERT_STR_EQ("test.example.com", stats1->vhost_name, "Vhost name correct"); TEST_ASSERT_EQ(0, stats1->total_requests, "Initial total requests is 0"); vhost_stats_t *stats2 = monitor_get_or_create_vhost_stats("test.example.com"); TEST_ASSERT(stats1 == stats2, "Same vhost returns same stats"); vhost_stats_t *stats3 = monitor_get_or_create_vhost_stats("other.example.com"); TEST_ASSERT(stats3 != NULL, "Second vhost stats created"); TEST_ASSERT(stats1 != stats3, "Different vhosts have different stats"); vhost_stats_t *null_stats = monitor_get_or_create_vhost_stats(NULL); TEST_ASSERT(null_stats == NULL, "NULL vhost returns NULL"); vhost_stats_t *empty_stats = monitor_get_or_create_vhost_stats(""); TEST_ASSERT(empty_stats == NULL, "Empty vhost returns NULL"); monitor_cleanup(); TEST_SUITE_END(); } void test_monitor_record_request(void) { TEST_SUITE_BEGIN("Monitor Record Request"); monitor_init(NULL); vhost_stats_t *stats = monitor_get_or_create_vhost_stats("api.test.com"); TEST_ASSERT(stats != NULL, "Stats created"); monitor_record_request_start(stats, 0); TEST_ASSERT_EQ(1, stats->total_requests, "Total requests incremented"); TEST_ASSERT_EQ(1, stats->http_requests, "HTTP requests incremented"); TEST_ASSERT_EQ(0, stats->websocket_requests, "WebSocket requests unchanged"); monitor_record_request_start(stats, 1); TEST_ASSERT_EQ(2, stats->total_requests, "Total requests is 2"); TEST_ASSERT_EQ(1, stats->http_requests, "HTTP requests still 1"); TEST_ASSERT_EQ(1, stats->websocket_requests, "WebSocket requests is 1"); monitor_record_request_start(NULL, 0); TEST_ASSERT(1, "NULL stats doesn't crash"); monitor_cleanup(); TEST_SUITE_END(); } void test_monitor_record_bytes(void) { TEST_SUITE_BEGIN("Monitor Record Bytes"); monitor_init(NULL); vhost_stats_t *stats = monitor_get_or_create_vhost_stats("bytes.test.com"); TEST_ASSERT(stats != NULL, "Stats created"); TEST_ASSERT_EQ(0, stats->bytes_sent, "Initial bytes sent is 0"); TEST_ASSERT_EQ(0, stats->bytes_recv, "Initial bytes recv is 0"); monitor_record_bytes(stats, 1000, 500); TEST_ASSERT_EQ(1000, stats->bytes_sent, "Bytes sent recorded"); TEST_ASSERT_EQ(500, stats->bytes_recv, "Bytes recv recorded"); monitor_record_bytes(stats, 500, 250); TEST_ASSERT_EQ(1500, stats->bytes_sent, "Bytes sent accumulated"); TEST_ASSERT_EQ(750, stats->bytes_recv, "Bytes recv accumulated"); monitor_record_bytes(NULL, 100, 100); TEST_ASSERT(1, "NULL stats doesn't crash"); monitor_cleanup(); TEST_SUITE_END(); } void test_monitor_update(void) { TEST_SUITE_BEGIN("Monitor Update"); monitor_init(NULL); monitor_update(); TEST_ASSERT(monitor.cpu_history.count >= 0, "CPU history has data after update"); TEST_ASSERT(monitor.memory_history.count >= 0, "Memory history has data after update"); monitor_update(); monitor_update(); TEST_ASSERT(1, "Multiple updates don't crash"); monitor_cleanup(); TEST_SUITE_END(); } void test_monitor_record_request_end(void) { TEST_SUITE_BEGIN("Monitor Record Request End"); monitor_init(NULL); vhost_stats_t *stats = monitor_get_or_create_vhost_stats("timing.test.com"); TEST_ASSERT(stats != NULL, "Stats created"); double start_time = 1000.0; monitor_record_request_end(stats, start_time); TEST_ASSERT(stats->avg_request_time_ms >= 0, "Avg request time recorded"); monitor_record_request_end(stats, start_time); monitor_record_request_end(stats, start_time); TEST_ASSERT(1, "Multiple request end calls work"); monitor_record_request_end(NULL, 0); TEST_ASSERT(1, "NULL stats doesn't crash"); monitor_cleanup(); TEST_SUITE_END(); } void test_monitor_deque_overflow(void) { TEST_SUITE_BEGIN("Monitor Deque Overflow Behavior"); history_deque_t dq; history_deque_init(&dq, 3); history_deque_push(&dq, 1.0, 10.0); history_deque_push(&dq, 2.0, 20.0); history_deque_push(&dq, 3.0, 30.0); TEST_ASSERT_EQ(3, dq.count, "Count is at capacity"); history_deque_push(&dq, 4.0, 40.0); TEST_ASSERT_EQ(3, dq.count, "Count stays at capacity"); history_deque_push(&dq, 5.0, 50.0); history_deque_push(&dq, 6.0, 60.0); TEST_ASSERT_EQ(3, dq.count, "Count still at capacity after multiple overflows"); free(dq.points); TEST_SUITE_END(); } void test_monitor_network_deque_overflow(void) { TEST_SUITE_BEGIN("Monitor Network Deque Overflow"); network_history_deque_t dq; network_history_deque_init(&dq, 3); network_history_deque_push(&dq, 1.0, 100.0, 50.0); network_history_deque_push(&dq, 2.0, 200.0, 100.0); network_history_deque_push(&dq, 3.0, 300.0, 150.0); TEST_ASSERT_EQ(3, dq.count, "Count is at capacity"); network_history_deque_push(&dq, 4.0, 400.0, 200.0); TEST_ASSERT_EQ(3, dq.count, "Count stays at capacity"); free(dq.points); TEST_SUITE_END(); } void test_monitor_disk_deque_overflow(void) { TEST_SUITE_BEGIN("Monitor Disk Deque Overflow"); disk_history_deque_t dq; disk_history_deque_init(&dq, 3); disk_history_deque_push(&dq, 1.0, 10.0, 5.0); disk_history_deque_push(&dq, 2.0, 20.0, 10.0); disk_history_deque_push(&dq, 3.0, 30.0, 15.0); TEST_ASSERT_EQ(3, dq.count, "Count is at capacity"); disk_history_deque_push(&dq, 4.0, 40.0, 20.0); TEST_ASSERT_EQ(3, dq.count, "Count stays at capacity"); free(dq.points); TEST_SUITE_END(); } void run_monitor_tests(void) { test_history_deque_init(); test_history_deque_push(); test_network_history_deque(); test_disk_history_deque(); test_request_time_deque(); test_monitor_init_cleanup(); test_monitor_vhost_stats(); test_monitor_record_request(); test_monitor_record_bytes(); test_monitor_update(); test_monitor_record_request_end(); test_monitor_deque_overflow(); test_monitor_network_deque_overflow(); test_monitor_disk_deque_overflow(); }