拓冰建站拓冰建站
首页 / 资讯中心 / 正文

zstd 回归测试(Regression tests)完全指南:从 nightly 守护到 results.csv 重建

zstd 回归测试Regression tests完全指南从 nightly 守护到 results.csv 重建【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongozstd 的回归测试框架通过固定数据集、固定压缩配置与多种压缩 API 组合持续监控压缩后的总字节数防止任何改动悄悄劣化压缩率。本文以 src/third_party/zstandard/zstd/tests/regression/README.md 为核心结合框架源码逐层拆解其数据缓存、配置矩阵、方法Method抽象与结果比对机制并给出完整的本地重建results.csv实战步骤帮助读者在遇到 nightly 失败时快速判断是真回归还是基线更新。一、回归测试在做什么回归测试regression tests的核心思想非常朴素用大量固定场景反复运行 zstd并确保压缩结果的体积不发生变化。也就是说它守护的是 zstd 的压缩率compression ratio——这是压缩库最宝贵的资产之一。任何一个提交如果让某个场景的压缩输出变大都可能意味着压缩率回退需要开发者立刻察觉并定位。从 test.c 的main()可以看出整个测试流程由四个阶段组成parse_args()解析命令行参数are_names_bad()校验各模块method / data / config的名字里不能包含逗号因为逗号会破坏 CSV 格式并顺便统计最长名字以对齐输出列宽method_set_zstdcli()设置 zstd CLI 路径、data_init()初始化必要时下载测试数据集run_all()遍历所有method × data × config组合把每个组合的压缩总字节数写入输出文件。每个数据、配置、方法三元组的唯一产物是Total compressed size压缩后的总字节数逐行追加写进results.csv同时实时回显到 stderr。这就是整个回归测试的输出格式——一张巨大的矩阵表。二、测试怎么跑CI 与本地两种途径2.1 每天深夜的 CircleCI 巡检README 明确指出这些测试每晚由 CircleCI 自动执行。这意味着任何合并进主干的改动第二天一早就会被这套矩阵跑一遍如果 job 失败先阅读 job 打印的 diff判断这次改动到底是不是压缩率回退如果确认一切正常比如有意识地调整了默认参数、更新了数据集或修复了 bug 改变了输出可以下载results.csv构建产物并把新结果作为新的基线提交或者完全在本机按照下面的流程自行重建results.csv。2.2 本地重建 results.csvREADME 原始步骤README 给出了从 zstd 仓库根目录开始的标准流程在本仓库中zstd 仓库根目录即src/third_party/zstandard/zstd/# 构建 zstd 二进制 make clean make -j zstd # 构建回归测试二进制 cd tests/regression make clean make -j test # 运行回归测试 ./test --cache>for (size_t method 0; methods[method] ! NULL; method) for (size_t datum 0; data[datum] ! NULL; datum) for (size_t config 0; configs[config] ! NULL; config) // 跳过不适用的组合然后压缩并记录 total_size3.1 Data被压缩的固定数据集data.c 中定义了 4 个数据对象数据名类型是否有字典silesia目录dir否silesia.tar文件file否github目录dir是github.dictgithub.tar文件file是github.dict每个数据对象都带有一个固定的 XXH64 校验和。这些数据不是随测试一起提交的而是在data_init()首次运行时由 libcurl 自动下载源码通过curl_easy_perform下载、popen(zstd -dc | tar -x -C ...)现场解压还原下载过程中curl_write回调会边写文件边累积 XXH64 哈希下载完成后与期望的xxhash64比对不一致即报错——这保证了全世界任何机器上跑出来的结果都基于逐字节完全相同的输入数据。缓存的复用依赖缓存目录里的STAMP文件stamp_check()用所有数据的名字、哈希、类型计算一个汇总 XXH64 哈希与STAMP中记录的值比对匹配则直接复用已有数据输出 stamp matches: reusing the cached data不匹配或不存在则重新下载并写新STAMP。这是可以反复重跑且结果可复现的关键机制。3.2 Config压缩配置矩阵config.c 用 C 宏批量生成了覆盖范围极广的配置每个 config 同时携带面向 CLI 的cli_args和面向高级 API 的param_valuesZSTD_cParameter → value键值对。主要配置族包括快速档位FAST_LEVEL(5/3/1)即level -5 / -3 / -1对应 CLI 参数--fastN标准档位LEVEL(0/1/3/4/5/6/7/9/13/16/19)其中 0 表示默认档每个档位都衍生出 5 个带字典的变体with dict普通字典with dict dmsZSTD_c_enableDedicatedDictSearch0ZSTD_dictForceAttach强制 Attach 字典、禁用专用字典搜索with dict ddsZSTD_c_enableDedicatedDictSearch1ZSTD_dictForceAttach启用专用字典搜索with dict copyZSTD_dictForceCopy强制复制字典with dict loadZSTD_dictForceLoad强制加载字典行哈希row hash变体ROW_LEVEL(5/7/11/12, 1/2)分别强制启用/禁用ZSTD_c_useRowMatchFinder覆盖 16/32/64 行条目row entries三种形态用于守护行哈希匹配器这个较新的实现路径特殊场景no source size不声明源大小、long distance mode--long、multithreaded-T2、multithreaded long distance mode-T2 --long、small window logwlog10、small hash log、small chain log、explicit params显式指定 strategy/wlog/hlog/clog/tlen、uncompressed literals--no-compress-literals、uncompressed literals optimal-19组合、huffman literals、multithreaded with advanced params。具体档位清单定义在 levels.h 中注释说明了选取原则所选档位要能触发每种 strategy 在各种源大小下的路径外加若干快速档和默认档。其中config_skip_data()负责矩阵剪枝凡是use_dictionary1而数据没有字典的config, data组合都会被跳过避免无意义的空跑。3.3 Method压缩 API 的多种调用方式method.c 定义了 10 种 method本质是zstd 各种压缩 API 的调用入口它们都应产生一致或可预期的输出体积Method 名对应实现覆盖的 APIcompress simplesimple_compress单次ZSTD_compress/ZSTD_decompresscompress cctxcompress_cctx_compressZSTD_compressCCtx/ZSTD_compress_usingDict/ZSTD_compress_advancedzstdclicli_compress直接 fork 出zstd -cqr args ...子进程advanced one passadvanced_one_pass_compressZSTD_compress2一次压缩advanced one pass small outadvanced_one_pass_compress_small_output输出缓冲区容量刻意少 1 字节的ZSTD_compress2考验动态扩容路径advanced streamingadvanced_streaming_compressZSTD_compressStream2流式压缩old streamingold_streaming_compress旧版ZSTD_compressStream/ZSTD_endStreamold streaming advancedold_streaming_compress_advanced旧版高级参数流式接口old streaming cdictold_streaming_compress_cdictZSTD_createCDict 流式字典压缩old streaming advanced cdictold_streaming_compress_cdict_advancedZSTD_createCDict_advanced 流式高级压缩method_t是一个典型的接口 状态结构create()负责做只跟数据有关的昂贵准备工作比如把整个数据集读进内存、预分配ZSTD_compressBound大小的输出缓冲compress()逐 config 执行压缩并返回result_tdestroy()释放状态。buffer_state_t通过container_of宏把各方法共用的缓冲区挂在基类method_state_t之下实现缓冲区在多次压缩调用间的复用。特别值得说明的是压缩后解压回环校验多数方法simple、cctx、advanced、old streaming 等在记录压缩体积之前都会解压并逐字节比对输入输出data_buffer_compare。一旦回环不一致会返回round trip error。也就是说这套框架不只守护压缩率还守护压出来的东西必须能完好解回去的正确性。result_t的结果状态在 result.c 中可查okay、skip组合被有意跳过如 CLI 方法不支持 advanced-only 配置、system error、compression error、decompression error、round trip error。这些错误字符串会直接以文本形式写入 CSV 的 Total compressed size 列因此查看results.csv时也能一眼看到哪些组合是 skip 或报错。四、results.csv一张 1480 行的基线矩阵仓库中已提交的基线文件 results.csv 共 1480 行表头为Data, Config, Method, Total compressed size从开头部分可以看到典型行silesia.tar, level -5, compress simple, 6861055 silesia.tar, level 3, compress simple, 4854086 silesia.tar, level 19, compress simple, 4265911 github.tar, level 19, compress simple, 32276规律一目了然同一数据同一方法下压缩级别越高-5 → 3 → 19总压缩体积越小6861055 → 4854086 → 4265911这正是 zstd 压缩率与速度权衡曲线的直接体现。这张表就是压缩率回归的黄金基线——任何改动如果让这些数字普遍变大就需要警惕。五、遇到失败怎么处理当 CI 报错时按 README 的指引分两步走读 diff对比 job 打印出的新旧结果差异。如果只有个别组合的数字变化先判断是否与本次改动有关例如动了字典策略、调整了默认参数、修复了特定 level 的匹配器确认无误后更新基线下载results.csvartifact或者按第三节的本地流程重建git diff检查无异常后连同代码改动一起提交 PR。这里需要特别强调提交纪律提交新 results.csv永远不应该是掩盖回归的借口。只有当你确信输出体积变化是本次改动的预期结果例如新增了压缩级别、数据集的 XXH64 哈希因为换数据而更新、修复 bug 使某个场景的压缩率提升时才应更新基线否则数字变大就意味着压缩率回退应当回头修复实现而不是更新基线。六、构建与运行前提Makefile 揭示了编译期依赖依赖 libcurl通过curl-config --cflags / --libs自动探测用于下载测试数据依赖 zstd 库本体与xxhash、util等内部模块编译时通过-I$(PROGDIR) -I$(LIBDIR)指向../../programs与../../libtest目标会先构建libzstd.a-mt再静态链接出最终二进制。因此本地重建前需要保证系统安装了 curl 开发库zstd 源码树完整本仓库内位于src/third_party/zstandard/zstd/首次运行有网络权限下载回归数据集之后由STAMP缓存复用。整个流程的产物test二进制与results.csv都在src/third_party/zstandard/zstd/tests/regression/目录内生成方便git diff直接审阅。七、小结zstd 的回归测试框架用固定数据 × 丰富配置 × 多 API 调用方式构成一张高覆盖矩阵用Total compressed size这一个简单到极致的指标守护压缩率并用results.csv作为可提交、可 diff、可审计的基线。理解data.c的缓存与校验、config.c的宏展开配置矩阵、method.c的 API 覆盖策略之后无论是本地重建基线、定位 CI 失败还是未来为 zstd 新增压缩路径时补齐回归覆盖都有章可循。若想继续深入可依次阅读 data.h、config.h 与 method.h 的接口注释再对照 test.c 的主循环把整条链路串起来。【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门