Browse Source

tests: inherit the ready echo listener on an automatic port

master
evgeny 5 days ago
parent
commit
efdfb1d835
  1. 48
      tests/test_tcp_proxy_server.c

48
tests/test_tcp_proxy_server.c

@ -18,7 +18,6 @@
#include "../lib/debug_config.h"
#include "../lib/mem.h"
#define ECHO_PORT 19991
#define TIMEOUT_MS 8000
#define PAYLOAD_SIZE 64
@ -30,12 +29,7 @@ static uint8_t send_buf[PAYLOAD_SIZE];
static void* timeout_id = NULL;
#ifndef _WIN32
static void echo_server(void) {
int srv = socket(AF_INET, SOCK_STREAM, 0);
if (srv < 0) _exit(1);
int opt = 1; setsockopt(srv, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in a = {.sin_family = AF_INET, .sin_port = htons(ECHO_PORT), .sin_addr.s_addr = inet_addr("127.0.0.1")};
if (bind(srv, (struct sockaddr*)&a, sizeof(a)) < 0 || listen(srv, 1) < 0) { close(srv); _exit(1); }
static void echo_server(socket_t srv) {
int cli = accept(srv, NULL, NULL);
if (cli < 0) { close(srv); _exit(1); }
uint8_t buf[8192]; ssize_t n;
@ -62,6 +56,7 @@ static int push_write(struct tcp_conn* tc, const uint8_t* data, size_t len) {
static void timeout_cb(void* arg) {
(void)arg;
timeout_id = NULL;
printf("[FAIL] timeout\n");
g_done = -1;
}
@ -69,33 +64,47 @@ static void timeout_cb(void* arg) {
int main(void) {
debug_config_init();
debug_set_level(DEBUG_LEVEL_WARN);
struct UASYNC* ua = NULL;
struct tcp_conn* tc = NULL;
socket_t sock = SOCKET_INVALID;
uint16_t echo_port = 0;
#ifdef _WIN32
printf("[SKIP] test_tcp_proxy_server — fork() not available on Windows\n");
return 0;
#else
socket_t listener = socket(AF_INET, SOCK_STREAM, 0);
if (listener == SOCKET_INVALID) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "echo socket: %s", strerror(errno)); return 1; }
struct sockaddr_in a = {.sin_family = AF_INET, .sin_addr.s_addr = inet_addr("127.0.0.1")};
if (bind(listener, (struct sockaddr*)&a, sizeof(a)) < 0 || listen(listener, 1) < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "echo listen: %s", strerror(errno)); socket_close_wrapper(listener); return 1;
}
echo_port = socket_get_bound_port(listener);
if (!echo_port) { socket_close_wrapper(listener); return 1; }
echo_pid = fork();
if (echo_pid == 0) { echo_server(); _exit(0); }
usleep(50000); // даём серверу запуститься
if (echo_pid < 0) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "echo fork: %s", strerror(errno)); socket_close_wrapper(listener); return 1; }
if (echo_pid == 0) { echo_server(listener); _exit(0); }
socket_close_wrapper(listener); // Слушатель уже готов, дочерний процесс сохраняет его fd и порт.
#endif
struct UASYNC* ua = uasync_create();
if (!ua) return 1;
ua = uasync_create();
if (!ua) { DEBUG_ERROR(DEBUG_CATEGORY_SYS, "echo test: uasync create failed"); goto done; }
timeout_id = uasync_set_timeout(ua, TIMEOUT_MS * 10, NULL, timeout_cb, "timeout");
if (!timeout_id) { DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "echo test: timeout allocation failed"); goto done; }
socket_t sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == SOCKET_INVALID) return 1;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == SOCKET_INVALID) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "echo client socket failed"); goto done; }
socket_set_nonblocking(sock);
struct tcp_conn* tc = tcp_conn_create(ua, sock, 1500, 8192, 32, 8, 0, on_fin_cb, on_error_cb, NULL);
if (!tc) return 1;
tc = tcp_conn_create(ua, sock, 1500, 8192, 32, 8, 0, on_fin_cb, on_error_cb, NULL);
if (!tc) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "echo client tcp_conn create failed"); goto done; }
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(ECHO_PORT);
addr.sin_port = htons(echo_port);
int ret = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
if (ret < 0 && errno != EINPROGRESS) { printf("[FAIL] connect: %s\n", strerror(errno)); g_done = -1; }
@ -125,8 +134,11 @@ int main(void) {
}
}
tcp_conn_destroy(tc);
uasync_destroy(ua, 0);
done:
if (timeout_id) uasync_cancel_timeout(ua, timeout_id);
if (tc) tcp_conn_destroy(tc);
else if (sock != SOCKET_INVALID) socket_close_wrapper(sock);
if (ua) uasync_destroy(ua, 0);
#ifndef _WIN32
kill(echo_pid, SIGKILL);
waitpid(echo_pid, NULL, 0);

Loading…
Cancel
Save