减少 Tacker 功能测试的时间

本提案旨在通过降低 zuul 上测试的成本来改善我们的开发体验,在某些最坏的情况下,完成合并一个补丁通常需要数周时间。

用例

本提案旨在修订当前的功能测试,不增加额外的用例。

问题描述

自从我们添加了一些新功能而没有考虑测试效率以来,tacker 中的功能测试数量有所增加。这些测试不仅涉及 Tacker 和 Openstack,还涉及其他功能,因为除了基本的 OpenStack 用例之外,我们还应该支持多种用例,例如在 Kubernetes 上部署 VNF,使用 Keystone 以外的身份验证/授权。结果是,功能测试的总数达到 23 个,其中大约一半用于包含外部工具或功能的用例。

实施功能测试作为端到端测试是一种良好的做法,以确保所有相关功能正常工作,而不是使用任何总是返回预期结果的模拟。在 zuul 上,我们可以在每次上传更改时检查实际部署的虚拟机上的功能,并发现不仅是更改本身,而且是由更改引起的所有相关功能中的任何问题。这对于在大系统中查找错误非常有用,因为在开发正在运行的功能时,我们无法理解该系统的所有细节。如果在运行功能测试时更改出现问题,我们可以从 gerrit 获取详细日志并在运行测试后随时分析它们。

然而,我们无法为功能测试保留我们实际希望保留的那么多资源,因为除了 Tacker 之外还有几个项目在运行其作业,而总资源量是有限的。例如,CPU 数量或内存大小的最大资源小于 Tacker 的控制器节点所需的资源。

功能测试可以在 zuul 上以某种方式运行,但这还不够,因为每个测试都必须在 zuul 中定义的三小时超时时间内完成,有时会因超时而失败。这导致 zuul 上的 CI/CD 过程不稳定,例如由于超时限制或 zuul 上测试可用资源不足而导致的失败。以下是 zuul 上当前状态的一个示例,显示了每个测试耗费的时间。您会注意到 tacker-functional-devstack-multinode-sol-v2-individual-vnfc-mgmttacker-compliance-devstack-multinode-sol 的耗时结果超过 2 小时,而大多数其他测试场景都超过 1 小时。

  • tacker-functional-devstack-multinode-sol-legacy-nfvo : 成功 42m 53s

  • tacker-functional-devstack-multinode-sol-vnflcm : 成功 1h 11m 24s

  • tacker-functional-devstack-multinode-sol-vnflcm-userdata : 成功 1h 58m 39s

  • tacker-functional-devstack-multinode-sol-vnfpkgm : 成功 30m 55s

  • tacker-functional-devstack-multinode-sol-separated-nfvo : 成功 55m 19s

  • tacker-functional-devstack-multinode-sol-kubernetes : 成功 1h 23m 54s

  • tacker-functional-devstack-multinode-sol-v2-basic : 成功 1h 38m 09s

  • tacker-functional-devstack-multinode-sol-v2-vnflcm : 成功 1h 51m 29s

  • tacker-functional-devstack-multinode-sol-v2-notification : 成功 1h 01m 53s

  • tacker-functional-devstack-multinode-sol-v2-prometheus : 成功 56m 07s

  • tacker-functional-devstack-multinode-sol-separated-nfvo-v2 : 成功 1h 05m 16s

  • tacker-functional-devstack-multinode-sol-v2-individual-vnfc-mgmt : 成功 2h 10m 32s

  • tacker-functional-devstack-multinode-sol-kubernetes-v2 : 成功 1h 26m 28s

  • tacker-functional-devstack-multinode-sol-multi-tenant : 成功 53m 24s

  • tacker-functional-devstack-multinode-sol-https-v2 : 成功 1h 04m 48s

  • tacker-functional-devstack-multinode-sol-encrypt-cred-barbican : 成功 37m 21s

  • tacker-functional-devstack-multinode-sol-encrypt-cred-local : 成功 39m 47s

  • tacker-functional-devstack-multinode-sol-kubernetes-multi-tenant : 成功 54m 16s

  • tacker-functional-devstack-kubernetes-oidc-auth : 成功 49m 48s

  • tacker-functional-devstack-multinode-sol-v2-az-retry : 成功 38m 01s

  • tacker-functional-devstack-enhanced-policy-sol : 成功 1h 28m 04s

  • tacker-functional-devstack-enhanced-policy-sol-kubernetes : 成功 1h 06m 13s

  • tacker-compliance-devstack-multinode-sol : 失败 2h 37m 13s (非投票)

  • tacker-functional-devstack-multinode-sol-terraform-v2 : 成功 1h 01m 25s

提议的变更

为实现减少 Tacker 功能测试总时间的目标,我们将建议采取四个步骤来重点关注主要部分。(1) 拆分耗时测试,(2) 将更新频率较低的测试移至非投票状态,(3) 从 zuul 中删除几乎未更新的测试,以及 (4) 重命名每个测试场景并修订目录结构。

本提案的首要任务是减少 zuul 每次上传补丁时的最大检查时间,尽管减少测试重试次数也很重要。因此,我们首先要做的是将最耗时的测试拆分成几个测试。这就是我们将 (1) 放在列表首位的原因。

第二个优先级是减少因意外失败而上传补丁时测试的重试次数,因为失败不是由更改本身引起的,而是由其他不相关的部分引起的。尽管通常可以通过多次重试来避免,但总时间也会线性增加。为了减少重试次数,将不经常更新的测试移至非投票状态,如 (2) 中所列。当更改导致失败时,这种修订非常有用,该失败不需要在补丁合并之前修复,但应在之后修复。我们可以首先关注更改本身,而不会被这种不相关的失败打断。

尽管如果完成 (1) 和 (2) 预计会减少一定的时间,但测试数量会增加以拆分当前耗时的测试,并且运行这些测试需要更多的资源。这不是一个好情况,我们应该避免它。考虑到 Tacker 上当前的开发活动,旧版或 v1 功能几乎没有更新,我们不需要在每次上传补丁时都为它们运行功能测试。因此,我们最好从 zuul 中删除此类测试,并在本地环境中运行。

最后的 (4) 是通过提高测试代码的可维护性来减少时间的另一种方法。目前的代码组织得不太好,例如,每个功能测试的名称都太长,使得开发或审查变得困难。.zuul.yaml 也应该修订,因为它的内容已经变得庞大而混乱,因为定义了许多相似的参数。

下面将描述这四个项目的每种策略,以及我们如何改进功能测试。

1. 拆分耗时测试

通过对 gerrit 上描述功能测试结果的报告进行简要分析,我们发现所有测试场景的耗时差异不大。因此,只需选取少数几个案例作为样本,即可确定每个测试场景的耗时。

以下是功能测试场景列表,与前一个列表相同,但添加了 category 以指示消耗的时间量。它由四个级别组成:S(短)表示少于一小时,M(中)表示少于一个半小时但超过 SL(长)表示少于两小时但超过 M,以及 LL(超长)表示超过两小时。

测试名称

类别

运行时间

tacker-functional-devstack-multinode-sol-legacy-nfvo

S

42m 53s

tacker-functional-devstack-multinode-sol-vnflcm

M

1h 11m 24s

tacker-functional-devstack-multinode-sol-vnflcm-userdata

L

1h 58m 39s

tacker-functional-devstack-multinode-sol-vnfpkgm

S

30m 55s

tacker-functional-devstack-multinode-sol-separated-nfvo

S

55m 19s

tacker-functional-devstack-multinode-sol-kubernetes

M

1h 23m 54s

tacker-functional-devstack-multinode-sol-v2-basic

L

1h 38m 09s

tacker-functional-devstack-multinode-sol-v2-vnflcm

L

1h 51m 29s

tacker-functional-devstack-multinode-sol-v2-notification

M

1h 01m 53s

tacker-functional-devstack-multinode-sol-v2-prometheus

S

56m 07s

tacker-functional-devstack-multinode-sol-separated-nfvo-v2

M

1h 05m 16s

tacker-functional-devstack-multinode-sol-v2-individual-vnfc-mgmt

LL

2h 10m 32s

tacker-functional-devstack-multinode-sol-kubernetes-v2

M

1h 26m 28s

tacker-functional-devstack-multinode-sol-multi-tenant

S

53m 24s

tacker-functional-devstack-multinode-sol-https-v2

M

1h 04m 48s

tacker-functional-devstack-multinode-sol-encrypt-cred-barbican

S

37m 21s

tacker-functional-devstack-multinode-sol-encrypt-cred-local

S

39m 47s

tacker-functional-devstack-multinode-sol-kubernetes-multi-tenant

S

54m 16s

tacker-functional-devstack-kubernetes-oidc-auth

S

49m 48s

tacker-functional-devstack-multinode-sol-v2-az-retry

S

38m 01s

tacker-functional-devstack-enhanced-policy-sol

M

1h 28m 04s

tacker-functional-devstack-enhanced-policy-sol-kubernetes

M

1h 06m 13s

tacker-compliance-devstack-multinode-sol

LL

2h 37m 13s

tacker-functional-devstack-multinode-sol-terraform-v2

M

1h 01m 25s

我们不需要关注归类为 S 的测试,因为通常等待测试一小时并不重要。另一方面,我们专注于 M 或更高级别的测试,并从 LL 开始拆分它们。

尽管从优化的角度来看,过度拆分测试并不是一个好方法,因为将测试拆分为多个意味着测试之间的共同过程(例如运行设置脚本)在每个测试场景之前运行。然而,如果我们可以减少 zuul 作业的整个间隔时间,它仍然很有用。

2. 将更新频率较低的测试移至非投票状态

在 Tacker 的仓库中,目前没有太多功能处于积极开发状态,其测试情况也类似。其余不活跃的功能通常偶尔只为维护目的而更新。

我们最近的版本一直专注于开发 ETSI NFV v2 API 和容器支持,这种情况将持续一段时间。因此,我们可以将除活动开发功能或基本功能之外的测试移走。考虑到 Tacker 仓库最近的活动,以下四个测试场景就足够了。

  • tacker-functional-devstack-multinode-sol-v2-basic

  • tacker-functional-devstack-multinode-sol-v2-vnflcm

  • tacker-functional-devstack-multinode-sol-v2-individual-vnfc-mgmt

  • tacker-functional-devstack-multinode-sol-kubernetes-v2

其余的测试可以移至 non-voting,或从 zuul 中删除。

  • tacker-functional-devstack-multinode-sol-legacy-nfvo

  • tacker-functional-devstack-multinode-sol-vnflcm

  • tacker-functional-devstack-multinode-sol-vnflcm-userdata

  • tacker-functional-devstack-multinode-sol-vnfpkgm

  • tacker-functional-devstack-multinode-sol-separated-nfvo

  • tacker-functional-devstack-multinode-sol-kubernetes

  • tacker-functional-devstack-multinode-sol-v2-notification

  • tacker-functional-devstack-multinode-sol-v2-prometheus

  • tacker-functional-devstack-multinode-sol-separated-nfvo-v2

  • tacker-functional-devstack-multinode-sol-multi-tenant

  • tacker-functional-devstack-multinode-sol-https-v2

  • tacker-functional-devstack-multinode-sol-encrypt-cred-barbican

  • tacker-functional-devstack-multinode-sol-encrypt-cred-local

  • tacker-functional-devstack-multinode-sol-kubernetes-multi-tenant

  • tacker-functional-devstack-kubernetes-oidc-auth

  • tacker-functional-devstack-multinode-sol-v2-az-retry

  • tacker-functional-devstack-enhanced-policy-sol

  • tacker-functional-devstack-enhanced-policy-sol-kubernetes

  • tacker-compliance-devstack-multinode-sol

  • tacker-functional-devstack-multinode-sol-terraform-v2

当然,我们可以根据情况的变化来更改类别。

3. 从 zuul 中删除几乎未更新的测试

一般来说,虽然通过频繁运行所有功能的端到端测试来保持代码健康是确保质量的最佳方法之一,但考虑到在 zuul 环境中运行,由于资源限制,我们无法在现实中涵盖所有功能。

考虑到 Tacker 团队当前的开发活动,对旧版或 ETSI NFV v1 功能的支持一直不活跃,并且很少为维护而更新。因此,如果未来没有重新激活的计划,我们可以从 zuul 作业中删除这些测试。即使这些测试从 zuul 检查中删除,我们仍然可以在本地环境中运行它们以检查功能的健康状况。

注意

将删除哪些测试的决定仍在讨论中。

  • tacker-functional-devstack-multinode-sol-legacy-nfvo

  • tacker-functional-devstack-multinode-sol-vnflcm

  • tacker-functional-devstack-multinode-sol-vnflcm-userdata

  • tacker-functional-devstack-multinode-sol-vnfpkgm

  • tacker-functional-devstack-multinode-sol-separated-nfvo

  • tacker-functional-devstack-multinode-sol-kubernetes

  • tacker-functional-devstack-multinode-sol-multi-tenant

  • tacker-functional-devstack-multinode-sol-kubernetes-multi-tenant

4. 重命名每个测试场景并修订目录结构

由于某些历史原因,每个测试场景的名称都类似于 tacker-functional-devstack-A-B-C。然而,它组织得不够好,因为 A`BCD 可能会添加,并且前缀太长,难以维护测试。

查看其他项目(例如 nova 中的 nova-tox-functional-py310 或 neutron 中的 neutron-functional-with-uwsgi)的名称,我们的项目可以使用更具意识的名称。

  • 保留前缀 tacker-functional 以显示项目名称和测试类别。

  • 删除 devstack 实际上没有意义。

  • 使用短名称,例如 k8s 代表 kubernetes,或 multi 代表 multinode

修订测试代码和 .zuul.yaml 的目录或文件结构。我们不需要更改测试代码本身而不更改测试名称,应该引入 zuul.d 目录以将 .zuul.yaml 拆分为多个文件,作为维护 zuul 作业的一种方式,当任务数量变大时。然而,如何拆分 .zuul.yaml 仍在讨论中。

备选方案

数据模型影响

REST API 影响

安全影响

通知影响

其他最终用户影响

为了通过功能测试作为端到端测试来评估 Tacker,您将能够按照添加到文档中的说明在本地环境中运行测试。该说明包含几个测试用例,例如在多节点上运行,或部署依赖应用程序,例如 Prometheus,用于测试性能/故障管理功能。

在本地环境运行的功能测试可以与在 zuul 上类似的方式运行。它通过 tox 命令启动,所有测试结果都会在您的终端上报告。此外,您可以使用您喜欢的工具主动评估功能测试,这在 zuul 上是无法做到的。对于开发人员来说,也可以使用他们喜欢的调试工具积极调试。

配置文件的示例,例如 local.conf 也包含在说明中。

性能影响

其他部署者影响

开发人员影响

其他最终用户影响 中描述的相同。

升级影响

实现

负责人

主要负责人

工作项

  • 修订功能测试代码或运行测试的方式,以通过以下步骤减少运行测试的总时间。

      1. 拆分耗时测试

      1. 将更新频率较低的测试移至非投票状态

      1. 从 zuul 中删除几乎未更新的测试

      1. 重命名每个测试场景并修订目录结构

  • 添加在本地环境中运行功能测试的说明,主要用于支持从 zuul 作业中删除的测试。

依赖项

测试

我们将提供一套脚本,用于部署 Tacker 的控制器和工作节点,以及一些额外的辅助脚本,用于创建运行功能测试所需的 VNF 包。

这里是运行测试用例的图像。首先,在您的主机上部署用于 Tacker 控制器或工作角色的专用虚拟机。这是一个使用 vagrant 的示例,但我们如何部署虚拟机仍在考虑中。

vagrant up

然后,使用 ansible 设置所有节点

ansible-playbook -i host site.yaml

所有节点准备好运行测试后,登录控制器节点并运行设置脚本和测试。

ssh stack@controller
cd /path/to/tacker
sh /path/to/setup-script.sh
tox -e tacker-functional-devstack-multinode-sol-vnflcm-userdata

文档影响

添加文档,描述上一节 测试 中解释的用法的详细信息。

参考资料

历史