/** * Integration test for ETCP protocol with packet pool * Tests: etcp_create, add_socket, packet processing, channel creation */ #include #include #include #include #include #include #include #include "../src/etcp.h" #include "../src/packet_buffer.h" #include "../src/packet_pool.h" static int g_data_ready_called = 0; static etcp_channel_t* g_last_channel = NULL; static packet_buffer_t* g_last_packet = NULL; static void test_data_ready_cb(struct ETCP_CONN* etcp, etcp_channel_t* channel, packet_buffer_t* pkt, void* user_data) { (void)etcp; (void)user_data; g_data_ready_called++; g_last_channel = channel; g_last_packet = pkt; printf(" Data ready: channel=%p, packet=%p, len=%zu\n", channel, pkt, packet_data_len(pkt)); } int main() { printf("=== ETCP Integration Test ===\n"); // Test 1: Create ETCP instance printf("Test 1: Creating ETCP instance..."); uint64_t node_id = 0x123456789ABCDEF0; struct ETCP_CONN* etcp = etcp_create(node_id, 1500); assert(etcp != NULL); assert(etcp->node_id == node_id); printf(" PASS (node_id=0x%llx)\n", (unsigned long long)node_id); // Test 2: Add socket printf("Test 2: Adding UDP socket..."); int ret = etcp_add_socket(etcp, "127.0.0.1", 0); // 0 = any port assert(ret == 0); assert(etcp->socket_count == 1); printf(" PASS (socket_count=%d)\n", etcp->socket_count); // Test 3: Set data ready callback printf("Test 3: Setting data ready callback..."); etcp_set_data_ready_callback(etcp, test_data_ready_cb, NULL); assert(etcp->data_ready_cb != NULL); printf(" PASS\n"); // Test 4: Create a test packet (simulating incoming packet) printf("Test 4: Processing incoming INIT packet..."); packet_buffer_t* pkt = packet_pool_get(&etcp->packet_pool); assert(pkt != NULL); // Fill packet as if it came from socket pkt->metadata.socket = etcp->sockets[0]; pkt->metadata.timestamp_us = 1000; pkt->metadata.flags = 0; pkt->metadata.stage = PACKET_STAGE_RX_SOCKET; // Set source address struct sockaddr_in src_addr; src_addr.sin_family = AF_INET; src_addr.sin_port = htons(50001); inet_pton(AF_INET, "127.0.0.1", &src_addr.sin_addr); memcpy(&pkt->metadata.src_addr, &src_addr, sizeof(src_addr)); // Set packet data (INIT packet) memcpy(packet_data(pkt), "INIT", 4); packet_set_data_len(pkt, 4); g_data_ready_called = 0; etcp_packet_input(etcp, pkt); // Check that callback was called and channel was created assert(g_data_ready_called == 1); assert(g_last_channel != NULL); assert(g_last_packet == pkt); assert(etcp->channel_count == 1); printf(" PASS (channel_count=%d, callback called)\n", etcp->channel_count); // Test 5: Get pool statistics printf("Test 5: Getting pool statistics..."); size_t allocs, reuse, overflow; packet_pool_get_stats(&etcp->packet_pool, &allocs, &reuse, &overflow); printf(" PASS (allocs=%zu, reuse=%zu, overflow=%zu)\n", allocs, reuse, overflow); // Test 6: Send data through channel printf("Test 6: Sending data through channel..."); const char* test_data = "Hello, ETCP!"; ret = etcp_send(etcp, g_last_channel, (const uint8_t*)test_data, strlen(test_data)); assert(ret == 0); printf(" PASS\n"); // Test 7: Get ETCP statistics printf("Test 7: Getting ETCP statistics..."); etcp_get_stats(etcp, &allocs, &reuse, NULL, NULL); printf(" PASS\n"); // Test 8: Destroy ETCP instance printf("Test 8: Destroying ETCP instance..."); etcp_destroy(etcp); printf(" PASS\n"); // Test 9: Test packet buffer operations printf("Test 9: Testing packet buffer operations..."); packet_buffer_t test_pkt; packet_init(&test_pkt); // Test metadata packet_set_encrypted(&test_pkt, 1); assert(packet_is_encrypted(&test_pkt) != 0); packet_set_fragmented(&test_pkt, 1); assert(packet_is_fragmented(&test_pkt) != 0); packet_set_stage(&test_pkt, PACKET_STAGE_RX_DECRYPTED); assert(packet_stage(&test_pkt) == PACKET_STAGE_RX_DECRYPTED); // Test addresses memcpy(packet_src_addr(&test_pkt), &src_addr, sizeof(src_addr)); assert(packet_src_port(&test_pkt) == src_addr.sin_port); printf(" PASS\n"); printf("\n=== All ETCP Integration Tests Passed ===\n"); return 0; }