librdkafka 自动化回归测试指南:从 trivup 集群搭建到 ASAN/TSAN/Valgrind 内存与线程检查

📅 发布时间:2026/9/17 1:17:27
librdkafka 自动化回归测试指南:从 trivup 集群搭建到 ASAN/TSAN/Valgrind 内存与线程检查
librdkafka 自动化回归测试指南从 trivup 集群搭建到 ASAN/TSAN/Valgrind 内存与线程检查【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit本指南以仓库内 lib/librdkafka-2.15.0/tests/README.md 为核心系统讲解 librdkafkaApache Kafka 官方 C/C 客户端库当前作为依赖被集成在 Fluent Bit 项目中测试套件的完整使用流程包括使用 trivup 一键拉起本地 Kafka 集群、通过make与run-test.sh运行/定位单个测试、编写新测试的规范以及面向 PR 与 Release 的 ASAN、TSAN、Valgrind 校验矩阵。读完本文你将能独立搭建测试环境、复现间歇性故障、评估内存与线程问题并按照项目规范贡献新测试。支持的测试环境官方文档明确标准测试套件在 macOS 与 Windows 上均可工作但由于完整测试套件依赖ASAN、KerberosGSSAPI等能力仅推荐在较新的 Linux 发行版上运行——尤其是 PR 与 Release 前必须执行的那套完整测试即文末的make release-test。这一约束在 tests/Makefile 中也有体现make asan、make tsan均会在运行前先调用../dev-conf.sh asan|tsan重新编译并设置CItrue通过broker_version_tests.py跑测试文档同时提示 OSX 版 ASAN 不提供内存泄漏检测、Valgrind 仅支持 Linux。因此开发调试建议直接在 Linux 上进行必要时使用 Docker。用 trivup 自动化搭建 Broker 集群测试套件本身不依赖外部 Kafka 集群而是推荐通过 trivupPyPi 上的 Python 包启动自包含集群。这类集群被用于针对不同 Broker 版本或特定 Broker 配置运行 librdkafka 测试套件。trivup 会将指定版本的 Kafka 下载到它的 root 目录该目录同时也用于存放集群实例产生的消息、日志等。root 目录默认是当前目录下的tmp可通过TRIVUP_ROOT环境变量改到任意位置$ TRIVUP_ROOT$HOME/trivup make full仓库中 tests/requirements.txt 固定了所需依赖trivup/trivup-0.15.0.tar.gz与jsoncomment先安装它们$ python3 -m pip install -U -r requirements.txt启动指定版本 Kafka 集群并进入交互式 shell退出 shell 时集群会被自动拆除删除$ python3 -m trivup.clusters.KafkaCluster 2.3.0 # Broker 版本 # 可追加的可选参数 # --ssl 启用 SSL listener # --sasl mechanism 启用 SASL 认证 # --sr 提供 Schema-Registry 实例 # ... 更多见 --help在 trivup shell 内即可运行测试套件$ make复用已有集群test.conf如果不希望使用 trivup可以复用现有集群通过test.conf指定 brokers 及其它 librdkafka 配置属性$ cp test.conf.example test.conf $ $EDITOR test.conf仓库中的 tests/test.conf.example 给出了可用的配置项整理如下配置项说明示例metadata.broker.list引导 Broker 地址必填localhost:9092test.timeout.multiplier慢速网络下统一放大测试超时浮点数3.5test.topic.prefix测试主题名前缀主题名形如prefix_suffix默认rdkafkatestbibtest.topic.random是否让主题名随机化形如prefix_randomnumber_suffixtruetest.sql.command将测试结果写入 SQLite 数据库的命令sqlite3 rdktestsdebug开启客户端调试输出metadata,topic,msg,broker其它任意合法的 librdkafka 配置属性均可写入—其中test.sql.command需要系统安装sqlite3命令行工具写入该配置后测试结果会自动落库便于历史对比与统计。运行测试并行、顺序、单测与调试器测试入口统一为test-runner二进制由tests目录下的 C/C 测试源文件编译而成见 tests/Makefile 中的BIN test-runner。常用运行方式# 并行运行更快但故障排查更困难 $ make # 精简快速测试集最快CI 构建使用的就是这个 $ make quick # 串行运行 $ make run_seq # 只运行指定测试 $ TESTS0004 make # 以 valgrind / helgrind / gdb 模式运行指定测试 $ TESTS0009 ./run-test.sh valgrind|helgrind|gdb测试编号体系所有0000-0999编号的测试会随make自动执行1000-1999编号的测试依赖非标准环境或特殊 Broker 配置必须用TESTS1nnn make手动运行具体前置条件见各测试源文件头注释8000-8999为手工测试编号。仓库中的测试文件命名严格遵循0nnn-被测内容约定例如 0009-mock_cluster.c、0103-transactions.c、0171-share_consumer_consume.c还有大量*.cpp测试如 0061-consumer_lag.cpp 用于覆盖 C API。除了直接跑maketests/Makefile 还定义了多个实用 targetmake smoke运行SMOKE_TESTS变量指定的一组快速冒烟测试默认0000,0001,0004,0012,0017,0022,0030,0039,0049,0087,0103理想情况下一分钟内完成make run_local/make run_local_quick以-l无 Broker 本地测试-P幂等 Producer方式运行make unit只跑TESTS0000单元测试串行make delete_topics按前缀清理所有测试主题TESTSnone ./run-test.sh -D bare。测试框架环境变量精细控制单次运行测试框架支持通过一组环境变量动态控制运行行为这些变量对make、run-test.sh、until-fail.sh等所有调用方式均生效环境变量作用示例TESTS0nnn只运行指定完整编号的测试文档注释指出本应命名为 TESTTESTS0102 makeSUBTESTS...只运行包含该字符串的子测试使用SUB_TEST()的测试SUBTESTSfooTESTS_SKIP...跳过指定测试TESTS_SKIP0003,0005TEST_DEBUG...自动为所有实例化客户端设置debug配置属性TEST_DEBUGbroker,protocol TESTS0001 makeTESTS_TO_DEBUG0nnn,0mmm配合TEST_DEBUG使用仅对指定编号的测试输出调试日志TESTS_TO_DEBUG0172,0171 TEST_DEBUGall makeTEST_LEVELn控制TEST_SAY()输出级别数字越大输出越多默认 2TEST_LEVEL3RD_UT_TESTname只运行包含name的单元测试需配合TESTS0000测试名见 ../src/rdunittest.cRD_UT_TESTrdkafka_confTESTS_SKIP_BEFORE0nnn跳过该编号之前的全部测试即使它们出现在TESTS中TESTS_SKIP_BEFORE0030实战复现单个消费者测试失败文档给出了典型排障流程。假设完整套件在测试 0061消费者相关失败先将其限定为单独运行并打开消费者常用调试开关cgrp组管理、fetch拉取$ TESTS0061 TEST_DEBUGcgrp,fetch make若单独运行不再失败说明是间歇性问题。此时用 until-fail.sh 反复运行直到复现# bare 表示不加 valgrind 直接运行 $ TESTS0061 TEST_DEBUGcgrp,fetch ./until-fail.sh bare编写新的测试文档推荐的最简方式复制一个编号靠后的现有测试如0nnn-被测内容改名为下一个空闲编号。关于 C 与 C 的选择优先使用C API因为一个 C 测试能同时覆盖 C 与 C 两套 API覆盖率更高但 C 测试框架不如 C 框架功能丰富涉及消息校验等需求时建议改用 C 测试。创建测试文件后需要在三处登记Makefile 无需改动会自动拾取tests/CMakeLists.txtwin32/tests/tests.vcxprojWindows 工程文件tests/test.c 中两处搜索一个已有测试编号即可看到需要登记的位置测试函数声明与_TEST()注册表。编写规范与辅助宏结合文档与 tests/test.h、tests/test.c 源码可总结以下硬性规范Broker 版本约束若测试依赖最低 Broker 版本必须在test.c中用TEST_BRKVER()指定文档以 0091 为例实测 0014-reconsume-191.c 中的test_broker_version TEST_BRKVER(0, 8, 2, 0)即是标准用法0016-client_swname.c 还展示了TEST_BRKVER(2, 5, 0, 0)与TEST_BRKVER(4, 0, 0, 0)的版本比较本地测试标记无需活跃集群即可运行的测试用TEST_F_LOCAL标记test.h 中定义为0x1注释为 Test is local, no broker requirementtest.c 的_TEST(0006_symbols, TEST_F_LOCAL)、_TEST(0025_timers, TEST_F_LOCAL)等即为范例CI 适配运行时间长或消息量大的测试不适合 CI应让测试在test_quick变量为 true 时运行更快、消息更少失败要快尽早用TEST_ASSERT()等断言暴露错误越早发现越容易排查test.h中定义了TEST_SAY0、TEST_SAYL(LVL, ...)按级别输出、TEST_SAY(...)等价于TEST_SAYL(2, ...)与TEST_SAY_ERROR等输出宏控制输出量用TEST_SAYL()配合TEST_LEVEL环境变量控制详细输出默认级别 2测试信息使用TEST_SAY()告知开发者当前行为便于故障定位超时自适应测试运行器会自动调整已知的超时valgrind、CI 等慢速环境下。为确保测试在这些环境下的稳健性传给非测试函数的超时值必须使用tmout_multip(毫秒)宏例如rd_kafka_poll(rk, tmout_multip(3000))——这在 0002-unkpart.c、0012-produce_consume.c 等大量测试中都有体现子测试区分一个文件内含多个独立子测试时在测试函数内部使用SUB_TEST()、SUB_TEST_QUICK()与SUB_TEST_PASS()帮助区分失败来源。测试场景Test Scenarios测试场景定义了测试使用的集群配置。大多数测试使用default场景它匹配 Apache Kafka 默认 Broker 配置如主题自动创建开启。若测试依赖的集群配置与默认配置互斥则必须在scenarios/scenario.json中定义替代场景——该文件是一个配置对象直接传给 trivup。仓库中的 scenarios/README.md 说明场景名即文件名去掉.json后缀文件内容即 trivup 配置字典tests/Makefile 中的SCENARIOS?noautocreate ak23定义了非默认场景集合。仓库目前提供了 default.json、noautocreate.json关闭主题自动创建与 ak23.json 三个场景。尽量复用已有场景每个新场景都需要一次全新的集群实例会显著拖慢测试时间。开发构建dev-conf.shdev-conf.sh仓库根目录下用于配置并构建面向开发的 librdkafka 与测试套件它会启用额外运行时检查ENABLE_DEVEL、rd_dassert()等关闭优化保证栈回溯与行号准确可选开启 ASAN / TSAN 等 sanitizer。# 重新配置 librdkafka 为开发模式并重建 $ ./dev-conf.sh # 带 ASAN 或 TSAN 的开发构建 $ ./dev-conf.sh asan $ ./dev-conf.sh tsan从 dev-conf.sh 源码看其支持clean|asan|tsan|ubsan|gprof五种参数非 clean 构建会强制-stdc99/-stdc98严格标准检查tsan 模式下因 glibc 的 C11 线程与 TSAN 不兼容会自动追加--disable-c11threads所有非 clean 构建均追加--enable-devel与--disable-optimization。构建完成后会进入tests目录执行make -j build。注意性能测试与基准测试绝不使用开发构建。内存、线程与并发问题的三种检查手段ASANAddressSanitizer——构建期插桩ASAN 是 clang/gcc 提供的构建期插桩在编译进库的代码中插入内存检查。启用方式$ ./dev-conf.sh asan之后照常运行测试。内存访问问题越界、use-after-free 等会实时输出到 stderr 并使测试最终失败内存泄漏则在测试运行成功退出时报告。若测试失败导致进程硬退出未做清理会产生大量泄漏报告——这些应忽略泄漏报告只在套件整体通过时有意义。两点注意OSX 版 ASAN 无泄漏检测需在 Linux原生或 Docker上跑ASAN、TSAN 与 valgrind互斥不能混用。Valgrind——虚拟机级内存检查Valgrind 拦截未修改程序的全部内存访问可报告访问违规、use-after-free、泄漏等提供比 ASAN 更全面的检查常用于 ASAN 无能为力时的崩溃/泄漏排查。使用前需保证 librdkafka 与测试套件是无任何插桩的干净构建不能带 ASAN/TSAN然后运行$ ./run-test.sh valgrind从 run-test.sh 源码可以看到valgrind 模式实际执行--leak-checkfull --show-leak-kindsall --errors-for-leak-kindsdefinite,possible --track-originsyes --track-fdsyes并配合 librdkafka.suppressions 抑制误报--exit-on-first-errorno让所有真实错误都被报告出来。helgrind线程检查、drd、cachegrind/callgrind 等模式同样通过./run-test.sh调用。Valgrind 仅支持 Linux。TSANThreadSanitizer——线程与锁问题librdkafka 内部有大量线程通过 op 队列、条件变量、互斥锁与原子操作通信和共享状态。源码注释虽标明了加锁要求但人工验证锁是否正确、以正确顺序获取避免死锁非常困难TSAN 正是为此而生$ ./dev-conf.sh tsan之后照常运行建议并行。TSAN 将线程错误输出到 stderr 并最终使测试失败。若 TSAN 信息不足可改用 helgrind./run-test.sh helgrind。资源使用阈值检查实验特性给test-runner传-R选项或使用make rusagetarget后测试框架会监控每个测试的资源使用超出默认或测试专属阈值即判失败。每个测试的专属阈值在test.c中用_THRES()宏指定例如 test.c 中的_THRES(.ucpu 100.0, .scpu 20.0, .rss 900.0)、_THRES(.ucpu 15.0)等。当前监控的资源资源含义默认阈值utime用户态 CPU 时间秒1.0sstime系统/内核态 CPU 时间秒0.5srssRSS 内存使用10.0 MBctxsw自愿上下文切换次数如系统调用10000测试成功完成后会输出一行资源使用摘要例如Test resource usage summary: 20.161s (32.3%) User CPU time, 12.976s (20.8%) Sys CPU time, 0.000MB RSS memory increase, 4980 Voluntary context switchesCPU 阈值基于基准机Intel Core i7-2600 3.40GHz8 核观察制定。由于各开发环境性能不同可用-RC传入本机相对基准机的 CPU 校准值默认 1.0小于 1.0 表示本机更快大于 1.0 表示更慢。例如 i5 机器传-R2.0允许更高 CPU 占用更快的机器传-R0.8。该值也可用TEST_CPU_CALIBRATION1.5环境变量设置。注意资源阈值检查会串行运行测试无法并行以保证逐测试测量的准确性。文档亦注明这是实验特性未来理想目标是自动校准。PR 与 Release 的完整验证提交 PR 前必须验证代码变更没有引入回归或新问题需要在多种模式下运行测试套件PLAINTEXT 与 SSL 传输全部 SASL 机制PLAIN、GSSAPI、SCRAM、OAUTHBEARER所有测试开启幂等idempotence内存检查ASAN/Valgrind线程检查TSAN/helgrind与旧版本 Broker 的兼容性。这些测试同样需在每个 release candidate 上运行。一条命令即可触发$ make release-test该命令大约耗时30 分钟。从 tests/Makefile 可见其完整组成各子 target 串行执行release-test: | asan tsan pristine-full scenarios compat即依次执行ASAN 测试 → TSAN 测试 → 干净 release 构建下的make full→ 非默认场景noautocreate ak23→ 多 Broker 版本兼容测试。务必在 Linux 上运行保证 ASAN 与 Kerberos 测试正常不要在 OSX 上执行。特定测试模式与完整套件以下小节均依赖已安装的 trivup。多 Broker 版本兼容测试为确保跨所有受支持 Broker 版本的兼容性完整套件会在 trivup 集群中按相关 Broker 版本逐一运行$ ./broker_version_tests.pytests/Makefile 中的COMPAT_KAFKA_VERSIONS默认覆盖0.8.2.2 0.9.0.1 0.11.0.3 1.0.2 2.4.1 2.8.1以及当前KAFKA_VERSION默认 3.4.0make compat即运行这套回溯兼容测试。SASL 测试SASL 测试需要在 Broker 上做额外配置自动化方式是让整个套件跑在 trivup 集群上$ ./sasl_tests.py完整套件与幂等 Producer 测试# 运行全部测试含 broker 版本与 SASL 测试等 $ make full注意make full是更完整的make release-test的子集full: broker broker_idempotent sasl。幂等 Producer 测试以enable.idempotencetrue运行整个套件使用make idempotent_seq串行或make idempotent_par并行。启用幂等时部分测试会被跳过或微调。手工测试记录以下测试目前仍以手工方式执行未来应实现为自动化测试。LZ4 互操作测试$ ./interactive_broker_version.py -c ./lz4_manual_test.py 0.8.2.2 0.9.0.1 2.3.0检查输出并按提示操作仓库 tests 目录中提供 lz4_manual_test.sh 等辅助脚本。测试编号一览区间类型0000-0999自动化测试make自动运行8000-8999手工测试仓库中同时存在1000-1999区间的特殊环境测试如 1000-unktopic.c与8000开头的手工测试如 8000-idle.cpp、8001-fetch_from_follower_mock_manual.c与 README 中0000-0999 自动运行、1000-1999 特殊配置、8000-8999 手工的编号体系相互印证。作为 Fluent Bit 项目集成的 Kafka 客户端库librdkafka 的这套测试体系覆盖了从单元测试、协议/集群集成测试到内存/线程/资源消耗的完整质量保障链路。无论是排查线上 Kafka 连接问题、为 Fluent Bit 的 Kafka 输出插件调试底层行为还是向上游贡献测试都可以直接复用本文所述的 trivup 集群、make运行框架与 sanitizer 校验流程。相关实现与入口均可在 lib/librdkafka-2.15.0/tests 目录下查阅。【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考