Skip to content

Conversation

kurisaW
Copy link
Member

@kurisaW kurisaW commented Sep 22, 2025

拉取/合并请求描述:(PR description)

注意:请先合并此PR:#10719

添加sal api测试用例覆盖

具体测试内容如下:

  • 验证 TCP/UDP socket 的正确创建和无效参数处理
  • 测试 socket 绑定到指定端口的正确性
  • listen() 在不同 backlog 配置下的行为
  • 测试连接建立、超时和错误处理
  • 验证 accept() 在阻塞和非阻塞模式下的行为
  • TCP 发送/接收数据及回声验证
  • 测试 sendto/recvfrom 操作
  • 验证正常关闭和异常情况处理
  • getsockname/getpeername 功能验证
  • socket 超时设置和非阻塞模式处理
  • 使用 RT-Thread 事件机制进行多线程同步测试
  • 无效参数和网络故障的异常处理
  • 避免端口冲突的并发测试机制

覆盖api:

  • sal_accept
  • sal_bind
  • sal_shutdown
  • sal_getpeername
  • sal_getsockname
  • sal_getsockopt
  • sal_setsockopt
  • sal_connect
  • sal_listen
  • sal_sendmsg
  • sal_recvmsg
  • sal_recvfrom
  • sal_sendto
  • sal_socket
  • sal_socketpair
  • sal_closesocket
  • sal_ioctlsocket

@Rbb666
Copy link
Member

Rbb666 commented Sep 22, 2025

@Ryan-CW-Code 大佬帮忙review下

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds comprehensive unit test coverage for the RT-Thread SAL (Socket Abstraction Layer) API. The tests validate socket operations including creation, binding, connection establishment, data transmission, and error handling scenarios.

  • Adds a new test file tc_sal_socket.c with 1030 lines of socket API test coverage
  • Updates build configuration to include SAL test cases when enabled
  • Reorganizes Kconfig structure to consolidate all network unit tests under a unified menu

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
components/net/utest/tc_sal_socket.c Complete test suite for SAL socket operations with TCP/UDP communication tests
components/net/utest/SConscript Adds SAL test source to build configuration
components/net/utest/Kconfig Reorganizes network test configuration menu and adds SAL test option

Comment on lines 232 to 248
int mode = 1;
sal_ioctlsocket(server_sock, FIONBIO, &mode);
LOG_D("Set server socket %d to non-blocking mode", server_sock);

int elapsed = 0;
int check_interval = 50;
int accepted_sock = -1;
while (elapsed < ACCEPT_POLL_TIMEOUT_MS)
{
accepted_sock = sal_accept(server_sock, RT_NULL, RT_NULL);
if (accepted_sock >= 0)
{
LOG_I("Accepted connection on socket %d", accepted_sock);
set_socket_timeout(accepted_sock, SOCKET_TIMEOUT_MS);
close_test_socket(accepted_sock);
break;
}
Copy link
Preview

Copilot AI Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

best_practices/最佳实践: The socket returned by sal_accept() should have its return value checked for errors before calling set_socket_timeout() and close_test_socket(). / sal_accept() 返回的套接字应该在调用 set_socket_timeout() 和 close_test_socket() 之前检查返回值是否有错误。

Copilot uses AI. Check for mistakes.

Comment on lines +269 to +270
sal_ioctlsocket(server_sock, FIONBIO, &mode);
LOG_D("Restored server socket %d to blocking mode", server_sock);
Copy link
Preview

Copilot AI Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

best_practices/最佳实践: The return value of sal_ioctlsocket() should be checked to ensure the socket mode was successfully restored to blocking. / 应该检查 sal_ioctlsocket() 的返回值以确保套接字模式成功恢复为阻塞模式。

Suggested change
sal_ioctlsocket(server_sock, FIONBIO, &mode);
LOG_D("Restored server socket %d to blocking mode", server_sock);
int restore_ret = sal_ioctlsocket(server_sock, FIONBIO, &mode);
if (restore_ret != 0)
{
LOG_E("Failed to restore server socket %d to blocking mode, ret=%d", server_sock, restore_ret);
}
else
{
LOG_D("Restored server socket %d to blocking mode", server_sock);
}

Copilot uses AI. Check for mistakes.

Comment on lines +742 to +748
int accepted_sock = sal_accept(server_sock, NULL, NULL);
if (accepted_sock < 0)
{
LOG_E("Server accept failed: %d", accepted_sock);
goto cleanup_sr;
}
LOG_I("Server accepted connection on socket %d", accepted_sock);
Copy link
Preview

Copilot AI Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] best_practices/最佳实践: Using NULL for address parameters in sal_accept() is acceptable for testing, but consider using proper sockaddr structures for more comprehensive testing coverage. / 在 sal_accept() 中使用 NULL 作为地址参数在测试中是可以接受的,但考虑使用适当的 sockaddr 结构以获得更全面的测试覆盖率。

Suggested change
int accepted_sock = sal_accept(server_sock, NULL, NULL);
if (accepted_sock < 0)
{
LOG_E("Server accept failed: %d", accepted_sock);
goto cleanup_sr;
}
LOG_I("Server accepted connection on socket %d", accepted_sock);
struct sockaddr_in peer_addr;
socklen_t peer_addr_len = sizeof(peer_addr);
int accepted_sock = sal_accept(server_sock, (struct sockaddr *)&peer_addr, &peer_addr_len);
if (accepted_sock < 0)
{
LOG_E("Server accept failed: %d", accepted_sock);
goto cleanup_sr;
}
char peer_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &peer_addr.sin_addr, peer_ip, sizeof(peer_ip));
LOG_I("Server accepted connection on socket %d from %s:%d", accepted_sock, peer_ip, ntohs(peer_addr.sin_port));

Copilot uses AI. Check for mistakes.

CPPPATH = [cwd]

if GetDepend('RT_UTEST_USING_ALL_CASES') or GetDepend('RT_UTEST_TC_USING_LWIP') or GetDepend('RT_UTEST_TC_USING_NETDEV'):
if GetDepend('RT_UTEST_USING_ALL_CASES'):
Copy link
Preview

Copilot AI Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

best_practices/最佳实践: The condition should also check for individual SAL test configuration to allow selective testing. Consider adding 'or GetDepend('RT_UTEST_TC_USING_SAL')' to the condition. / 条件应该也检查单独的 SAL 测试配置以允许选择性测试。考虑在条件中添加 'or GetDepend('RT_UTEST_TC_USING_SAL')'。

Suggested change
if GetDepend('RT_UTEST_USING_ALL_CASES'):
if GetDepend('RT_UTEST_USING_ALL_CASES') or GetDepend('RT_UTEST_TC_USING_SAL'):

Copilot uses AI. Check for mistakes.

@Ryan-CW-Code
Copy link
Contributor

明天看看,这部分要不要跟 #10675 整合互补一下,抽一下公共代码?
之后还有at_socket如果也创建一份大部分都相似的tc就太灾难了

@kurisaW
Copy link
Member Author

kurisaW commented Sep 22, 2025

sal testcase仅针对rtt sal组件提供api覆盖测试,本身sal就是对上支持标准bsd接口,向下对lwip,at组件等接口,这块的共性是肯定的,包括说后续的bsd socket,这块肯定也是有相似之处的。

个人建议保留对标准bsd socket,sal socket测试用例的覆盖

对于底层lwip,at等组件建议仅针对组件本身特色接口保留测试,其余socket通信接口由上层进行测试(最终会调用到底层lwip等接口)

Copy link
Contributor

@unicornx unicornx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

只 review 了 utest 的框架使用,没有 review 具体的 tc_sal_socket.c 的内容

@Rbb666
Copy link
Member

Rbb666 commented Sep 23, 2025

这个PR也添加 utest_auto_run 进来吧,这类测试用例是需要ci去进行持续运行维护的

@kurisaW
Copy link
Member Author

kurisaW commented Sep 23, 2025

@Ryan-CW-Code 另外对于异常参数的检查,其实也包含了一部分,只不过覆盖的可能不是那么全,后续可以补充

@kurisaW
Copy link
Member Author

kurisaW commented Sep 23, 2025

运行截图:

ps:这里的断言信息需要该PR合并:

sal utestcase

[I/utest] [==========] [ utest ] loop 1/1
[I/utest] [==========] [ utest ] started
[I/utest] [----------] [ testcase ] (components.net.sal.socket_basic) started
[I/utest] ===========================================
[I/utest] Starting SAL Socket Basic API Tests
[I/utest] ===========================================
[I/utest] Checking network device status...
[I/utest] Network test socket created successfully: 0
[I/utest] Using loopback IP address for testing: 127.0.0.1
[I/utest] Network device appears operational
[I/utest] [==========] utest unit name: (TC_sal_socket_create)
[I/utest] Starting TC_sal_socket_create tests...
[I/utest] Testing TCP socket creation...
[I/utest] TCP socket created: 0
[I/utest] Closed socket 0
[I/utest] Testing UDP socket creation...
[I/utest] UDP socket created: 0
[I/utest] Closed socket 0
[I/utest] Testing invalid family parameter...
[E/sal.skt] SAL socket protocol family input failed, return error -1.
[I/utest] Invalid family result: -1
[I/utest] Testing invalid type parameter...
[E/sal.skt] SAL socket protocol family input failed, return error -2.
[I/utest] Invalid type result: -1
[I/utest] Testing invalid protocol parameter...
[I/utest] Invalid protocol result: 0
[E/utest] [ ASSERT ] [ unit ] at (tc_sal_socket.c); func: (TC_sal_socket_create:463); msg: ((sock < 0) is false)
[I/utest] TC_sal_socket_create tests completed
[I/utest] [==========] utest unit name: (TC_sal_socket_bind)
[I/utest] Starting TC_sal_socket_bind tests...
[I/utest] Creating socket for bind test on port 9000...
[I/utest] Created socket 1 (domain=2, type=1, protocol=0)
[I/utest] Attempting to bind socket 1 to port 9000...
[I/utest] Bind result: 0 (expected 0)
[I/utest] Closed socket 1
[I/utest] Skipping NULL address bind test (would cause assertion)
[I/utest] Testing bind with invalid socket...
[I/utest] Invalid socket bind result: -1 (expected -1)
[I/utest] TC_sal_socket_bind tests completed
[I/utest] [==========] utest unit name: (TC_sal_socket_listen)
[I/utest] Starting TC_sal_socket_listen tests...
[I/utest] Creating socket for listen test...
[I/utest] Created socket 1 (domain=2, type=1, protocol=0)
[I/utest] Binding socket 1 for listen test on port 9002...
[I/utest] Testing listen with backlog 5 on socket 1...
[I/utest] Listen result: 0 (expected 0)
[I/utest] Testing listen with invalid backlog (-1)...
[I/utest] Invalid backlog listen result: 0
[I/utest] Closed socket 1
[I/utest] Testing listen on invalid socket...
[I/utest] Invalid socket listen result: -1 (expected -1)
[I/utest] TC_sal_socket_listen tests completed
[I/utest] [==========] utest unit name: (TC_sal_socket_connect)
[I/utest] Starting TC_sal_socket_connect tests...
[I/utest] Setting up test server on port 9004...
[I/utest] Setting up threaded test server on port 9004
[I/utest] Created server thread
[I/utest] Created client thread
[I/utest] Started server and client threads
[I/utest] Starting client thread for port 9004
[I/utest] Starting server thread on port 9004
[I/utest] Created socket 1 (domain=2, type=1, protocol=0)
[I/utest] Server socket 1 bound to port 9004
[I/utest] Server socket 1 listening with backlog 5
[I/utest] Server ready and signaled on port 9004
[I/utest] Created socket 2 (domain=2, type=1, protocol=0)
[I/utest] Attempting to connect to server 127.0.0.1:9004
[I/utest] Connect result: 0
[I/utest] Connection to server successful
[I/utest] Closed socket 2
[I/utest] Cleaned up threads and event
[I/utest] Test server setup partially successful (connect verified)
[I/utest] Test server setup completed successfully
[I/utest] Testing connect to invalid address 192.168.999.999...
[I/utest] Created socket 2 (domain=2, type=1, protocol=0)
[I/utest] Invalid address connect result: -1 (expected -1)
[I/utest] Closed socket 2
[I/utest] TC_sal_socket_connect tests completed
[I/utest] [==========] utest unit name: (TC_sal_socket_accept)
[I/utest] Starting TC_sal_socket_accept tests...
[I/utest] Creating server socket...
[I/utest] Created socket 2 (domain=2, type=1, protocol=0)
[I/utest] Binding server socket 2 to port 9006...
[I/utest] Starting to listen on server socket 2...
[I/utest] Testing accept with timeout on socket 2...
[I/utest] Accept timed out as expected: -1
[I/utest] Closed socket 2
[I/utest] Testing accept on invalid socket...
[I/utest] Invalid socket accept result: -1 (expected -1)
[I/utest] TC_sal_socket_accept tests completed
[I/utest] [==========] utest unit name: (TC_sal_socket_send_recv)
[I/utest] Starting TC_sal_socket_send_recv tests...
[I/utest] Setting up test server on port 9008...
[I/utest] Setting up threaded test server on port 9008
[I/utest] Created server thread
[I/utest] Created client thread
[I/utest] Started server and client threads
[I/utest] Starting client thread for port 9008
[I/utest] Starting server thread on port 9008
[I/utest] Created socket 2 (domain=2, type=1, protocol=0)
[I/utest] Server socket 2 bound to port 9008
[I/utest] Server socket 2 listening with backlog 5
[I/utest] Server ready and signaled on port 9008
[I/utest] Created socket 3 (domain=2, type=1, protocol=0)
[I/utest] Attempting to connect to server 127.0.0.1:9008
[I/utest] Connect result: 0
[I/utest] Connection to server successful
[I/utest] Closed socket 3
[I/utest] Cleaned up threads and event
[I/utest] Test server setup partially successful (connect verified)
[I/utest] Testing send/recv with data exchange...
[I/utest] Created socket 3 (domain=2, type=1, protocol=0)
[I/utest] Created socket 4 (domain=2, type=1, protocol=0)
[I/utest] Server socket 3 bound to port 9009
[I/utest] Server socket 3 listening
[I/utest] Client socket 4 connected
[I/utest] Server accepted connection on socket 5
[I/utest] Client sent 21 bytes
[I/utest] Server received 21 bytes, matches sent data
[I/utest] Server sent echo 21 bytes
[I/utest] Client received echo 21 bytes, matches sent data
[I/utest] Closed socket 5
[I/utest] Closed socket 4
[I/utest] Closed socket 3
[I/utest] Cleaned up test connection sockets
[I/utest] TC_sal_socket_send_recv tests completed
[I/utest] [==========] utest unit name: (TC_sal_socket_udp_communication)
[I/utest] Starting TC_sal_socket_udp_communication tests...
[I/utest] Created socket 3 (domain=2, type=2, protocol=0)
[I/utest] Created socket 4 (domain=2, type=2, protocol=0)
[I/utest] Server socket 3 bound to port 9010
[I/utest] Client socket 4 bound to port 9110
[I/utest] Sending 21 bytes from client to server...
[I/utest] Client sent 21 bytes to server
[I/utest] Server received 21 bytes
[I/utest] Sending 21 bytes from server to client...
[I/utest] Server sent 21 bytes to client
[I/utest] Client received 21 bytes
[I/utest] Closed socket 3
[I/utest] Closed socket 4
[I/utest] TC_sal_socket_udp_communication tests completed
[I/utest] [==========] utest unit name: (TC_sal_socket_getpeername_getsockname)
[I/utest] Starting TC_sal_socket_getpeername_getsockname tests...
[I/utest] Created socket 3 (domain=2, type=1, protocol=0)
[I/utest] Server socket 3 bound to port 9012
[I/utest] Testing getsockname on socket 3...
[I/utest] Getsockname result: 0 (expected 0)
[I/utest] Closed socket 3
[I/utest] Testing getsockname/getpeername on invalid socket...
[I/utest] Invalid socket getsockname result: -1 (expected -1)
[I/utest] Invalid socket getpeername result: -1 (expected -1)
[I/utest] TC_sal_socket_getpeername_getsockname tests completed
[I/utest] [==========] utest unit name: (TC_sal_socket_close)
[I/utest] Starting TC_sal_socket_close tests...
[I/utest] Testing close valid socket...
[I/utest] Created socket 3 (domain=2, type=1, protocol=0)
[I/utest] Closing socket 3...
[I/utest] Testing close invalid socket...
[I/utest] Testing double close...
[I/utest] Created socket 3 (domain=2, type=1, protocol=0)
[I/utest] Double closing socket 3 (should be safe)
[I/utest] TC_sal_socket_close tests completed
[I/utest] ===========================================
[I/utest] SAL Socket Basic API Tests Completed
[I/utest] ===========================================
[I/utest] [ PASSED ] [ result ] testcase (components.net.sal.socket_basic)
[I/utest] [----------] [ testcase ] (components.net.sal.socket_basic) finished
[I/utest] [==========] [ utest ] 1 tests from 1 testcase ran.
[I/utest] [ PASSED ] [ result ] 1 tests.
[I/utest] [==========] [ utest ] finished

Copy link

github-actions bot commented Sep 23, 2025

📌 Code Review Assignment

🏷️ Tag: components

Reviewers: Maihuanyi

Changed Files (Click to expand)
  • components/net/utest/Kconfig
  • components/net/utest/SConscript
  • components/net/utest/tc_sal_socket.c

🏷️ Tag: workflow

Reviewers: Rbb666 kurisaW supperthomas

Changed Files (Click to expand)
  • .github/utest/net/lwip.cfg
  • .github/utest/net/netdev.cfg
  • .github/utest/net/sal_lwip.cfg
  • .github/workflows/utest_auto_run.yml

📊 Current Review Status (Last Updated: 2025-09-26 18:12 CST)

  • Maihuanyi Pending Review
  • Rbb666 Pending Review
  • kurisaW Pending Review
  • supperthomas Pending Review

📝 Review Instructions

  1. 维护者可以通过单击此处来刷新审查状态: 🔄 刷新状态
    Maintainers can refresh the review status by clicking here: 🔄 Refresh Status

  2. 确认审核通过后评论 LGTM/lgtm
    Comment LGTM/lgtm after confirming approval

  3. PR合并前需至少一位维护者确认
    PR must be confirmed by at least one maintainer before merging

ℹ️ 刷新CI状态操作需要具备仓库写入权限。
ℹ️ Refresh CI status operation requires repository Write permission.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action github action yml imporve component: net Component
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants