Add regression test for sendmsg/recvmsg

This commit is contained in:
Jianfeng Jiang 2024-09-10 11:21:24 +00:00 committed by Tate, Hongliang Tian
parent b4003b8aeb
commit ea8327af0f
2 changed files with 139 additions and 4 deletions

View File

@ -364,7 +364,8 @@ FN_TEST(sendmsg_and_recvmsg)
msg.msg_iov = iov; msg.msg_iov = iov;
msg.msg_iovlen = 2; msg.msg_iovlen = 2;
// Send one message and recv one message // TEST CASE 1: Send one message and recv one message
TEST_RES(sendmsg(sk_connected, &msg, 0), TEST_RES(sendmsg(sk_connected, &msg, 0),
_ret == strlen(message) + strlen(message2)); _ret == strlen(message) + strlen(message2));
@ -382,7 +383,7 @@ FN_TEST(sendmsg_and_recvmsg)
_ret == strlen(concatenated) && _ret == strlen(concatenated) &&
strcmp(buffer, concatenated) == 0); strcmp(buffer, concatenated) == 0);
// Send two message and receive two message // TEST CASE 2: Send two message and receive two message
iov[0].iov_base = message; iov[0].iov_base = message;
iov[0].iov_len = strlen(message); iov[0].iov_len = strlen(message);
@ -402,5 +403,60 @@ FN_TEST(sendmsg_and_recvmsg)
sleep(1); sleep(1);
TEST_RES(recvmsg(sk_connected, &msg, 0), _ret == strlen(message) * 2); TEST_RES(recvmsg(sk_connected, &msg, 0), _ret == strlen(message) * 2);
// TEST CASE 3: Send via a partially bad send buffer
char *good_buffer = "abc";
char *bad_buffer = (char *)1;
iov[0].iov_base = good_buffer;
iov[0].iov_len = strlen(good_buffer);
iov[1].iov_base = bad_buffer;
iov[1].iov_len = 1;
msg.msg_iov = iov;
msg.msg_iovlen = 2;
TEST_ERRNO(sendmsg(sk_accepted, &msg, 0), EFAULT);
// TEST CASE 4: Receive via a partially bad receive buffer
iov[0].iov_base = good_buffer;
iov[0].iov_len = strlen(good_buffer);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
TEST_RES(sendmsg(sk_accepted, &msg, 0), _ret == strlen(good_buffer));
sleep(1);
char recv_buffer[4096] = { 0 };
iov[0].iov_base = recv_buffer;
iov[0].iov_len = 1;
TEST_RES(recvmsg(sk_connected, &msg, 0), _ret == 1);
iov[0].iov_base = recv_buffer;
iov[0].iov_len = 1;
iov[1].iov_base = (char *)1;
iov[1].iov_len = 1;
msg.msg_iovlen = 2;
TEST_ERRNO(recvmsg(sk_connected, &msg, 0), EFAULT);
iov[0].iov_base = recv_buffer;
iov[0].iov_len = 4096;
msg.msg_iovlen = 1;
TEST_RES(recvmsg(sk_connected, &msg, 0),
_ret == strlen(good_buffer) - 1);
// TEST CASE 5: Send a large buffer
int big_buffer_size = 1000000;
char *big_buffer = (char *)calloc(0, big_buffer_size);
iov[0].iov_base = big_buffer;
iov[0].iov_len = big_buffer_size;
msg.msg_iovlen = 2;
int sndbuf = 0;
socklen_t optlen = sizeof(sndbuf);
TEST_SUCC(getsockopt(sk_accepted, SOL_SOCKET, SO_SNDBUF, &sndbuf,
&optlen));
TEST_RES(sendmsg(sk_accepted, &msg, 0), _ret <= sndbuf);
} }
END_TEST() END_TEST()

View File

@ -276,7 +276,8 @@ FN_TEST(sendmsg_and_recvmsg)
msg.msg_name = (struct sockaddr *)&sk_addr; msg.msg_name = (struct sockaddr *)&sk_addr;
msg.msg_namelen = addrlen; msg.msg_namelen = addrlen;
// Send one message and receive one message // TEST CASE 1: Send one message and receive one message
TEST_RES(sendmsg(sk_connected, &msg, 0), _ret == strlen(message)); TEST_RES(sendmsg(sk_connected, &msg, 0), _ret == strlen(message));
#define BUFFER_SIZE 50 #define BUFFER_SIZE 50
@ -287,7 +288,8 @@ FN_TEST(sendmsg_and_recvmsg)
TEST_RES(recvmsg(sk_bound, &msg, 0), TEST_RES(recvmsg(sk_bound, &msg, 0),
_ret == strlen(message) && strcmp(message, buffer) == 0); _ret == strlen(message) && strcmp(message, buffer) == 0);
// Send two messages and receive two messages // TEST CASE 2: Send two messages and receive two messages
iov[0].iov_base = message; iov[0].iov_base = message;
iov[0].iov_len = strlen(message); iov[0].iov_len = strlen(message);
msg.msg_name = (struct sockaddr *)&sk_addr; msg.msg_name = (struct sockaddr *)&sk_addr;
@ -305,3 +307,80 @@ FN_TEST(sendmsg_and_recvmsg)
_ret == strlen(message) && strcmp(message, buffer) == 0); _ret == strlen(message) && strcmp(message, buffer) == 0);
} }
END_TEST() END_TEST()
void set_nonblocking(int sockfd)
{
int flags = CHECK(fcntl(sockfd, F_GETFL, 0));
CHECK(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK));
}
FN_SETUP(enter_nonblocking_mode)
{
set_nonblocking(sk_connected);
set_nonblocking(sk_bound);
}
END_SETUP()
FN_TEST(sendmsg_and_recvmsg_bad_buffer)
{
struct sockaddr_in saddr;
socklen_t addrlen = sizeof(saddr);
sk_addr.sin_port = C_PORT;
struct msghdr msg = { 0 };
struct iovec iov[2];
msg.msg_name = (struct sockaddr *)&sk_addr;
msg.msg_namelen = addrlen;
// TEST CASE 1: Send via a partially bad send buffer
char *good_buffer = "abc";
char *bad_buffer = (char *)1;
iov[0].iov_base = good_buffer;
iov[0].iov_len = strlen(good_buffer);
iov[1].iov_base = bad_buffer;
iov[1].iov_len = 1;
msg.msg_iov = iov;
msg.msg_iovlen = 2;
TEST_ERRNO(sendmsg(sk_connected, &msg, 0), EFAULT);
// TEST CASE 2: Receive via a partially bad receive buffer
iov[0].iov_base = good_buffer;
iov[0].iov_len = strlen(good_buffer);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
TEST_RES(sendmsg(sk_connected, &msg, 0), _ret == strlen(good_buffer));
TEST_RES(sendmsg(sk_connected, &msg, 0), _ret == strlen(good_buffer));
TEST_RES(sendmsg(sk_connected, &msg, 0), _ret == strlen(good_buffer));
TEST_RES(sendmsg(sk_connected, &msg, 0), _ret == strlen(good_buffer));
sleep(1);
char recv_buffer[4096] = { 0 };
iov[0].iov_base = recv_buffer;
iov[0].iov_len = 1;
TEST_RES(recvmsg(sk_bound, &msg, 0), _ret == 1);
iov[0].iov_base = recv_buffer;
iov[0].iov_len = 1;
iov[1].iov_base = (char *)1;
iov[1].iov_len = 1;
msg.msg_iovlen = 2;
TEST_ERRNO(recvmsg(sk_bound, &msg, 0), EFAULT);
iov[0].iov_base = recv_buffer;
iov[0].iov_len = 4096;
msg.msg_iovlen = 1;
TEST_RES(recvmsg(sk_bound, &msg, 0), _ret == strlen(good_buffer));
iov[0].iov_base = recv_buffer;
iov[0].iov_len = 4096;
iov[1].iov_base = (char *)1;
iov[1].iov_len = 1;
msg.msg_iovlen = 2;
TEST_RES(recvmsg(sk_bound, &msg, 0), _ret == strlen(good_buffer));
}
END_TEST()