AutoMQ 系统测试体系揭秘

01 前言

Apache Kafka 有着比较完备的自测体系。除了常规的单元测试和集成测试以外,Apache Kafka 还有着 1000+ 的“系统集成和性能测试”(以下简称系统测试)。系统测试会拉起一套真实的 Kafka 集群,并模拟用户使用 Kafka 集群的方式,进行消息的收发,并验证测试结果是否符合预期。整个流程可以实现自动化运行。

AutoMQ 继承了 Apache Kafka 的系统测试框架,并利用该框架保障代码的健壮性,以及对 Apache Kafka 的 100% 兼容性。本文将简要介绍系统测试的原理、演示系统测试过程,并给出 AutoMQ 对系统测试的实践。

02 系统测试框架介绍

2.1 基本信息

系统测试基于 ducktape[1] 框架,该框架旨在让开发者可以像使用单元测试一样编写系统测试的 case。ducktape 框架并不仅仅支持 Kafka 的系统测试。理论上,任意分布式系统都可以基于 ducktape 框架,搭建自己的系统测试体系。
Ducktape 提供如下特性:
ꔷ 保障测试隔离;
ꔷ 多种环境下(Docker、k8s、云厂商 VM)Service 的拉起和销毁;
ꔷ 自定义事件的触发(例如 Kafka node 的强制关机);
ꔷ 测试结果的收集和总结;
Apache Kafka 目前支持以下三种集成测试环境:
ꔷ Docker;
ꔷ 虚拟机;
ꔷ AWS EC2;

AutoMQ 主要使用的是 Docker 环境下的系统测试。在后续的内容中,我们默认系统测试的使用环境为 Docker,默认工程为 AutoMQ[2] 而非 Apache Kafka。

2.2 目录结构

系统测试的基本目录为工程主目录下的 tests 子目录。

主要的子目录包括:
ꔷ Docker:系统测试运行在 Docker 环境时,镜像的打包逻辑、测试的触发脚本等;
ꔷ kafkatest:系统测试的主目录,包含 Kafka 对 ducktape 框架的适配 Service、系统测试 case 等;
ꔷ spec:trogdor 的一些简单负载 example;
ꔷ unit:一些极简的测试,目前基本没有使用;

注:trogdor 是 Kafka 工程中定义的一个测试框架,系统测试中会利用该框架跑一些复杂的负载场景。

进一步地,kafkatest 的子目录包括:

ꔷ benchmarks:性能测试的 case;
ꔷ sanity_checks:较为基础的 case,主要验证简单生产消费、Kafka node 重启等基本场景;
ꔷ services:ducktape 的基本测试资源为 Service,本目录下是 Kafka 集群中各种测试资源对 Service 的实现,其中最重要的就是 KafkaService (对应的是 Kafka 集群);
ꔷ tests:Kafka 工程中各个模块的系统测试,包括 Kafka Client、Kafka Connect、Kakfa Core、Kafka Streams 和 Kafka Tools 等;

2.3 运行系统测试

Talk is cheap. 本小结将以“sanity_checks/test_verifiable_producer.py”中的“test_multiple_kraft_security_protocols” 测试 case 为例,实际跑一下系统测试。

在 AutoMQ 工程的主目录下,输入以下命令触发上述系统测试:

TC_GENERAL_MIRROR_URL="mirrors.ustc.edu.cn" TC_PATHS="tests/kafkatest/sanity_checks/test_verifiable_producer.py::TestVerifiableProducer.test_multiple_kraft_security_protocols" bash tests/Docker/run_tests.sh

其中 TC_GENERAL_MIRROR_URL 的设置是为了在国内环境下加速 Docker image 的打包,TC_PATHS 指定系统测试 case。

如果你此前没有打包过系统测试的 Docker image,上述命令会自动触发打包逻辑。之后自动触发指定的系统测试,测试的输出类似于:

206 actionable tasks: 206 up-to-date
Docker exec ducker01 bash -c "cd /opt/Kafka-dev && ducktape --cluster-file /opt/Kafka-dev/tests/Docker/build/cluster.json  ./tests/kafkatest/sanity_checks/test_verifiable_producer.py::TestVerifiableProducer.test_multiple_kraft_security_protocols "
/usr/local/lib/python3.9/dist-packages/paramiko/transport.py:236: CryptographyDeprecationWarning: Blowfish has been deprecated and will be removed in a future release"class": algorithms.Blowfish,
[INFO:2024-04-25 08:13:03,399]: starting test run with session id 2024-04-25--002...
[INFO:2024-04-25 08:13:03,400]: running 4 tests...
[INFO:2024-04-25 08:13:03,400]: Triggering test 1 of 4...
[INFO:2024-04-25 08:13:03,418]: RunnerClient: Loading test {'directory': '/opt/Kafka-dev/tests/kafkatest/sanity_checks', 'file_name': 'test_verifiable_producer.py', 'cls_name': 'TestVerifiableProducer', 'method_name': 'test_multiple_kraft_security_protocols', 'injected_args': {'inter_broker_security_protocol': 'PLAINTEXT', 'metadata_quorum': 'ISOLATED_KRAFT'}}
[INFO:2024-04-25 08:13:03,422]: RunnerClient: kafkatest.sanity_checks.test_verifiable_producer.TestVerifiableProducer.test_multiple_kraft_security_protocols.inter_broker_security_protocol=PLAINTEXT.metadata_quorum=ISOLATED_KRAFT: on run 1/1
[INFO:2024-04-25 08:13:03,425]: RunnerClient: kafkatest.sanity_checks.test_verifiable_producer.TestVerifiableProducer.test_multiple_kraft_security_protocols.inter_broker_security_protocol=PLAINTEXT.metadata_quorum=ISOLATED_KRAFT: Setting up...
[INFO:2024-04-25 08:13:03,426]: RunnerClient: kafkatest.sanity_checks.test_verifiable_producer.TestVerifiableProducer.test_multiple_kraft_security_protocols.inter_broker_security_protocol=PLAINTEXT.metadata_quorum=ISOLATED_KRAFT: Running...
[INFO:2024-04-25 08:13:37,574]: RunnerClient: kafkatest.sanity_checks.test_verifiable_producer.TestVerifiableProducer.test_multiple_kraft_security_protocols.inter_broker_security_protocol=PLAINTEXT.metadata_quorum=ISOLATED_KRAFT: Tearing down...
[INFO:2024-04-25 08:13:59,432]: RunnerClient: kafkatest.sanity_checks.test_verifiable_producer.TestVerifiableProducer.test_multiple_kraft_security_protocols.inter_broker_security_protocol=PLAINTEXT.metadata_quorum=ISOLATED_KRAFT: PASS
[INFO:2024-04-25 08:13:59,434]: RunnerClient: kafkatest.sanity_checks.test_verifiable_producer.TestVerifiableProducer.test_multiple_kraft_security_protocols.inter_broker_security_protocol=PLAINTEXT.metadata_quorum=ISOLATED_KRAFT: Data: None
[INFO:2024-04-25 08:13:59,447]: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
================================================================================
SESSION REPORT (ALL TESTS)
ducktape version: 0.11.4
session_id:       2024-04-25--002
run time:         3 minutes 50.640 seconds
tests run:        4
passed:           4
flaky:            0
failed:           0
ignored:          0
================================================================================
test_id:    kafkatest.sanity_checks.test_verifiable_producer.TestVerifiableProducer.test_multiple_kraft_security_protocols.inter_broker_security_protocol=PLAINTEXT.metadata_quorum=ISOLATED_KRAFT
status:     PASS
run time:   56.010 seconds
--------------------------------------------------------------------------------
...

可以看到成功触发了 4 个系统测试,测试全部成功。
在工程的主目录下的 results 目录下,可以看到测试的详细产物:

.
├── TestVerifiableProducer #测试类
│   └── test_multiple_kraft_security_protocols # 测试类中的方法
│       ├── inter_broker_security_protocol=PLAINTEXT.metadata_quorum=ISOLATED_KRAFT # 测试方法的参数信息
│       │   └── 1
│       │       ├── KafkaService-0-281473792730304 # controller节点群
│       │       │   └── ducker02
│       │       │       ├── info # 日志信息
│       │       │       │   ├── controller.log
│       │       │       │   ├── Kafka-authorizer.log
│       │       │       │   ├── Kafka-request.log
│       │       │       │   ├── log-cleaner.log
│       │       │       │   ├── server.log
│       │       │       │   └── state-change.log
│       │       │       └── server-start-stdout-stderr.log
│       │       ├── KafkaService-1-281473792730160 # broker节点群
│       │       │   └── ducker03
│       │       │       ├── info
│       │       │       │   ├── controller.log
│       │       │       │   ├── Kafka-authorizer.log
│       │       │       │   ├── Kafka-request.log
│       │       │       │   ├── log-cleaner.log
│       │       │       │   ├── server.log
│       │       │       │   └── state-change.log
│       │       │       └── server-start-stdout-stderr.log
│       │       ├── MiniKdc-0-281473793298144
│       │       │   └── ducker05
│       │       │       └── minikdc.log
│       │       ├── VerifiableProducer-0-281473792730400 # 消费者日志
│       │       │   └── ducker04
│       │       │       └── verifiable_producer.log
│       │       ├── report.json
│       │       ├── report.txt
│       │       ├── test_log.debug
│       │       └── test_log.info # 测试过程的 std 信息
├── report.css
├── report.html # 测试的整体结果报告
├── report.json
├── report.txt
├── report.xml
├── session_log.debug
└── session_log.info

对于成功的测试,只会保留 info 级别日志;对于失败的测试,还会保留 debug 级别的日志。

使用以下命令销毁测试容器:

./tests/Docker/ducker-ak down

2.4 细节信息

默认情况下,系统测试会启动 14 个 ducker 容器 ducker01 ~ ducker14(前文中打包的测试镜像的实例) + 1 个 S3 服务容器。所有 ducker 容器只负责一个职能,即作为 Kafka 节点、 producer、consumer 等。其中 ducker01 为管控容器,负责拉起关闭 Kafka 节点、拷贝日志之类的操作。S3 服务容器使用了 localstack[3] 在本地模拟 S3 存储。

每个 ducker 容器会将宿主机上的工程主目录映射到容器的 /opt/Kafka-dev 下,默认测试的都是开发版本的 Kafka 代码。在 ducker 容器的 /opt 目录下,还可以看到其他版本的 Kafka 产物:

ducker@ducker01:/opt$ ls
kafka-0.10.0.1  kafka-0.10.2.2  kafka-0.8.2.2  kafka-1.0.2  kafka-2.0.1  kafka-2.2.2  kafka-2.4.1  kafka-2.6.3  kafka-2.8.2  kafka-3.1.2  kafka-3.3.2  kafka-3.5.2  kafka-3.7.0  kibosh
kafka-0.10.1.1  kafka-0.11.0.3  kafka-0.9.0.1  kafka-1.1.1  kafka-2.1.1  kafka-2.3.1  kafka-2.5.1  kafka-2.7.2  kafka-3.0.2  kafka-3.2.3  kafka-3.4.1  kafka-3.6.1  kafka-dev

在某些系统测试中,这些产物会用来验证 Kafka 各个版本的客户端和服务端能够互相兼容。

系统测试的过程大致可以分为以下步骤:

  1. 测试扫描:统计本次运行涉及的所有 case;

  2. 节点分配:从 14 个 ducker 容器中分配节点,这些节点将负责执行 Service 的实现(KafkaService、 VerifiableProducer、MiniKdc 等);

  3. Service 的启动:为了保证幂等性,一般是先做现场的清理(stop service、日志删除等),然后按照系统测试的配置启动 Service。

  4. 执行测试:所有 Service ready 以后,执行系统测试的详细逻辑;

  5. 收尾:一次测试结束后,记录测试的结果、拷贝测试过程中的日志,并清理现场(stop service、日志删除等)

需要注意的是,上述过程均由 ducker01 容器管控,管控的方式是 SSH 免密登录到目标容器,然后执行命令。集成测试的验证逻辑,例如生产消息的数目是否预期,也是基于 SSH 远程查询、解析来实现的。

另外,所有测试是串行执行的,会复用这 14 个 ducker 容器 + 1 个 S3 服务容器。

2.5 参数化测试

在软件测试中,参数化测试是一种常见的策略,它允许开发者使用不同的输入数据来执行相同的测试用例,从而实现更全面的覆盖。这种方法非常适合于需要测试多种输入组合的情况。Kafka的系统测试采用了这种优秀的测试参数注入设计。以其系统测试背后的一个例子为例,我们可以看到测试方法上有两种注解:
ꔷ @cluster:指定测试涉及的最大节点数;
ꔷ @matrix:测试参数注入;

@cluster(num_nodes=4)
@matrix(inter_broker_security_protocol=['PLAINTEXT', 'SSL'], metadata_quorum=[quorum.isolated_kraft])
@matrix(inter_broker_security_protocol=['SASL_SSL'], inter_broker_sasl_mechanism=['PLAIN', 'GSSAPI'],metadata_quorum=[quorum.isolated_kraft])
def test_multiple_kraft_security_protocols(self, inter_broker_security_protocol, inter_broker_sasl_mechanism='GSSAPI', metadata_quorum=quorum.isolated_kraft)

@matrix注解用于定义参数的可能值,它可以看作是一个参数的集合。例如,@matrix(inter_broker_security_protocol=[‘PLAINTEXT’, ‘SSL’], metadata_quorum=[quorum.isolated_kraft]) 这个注解表示方法参数 inter_broker_security_protocol 可以分别取值 ‘PLAINTEXT’ 和 ‘SSL’,而 metadata_quorum 取值为 quorum.isolated_kraft。这样,就形成了一个2 * 1的测试矩阵,即两种可能的测试场景。

如果存在多个 @matrix 注解,那么会生成一个包含所有可能组合的测试矩阵。例如,在这个例子中,test_multiple_kraft_security_protocols 方法使用一份代码构造了21 + 12*1 = 4种测试场景。

这种矩阵式的测试参数方法有一个显著的优点,那就是它可以大大减少重复的代码。通过使用参数化测试,开发者可以用一份代码来测试许多不同的场景,从而提高代码的可重用性,同时也提高了测试的效率和覆盖率。

03 AutoMQ系统测试现状

AutoMQ 完全适配并继承了 Apache Kafka 的系统测试。由于 AutoMQ 使用 S3 作为主要存储, 所以系统测试中引入了 S3 服务容器,并在测试之间清理 S3 的数据(以保证测试隔离)。

系统测试很好地监督了 AutoMQ 的代码改动,确保其对 Apache Kafka 保证100%的兼容性。例如,ISSUE-751[4] 中,QuotaTest 及时发现了此前 AutoMQ 对网络层模型的修改带来的衍生问题。

AutoMQ 目前只支持 KRaft 模式下启动 Kafka 集群,因此我们更关注 KRaft 模式下的系统测试。除了适配已有的系统测试 case,在 2024 年 1 月,我们还全量改造了所有 case 以支持 KRaft 模式的测试:由于 Kafka 早期是基于 zk 集群运行的,大量系统测试还是仅限 zk 模式下运行的,我们梳理并改造了相关测试,以支持 KRaft 模式下的验证。

截止到 2024 年 4 月,AutoMQ 共有 543 个系统测试案例(其余基本都是 zk 模式的测试,或者已经废弃的测试)。自 2023 年以来,系统测试每日由 github action 触发,并自动报告测试的结果:

注:上图是 Kafka Connect 模块中系统测试概览报告,并不是全量的报告。你也可以通过 [5] 和 [6] 查看 AutoMQ main 分支下的代码每天全量系统测试的结果。

利用系统测试,AutoMQ 可以确保 0.9.x 版本以来的 Kafka 客户端与 AutoMQ 的兼容性,以及 Kafka Connect 等衍生产品与 AutoMQ 的兼容性。此外还可以验证真实用户场景(事务消息、消费者动态平衡)、灾难场景(Kafka node 宕机、 进程卡死)下 AutoMQ 服务的健壮性。

04 总结

本文主要介绍了 Kafka 的系统测试框架,并简要介绍了系统测试的原理。AutoMQ 完全继承了 Apache Kafka 丰富的系统测试案例,模拟真实用户使用 Kafka 集群的行为,并验证行为的结果是否符合预期。500+ 系统测试案例在一定程度上保证了 AutoMQ 代码的健壮性,同时能够保证 AutoMQ 对 Apache Kafka 的 100% 兼容性。

引用

[1]ducktape: https://ducktape.readthedocs.io/en/latest/ 
[2] AutoMQ: https://github.com/AutoMQ/AutoMQ 
[3] localstack: https://github.com/localstack/localstack 
[4] ISSUE-751: https://github.com/AutoMQ/automq/issues/751 
[5] main E2E tests:Nightly Main E2E tests · Workflow runs · AutoMQ/AutoMQ 
[6] extra E2E tests: Nightly Main E2E tests · Workflow runs · AutoMQ/AutoMQ

关于我们

我们是来自 Apache RocketMQ 和 Linux LVS 项目的核心团队,曾经见证并应对过消息队列基础设施在大型互联网公司和云计算公司的挑战。现在我们基于对象存储优先、存算分离、多云原生等技术理念,重新设计并实现了 Apache Kafka 和 Apache RocketMQ,带来高达 10 倍的成本优势和百倍的弹性效率提升。
🌟 GitHub 地址:https://github.com/AutoMQ/automq
💻 官网:https://www.automq.com
👀 B站:AutoMQ官方账号
🔍 视频号:AutoMQ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/830565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA 中间件之 Mycat2

Mycat2应用与实战教程 1.Mycat2概述 1.1 什么是MyCat 官网: http://mycatone.top/ Mycat 是基于 java 语言编写的数据库中间件,是一个实现了 MySQL 协议的服务器,前端用户可以把它看作是一个数据库代理,用 MySQL 客户端工具和…

HEVC/H.265视频编解码学习笔记–框架及块划分关系

前言 由于本人在学习视频的过程中,觉得分块单元太多搞不清楚其关系,因此本文着重记录这些分块单元的概念以及关联。 一、框架 视频为一帧一帧的图像,其编码的主要核心是压缩空间以及时间上的冗余。因此,视频编码有帧内预测和帧间…

Linux 进程概念和状态

目录 一、冯诺依曼体系结构 二、操作系统 1.概念 2.理解操作系统的管理 硬件和管理 为什么要有操作系统 三、进程的概念 PCB: 进程的删除和子进程的创建 删除 创建子进程 四、进程的状态 七种状态: 实验查看部分状态: R&#x…

如何把为知笔记导入到Notion笔记里面

💡 大家好,我是可夫小子,《小白玩转ChatGPT》专栏作者,关注AIGC、读书和自媒体。 为知笔记并不开放,笔记文件只能以pdf或者图片的方向导出来,无法与其他笔记文件相互导入导出,然而,稍…

PCF应用切换至CAAS

刚刚开通了一个公众号,会分享一些技术博客和自己觉得比较好的项目,同时会更新一些自己使用的工具和图书资料,后面会整理一些面试资料进行分享,觉得有兴趣的可以关注一下。 文章目录 前言打包镜像Dockerfile语法项目使用遇到的问题…

屎里淘金,买二手显卡不翻车指南

马上五一了,应该也有不少小伙伴在摩拳擦掌想装机吧? 但是奈何最近显卡疯涨,装机大头显卡还没搞定,想一步到位吧,感觉目前显卡都太贵了,没必要。 想向现实妥协吧,但是好像又有点心有不甘。 那…

测试工程师——招聘分析

测试工程师 随着互联网行业的高速发展,快速高质量的产品版本迭代成为企业始终立于不败之地的迫切需求,而在短期迭代的快节奏中,传统测试工作面对更大压力,无法持续提供高效率高质量的人力支撑,所以越来越多的企业需要技术更为全面的测试开发工程师。测试开发 本质上属于测…

【MATLAB源码-第201期】基于matlab的黏菌群优化算法(SMA)无人机三维路径规划,输出做短路径图和适应度曲线

操作环境: MATLAB 2022a 1、算法描述 黏菌优化算法(Slime Mould Algorithm, SMA)是一种新颖的启发式优化方法,其灵感来源于自然界中的真菌——黏菌。这种算法模拟了黏菌在寻找食物时的行为和网络形成策略。在本文中&#xff0c…

触发器的启用和禁用

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 在 Oracle 数据库中,所创建的触发器可以根据情况,灵活修改它的状态,使其有效或者无效,即启用或者禁用。 其语法格式如下所示。…

社区新零售:重构邻里生活圈,赋能美好未来

新时代的邻里脉动 在城市的肌理中,社区作为生活的基本单元,正经历一场由新零售引领的深刻变革。社区新零售,以其独特的商业模式、创新的技术手段和以人为本的服务理念,重新定义了社区商业的边界,重构了邻里生活的形态…

CAD的DWG文件如何进行搜索文字

1.目的 想搜索CAD文件中的数字或文字是否存在DWG文件中。 2.方法 方式1:菜单栏 编辑→查找 方式2:指令格式 图纸的左下侧→命令处,进行输入find→再按回车enter 3.结果

开源AI智能名片商城小程序:深度解读IMC(IP、MarTech、Content)视角

在数字化浪潮中,私域流量的运营已成为企业不可或缺的增长引擎。而开源AI智能名片商城小程序,则是以一种全新的视角——IMC(IP、MarTech、Content),为企业打开私域流量运营的新篇章。今天,我们就来一起深入解…

智慧农场系统 搭建重点,会用到哪些三方服务?

智慧农场小游戏的搭建重点主要集中在游戏设计、用户体验、数据安全和稳定性等方面。为了实现这些目标,可能会用到以下第三方服务: 游戏引擎和开发工具:使用成熟的游戏引擎和开发工具可以极大地简化开发流程,提高开发效率。例如&a…

stm32cubeMX智能小车蓝牙模块

本文使用的代码是 HAL 库。 文章目录 前言一、蓝牙模块介绍二,AT指令测试蓝牙模块三,原理图分析四,cubeMX 配置五,编写代码总结 前言 实验小车:STM32F103C8T6。 蓝牙模块:HC-05。 所需软件:kei…

Rust中的并发性:Sync 和 Send Traits

在并发的世界中,最常见的并发安全问题就是数据竞争,也就是两个线程同时对一个变量进行读写操作。但当你在 Safe Rust 中写出有数据竞争的代码时,编译器会直接拒绝编译。那么它是靠什么魔法做到的呢? 这就不得不谈 Send 和 Sync 这…

Spirng 当中 Bean的作用域

Spirng 当中 Bean的作用域 文章目录 Spirng 当中 Bean的作用域每博一文案1. Spring6 当中的 Bean的作用域1.2 singleton 默认1.3 prototype1.4 Spring 中的 bean 标签当中scope 属性其他的值说明1.5 自定义作用域,一个线程一个 Bean 2. 总结:3. 最后: 每…

Navicat 每次打开数据库时,总是弹出 “正在获取 ER 图表信息“

文章目录 1 问题描述2 问题截图3 解决办法 1 问题描述 使用 Navicat 打开数据库时,总是弹出 “正在获取 ER 图表信息”每次都弹出来,耗时长,有时候点 “取消” 还卡死,烦人 2 问题截图 获取表信息 解析为 ER 图(最…

React正式更新!开始学习React 19!

本文为原创文章,原文链接:J实验室,未经授权请勿转载 今年2月份,React 发布消息确认今年发布 v19 版本,尘封两年的版本号终于要更新了(详情点击:React 19 发布在即,抢先学习一下新特性…

打靶日记:midnight

前置 1. 下载靶机 前往https://www.vulnhub.com/,下载我们想要使用的靶机 本次实战使用的靶机是sunset: midnight 2. 导入VMware 我是用的是VM15,这里我们直接 点击文件-》打开-》选择我们下载完的文件(如果是压缩包的话记得解压&#…

陪孩子终身成长

文章目录 自序 你必须成长,才能陪孩子成长1 理解养育的本质第1章 为什么说亲子关系决定孩子的一生亲子关系,决定了我们与世界的关系父母对孩子的影响是最大的所有关系都是原生家庭关系的投射我们的思维模式,由父母决定 第2章 远离劣质亲子…