恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
libwebsockets 的 CTest 测试体系:从环境准备到测试编写与 CI 集成
首页
资讯中心
/
libwebsockets 的 CTest 测试体系:从环境准备到测试编写与 CI 集成
libwebsockets 的 CTest 测试体系:从环境准备到测试编写与 CI 集成
发布时间:2026/10/14 20:59:36
后端网络通信【免费下载链接】libwebsocketscanonical libwebsockets.org networking library项目地址https://gitcode.com/gh_mirrors/li/libwebsockets点击查看免费下载本文以 libwebsockets 仓库中的 README.ctest.md 为主线系统讲解如何用 CTest 对 libwebsockets 及其 minimal examples、api-tests 进行自动化回归测试。你将掌握如何在旧发行版上升级 cmake、如何以非特权方式构建并运行测试、如何阅读与理解测试输出以及如何利用 cmake 的 Test Fixtures 机制为网络测试编排服务端搭档进程并规避端口冲突。文中所有结论均可对照仓库中的 ctest 辅助脚本、CMakeLists.txt 与各示例的测试定义源码进行验证。为什么 libwebsockets 选择 CTest 作为回归测试框架libwebsockets 是一个覆盖 HTTP/1.1、HTTP/2、HTTP/3(QUIC)、WebSocket、MQTT、Secure Streams 等大量协议的跨平台网络库。协议栈的任何一次重构都可能悄悄破坏某个边缘功能因此仓库在 README.ci.md 中明确提出凡是希望持续可用的新功能都应该被 CI 测试覆盖。在 libwebsockets 中测试任务直接以 ctest/cmake 语言写在各个 minimal examples 和 api-tests 的 CMakeLists.txt 里由当前构建选项决定哪些测试被启用。测试的运行逻辑非常简单运行某个示例程序或 api 测试程序进程以 exit code 0 退出视为通过其他任何退出码都视为失败。这套设计有两个明显优势测试与示例代码天然对齐测试驱动的正是仓库中真实可运行的示例程序测试通过即代表示例可用按构建选项自动伸缩启用-DLWS_WITH_MINIMAL_EXAMPLES1后凡是被当前构建配置启用的示例都会自动注册进 ctest 测试列表见 CMakeLists.txt 中add_subdirectory逻辑。第一步确保拥有足够新的 cmake 版本CTest 的 Fixtures 等高级特性依赖较新的 cmake。如果你的发行版自带 cmake 过于陈旧需要先升级。README 针对 Ubuntu bionic 和 xenial 给出了使用 Kitware 官方软件源的完整步骤移除发行版自带的旧 cmake并安装获取新软件源密钥所需的工具# apt purge --auto-remove cmake # apt install gnupg wget apt-transport-https ca-certificates # wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2/dev/null | sudo apt-key add - # apt edit-sources在源列表末尾追加一行bionic 用户写bionicxenial 用户替换为xenial保存退出:wqdeb https://apt.kitware.com/ubuntu/ bionic main更新软件源并安装新 cmake# apt update # apt install cmake说明当前仓库要求各示例项目自身cmake_minimum_required(VERSION 3.10)见 minimal-http-client 的 CMakeLists.txt但根 CMakeLists.txt 使用了include(CTest)等机制想完整跑 Fixtures 并发测试仍建议使用较新的 cmake。构建与运行测试无 root、无污染的完整流程生成测试只需一个构建选项主测试套件的生成只需要一个配置项cmake .. -DLWS_WITH_MINIMAL_EXAMPLES1注意 CMakeLists.txt 中LWS_WITH_MINIMAL_EXAMPLES的默认值在 ESP32/FreeRTOS 等嵌入式平台默认OFF在常规平台默认ON显式指定-DLWS_WITH_MINIMAL_EXAMPLES1是最稳妥的做法。README 特别强调所有测试都只针对本地服务器对端local server peers运行不需要任何互联网连接。根 CMakeLists.txt 也印证了这一点测试中使用的LWS_CTEST_SERVER_RESOLVE会根据 IPv4/IPv6 构建选项自动解析为::1、127.0.0.1或localhost。非特权侧装DESTDIR 安装测试被设计为不需要 root 权限也不能干扰构建机上已安装的其他 libwebsockets 版本。因此必须把刚构建的产物侧装side-install到一个独立的目录make -j12 DESTDIR../destdir install这是把安装根目录强制改到../destdir所有.so、插件、头文件都会落在该目录下而不是覆盖系统的/usr/local。运行测试用 LD_LIBRARY_PATH 确保加载自建产物由于没有 root必须保证运行时加载的是刚刚构建的库与插件而不是机器上已安装的某个旧版本 lws。做法是把侧装目录中插件路径放进LD_LIBRARY_PATH让动态链接器优先搜索我们自己的产物build $ make -j12 \ rm -rf ../destdir \ make -j12 DESTDIR../destdir install \ LD_LIBRARY_PATH../destdir/usr/local/share/libwebsockets-test-server/plugins ctest -j2 --output-on-failure逐段解释片段作用make -j12并行编译库与示例rm -rf ../destdir清掉上一次侧装残留避免旧文件混入make -j12 DESTDIR../destdir install侧装到../destdirLD_LIBRARY_PATH...plugins确保刚构建的测试服务器插件优先于系统安装的插件ctest -j2 --output-on-failure并行运行 2 个测试只有失败时才输出详细日志在 Windows 上命令形式不同需要显式指定构建配置ctest . -C DEBUG # 或 RELEASE取决于当时构建类型这一调用形态与仓库 CI 完全一致在 .sai.json 中Sai 对每个平台执行的核心测试命令就是ctest -j$SAI_PARALLEL --output-on-failure --repeat until-pass:3Windows builder 则使用ctest.exe --test-dir build -C DEBUG -j%SAI_PARALLEL%。一份真实的全部通过输出解读取决于构建选项具体跑哪些测试会不同。下面是一份 73 个测试全部通过的输出节选完整清单见 README.ctest.mdTest project /projects/libwebsockets/build Start 71: st_wcs_srv Start 43: st_hcp_srv 1/73 Test #71: st_wcs_srv .................................. Passed 5.01 sec ... 5/73 Test #55: st_ssproxyctx ............................... Passed 1.02 sec ... 64/73 Test #7: api-test-lws_struct_sqlite .................. Passed 0.03 sec ... 73/73 Test #5: api-test-lws_smd ............................ Passed 4.22 sec 100% tests passed, 0 tests failed out of 73 Total Test time (real) 137.76 sec可以从这份输出里读出测试的分类规律st_xxx_srv/ki_xxx_srvst(setup/start) 和ki(kill) 成对出现是用于拉起和回收服务端搭档的 Fixture 测试如st_hcm_srv、ki_hcm_srvapi-test-*纯 API 级自测无需网络对端通常毫秒级完成如api-test-lwsac0.00 sechttp-client-multi*、ws-client-*、sspc-*、ss-*真正跑协议交互的客户端/服务端测试耗时从数秒到数十秒不等如ss-tf55.51 sec网络类测试耗时明显高于纯 API 测试这也是下文要为每个测试单独设置TIMEOUT的原因。编写测试的核心注意事项README 给出了四个关键实践全部可以在仓库源码中得到印证。1. 永远为每个测试设置 TIMEOUTctest 的默认超时是1500 秒。一旦测试卡死你要等 25 分钟才能看到失败因此在每个测试上设置合适的TIMEOUT是基本素养。例如 minimal-http-client 的 CMakeLists.txt 把TIMEOUT 60应用到了所有 HTTP 客户端测试而 minimal-http-client-multi 的 CMakeLists.txt 使用了TIMEOUT 50。2. 正确设置 WORKING_DIRECTORY服务端示例通常需要从它自己的./minimal-examples/...目录运行才能访问index.html等资源文件当使用-DLWS_WITH_MBEDTLS1构建时客户端程序也必须从自己的目录运行因为它需要额外读取 warmcat.com 或 libwebsockets.org 的受信 CA 文件。因此 README 建议在所有情况下都把WORKING_DIRECTORY设置为示例应用所在目录。仓库实现正是如此例如 minimal-http-client-multi 的 CMakeLists.txt 将 Fixturest_hcm_srv的工作目录指向minimal-examples-lowlevel/http-server/minimal-http-server-tls以便 TLS 服务器能读取其证书。3. 用 Test Fixtures 孵化 服务端搭档进程很多网络测试需要对端buddy客户端测试需要先有一个服务器在监听反之亦然。cmake 本身不直接支持把守护进程声明为测试依赖所以 libwebsockets 提供了两个辅助脚本scripts/ctest-background.sh后台拉起被测进程把 pid 写进带装饰名decorated的 pid 文件并在进程提前退出时转储其日志scripts/ctest-background-kill.sh优雅回收后台进程先 SIGTERM、再 SIGKILL并检查后台进程是否意外早死、打印其日志。这两个脚本共享 scripts/ctest-fixture-key.sh后者负责推导 pid/log 文件位置因为同一台机器上可能同时跑多个构建树Sai 允许每 builder 多个构建fixture 文件按构建树定位存放在该构建树的Testing/fixtures/目录下文件名形如exe.fixture.SAI_INSTANCE_IDX.pid。以 minimal-http-client-multi 为例完整定义见 minimal-http-client-multi/CMakeLists.txt编排过程分三步第一步定义启动搭档与回收搭档两个 phony 测试add_test(NAME st_hcm_srv COMMAND ${CMAKE_SOURCE_DIR}/scripts/ctest-background.sh hcm_srv $TARGET_FILE:lws-minimal-http-server-tls -p ${PORT_HCM_SRV} ) add_test(NAME ki_hcm_srv COMMAND ${CMAKE_SOURCE_DIR}/scripts/ctest-background-kill.sh hcm_srv $TARGET_FILE_NAME:lws-minimal-http-server-tls -p ${PORT_HCM_SRV})第二步用FIXTURES_SETUP/FIXTURES_CLEANUP把它们绑定为名为hcm_srv的 fixture并为启动阶段单独设置较长超时服务器冷启动 并行磁盘压力下可能较慢set_tests_properties(st_hcm_srv PROPERTIES WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/minimal-examples-lowlevel/http-server/minimal-http-server-tls FIXTURES_SETUP hcm_srv TIMEOUT 800) set_tests_properties(ki_hcm_srv PROPERTIES FIXTURES_CLEANUP hcm_srv)第三步在真正被测的测试上声明FIXTURES_REQUIRED hcm_srvcmake/ctest 就会自动在测试前启动搭档、测试后回收搭档set_tests_properties(http-client-multi PROPERTIES FIXTURES_REQUIRED hcm_srv WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/minimal-examples-lowlevel/http-client/minimal-http-client-multi TIMEOUT 50)配套的还有 cmake/LwsCheckRequirements.cmake 中的lws_get_free_port()它通过带锁的计数器文件Linux 下为/tmp/lws_port_counter_$USER在 15000~30000 区间内递增分配端口lws_get_free_ports()则一次分配一段连续端口供需要同时监听多个端口的测试使用——这些函数正是Buddy sockets一节所讲端口隔离的第一道保险。4. Buddy socket 端口与并发隔离在同一台机器/同一个 systemd-nspawn 网络上下文里不能直接使用 7681 这类众所周知的端口原因有二ctest 本身通常并行执行-jSai 通常会在同一台机器上并行构建多个实例可能多达几十个即同一 VM 内可能同时跑多个不同的 ctest。解决办法是给不同的测试约定各自的端口区间当存在多个 ctest 同时运行时再叠加环境变量$ENV{SAI_INSTANCE_IDX}一个 0、1、33 之类的序号把端口进一步错开。如果你不用 Sai也可以自己在环境里设置该变量让它反映你的构建实例序号# # instantiate the server per sai builder instance, they are running in the same # machine context in parallel so they can tread on each other otherwise # set(PORT_HCM_SRV 7670) if ($ENV{SAI_INSTANCE_IDX}) math(EXPR PORT_HCM_SRV 7671 $ENV{SAI_INSTANCE_IDX}) endif()默认值7670/7671idx服务于手动运行测试的场景而 Sai 场景下每个实例都会拿到不同端口。仓库最新实现实际上更进一步像 minimal-http-client-multi 的 CMakeLists.txt 直接用lws_get_free_port()分配端口并在启动测试上注入SAI_LIST_PORT环境变量让 ctest-background.sh 得以轮询等待监听端口就绪而不是盲目 sleep并通过kill -0检查子进程存活来排除端口被旧进程占用的误判。由于这套编排足够复杂README 的建议非常务实复制一个现成的简单用例如 minimal-http-client 的 CMakeLists.txt改掉名字和端口使其唯一而不是从零编写。与 CI 的衔接Sai、ctest 与独立脚本libwebsockets 的 CI 由 Sailibwebsockets.org 的 CI 工具驱动配置在仓库根目录的 .sai.json 中。该文件把每个平台/配置映射到它需要的 CMake 选项、构建与测试步骤以及最终调用 ctest 的命令。可以看到api-tests./minimal-examples-lowlevel/api-tests与minimal example selftests都从各自的 CMakeLists 注册进 ctest因此新增一个测试只需要在 cmake 里接线之后每个启用了它的 Sai builder 都会自动运行每个 builder 的 ctest 调用还会带上--repeat until-pass:3用于容忍偶发性的时序抖动Windows buildermsvc、msvc-schannel、msvc-mbedtls使用ctest.exe --test-dir build -C DEBUG形式与 README 中的 Windows 说明一致。除此之外scripts/h2spec.sh 这类独立脚本不在默认 ctest 运行之列它们需要从构建目录手动运行针对已安装的构建执行更专业的协议一致性测试例如 h2spec 对 HTTP/2 的符合性测试。这形成了三档测试纵深api-tests纯单元级→ ctest 集成测试默认 CI 覆盖→ 独立专项脚本按需手动触发。小结为 libwebsockets 增加一个测试的完整清单结合 README.ctest.md 与仓库实现往这套体系里加一个新测试的最小行动清单是在示例/api-test 的CMakeLists.txt中调用add_test(NAME ... COMMAND ...)若测试需要网络对端参照 minimal-http-client-multi/CMakeLists.txt 增加st_*/ki_*成对 Fixture并声明FIXTURES_SETUP/FIXTURES_CLEANUP/FIXTURES_REQUIRED用lws_get_free_port()见 cmake/LwsCheckRequirements.cmake或SAI_INSTANCE_IDX偏移保证端口隔离为每个测试设置合理的WORKING_DIRECTORY与TIMEOUT用-DLWS_WITH_MINIMAL_EXAMPLES1构建、DESTDIR 侧装再以LD_LIBRARY_PATH指向自建产物运行ctest -jN --output-on-failure验证通过通过 .sai.json 接入 Sai CI让测试在每个平台上持续运行。这套体系的价值在于它把示例可用性直接变成了可自动验证的回归资产任何重构只要破坏了某个协议路径对应测试就会在几十秒内报错从而保住各功能持续可用的承诺。赞分享后端网络通信【免费下载链接】libwebsocketscanonical libwebsockets.org networking library项目地址https://gitcode.com/gh_mirrors/li/libwebsockets点击查看免费下载相关推荐DataHub Java SDK V2 集成测试实战指南环境准备、测试编写与故障排查DataHub Java SDK V2 集成测试实战指南环境准备、测试编写与故障排查 本篇指南以 DataHub 仓库中 metadata integrati数据目录数据治理数据血缘后端前端数据工程数据集成TDengine 端到端测试框架全指南基于 Pytest 的新测试体系从环境部署到 CI 集成TDengine 端到端测试框架全指南基于 Pytest 的新测试体系从环境部署到 CI 集成 TDengine 在 test/ 目录下维护着一套全新的端到端数据库时序数据库物联网大数据实时分析云原生openHiTLS 测试指南从环境准备、测试框架到 CI 流水线的完整实践openHiTLS 测试指南从环境准备、测试框架到 CI 流水线的完整实践 本篇技术指南系统讲解 openHiTLS 开源密码套件的测试体系如何准备测试环境密码学网络安全创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考