注意
本文档适用于 Ceph 开发版本。
测试 - 集成测试 - 简介
Ceph 有两种类型的测试:make check测试和ceph/qa 子目录中,并使用teuthology-suite
command.
The teuthology-suite
命令运行,该命令是teuthology 框架的一部分。
Teuthology 消耗软件包
理解这一事实的重要性可能需要一些时间,但它很重要。这意味着可以在多个平台上使用相同的软件包(RPM、DEB)进行自动化测试,这些软件包可以安装在运行这些平台的任何机器上。非常 significant. It means that automated tests can be conducted on multiple platforms using the same packages (RPM, DEB) that can be installed on any machine running those platforms.
Teuthology 有一个它支持的平台列表(截至 2020 年 9 月,该列表包括“RHEL/CentOS 8”和“Ubuntu 18.04”)。它期望为这些平台提供预构建的 Ceph 软件包。Teuthology 在机器(裸金属或云提供)上部署这些平台,在这些机器上安装这些软件包,并在它们上部署 Ceph 集群——所有这些都是根据测试的要求进行的。
Nightlies
一些集成测试定期在Sepia中针对官方 Ceph 存储库(在开发分支和稳定分支上)运行。传统上,这些测试被称为“nightlies”,因为 Ceph 核心开发人员曾经住在同一个时区,从他们的角度来看,测试是在夜间运行的。master
development
branch and the stable branches). Traditionally, these tests are called “the
nightlies” because the Ceph core developers used to live and work in
the same time zone and from their perspective the tests were run overnight.
Nightlies 测试运行的结果发布在http://pulpito.ceph.com/下,用户为teuthology
。开发者的昵称出现在测试结果的 URL 中,以及 Pulpito 仪表板的第一列中。结果还报告在ceph-qa 邮件列表.
测试优先级
简而言之:在teuthology-suite
命令选项-p <N>
中,将<N>
的值设置为小于 500 的数字。原因如下。
The teuthology-suite
命令包括一个选项-p <N>
。此选项指定提交到队列的工作的优先级。的值越低,N
,优先级越高。
The default value of N
是1000
。大多数 nightlies 测试自动teuthology@teuthology.front.sepia.ceph.com
安排的测试都使用N >=
500
。一些关键的 nightlies 测试被赋予更高的优先级,例如冒烟测试或即将发布的重大版本的 QA 运行。
Note
夜lies 测试期间进行的测试量通常很大,以至于在分配给它们运行的时间内无法运行所有 nightlies 测试。
将N
的值设置为500
或以下,否则您的测试将不会比 nightlies 测试具有优先级。这意味着它们可能永远不会运行。
根据以下指南选择您工作任务的优先级(的值N
):
优先级 |
解释 |
---|---|
N < 10 |
如果天空塌下来,并且必须立即运行一些测试组,请使用此选项。 |
10 <= N < 50 |
如果您的测试很紧急并且阻塞了其他重要开发,请使用此选项。 |
50 <= N < 75 |
如果您正在测试特定功能/修复,并且运行少于大约 25 个作业,请使用此选项。此范围也用于紧急发布测试。 |
75 <= N < 100 |
Tech Leads 定期使用此优先级安排集成测试,以验证对主干的拉取请求。 |
100 <= N < 150 |
此优先级用于 QE 验证点发布。 |
150 <= N < 200 |
使用此优先级为 100 个或更少的作业测试特定功能或修复。大约 24 小时后即可获得结果。 |
200 <= N < 500 |
使用此优先级进行大型测试运行。大约一周后即可获得结果。 |
要查看teuthology-suite
命令将触发多少个作业,请使用--dry-run
标志。如果您对teuthology-suite
标志返回的作业数量满意,请再次发出--dry-run
和-p
并提供一个适当的数字作为参数。
要跳过优先级检查,请使用--force-priority
。考虑到其他开发人员运行测试的需求,仅在紧急情况下使用--force-priority
。
测试套件清单
The suites
ceph/qa 子目录ceph/qa 子目录的目录包含所有 Ceph 组件的集成测试。
组件 |
功能 |
使用 ceph-deploy man page 安装 Ceph 集群 |
|
获取一台机器,不做任何事并返回成功(通常用于验证集成测试基础设施是否按预期工作) |
|
测试使用内核和 FUSE 客户端挂载的 CephFS,还有多个 MDS。 |
|
测试 RBD 内核模块 |
|
验证当机器关闭并再次开启时 Ceph 集群的行为 |
|
在各种压力条件下运行包括 OSD 和 MON 的 Ceph 集群 |
|
使用实际的 Ceph 集群运行 RBD 测试,有和没有 qemu |
|
使用实际的 Ceph 集群运行 RGW 测试 |
|
使用实际的 Ceph 集群运行测试,以锻炼 Ceph API |
|
验证 teuthology 是否可以运行集成测试,有和没有 OpenStack |
|
针对各种版本的 Ceph,验证升级可以在不中断任何正在进行的工作负载的情况下完成(升级测试) |
teuthology-describe
teuthology-describe
被添加到teuthology 框架以促进文档编写和更好地理解集成测试。
可以通过在用于定义测试的 yaml 文件中嵌入meta:
注释来记录测试。结果可以在teuthology-describe
由于这是一个新功能,许多 yaml 文件尚未进行注释。鼓励开发人员提高覆盖范围和文档质量。
如何运行集成测试
通常使用Sepia实验室来运行集成测试。但作为新的 Ceph 开发者,您可能无法访问Sepia实验室。但是,您可能能够在与Sepia实验室分开的环境中运行一些集成测试。询问相关团队的成员如何操作。
运行您自己的集成测试的一种方法是在裸金属上设置一个 teuthology 集群。在裸金属上设置 teuthology 集群是一项复杂的任务。如果您决定对在裸金属上设置 teuthology 集群的复杂任务感兴趣,以下是一些注意事项来帮助您开始。
在您的代码贡献上运行集成测试并发布结果,可以让审查者验证代码库的更改不会导致回归,并且可以让审查者在出现测试失败时进行分析。
每个teuthology 集群,无论是裸金属还是云提供,都有一个所谓的“teuthology 机器”,测试套件是使用teuthology-suite
command.
从该机器上触发:teuthology-suite选项的描述可以通过在 teuthology 机器上运行以下命令来获得:
teuthology-suite --help
集成测试是如何定义的
集成测试由在suites
ceph/qa 子目录ceph/qa 子目录的子目录中找到的 yaml 文件定义,并由在tasks
子目录中找到的 python 代码实现。一些测试(“独立的测试”)在单个 yaml 文件中定义,而其他测试由包含 yaml 文件的目录树定义,这些 yaml 文件在运行时被组合成一个更大的 yaml 文件。
读取一个独立的测试
让我们首先检查一个独立的测试,或“单例”。
这是一个使用集成测试rados/singleton/all/admin-socket.yaml
roles:
- - mon.a
- osd.0
- osd.1
tasks:
- install:
- ceph:
- admin_socket:
osd.0:
version:
git_version:
help:
config show:
config set filestore_dump_file /tmp/foo:
perf dump:
perf schema:
The roles
的注释示例a
的 MON(即列表中的mon.a
),以及两个 OSDsosd.0
和osd.1
).
测试的主体在tasks
数组中:每个元素按顺序评估,导致在tasks
ceph/qa 子目录teuthology repository或ceph/qa 子目录中找到的相应 python 文件被运行。“运行”在这种情况下意味着调用该文件中定义的task()
函数。
在这种情况下,安装任务首先执行。它在每台机器上安装 Ceph 软件包(由roles
array 定义)。关于install
任务的完整描述可以在 python 文件中找到(搜索“def task”)。
The ceph
任务,该任务被记录这里(再次,搜索“def task”),根据roles
数组的要求启动 OSDs 和 MONs(以及可能还有 MDSs)mon.a
)和两个 OSDsosd.0
和osd.1
),所有这些都位于同一台机器上。当 Ceph 集群达到HEALTH_OK
状态。
时,控制将转移到下一个任务。下一个任务是admin_socket
(source code)。admin_socket
任务的参数(以及任何其他任务的参数)是一个结构,该结构按任务中记录的解释进行解释。在这个例子中,参数是一组要发送到osd.0
的 admin socket 的命令。该任务验证它们中的每一个都成功返回(即退出码为零)。
此测试可以使用
teuthology-suite --machine-type smithi --suite rados/singleton/all/admin-socket.yaml fs/ext4.yaml
测试描述
每个测试都有一个“测试描述”,它类似于一个目录路径,但并不相同。对于像在读取一个独立的测试中那样的独立测试,测试描述与定义测试的 yaml 文件的相对路径(从suites/
ceph/qa 子目录ceph/qa 子目录)相同。
更常见的是,测试不是由单个 yaml 文件定义,而是由yaml 文件目录树定义。在运行时,会遍历该树,并将所有 yaml 文件(方面)组合成更大的 yaml“程序”,这些程序定义了测试。每个测试日志的开头都包含了定义测试的 yaml 的完整列表。
在这种情况下,每个测试的描述包括suites/下包含 yaml 方面的子目录,后跟一个由花括号{}
组成的表达式,其中包含按连接顺序排列的 yaml 方面的列表。例如,测试描述:
ceph-deploy/basic/{distros/centos_7.0.yaml tasks/ceph-deploy.yaml}
表示两个文件的连接:
ceph-deploy/basic/distros/centos_7.0.yaml
ceph-deploy/basic/tasks/ceph-deploy.yaml
如何从目录构建测试
如前一节所述,大多数测试不是在单个 yaml 文件中定义,而是作为从combination定义。由给定子目录定义的所有测试的集合称为“集成测试套件”,或“teuthology 套件”。suites/
ceph/qa 子目录ceph/qa 子目录.
的子目录suites/
内的目录树中收集的文件组合
YAML 方面的组合由特殊文件控制%
, +
和$
,这些文件放置在目录树中,可以将其视为运算符。 2205c7: 文件是“卷积”运算符,%
file is the “convolution” operator, +
表示连接,d8d11d: 是“随机选择”运算符。$
is the “random selection” operator.
卷积运算符 -%
卷积运算符,作为一个(通常是空的)文件称为%
,告诉 teuthology 从包含运算符的目录下子目录中找到的 YAML 方面构建测试矩阵。
例如,ceph-deploy 套件是由suites/ceph-deploy/
树定义的,该树由以下结构中的文件和子目录组成
qa/suites/ceph-deploy
├── %
├── distros
│ ├── centos_latest.yaml
│ └── ubuntu_latest.yaml
└── tasks
├── ceph-admin-commands.yaml
└── rbd_import_export.yaml
这被解释为 2x1 矩阵,其中包含两个测试:
ceph-deploy/basic/{distros/centos_7.0.yaml tasks/ceph-deploy.yaml}
ceph-deploy/basic/{distros/ubuntu_16.04.yaml tasks/ceph-deploy.yaml}
i.e. centos_7.0.yaml 和 ceph-deploy.yaml 的连接,以及 ubuntu_16.04.yaml 和 ceph-deploy.yaml 的连接,分别。用人类语言来说,这意味着ceph-deploy.yaml
中找到的任务旨在同时在 CentOS 7.0 和 Ubuntu 16.04 上运行。
没有文件 percent,dca1da: 树将被解释为三个独立的测试:ceph-deploy
tree would be interpreted as
three standalone tests:
ceph-deploy/basic/distros/centos_7.0.yaml
ceph-deploy/basic/distros/ubuntu_16.04.yaml
ceph-deploy/basic/tasks/ceph-deploy.yaml
(当然,在这种情况下这是错误的)。
参考到ceph/qa 子目录,您会注意到centos_7.0.yaml
和ubuntu_16.04.yaml
目录中的文件被实现为符号链接。通过使用符号链接而不是复制,单个文件可以出现在多个套件中。这简化了整个测试框架的维护。suites/ceph-deploy/basic/distros/
directory are implemented as symlinks.
By using symlinks instead of copying, a single file can appear in multiple
suites. This eases the maintenance of the test framework as a whole.
从suites/ceph-deploy/
目录树生成的所有测试(也称为“ceph-deploy 套件”)都可以使用
teuthology-suite --machine-type smithi --suite ceph-deploy
运行。从ceph-deploy 套件中运行单个测试可以通过添加--filter
选项
teuthology-suite \
--machine-type smithi \
--suite ceph-deploy/basic \
--filter 'ceph-deploy/basic/{distros/ubuntu_16.04.yaml tasks/ceph-deploy.yaml}'
Note
来实现。要单独运行像在读取一个独立的测试, --suite
这样的独立测试就足够了。如果您想运行定义为目录树的套件中的单个测试,必须将--suite
与--filter
。这是因为--suite
选项组合
嵌套子集
套件可能会因为 yaml 配置的组合爆炸而变得相当大。在编写时,rados`
套件有超过--subset
作业。因此,调度通常使用减少测试数量)。但是,这仅适用于正在运行的套件的最顶层(例如fs
)。这可能会偶然增加某些较大的子套件(如fs:workload
)与较小的但关键的套件(如fs:volumes
).
因此,自动子集一些从未完全运行的子套件很有吸引力。这是通过为卷积运算符文件提供一个整数除数来完成的,而不是将其留空。该除数自动子集生成的矩阵。例如,如果卷积文件%
convolution operator file instead of leaving it empty. That divisor
automatically subsets the resulting matrix. For example, if the convolution
file %
包含2
,矩阵将使用与--subset
机制相同的逻辑分为两部分。
注意分子没有像--subset
选项那样指定,因为当存在多层嵌套时,没有有意义的方式来表达它。相反,会随机选择一个子集(我们的例子中为 1 of 2)。选择基于用于调度的随机种子--seed
。请记住种子被保存在结果中,以便即使有多个失败的测试,仍然可以保留正确的分子(子集的子集)。--rerun
of failed
tests will still preserve the correct numerator (subset of subsets).
您可以使用--no-nested-subset
参数来禁用嵌套子集teuthology-suite
.
连接运算符 -+
为了在套件之间共享 yaml 文件提供更大的灵活性,可以使用特殊文件 plus+
来连接目录内的文件。例如,考虑suites/rbd/thrash树
qa/suites/rbd/thrash
├── %
├── clusters
│ ├── +
│ ├── fixed-2.yaml
│ └── openstack.yaml
└── workloads
├── rbd_api_tests_copy_on_read.yaml
├── rbd_api_tests.yaml
└── rbd_fsx_rate_limit.yaml
这会创建两个测试:
rbd/thrash/{clusters/fixed-2.yaml clusters/openstack.yaml workloads/rbd_api_tests_copy_on_read.yaml}
rbd/thrash/{clusters/fixed-2.yaml clusters/openstack.yaml workloads/rbd_api_tests.yaml}
由于clusters/
子目录包含特殊文件 plus+
,该子目录中的所有其他文件(2d8a0a: 在此情况下)都被连接在一起并视为单个文件。如果没有特殊文件 plus,它们将与来自 workloads 目录的文件卷积,以创建一个 2x2 矩阵:fixed-2.yaml
和openstack.yaml
in this case) are concatenated together
and treated as a single file. Without the special file plus, they would
have been convolved with the files from the workloads directory to create
a 2x2 matrix:
rbd/thrash/{clusters/openstack.yaml workloads/rbd_api_tests_copy_on_read.yaml}
rbd/thrash/{clusters/openstack.yaml workloads/rbd_api_tests.yaml}
rbd/thrash/{clusters/fixed-2.yaml workloads/rbd_api_tests_copy_on_read.yaml}
rbd/thrash/{clusters/fixed-2.yaml workloads/rbd_api_tests.yaml}
The clusters/fixed-2.yaml
文件在许多套件中共享,以定义上面定义的以下套件,其中包含两个测试,roles
roles:
- [mon.a, mon.c, osd.0, osd.1, osd.2, client.0]
- [mon.b, osd.3, osd.4, osd.5, client.1]
The rbd/thrash
suite as defined above, consisting of two tests,
can be run with
teuthology-suite --machine-type smithi --suite rbd/thrash
运行。从 rbd/thrash 套件中运行单个测试可以通过添加--filter
选项
teuthology-suite \
--machine-type smithi \
--suite rbd/thrash \
--filter 'rbd/thrash/{clusters/fixed-2.yaml clusters/openstack.yaml workloads/rbd_api_tests_copy_on_read.yaml}'
升级测试
使用升级套件,我们能够验证从早期版本升级可以成功完成,而不会中断任何正在进行的工作负载。parallel并行完成的。
例如,Quincy 发布分支的升级测试目录如下:
.
├── octopus-x
└── pacific-x
可以测试从 Octopus(2-x)或从 Pacific(1-x)到 Quincy(x)的升级。
├── 0-start.yaml
├── 1-tasks.yaml
├── upgrade-sequence.yaml
└── workload
在使用旧版本启动集群后,我们开始并行运行给定的workload
和upgrade-sequnce
。
- print: "**** done start parallel"
- parallel:
- workload
- upgrade-sequence
- print: "**** done end parallel"
而workload
目录包含与其他套件中一样常规的 yaml 文件,而upgrade-sequnce
负责运行升级并等待其完成:
- print: "**** done start upgrade, wait"
...
mon.a:
- ceph orch upgrade start --image quay.ceph.io/ceph-ci/ceph:$sha1
- while ceph orch upgrade status | jq '.in_progress' | grep true ; do ceph orch ps ; ceph versions ; sleep 30 ; done\
...
- print: "**** done end upgrade, wait..."
也可以在运行这些之间的工作负载时分阶段进行升级:
├── %
├── 0-cluster
├── 1-ceph-install
├── 2-partial-upgrade
├── 3-thrash
├── 4-workload
├── 5-finish-upgrade.yaml
├── 6-quincy.yaml
└── 8-final-workload
在启动集群后,我们只升级集群的 2/3 (2-partial-upgrade
)。5-finish-upgrade.yaml
。ceph require-osd-release quincy
,
ceph osd set-require-min-compat-client quincy
并运行final-workload
.
随机选择运算符 -$
文件名$
的存在提示 teuthology 随机包含测试中的一个 YAML 片段。这种情况通常在我们需要随机选择要测试的功能/选项中的一个风味时出现。
位置无关链接
在qa/suites
目录下是每个目录中的符号链接。每个链接都是递归的,始终链接到.qa
symbolic links in every
directory. Each link is recursive by always linking to ../.qa/
。最终终止链接位于qa/
目录本身作为qa/.qa -> .
。
qa/suites/fs/upgrade/nofs/centos_latest.yaml -> .qa/distros/supported/centos_latest.yaml
如果我们复制nofs
套件到其他地方,在nofs
上添加一个父目录,或移动centos_latest.yaml
片段到一个子目录中,链接将不会断开。比较:
qa/suites/fs/upgrade/nofs/centos_latest.yaml -> ../../../../distros/supported/centos_latest.yaml
如果链接被移动,它很可能断开,因为到达distros
目录的父目录数量可能会改变。
添加新目录或套件时,建议也记得添加.qa
符号链接。一个简单的 find 命令可能对此有所帮助:
find qa/suites/ -type d -execdir ln -sfT ../.qa/ {}/.qa \;
根据描述过滤测试
当几个作业失败并需要再次运行时,可以使用--filter
选项选择具有匹配描述的测试。例如,如果rados
套件失败了all/peer.yaml测试,则以下内容将只运行包含此文件的测试
teuthology-suite --machine-type smithi --suite rados --filter all/peer.yaml
The --filter-out
选项做相反的事情(它匹配不包含给定字符串的测试),并且可以与firefly 发布。Firefly 将延迟至少另一个冲刺,以便我们可以对新代码进行一些操作经验,并进行一些额外的测试,然后再承诺长期支持。
contain a given string), and can be combined with the --filter
option.
双--filter
和--filter-out
结合使用,它接受逗号分隔的字符串列表(这意味着逗号字符在ceph/qa 子目录中找到的文件名中隐式禁止)。例如
teuthology-suite --machine-type smithi --suite rados --filter all/peer.yaml,all/rest-api.yaml
将运行包含all/peer.yaml或all/rest-api.yaml
每个字符串都在测试描述中的任何地方查找,并且必须是一个确切的匹配:它们不是正则表达式。
减少测试数量
The rados
套件会从几百个文件生成数十甚至数百万个测试。这发生是因为 teuthology 在遇到名为%
的文件时从子目录构建测试矩阵。例如,所有在rados/basic 套件中运行的测试都使用simple
, async
和random
,因为它们是通过特殊文件%
与msgr 目录
组合的。所有集成测试都必须在发布 Ceph 版本之前运行。当仅仅验证贡献是否可以合并而不会导致简单的回归风险时,运行子集就足够了。可以使用--subset
选项来减少触发的测试数量。例如
teuthology-suite --machine-type smithi --suite rados --subset 0/4000
将尽可能少地运行测试。在这种情况下,权衡是测试变体的所有组合不会一起,但无论--subset
中提供的比例有多小,teuthology 都会确保套件中的所有文件至少在一个测试中。理解实际驱动此逻辑需要阅读 teuthology 源代码。
注意:一些套件现在正在使用一个嵌套子集功能,该功能会自动应用于精心选择的一组 yaml 配置。您可以使用--no-nested-subset
option.
The --limit
选项禁用此行为(可能用于自定义过滤),只运行套件中的前N
个测试:
由 Ceph 基金会带给您
Ceph 文档是一个社区资源,由非盈利的 Ceph 基金会资助和托管Ceph Foundation. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.