资讯动态

如何为PostgreSQL扩展构建完整测试体系?pg_pathman三层测试方案详解

发布时间:2026/8/22 14:47:41 来源:尧图企业网站定制
如何为PostgreSQL扩展构建完整测试体系pg_pathman三层测试方案详解【免费下载链接】pg_pathmanPartitioning tool for PostgreSQL项目地址: https://gitcode.com/gh_mirrors/pg/pg_pathmanpg_pathman 是一个经典的 PostgreSQL 分区工具扩展它不仅实现了 RANGE / HASH 分区、分区自动创建等核心功能更值得学习的是它构建的一套完整测试体系回归测试、cmocka 单元测试与 Python 集成测试三层防线配合 Docker 一键执行和代码覆盖率统计堪称 PostgreSQL 扩展测试的教科书级范例。本文带你从零看懂这套体系是怎么搭起来的。 全景图pg_pathman 的四层测试防线在动手之前先看清整个测试架构。pg_pathman 的测试由四类组成测试类型位置作用是否需要数据库SQL 回归测试sql/expected/验证 SQL 语句的实际输出需要隔离并发测试specs/验证多会话并发行为需要cmocka 单元测试tests/cmocka/纯 C 层面测试内部算法不需要Python 集成测试tests/python/验证回归测试覆盖不到的场景需要入口脚本run_tests.sh按顺序驱动以上全部流程最后生成覆盖率报告。这种分层 单入口的设计是新手搭建测试体系最值得抄的作业。️ 第一层回归测试——用 SQL 对答案回归测试是 PostgreSQL 扩展的标配pg_pathman 在 Makefile 中通过REGRESS变量注册了 30 多个测试用例如pathman_basic、pathman_inserts、pathman_hashjoin等。它的工作方式非常直观sql/目录下每个.sql文件是一段操作脚本比如 sql/pathman_basic.sql 会创建分区表并执行各种查询测试框架把每条语句在真实数据库里跑一遍把实际输出与expected/目录下同名的期望文件逐行对比不一致即失败。这种录制-回放-对答案的模式有三个优点门槛低会写 SQL 就能写测试可读性强期望文件本身就是一份行为文档防回归任何一次修改导致输出变化都会立刻暴露。细节加分项防止冗余期望文件pg_pathman 还配了一个小技巧脚本 expected/test_variants.shPostgreSQL 支持为同一测试生成带数字后缀的多个输出文件如xxx_1.out、xxx_2.out该脚本会自动diff这些变体如果发现内容完全相同就报警告防止测试文件越积越多、互相冗余。这是很多项目容易忽略的测试卫生细节。⚔️ 第二层隔离测试——把并发场景钉死并发行为是分区场景的重灾区两个事务同时插入数据、一个提交一个回滚后台工作进程该建几个分区这类问题用回归测试根本测不出来。pg_pathman 使用 PostgreSQL 自带的隔离测试框架在 specs/ 目录下放置测试脚本例如 specs/insert_nodes.spec 定义了s1、s2两个会话每个会话拆成多个 step开始事务、插入、回滚、查看分区再用permutation枚举出各种执行顺序s1 回滚、s2 提交 → 验证只建出 s2 数据所需的分区两个都回滚 → 验证分区不落地。给新手的建议凡是涉及多事务 自动创建分区之类的逻辑都建议用隔离测试把关键排列组合固定下来而不是靠人工手动试。 第三层cmocka 单元测试——不启动数据库也能测纯 C 写的内部算法比如把一堆区间合并去重的 rangeset 数据结构如果必须启动完整数据库才能测效率极低。pg_pathman 的解法在 tests/cmocka/ 目录rangeset_tests.c 是真正的测试用例基于 cmocka 框架编写missing_list.c、missing_bitmapset.c等文件补齐了无法直接链接进测试程序的 PostgreSQL 基础数据结构实现编译时直接链接扩展源码里的src/rangeset.o测试二进制rangeset_tests独立运行完全不依赖数据库。这个目录的 Makefile 展示了关键技巧通过pg_config --includedir-server获取头文件路径再链接-lcmocka。新手做 C 扩展单元测试时把被测对象和最小依赖编译成独立程序这个思路完全可以照搬。 第四层Python 集成测试——补齐回归测试的盲区有些特性靠静态 SQL 对比根本验证不了例如分区创建后台任务BGW在并发压力下是否会重复建分区、大量并发插入时的边界行为、FDW 外部分区的联动等。这些场景由 tests/python/partitioning_test.py 承担。它基于testgres库一个能动态创建、配置、销毁 PostgreSQL 测试实例的工具核心套路用get_new_node()拉起临时数据库节点多线程 / 多进程并发执行 SQL模拟真实压力用断言检查最终状态分区数量、数据完整性、JSON 输出等。运行方式很简单先安装依赖再跑单测即可pip3 install testgres python3 -m unittest partitioning_test如果只想测某个特定编译版本的 PostgreSQL设置PG_CONFIG环境变量指向对应的pg_config即可不想测 FDW 部分时设置FDW_DISABLED1跳过。详细说明见 tests/python/README.md。 隐藏彩蛋升级一致性检查器分区工具经常要处理旧版本升级问题。pg_pathman 在 tests/update/ 目录提供了一组工具dump_pathman_objects.sql把扩展创建的所有对象 dump 成 SQLcheck_update.py自动执行ALTER EXTENSION pg_pathman UPDATE并对比升级后的数据库与全新安装的 dump 结果是否一致还有pgbench压力脚本tests/python/pgbench_scripts/用于辅助验证。这解决了一个很实际的问题升级路径不会悄悄改变数据库结构对用户来说是无感知的。 一键执行Docker 四级测试强度整套测试最优雅的地方在于一键运行。docker-compose.yml 只有一行服务定义配合 Dockerfile.tmpl 模板可以在任意 PostgreSQL 版本的基础镜像上搭建完整测试环境含 cmocka、valgrind、clang 静态分析等依赖。入口脚本run_tests.sh根据LEVEL环境变量提供四档强度新手可以按需选择强度包含内容适用场景standard编译 回归测试 Python 测试 cmocka 测试日常开发scan-build增加 clang 静态分析scan-build提交前体检hardcore重新编译带 cassert 断言的 PostgreSQL 内核深度验证nightmare用 valgrind 内存检查跑整个数据库发布前终极考验其中hardcore/nightmare档位会下载对应版本的 PostgreSQL 源码对 14 及以上版本还会应用 patches/ 目录下的核心补丁如REL_14_STABLE-pg_pathman-core.diff重新编译出一个带调试开关的数据库实例再跑测试——这就是跨版本兼容性的底气来源。覆盖率让测试是否充分可量化注意run_tests.sh中编译时始终带上了-coveragegcov参数测试跑完后执行gcov生成覆盖率文件再上传到覆盖率平台。这样每个 PR 都能直观看到这次改动覆盖了几个百分点的代码而不是凭感觉说我测过了。 给新手的 4 点借鉴分层别贪多SQL 能测的别上 Python纯函数逻辑别启动数据库每层解决自己的问题统一入口一个run_tests.sh 一个 Docker 文件让跑测试的成本降到一条命令测试也要做卫生像test_variants.sh那样定期检查测试资产是否冗余用数据说话接入 gcov 覆盖率统计让测试充分程度可度量、可追溯。pg_pathman 的这套体系回归 隔离 单元测试 集成 升级校验 覆盖率体量适中、职责清晰非常适合作为你自己 PostgreSQL 扩展项目的测试模板。【免费下载链接】pg_pathmanPartitioning tool for PostgreSQL项目地址: https://gitcode.com/gh_mirrors/pg/pg_pathman创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价