/** * Test for UDP socket API * Tests basic create/destroy, send/receive functionality */ #include #include #include #include #include #include #include #include #include "../src/udp_socket.h" static int g_packet_received = 0; static char g_received_data[1024]; static size_t g_received_len = 0; static struct sockaddr_storage g_received_from; static void test_recv_callback(udp_socket_t* sock, const uint8_t* data, size_t len, const struct sockaddr* from_addr, void* user_data) { (void)sock; (void)user_data; g_packet_received = 1; g_received_len = len < sizeof(g_received_data) ? len : sizeof(g_received_data) - 1; memcpy(g_received_data, data, g_received_len); g_received_data[g_received_len] = '\0'; memcpy(&g_received_from, from_addr, from_addr->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)); } int main() { printf("=== UDP Socket Test ===\n"); // Test 1: Create socket printf("Test 1: Creating UDP socket..."); udp_socket_t* sock1 = udp_socket_create(NULL, 0); assert(sock1 != NULL); printf(" PASS (fd=%d)\n", udp_socket_get_fd(sock1)); // Test 2: Get local address printf("Test 2: Getting local address..."); struct sockaddr_storage local_addr; socklen_t addr_len; udp_socket_get_local_addr(sock1, &local_addr, &addr_len); assert(local_addr.ss_family == AF_INET); struct sockaddr_in* sin = (struct sockaddr_in*)&local_addr; printf(" PASS (port=%d)\n", ntohs(sin->sin_port)); uint16_t bound_port = ntohs(sin->sin_port); // Test 3: Create second socket printf("Test 3: Creating second UDP socket..."); udp_socket_t* sock2 = udp_socket_create(NULL, 0); assert(sock2 != NULL); printf(" PASS (fd=%d)\n", udp_socket_get_fd(sock2)); // Test 4: Set receive callback printf("Test 4: Setting receive callback..."); udp_socket_set_recv_callback(sock1, test_recv_callback, NULL); printf(" PASS\n"); // Test 5: Send data from sock2 to sock1 printf("Test 5: Sending data..."); struct sockaddr_in dest_addr; dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(bound_port); inet_pton(AF_INET, "127.0.0.1", &dest_addr.sin_addr); const char* test_data = "Hello, UDP!"; int sent = udp_socket_send(sock2, (const uint8_t*)test_data, strlen(test_data), (struct sockaddr*)&dest_addr); assert(sent > 0); printf(" PASS (sent %d bytes)\n", sent); // Даем время на доставку usleep(10000); // Test 6: Receive data (simulate - нужен poll loop в реальном приложении) printf("Test 6: Checking receive (manual test required)...\n"); printf(" To test receive, use: echo -n \"test\" | nc -u 127.0.0.1 %d\n", bound_port); // Test 7: Test port binding printf("Test 7: Testing port binding conflict..."); udp_socket_t* sock3 = udp_socket_create(NULL, bound_port); assert(sock3 == NULL); // Should fail - port already in use printf(" PASS (correctly rejected binding to used port)\n"); // Test 8: Set socket option printf("Test 8: Setting socket option (SO_REUSEADDR)..."); int reuse = 1; int ret = udp_socket_set_option(sock1, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); assert(ret == 0); printf(" PASS\n"); // Cleanup printf("Test 9: Destroying sockets..."); udp_socket_destroy(sock1); udp_socket_destroy(sock2); printf(" PASS\n"); printf("\n=== All UDP Socket Tests Passed ===\n"); return 0; }