You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

111 lines
3.8 KiB

/**
* Test for UDP socket API
* Tests basic create/destroy, send/receive functionality
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#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;
}