ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Databend 无状态测试(Stateless Tests)规范:目录结构、命名规则与测试运行机制全解析

Databend 无状态测试(Stateless Tests)规范:目录结构、命名规则与测试运行机制全解析 Databend 无状态测试Stateless Tests规范目录结构、命名规则与测试运行机制全解析【免费下载链接】databendData Agent Ready Warehouse : One for Analytics, Search, AI, Python Sandbox. — rebuilt from scratch. Unified architecture on your S3.项目地址: https://gitcode.com/GitHub_Trending/da/databend本篇技术指南聚焦 Databend 开源仓库中的无状态测试体系Stateless Tests以 tests/suites/0_stateless/README.md 为核心骨架结合测试运行器 tests/databend-test、CI 脚本与真实测试用例完整讲解测试目录的组织方式、xx_yyyy_test_name命名规范、十大测试分类、.sql/.sh/.py三种测试载体以及结果比对与并行执行等底层运行机制。读完本篇你将掌握如何为 Databend 编写合规、可复现的无状态测试用例并理解测试框架从收集、执行到结果校验的完整链路。一、无状态测试在 Databend 测试体系中的定位Databend 仓库在tests/suites/下按测试场景划分了多套测试套件suite从目录命名即可窥见其分层设计tests/suites/ ├── 0_stateless/ # 无状态测试不依赖预置数据自建自清 ├── 1_stateful/ # 有状态测试依赖预置数据集 ├── 3_stateful_iceberg/ # Iceberg 目录/外部目录相关有状态测试 ├── 3_stateful_paimon/ # Paimon 相关有状态测试 ├── 4_stateful_large_data/# 大数据量有状态测试 ├── 5_ee/ # 企业版EE功能测试 └── 7_management/ # 管理面Management Mode测试其中0_stateless是开发迭代最频繁、覆盖面最广的基础套件。所谓无状态是指每个测试用例自行负责数据的创建与清理——测试启动前不依赖任何预置数据或外部数据集测试结束后的残留也由用例自行处理从而保证用例之间相互独立、可任意排序、可并行执行。从运行器 tests/databend-test基于 Apache 协议的 clickhouse-test 改造而来的实现看每个以数字开头命名的目录都会被识别为一个 suite通过--run-dir 0_stateless可以只运行无状态套件这正是 CI 中的典型用法。二、测试目录结构原文档给出了测试目录的组织范式like this 示例00_dummy/ ├── 00_0000_dummy_select_1.result ├── 00_0000_dummy_select_1.sql ├── 00_0000_dummy_select_sh.sh ├── 00_0001_select_with_stackoverflow.result ├── 00_0001_select_with_stackoverflow.sql ├── 00_0002_dummy_select_py.py ├── 00_0002_dummy_select_py.result └── 00_0002_dummy_select_sh.result归纳为以下规则一个测试用例 一个执行文件.sql/.sh/.py 一个同名的.result期望结果文件所有测试文件平铺在分类目录下同名文件共享同一个测试名xx_yyyy_名称目录名以数字前缀开头例如00_dummy、03_dml、20_others运行器会递归收集子目录中的测试见 tests/databend-test 中get_all_tests_under_dir_recursive函数因此测试也可以按需放入子目录分组。当前仓库tests/suites/0_stateless/实际包含以下分类目录00_dummy、01_transaction、02_ddl、03_dml、05_hints、10_drivers、12_time_travel、16_flashback、17_altertable、18_rbac、19_fuzz、20_others可以看出分类体系随项目演进处于持续演化中下文详述。三、测试命名规范xx_yyyy_test_name原文档明确规定测试名称必须遵循三段式格式xx_yyyy_[test_name]xx分类编号category number即该测试所属主题类别yyyy该分类下的序号sequence number从0000开始递增[test_name]描述性的测试名称。该规范不仅是文档约定更是运行器的硬性校验。在 tests/databend-test 中运行器会对收集到的每一个测试文件做正则校验^[0-9]_[0-9]_(.*)$不满足该模式的文件会被判为 Illegal test case names并直接以非零退出码终止整个测试运行sys.exit(1)。因此新增测试时文件命名必须形如02_0001_autoincrement.sql、10_0000_python_mysql_driver.py缺一个下划线或序号段都会导致整次测试失败。此外命名中的序号段还承担执行顺序职责运行器按分类号优先、序号其次对测试排序key_func解析xx_前缀并转为整数排序同一分类内的用例按 yyyy 从小到大依次执行这对存在先后依赖关系的用例例如先建表后查询至关重要。四、测试分类体系原文档列出的标准分类如下分类编号目录名测试内容0000_dummyDummy 测试框架冒烟/示例0101_systemSystem 系统表测试0202_function函数测试0303_dmlSELECT、INSERT、UPDATE、DELETE测试0404_explainEXPLAIN测试0505_ddlDDL 测试0606_showSHOW语句测试0707_useUSE语句测试0808_optimizer优化器测试0909_fuse_engineFUSE存储引擎测试1010_drivers驱动集成测试2020_others其他测试文档特别注明If your test is not in the above category, please add it——即分类体系是开放的不属于现有分类的测试应新增编号与目录而不是硬塞进不相关的分类。对比当前仓库的实际目录01_transaction、05_hints、12_time_travel、16_flashback、17_altertable、18_rbac、19_fuzz等可以推断随着 Databend 功能不断演进事务、Hint、时态旅行、闪回、RBAC 等能力的引入分类表在原文档基础上做了多次增补与调整——例如01_transaction承接了事务相关测试12_time_travel对应SHOW TABLES HISTORY等时态查询19_fuzz承载模糊测试而原01_system中的系统表测试能力大概率已被 tests/suites/1_stateful 与 sqllogictests 体系分流。因此阅读本文档时应将其视为基线与约定实际分类以仓库目录为准。五、三种测试载体.sql / .sh / .py运行器只收集三种扩展名的测试文件.sql、.sh、.py见collect_files_with_pattern中的.sql|.sh|.py模式它们分别对应三种测试写法1..sql文件纯 SQL 脚本最直观的形态直接书写 SQL 语句。以 tests/suites/0_stateless/12_time_travel/12_0002_time_travel_show.sql 为例DROP DATABASE IF EXISTS db12_0002; CREATE DATABASE db12_0002; USE db12_0002; CREATE TABLE t(c1 int); create view v_t as select * from t; show full tables from db12_0002; DROP TABLE t; show tables history like t; DROP database db12_0002;运行器对.sql文件的执行方式非常特别对应run_single_test函数sed /^\s*--/d {test} | {client} {options} {stdout} 21即先用sed剔除以--开头的注释行再通过客户端默认mysql --user default -s连接127.0.0.1:3307把整段 SQL 灌入执行标准输出与错误输出统一重定向到 stdout 文件作为结果比对的输入。2..sh文件Shell 脚本适合需要连接信息、环境变量或多次交互的场景。以 tests/suites/0_stateless/00_dummy/00_0003_dummy_select_sh.sh 为例#!/usr/bin/env bash CURDIR$(cd $(dirname ${BASH_SOURCE[0]}) pwd) . $CURDIR/../../../shell_env.sh echo SELECT 1;select 2;select 3; | bendsql_connect_root脚本通过sourcetests/shell_env.sh 获取运行环境QUERY_MYSQL_HANDLER_HOST、QUERY_HTTP_HANDLER_PORT等默认值并借助其中定义的bendsql_connect、bendsql_connect_user、bendsql_connect_root辅助函数发起查询。shell_env.sh中可以看到默认连接参数MySQL 处理端口3307、HTTP 处理端口8000同时设置了AWS_ACCESS_KEY_IDminioadmin等对象存储相关环境变量说明 Shell 测试可覆盖涉及外部存储的集成场景。3..py文件Python 脚本适合复杂断言、mock 外部依赖或驱动级集成验证。以 tests/suites/0_stateless/00_dummy/00_0002_dummy_select_py.py 为例它复用 tests/helpers/client.py 中封装的client类基于mysql命令行客户端默认连接127.0.0.1:3307from client import client client1 client(nameclient1, loglog) client1.run(select 1) client1.run(select 2) client1.run(select 3)同一文件还演示了结合moto库对 AWS S3 接口做本地 mock 的能力mock_aws装饰器可见 Python 载体可以覆盖 SQL 之外的存储协议、驱动行为等复杂场景例如 tests/suites/0_stateless/10_drivers/10_0000_python_mysql_driver.py 便用于验证 MySQL 驱动与 Databend 的兼容性。六、结果文件与比对机制每个测试必须配套同名的.result期望文件。运行流程如下执行测试将 stdout/stderr 重定向到.stdout临时文件若测试退出码为 0 且存在同名.result_filter文件则逐行按正则对输出做归一化替换re.sub(flt, repl, line)正则与替换值成对排列在过滤文件中用diff将最终 stdout 与.result比对一致则OK不一致则输出 unified diff默认上下文 3 行并判为FAIL若测试进程超时默认单用例超时 900 秒见--timeout判为Timeout失败支持--record参数用当前 stdout强制覆盖.result文件用于批量更新期望结果CI 中通常配合评审流程使用。.result_filter的价值在于屏蔽不稳定输出。例如 tests/suites/0_stateless/20_others/20_0016_udf_timestamp.result_filter 将形如2026-09-15 05:19:28.123456的时间戳正则替换为固定占位符yyyy-mm-dd HH:MM:SS.ssssss从而保证含CURRENT_TIMESTAMP等动态值的用例也能稳定通过 diff。Cluster 模式下还会优先使用test_name_cluster.result作为期望文件见--mode cluster相关逻辑。七、运行器 databend-test 的工作机制tests/databend-test 是承载这套规范的核心 Python 运行器其关键行为均与文档规范一一对应suite 识别扫描 suites 根目录仅接受匹配^[0-9]_(.*)$的目录作为 suite跳过.gitignore等杂项递归收集get_all_tests_under_dir_recursive从 suite 目录出发按深度优先递归所有以^[0-9]开头的子目录收集.sql/.sh/.py文件命名强校验对每个用例名执行^[0-9]_[0-9]_(.*)$正则校验非法命名直接终止运行有序执行按xx分类号、yyyy序号双重排序先运行新分类、分类内按序号升序跳过机制支持--skip按正则跳过用例、--skip-dir跳过整个目录、--run-dir仅运行指定目录存在用例名.disabled文件时默认跳过可用--disabled强制运行并行与分片--jobs控制进程池并行度--parallel n/total支持多机分片CI 中用于大规模并行加速--test-runs可让同一用例重复执行多次用于排查 flaky 测试结果输出运行结束打印[ OK ] / [ FAIL ] / [ UNKNOWN ] / [ SKIPPED ]状态汇总失败用例统一列出路径并以非零退出码结束便于 CI 门禁。运行器的全部命令行参数--suites/-q、--binary/-b、--client/-c、--timeout/-t、--record、--parallel、--jobs/-j、--mode、--database、--complete等均可通过python3 tests/databend-test --help查看--database默认为随机生成的test_XXXXXX库名输出中会统一归一化为default避免并行冲突。八、如何运行无状态测试方式一复用 CI 脚本仓库提供了现成的 CI 入口 scripts/ci/ci-run-stateless-tests-standalone.sh其核心调用为./databend-test --mode standalone --run-dir 0_stateless --print-time脚本前置步骤会通过 scripts/ci/deploy/databend-query-standalone.sh 启动单机 DatabendQuerydebug 版然后在tests目录下执行运行器。--print-time会在每个用例后打印耗时便于定位慢用例。方式二手动运行指定用例在已启动 DatabendQuery默认监听127.0.0.1:3307的前提下可针对性运行cd tests ./databend-test --mode standalone --run-dir 0_stateless --print-time 03_0016_update_with_lock末尾的test位置参数为正则表达式用于过滤指定用例名。集群模式只需将--mode改为cluster此时期望结果自动切换为_cluster.result对应 CI 脚本为 scripts/ci/ci-run-stateless-tests-cluster.sh。九、如何新增一个无状态测试完整步骤结合规范与源码新增用例的推荐流程如下选定分类根据主题在 tests/suites/0_stateless 下选择最贴切的目录如 DML 用03_dml、驱动集成用10_drivers若无合适分类遵循文档指引新增编号目录如11_xxx并在 README 分类表中补记确定序号查看目标目录内最大yyyy序号并 1例如03_0017_xxx编写用例按需选择载体——纯 SQL 交互用.sql涉及连接/环境用.sh复杂断言或 mock 用.py生成期望结果先用--record参数运行生成.result再人工核对结果文件内容是否符合预期严禁直接提交未经审查的记录结果稳定性处理若输出含时间戳、随机值等动态内容创建.result_filter做正则归一化可参考 tests/suites/0_stateless/20_others/20_0016_udf_timestamp.result_filter自测验证本地执行./databend-test --mode standalone --run-dir 0_stateless 你的用例名确认输出[ OK ]遵守命名红线确保文件名满足^[0-9]_[0-9]_(.*)$否则运行器会直接拒绝整轮测试。十、小结Databend 的无状态测试规范看似简单实则通过数字前缀分类 三段式命名 同名 result 比对三位一体的约定支撑起了上万用例的高效并行与稳定回归xx分类号划定边界、yyyy序号保证顺序、.result/.result_filter保证可判定性而 tests/databend-test 运行器将这套约定固化为可强制校验的规则。对于任何希望为 Databend 贡献测试或深入理解其 CI 质量体系的开发者掌握 tests/suites/0_stateless/README.md 所定义的这套规范是融入项目测试文化的第一步。【免费下载链接】databendData Agent Ready Warehouse : One for Analytics, Search, AI, Python Sandbox. — rebuilt from scratch. Unified architecture on your S3.项目地址: https://gitcode.com/GitHub_Trending/da/databend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表