feat: add TCP_NODELAY socket optimization and upstream handling with connection caching tests

This commit is contained in:
2025-12-15 00:31:27 +00:00
parent 9e7c5940dc
commit 353e6b08b6
3 changed files with 154 additions and 0 deletions
+144
View File
@@ -460,6 +460,144 @@ void test_connection_do_read_eagain(void) {
TEST_SUITE_END();
}
void test_connection_optimize_socket(void) {
TEST_SUITE_BEGIN("Connection Optimize Socket");
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT(sockfd >= 0, "Socket created");
connection_optimize_socket(sockfd, 0);
int optval;
socklen_t optlen = sizeof(optval);
getsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, &optlen);
TEST_ASSERT_EQ(1, optval, "TCP_NODELAY is enabled for client");
close(sockfd);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT(sockfd >= 0, "Second socket created");
connection_optimize_socket(sockfd, 1);
getsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, &optlen);
TEST_ASSERT_EQ(1, optval, "TCP_NODELAY is enabled for upstream");
close(sockfd);
TEST_SUITE_END();
}
extern time_t cached_time;
void connection_update_cached_time(void);
void test_connection_cached_time(void) {
TEST_SUITE_BEGIN("Connection Cached Time");
time_t before = time(NULL);
connection_update_cached_time();
time_t after = time(NULL);
TEST_ASSERT(cached_time >= before, "Cached time >= before");
TEST_ASSERT(cached_time <= after, "Cached time <= after");
TEST_SUITE_END();
}
void test_connection_epoll_event_caching(void) {
TEST_SUITE_BEGIN("Connection Epoll Event Caching");
connection_init_all();
int old_epoll = epoll_fd;
epoll_fd = epoll_create1(0);
TEST_ASSERT(epoll_fd >= 0, "Epoll created");
int sockfd[2];
int result = socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd);
TEST_ASSERT_EQ(0, result, "Socket pair created");
connection_add_to_epoll(sockfd[0], EPOLLIN);
TEST_ASSERT_EQ((uint32_t)EPOLLIN, connections[sockfd[0]].epoll_events, "Events cached on add");
connection_modify_epoll(sockfd[0], EPOLLIN | EPOLLOUT);
TEST_ASSERT_EQ((uint32_t)(EPOLLIN | EPOLLOUT), connections[sockfd[0]].epoll_events, "Events cached on modify");
connection_modify_epoll(sockfd[0], EPOLLIN | EPOLLOUT);
TEST_ASSERT(1, "Redundant modify doesn't crash");
close(sockfd[0]);
close(sockfd[1]);
close(epoll_fd);
epoll_fd = old_epoll;
TEST_SUITE_END();
}
void test_connection_splice_pipe_init(void) {
TEST_SUITE_BEGIN("Connection Splice Pipe Init");
connection_init_all();
TEST_ASSERT_EQ(-1, connections[0].splice_pipe[0], "Splice pipe[0] initialized to -1");
TEST_ASSERT_EQ(-1, connections[0].splice_pipe[1], "Splice pipe[1] initialized to -1");
TEST_ASSERT_EQ(0, connections[0].can_splice, "can_splice initialized to 0");
TEST_SUITE_END();
}
void test_connection_patch_buf_cleanup(void) {
TEST_SUITE_BEGIN("Connection Patch Buffer Cleanup");
connection_init_all();
int old_epoll = epoll_fd;
epoll_fd = epoll_create1(0);
TEST_ASSERT(epoll_fd >= 0, "Epoll created");
int sockfd[2];
socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd);
connection_t *conn = &connections[sockfd[0]];
memset(conn, 0, sizeof(connection_t));
conn->fd = sockfd[0];
conn->type = CONN_TYPE_CLIENT;
buffer_init(&conn->read_buf, 4096);
buffer_init(&conn->write_buf, 4096);
conn->patch_buf = malloc(1024);
conn->patch_buf_capacity = 1024;
struct epoll_event ev = { .events = EPOLLIN, .data.fd = sockfd[0] };
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sockfd[0], &ev);
connection_close(sockfd[0]);
TEST_ASSERT_EQ(CONN_TYPE_UNUSED, conn->type, "Connection closed");
close(sockfd[1]);
close(epoll_fd);
epoll_fd = old_epoll;
TEST_SUITE_END();
}
void test_connection_tcp_nodelay(void) {
TEST_SUITE_BEGIN("Connection TCP NODELAY");
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
TEST_ASSERT(sockfd >= 0, "Socket created");
connection_set_tcp_nodelay(sockfd);
int optval;
socklen_t optlen = sizeof(optval);
getsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, &optlen);
TEST_ASSERT_EQ(1, optval, "TCP_NODELAY is set");
close(sockfd);
TEST_SUITE_END();
}
void run_connection_tests(void) {
test_connection_init_all();
test_connection_set_non_blocking();
@@ -479,4 +617,10 @@ void run_connection_tests(void) {
test_connection_do_write_full_buffer();
test_connection_multiple_error_responses();
test_connection_do_read_eagain();
test_connection_optimize_socket();
test_connection_cached_time();
test_connection_epoll_event_caching();
test_connection_splice_pipe_init();
test_connection_patch_buf_cleanup();
test_connection_tcp_nodelay();
}