TimescaleDB 的 Perl TAP 测试框架:基于 prove 的端到端集成测试指南
时序数据库数据库关系型数据库【免费下载链接】timescaledbA time-series database for high-performance real-time analytics packaged as a Postgres extension项目地址https://gitcode.com/gh_mirrors/ti/timescaledb点击查看免费下载TimescaleDB 是构建在 PostgreSQL 之上的时序数据库扩展其测试体系由多种层次构成基于pg_regress的 SQL 回归测试、isolation tester 规范以及本文重点介绍的基于 Perl 的 TAPTest Anything Protocol测试。test/perl/目录承载了这套 TAP 测试的共享基础设施通过TimescaleNode类对 PostgreSQL 官方测试节点管理框架进行扩展让开发者可以用接近真实生产环境的方式启动独立 PostgreSQL 实例、创建 TimescaleDB 扩展并执行端到端场景断言。读完本文你将掌握如何在仓库中运行与编写 Perl TAP 测试、理解TimescaleNode的关键实现并能借助仓库内真实测试用例如流复制遥测、许可证切换回归快速上手编写自己的集成测试。一、TAP 测试在 TimescaleDB 测试体系中的定位TimescaleDB 的测试覆盖多个层次test/sql/下的 SQL 脚本由pg_regress驱动test/isolation/specs/下的场景由 isolation tester 执行而 Perl TAP 测试则用于那些难以用纯 SQL 表达的场景——例如多节点拓扑主备流复制、后台进程、崩溃恢复、并发竞争与 GUC 配置切换等。官方文档test/perl/README.md明确指出了一条编写原则只要能用pg_regress或 isolation tester 规范实现就应该优先使用这两种方式TAP 测试用于它们覆盖不了的场景。也就是说TAP 测试是最后的手段但同时也是最接近真实部署形态的手段——每个测试脚本都能自建一套完整、独立的 PostgreSQL 实例并安装扩展拥有完整的控制权。二、共享基础设施TimescaleNode 类test/perl/中唯一的共享模块是 TimescaleNode.pm它继承并扩展了 PostgreSQL 官方测试框架中的节点管理类加入了 Timescale 专属的配置参数和常用辅助函数。2.1 类层次与依赖从源码头部可以看到package TimescaleNode; use parent PostgreSQL::Test::Cluster; use PostgreSQL::Test::Utils qw(slurp_file);它直接以 PostgreSQL 的PostgreSQL::Test::Cluster为父类这是src/test/perl提供的官方基础设施对应 README 中提到的PostgresNode.pm文档因此自动获得节点初始化、启动/停止、备份、流复制、psql调用等能力。2.2 核心方法剖析create—— 一站式建节点类方法完成创建节点 → 初始化 → 启动 → 安装扩展的全流程是测试中最常用的入口sub create { my ($class, $name, %kwargs) _; my $self $class-new($name); $self-init(%kwargs); $self-start(%kwargs); $self-safe_psql(postgres, CREATE EXTENSION timescaledb); return $self; }调用TimescaleNode-create(primary, ...)后即可直接获得一个已运行且已创建timescaledb扩展的节点。init—— 注入 Timescale 专属配置在父类初始化数据目录后把模板配置文件追加进postgresql.conf并强制datestyleISO$self-SUPER::init(%kwargs); $self-append_conf(postgresql.conf, slurp_file($ENV{CONFDIR}/postgresql.conf)); $self-append_conf(postgresql.conf, datestyleISO);这里的$ENV{CONFDIR}指向 CMake 配置阶段生成的主测试配置文件其内容由 postgresql.conf.in 模板生成包含了一批测试专用的参数例如shared_preload_librariestimescaledb timescaledb.passfileTEST_PASSFILE timescaledb.licenseapache timescaledb.enable_compression_ratio_warningsfalse max_worker_processes24 wal_level logical注意该模板默认timescaledb.licenseapache因此需要 TSL 功能如压缩的 TAP 测试会在运行时自行覆盖此设置见后文 002 号测试。psql_is—— 三重断言封装一次性检查psql返回码、标准错误与标准输出三个维度是 TAP 测试中查询结果是否符合预期的标准姿势sub psql_is { my ($self, $db, $query, $expected_stdout, $testname) _; my ($psql_rc, $psql_out, $psql_err) $self-SUPER::psql($db, $query); PostgreSQL::Test::Cluster::ok(!$psql_rc, $testname: err_code check); PostgreSQL::Test::Cluster::is($psql_err, , $testname: error_msg check); PostgreSQL::Test::Cluster::is($psql_out, $expected_stdout, $testname: psql output check); }safe_psql/strip—— 去除空白干扰safe_psql在调用父类方法后剥掉结果首尾空白避免对齐差异导致断言误报sub strip { my ($str) _; $str ~ s/^\s|\s$//g; return $str; }2.3 模块的安装与分发test/perl/CMakeLists.txt 负责把该模块安装到 PostgreSQL 的 PGXS 测试目录供全仓库包括tsl/的测试脚本统一引用set(PERL_FILES TimescaleNode.pm) # Check if PostgreSQL was compiled with --enable-tap-tests if(TAP_CHECKS AND EXISTS ${PG_PKGLIBDIR}/pgxs/src/test/perl) install(FILES ${PERL_FILES} DESTINATION ${PG_PKGLIBDIR}/pgxs/src/test/perl) endif()可以看到该安装行为受TAP_CHECKS开关控制对应根 CMakeLists.txt 中的option(TAP_CHECKS Enable TAP test support ON)并要求 PostgreSQL 以--enable-tap-tests编译。三、运行 TAP 测试3.1 通过 prove 与 make 目标执行所有 TAP 测试通过 Perl 的prove命令驱动。默认情况下t/子目录下的每个测试脚本都会被执行也可以只运行指定的一个或几个测试make provecheck PROVE_TESTSt/001_testname.pl t/002_othertestname.plPROVE_TESTS还支持正则表达式匹配例如只跑名称包含chunk的测试make provecheck PROVE_TESTSt/*chunk*这套调度逻辑实现在 pg_prove.sh 中未指定PROVE_TESTS时自动列出t/*.pl支持SKIPS环境变量做通配符排除最终通过-I把仓库的test/perl、PostgreSQL 的pgxs/src/test/perl等目录加入INC后调用provePG_VERSION_MAJOR${PG_VERSION_MAJOR} ${PROVE} \ -I ${SRC_DIR}/src/test/perl \ -I ${CM_SRC_DIR}/test/perl \ -I ${PG_LIBDIR}/pgxs/src/test/perl \ ... $FINAL_TESTS对应的 CMake 目标定义在 test/CMakeLists.txtprovecheck与 tsl/test/CMakeLists.txtprovecheck-t二者均受TAP_CHECKS门控。3.2 哪些测试被纳入构建test/t/CMakeLists.txt 只在Debug构建类型下列入两个主仓库 TAP 测试if(CMAKE_BUILD_TYPE MATCHES Debug) list(APPEND PROVE_TEST_FILES 001_replication_telemetry.pl 002_compressed_chunk_apache.pl) endif(CMAKE_BUILD_TYPE MATCHES Debug)TSL 侧的 tsl/test/t/CMakeLists.txt 则按功能与 PostgreSQL 版本条件化地收录了 7 个测试作业崩溃日志、逻辑复制解压标记、MVCC 连续聚合、自旋锁竞争、自定义 TOAST 等其中部分如003_mvcc_cagg.pl、005_recompression_spin_lock_test.pl同样仅在 Debug 构建下启用——这类测试对时序、内存布局敏感Debug 构建能提供更充分的检查。四、编写 TAP 测试4.1 测试脚本骨架官方 README 给出的标准开头是use strict; use warnings; use TimescaleNode; use TestLib; # Replace with the number of tests to execute: use Test::More tests 1;strict/warnings是 Perl 的强制卫生开关TimescaleNode提供 Timescale 专属基础设施TestLib是 PostgreSQL 官方测试工具库Test::More提供is、ok、like等断言tests N声明测试总数。同目录下的t/子目录内测试脚本按文件名首字符的字母顺序依次执行所以仓库内测试统一采用001_xxx.pl、002_xxx.pl这样的数字前缀来显式控制执行顺序。4.2 节点生命周期从启动到断言README 提供了最小可运行示例节点创建 → 启动 → 查询断言 → 停止my $node get_new_ts_node(access_node); $node-init; $node-start; my $ret $node-safe_psql(postgres, SELECT 1); is($ret, 1, SELECT 1 returns 1); $node-stop(fast);而在当前仓库的源码实现中更常见也更简洁的写法是直接使用TimescaleNode-create例如 002_compressed_chunk_apache.plmy $node TimescaleNode-create(compressed_apache); # Override the default apache license from the shared postgresql.conf # template so we can actually create and compress a hypertable. $node-append_conf(postgresql.conf, timescaledb.licensetimescale); $node-restart;create自动完成 init start CREATE EXTENSION timescaledb随后用append_confrestart调整 GUC这与 README 中一般需要设置一个或多个节点、对其运行命令并评估结果的描述完全对应。4.3 正则断言中的 Perl 兼容性陷阱README 特别提醒Test::More::like使用qr//运算符构造正则时不要在同一正则中同时使用$元字符与/m修饰符否则会触发 Perl 5.8.8 的 bug #39185。替代写法是把$换成\n或(?\n|\z)。例如要匹配多行输出中的某行结尾应写作like($output, qr/querying compressed data is not supported(?\n|\z)/m, ...);4.4 文档查阅Perl 基础断言能力perldoc Test::MorePostgreSQL 专属测试方法与示例进入 PostgreSQL 源码目录执行perldoc src/test/perl/PostgresNode.pm仓库内TimescaleNode的扩展能力可直接阅读 TimescaleNode.pm 源码五、仓库源码中的真实测试用例5.1 001_replication_telemetry.pl多节点拓扑与遥测test/t/001_replication_telemetry.pl 演示了 TAP 测试的典型重活搭建一主一备的流复制集群再验证遥测报告中的复制状态。my $node_primary TimescaleNode-create( primary, allows_streaming 1, auth_extra [ --create-role, repl_role ]); my $backup_name my_backup; # Take backup $node_primary-backup($backup_name); # Create streaming standby linking to primary my $node_standby PostgreSQL::Test::Cluster-new(standby_1); $node_standby-init_from_backup($node_primary, $backup_name, has_streaming 1); $node_standby-start; # Wait for standby to catch up $node_primary-wait_for_catchup($node_standby, replay, $node_primary-lsn(insert));随后通过get_telemetry_report()断言主备两端的num_wal_senders与is_wal_receiver字段——这种跨会话、跨进程的状态验证用纯 SQL 回归测试几乎无法完成正是 TAP 测试的价值所在。5.2 002_compressed_chunk_apache.pl许可证切换回归test/t/002_compressed_chunk_apache.pl 是针对 issue #7787 的回归测试当用户用 Timescale 许可证压缩了数据块随后把timescaledb.licenseGUC 切到apache时对超表的SELECT必须报出指向许可证的明确错误而不能静默返回未压缩数据块的近似空结果。测试流程清晰展示了 TAP 测试改配置 → 重启 → 断言错误的能力# 先切到 timescale 许可证创建并压缩数据 $node-append_conf(postgresql.conf, timescaledb.licensetimescale); $node-restart; $node-safe_psql(postgres, q[ CREATE TABLE metrics(time timestamptz NOT NULL, value float) WITH (tsdb.hypertable); INSERT INTO metrics SELECT generate_series(2023-01-01::timestamptz, 2023-01-03::timestamptz, 1 hour::interval), random(); SELECT count(compress_chunk(c)) FROM show_chunks(metrics) c; ]); # 再切回 apache 许可证 $node-append_conf(postgresql.conf, timescaledb.licenseapache); $node-restart; my ($rc, $stdout, $stderr) $node-psql(postgres, SELECT count(*) FROM metrics); isnt($rc, 0, querying compressed hypertable under apache license errors); like($stderr, qr/querying compressed data is not supported/, error message points at the license);它同时示范了psql三返回值返回码、stdout、stderr的用法以及如何用append_conf覆盖 postgresql.conf.in 模板中的默认许可证。5.3 TSL 侧测试tsl/test/t/ 下的 7 个 TAP 测试进一步覆盖了作业崩溃日志001_job_crash_log.pl、逻辑复制解压标记002_logrepl_decomp_marker.pl、MVCC 连续聚合003_mvcc_cagg.pl、truncate/delete 自旋锁004_truncate_or_delete_spin_lock.pl等场景可作为编写复杂并发与后台任务测试的进阶参考。六、环境要求与格式化规范6.1 Perl 版本与依赖测试必须能在Perl 5.8.0 及以上运行需要IPC::Run模块prove命令可用。README 推荐使用perlbrew管理旧版 Perlperlbrew --force install 5.8.0 perlbrew use 5.8.0 perlbrew install-cpanm cpanm install IPC::Run安装后重新运行 configure确保测试使用正确的 Perl。验证方法grep ^PERL config.log6.2 前置构建条件所依赖的 PostgreSQL 必须以--enable-tap-tests编译否则pgxs/src/test/perl目录不存在TAP_CHECKS会被关闭根 CMakeLists.txt 中的检测逻辑会给出相应提示仓库构建时通过bootstrap脚本与 version.config 中的版本号驱动 CMake 配置。6.3 perltidy 格式化所有测试与测试工具都必须使用perltidy格式化遵循仓库根目录.perltidyrc配置perltidy --profile$TS_SRC_DIR/.perltidyrc /path/to/taptest这也是 TimescaleNode.pm 注释中特意说明使用换行防止 perltidy 做垂直对齐的原因——格式一致性是仓库 CI 的一部分。七、小结TimescaleDB 的 Perl TAP 测试体系由三块拼图构成官方 PostgreSQL 的src/test/perl节点管理框架、仓库自研的 TimescaleNode.pm注入postgresql.conf模板、封装psql断言以及prove/make provecheck的调度入口 pg_prove.sh。编写时遵循 README 的骨架与正则兼容性约定运行时通过PROVE_TESTS精确圈定用例即可用最贴近生产的方式验证多节点、跨会话、许可证切换与后台任务等 SQL 回归测试难以覆盖的复杂行为。赞分享时序数据库数据库关系型数据库【免费下载链接】timescaledbA time-series database for high-performance real-time analytics packaged as a Postgres extension项目地址https://gitcode.com/gh_mirrors/ti/timescaledb点击查看免费下载相关推荐Cog 集成测试框架完全指南基于 testscript 与 txtar 的端到端测试体系Cog 集成测试框架完全指南基于 testscript 与 txtar 的端到端测试体系 本文深入讲解 CogContainers for machineMLOps容器模型推理服务开发工具Milvus 集成测试框架实战指南基于 MiniClusterV3 的端到端测试编写与运行Milvus 集成测试框架实战指南基于 MiniClusterV3 的端到端测试编写与运行 本文基于 Milvus 仓库的 tests/integration数据库向量数据库分布式数据库后端curl测试框架单元测试、集成测试、端到端测试curl测试框架单元测试、集成测试、端到端测试 概述 curl作为业界领先的网络传输工具和库其测试框架经过多年发展已形成一套完整的多层次测试体系。本文深入解CLI网络通信上一篇Swin Transformer图像分类模型在工业场景中的5个应用案例指南下一篇《20天吃掉那只Pytorch》项目安装与配置指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考