testing/nettest: add cmocka test for local socket SCM_RIGHTS

Add CMocka regression test case to verify local socket SCM_RIGHTS
behavior when the file descriptor table is exhausted.

Signed-off-by: Bogdan <Bogdan4ik0759@gmail.com>
This commit is contained in:
Bogdan 2026-08-20 17:08:54 +03:00 committed by Xiang Xiao
parent a71c329cfb
commit 31342e02ce
7 changed files with 333 additions and 0 deletions

View file

@ -50,6 +50,29 @@ if(CONFIG_TESTING_NET_TEST)
${SRCS})
endif()
if(CONFIG_TESTING_NET_LOCAL)
set(SRCS
${CMAKE_CURRENT_LIST_DIR}/local/test_local.c
${CMAKE_CURRENT_LIST_DIR}/local/test_local_common.c
${CMAKE_CURRENT_LIST_DIR}/local/test_local_scm_rights.c)
nuttx_add_application(
NAME
cmocka_net_local
PRIORITY
${CONFIG_TESTING_NET_TEST_PRIORITY}
STACKSIZE
${CONFIG_TESTING_NET_TEST_STACKSIZE}
MODULE
${CONFIG_TESTING_NET_TEST}
DEPENDS
cmocka
INCLUDE_DIRECTORIES
${CMAKE_CURRENT_LIST_DIR}/utils
SRCS
${SRCS})
endif()
if(CONFIG_TESTING_NET_OTHERS)
set(SRCS
${CMAKE_CURRENT_LIST_DIR}/others/test_others.c

View file

@ -35,6 +35,11 @@ config TESTING_NET_TCP_PORT
endif
config TESTING_NET_LOCAL
bool "Enable cmocka net local test"
depends on NET_LOCAL && NET_LOCAL_SCM
default y
config TESTING_NET_OTHERS
bool "Enable cmocka net other test"
default y

View file

@ -45,6 +45,12 @@ endif
endif
ifeq ($(CONFIG_TESTING_NET_LOCAL),y)
MAINSRC += local/test_local.c
PROGNAME += cmocka_net_local
CSRCS += local/test_local_common.c local/test_local_scm_rights.c
endif
ifeq ($(CONFIG_TESTING_NET_OTHERS),y)
MAINSRC += others/test_others.c
PROGNAME += cmocka_net_others

View file

@ -0,0 +1,46 @@
/****************************************************************************
* apps/testing/nettest/local/test_local.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <cmocka.h>
#include "test_local.h"
/****************************************************************************
* Public Functions
****************************************************************************/
int main(int argc, FAR char *argv[])
{
const struct CMUnitTest local_tests[] =
{
cmocka_unit_test(test_local_scm_rights),
};
return cmocka_run_group_tests(local_tests, test_local_group_setup,
test_local_group_teardown);
}

View file

@ -0,0 +1,52 @@
/****************************************************************************
* apps/testing/nettest/local/test_local.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __APPS_TESTING_NETTEST_LOCAL_TEST_LOCAL_H
#define __APPS_TESTING_NETTEST_LOCAL_TEST_LOCAL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/compiler.h>
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: test_local_group_setup
****************************************************************************/
int test_local_group_setup(FAR void **state);
/****************************************************************************
* Name: test_local_group_teardown
****************************************************************************/
int test_local_group_teardown(FAR void **state);
/****************************************************************************
* Name: test_local_scm_rights
****************************************************************************/
void test_local_scm_rights(FAR void **state);
#endif /* __APPS_TESTING_NETTEST_LOCAL_TEST_LOCAL_H */

View file

@ -0,0 +1,47 @@
/****************************************************************************
* apps/testing/nettest/local/test_local_common.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include "test_local.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: test_local_group_setup
****************************************************************************/
int test_local_group_setup(FAR void **state)
{
return 0;
}
/****************************************************************************
* Name: test_local_group_teardown
****************************************************************************/
int test_local_group_teardown(FAR void **state)
{
return 0;
}

View file

@ -0,0 +1,154 @@
/****************************************************************************
* apps/testing/nettest/local/test_local_scm_rights.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <errno.h>
#include <fcntl.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <cmocka.h>
#include "test_local.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define SEND_FDS 3
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: test_local_scm_rights
****************************************************************************/
void test_local_scm_rights(FAR void **state)
{
int sv[2];
int p1[2];
int p2[2];
struct msghdr msg;
struct iovec iov;
char send_buf = 'X';
char recv_buf;
char cmsgbuf[CMSG_SPACE(sizeof(int) * SEND_FDS)];
struct cmsghdr *cmsg;
int send_fds[SEND_FDS];
int junk[256];
int n_open = 0;
int ret;
int i;
ret = pipe(p1);
assert_return_code(ret, errno);
ret = pipe(p2);
assert_return_code(ret, errno);
ret = socketpair(AF_LOCAL, SOCK_STREAM, 0, sv);
assert_return_code(ret, errno);
send_fds[0] = p1[0];
send_fds[1] = p1[1];
send_fds[2] = p2[0];
memset(&msg, 0, sizeof(msg));
memset(cmsgbuf, 0, sizeof(cmsgbuf));
iov.iov_base = &send_buf;
iov.iov_len = 1;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = CMSG_SPACE(sizeof(int) * SEND_FDS);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * SEND_FDS);
memcpy(CMSG_DATA(cmsg), send_fds, sizeof(int) * SEND_FDS);
ret = sendmsg(sv[0], &msg, 0);
assert_true(ret >= 0);
for (i = 0; i < 256; i++)
{
junk[i] = open("/dev/null", O_RDONLY);
if (junk[i] < 0)
{
break;
}
n_open++;
}
if (n_open == 0)
{
/* If /dev/null is not available, try to dup p1[0] */
for (i = 0; i < 256; i++)
{
junk[i] = dup(p1[0]);
if (junk[i] < 0)
{
break;
}
n_open++;
}
}
memset(&msg, 0, sizeof(msg));
memset(cmsgbuf, 0, sizeof(cmsgbuf));
iov.iov_base = &recv_buf;
iov.iov_len = 1;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
recvmsg(sv[1], &msg, 0);
/* cleanup descriptors */
for (i = 0; i < n_open; i++)
{
close(junk[i]);
}
close(sv[0]);
close(sv[1]);
close(p1[0]);
close(p1[1]);
close(p2[0]);
close(p2[1]);
}