☰
OpenShift Extended 测试实战:在 origin 仓库中编写、运行与结构化组织扩展测试
2026/9/25 16:14:33 网站建设 项目流程
  • 测试
  • 云原生
  • 质量保障

【免费下载链接】origin

Conformance test suite for OpenShift

项目地址:https://gitcode.com/gh_mirrors/or/origin
点击查看免费下载

在 origin(OpenShift 的 Conformance 测试套件仓库)中,test/extended/目录承载着一套基于 Ginkgo/Gomega 的功能级扩展测试(extended tests)。这些测试通过程序化调用ocCLI 和 Kubernetes/OpenShift 客户端来验证构建、镜像、OAuth、路由等核心功能。读完本文,你将掌握 extended 测试的运行方式、测试标签规范、目录组织结构、独立测试组启动器的创建方法,以及如何用exutil.CLI在 Ginkgo 用例中精确模拟oc命令并断言结果。

一、前置条件

按照 test/extended/README.md 的说明,开发 extended 测试前需要满足两个前提:

  1. 在仓库中同时编译oc与openshift-tests两个命令行工具:
$ make WHAT=cmd/openshift-tests
  1. 设置环境变量KUBECONFIG,使其指向你要测试的目标集群:
$ export KUBECONFIG=/path/to/kubeconfig

openshift-tests的入口源码位于 cmd/openshift-tests/openshift-tests.go,其子命令实现分散在pkg/cmd/openshift-tests/下,例如run、list、monitor、disruption等目录,覆盖了运行测试、列出套件、监控测试、扰动测试等场景。

二、运行 Extended 测试

按全名运行单个测试

$ openshift-tests run-test <FULL_TEST_NAME>

查看可用套件列表

$ openshift-tests help run

具体的测试前置依赖(prerequisites)会写在各测试的描述文字中,运行前先阅读被测用例的 Description。

用正则过滤子集运行

官方推荐的做法是先把全量测试列表以 dry-run 方式打印出来,再用grep -E过滤后通过-f -从标准输入喂给运行器:

$ openshift-tests run all --dry-run | grep -E "<REGEX>" | openshift-tests run -f -

这种方式适合在本地只跑与某功能相关的测试子集,而不改动 CI 配置。

三、测试标签(Test Labels)规范

extended 测试的标签体系与 Kubernetes e2e 测试的标签约定一致(README 中引用了 k8s 社区的 e2e-tests 标签说明文档)。核心规则如下:

标签含义与使用条件
无标签测试应快速完成(5 分钟内)、可并行运行且结果一致
[Serial]不能与其他测试并行(例如占用大量资源或重启节点),必须作为独立套件串行运行
[Slow]单独或并行运行超过 5 分钟。把慢测试分到独立分区,可以让绝大多数测试快速并行跑完。特别注意:凡是涉及构建(builds)的 OpenShift extended 测试都应标记[Slow]
[Conformance]覆盖集群核心关键功能且不与其它 conformance 测试重复覆盖的用例才算有效。README 给出的正例是“构建能否工作(Do builds work)”,反例是“设置 forcePull 标志后构建能否工作”——后者属于特殊配置,不属于 conformance
[local]需要访问测试机本地资源(例如使用 docker socket)的测试;原则上 extended 测试应避免访问本地宿主,无法避免时才打此标签

四、Extended 测试的目录结构

扩展测试统一位于 test/extended/ 目录,其组织结构为:

  • test/extended/util:提供 extended 测试共用的辅助函数与工具。它封装了对 OpenShift CLI 的易用接口(前文提到的exutil),同时提供对 Kubernetes E2E framework 的访问,以及跨多个测试用例共享的 OpenShift 辅助逻辑,让测试用例保持 DRY。其核心文件 test/extended/util/client.go 定义了CLI类型。
  • test/extended/testdata:存放 extended 测试用到的 JSON/YAML 等 fixture 文件(当前约 400 个 manifest 文件)。
  • test/extended/[images,builds,...]:每个 Go 包包含一组相关联的 extended 测试。例如images目录存放验证容器镜像使用场景的用例,builds存放构建相关用例。

从当前仓库实际目录看,除了util与testdata,还有apiserver、authentication、authorization、builds、etcd、networking、oauth、operators、router、storage等数十个功能包,每个包对应一类被测功能域。

五、包(Package)与测试组(Group)的区别

README 给出的组织原则是:每一类功能测试都应当放在自己的 Go 包里;但如果你的测试包需要以不同于标准路径的方式专门配置服务端,则要在test/extended目录下创建一个与包同名的 launcher 脚本(shell 启动器)。

典型的例子是 LDAP 认证测试:你需要先把 OpenShift server 配置成启用 LDAP 认证,才能测认证流程。做法是:

  1. 新建测试组ldap,并提供 shell 启动器./test/extended/ldap.sh,用于以所需配置启动 OpenShift;
  2. 把测试源码放到对应功能包的 Go 目录下,例如./test/extended/ldap;
  3. 在顶层 suite 上给你的用例加组前缀:
var _ = g.Describe("[ldap] Authenticate using LDAP", func() { # ... })

创建新的测试组 Runner

如果你的测试需要与其它 extended 用例不同的配置,应在test/extended下新建执行脚本,并注意用 Ginkgo 的 focus 机制只选中你自己的测试。如果你的测试无法作为默认组的一部分运行,务必确保该包不被test/extended的默认入口包含。

当前仓库中仍保留了这种 shell runner 的范例——test/extended/cmd.sh。它演示了一个完整的组 runner 生命周期:

source "$(dirname "${BASH_SOURCE}")/../../hack/lib/init.sh" os::util::environment::setup_time_vars os::build::setup_env # 以默认配置启动 OpenShift server(无 registry/router) os::util::environment::use_sudo os::cleanup::tmpdir os::util::environment::setup_all_server_vars os::start::configure_server os::start::server export KUBECONFIG="${ADMIN_KUBECONFIG}" # 注册 junit suite 并执行 oc 命令断言 os::test::junit::declare_suite_start "extended/cmd/new-app" os::cmd::expect_success "oc new-app test/scratchimage~https://github.com/openshift/ruby-hello-world.git --strategy=docker" ... os::test::junit::declare_suite_end

可以看到 launcher 脚本负责环境准备(setup_env、use_sudo)、服务端配置与启动(configure_server、server),并用os::test::junit::declare_suite_start/end向 JUnit 报告注册测试套件;测试断言则大量使用os::cmd::expect_success_and_text、os::cmd::try_until_text等对oc命令输出做正则验证的封装。

Bash 辅助函数

README 指出 extended 测试的通用函数位于./hack/util.sh,环境设置脚本位于 hack/lib/util/environment.sh,主要函数包括:

函数作用
ginkgo_check_extended()检查 Ginkgo 二进制是否已安装
compile_extended()将 Go 测试编译为测试二进制
test_privileges()校验是否有权限启动 OpenShift server
os::util::environment::setup_all_server_vars()设置 OpenShift server 所需的全部环境变量
os::start::configure_server()生成 OpenShift server 的所有配置文件
os::start::server()启动 OpenShift master 与 node
os::start::router()安装 OpenShift 路由服务
os::start::registry()安装 OpenShift 容器镜像 registry 服务
create_image_streams_extended()为所有 OpenShift 镜像创建 ImageStream

从源码结构看,os::util::environment::setup_all_server_vars的实际定义在 hack/lib/util/environment.sh,os::start::configure_server与os::start::server定义在 hack/lib/start.sh——configure_server会生成 master 证书、node 配置与 OpenShift 配置,server则启动服务并等待端点可用。编写 launcher 时直接source这些库即可复用整套启动流程。

六、CLI 接口:在测试中模拟 oc 命令

extended 测试的核心能力是通过exutil.CLI(包路径 test/extended/util/client.go)调用 OpenShift CLI 与 Kubernetes/OpenShift 客户端,从而在 Ginkgo 用例中模拟oc命令。

顶层 Describe 中创建 CLI 实例

要在测试套件中模拟oc命令,必须先创建 CLI 实例,且应放在顶层 GinkgoDescribe容器中。顶层 Describe 的标签需要同时给出测试所属的 bucket 与简短描述,其它全局可访问变量(如 fixtures)也在此声明:

package extended import ( g "github.com/onsi/ginkgo/v2" o "github.com/onsi/gomega" ) var _ = g.Describe("[<test bucket>] <Testing scenario>", func() { defer g.GinkgoRecover() var ( oc = exutil.NewCLI("test-name") testFixture = filepath.Join("testdata", "test.json") ) })

测试套件应进一步组织为更下层的Describe容器,用消息描述测试目标;每个下层容器内用单个It承载具体 spec,It共享上下文并说明如何达成测试目标:

var _ = g.Describe("[default] STI build", func() { defer GinkgoRecover() var ( stiBuildFixture = filepath.Join("testdata", "test-build.yaml") oc = exutil.NewCLI("build-sti", kubeConfigPath()) ) g.Describe("Building from a template", func() { g.It(fmt.Sprintf("should create a image from %q template", filepath.Base(stiBuildFixture)), func() { ... } } }

源码层面,NewCLI() 会基于给定的 namespace 名称初始化 CLI 及 Kube framework 辅助结构,并注册g.BeforeEach(cli.SetupProject)在每条用例前创建项目、g.AfterEach(cli.TeardownProject)在用例后回收项目,因此测试用例无需自行管理项目生命周期。从 NewCLIWithoutNamespace() 的实现看,底层framework.Framework默认使用ClientQPS: 20、ClientBurst: 50的客户端限流参数,execPath固定为oc,kubeconfig 路径取自KubeConfigPath()——这与前置条件中要求设置KUBECONFIG环境变量相呼应。

命令动词与参数:Run / Args / Template

模拟oc命令时,先用Run()指定命令动词(get、create、start-build等),再用Args()追加参数,方法可以自由链式调用:

oc = oc.Run("create")
oc = oc.Run("create").Args("-f", testFixture)

Template()方法可给 CLI 命令附加 Go 模板参数,但前提是Run()中指定了get动词:

oc = oc.Run("get").Args("foo").Template("{{ .spec }}")

它等价于命令行执行:

$ oc get foo -o template --template='{{ .spec }}'

执行与断言:Execute / Output / By / Expect

执行命令有两种方式:Execute()执行命令并返回过程中发生的错误;Output()除返回错误外还返回命令输出:

err := oc.Run("create").Args("-f", testFixture).Execute()
buildName, err := oc.Run("start-build").Args("test").Output()

用 Ginkgo 的By函数打印下一组命令的意图,使测试日志可读:

g.By("starting a test build") buildName, err := oc.Run("start-build").Args("test").Output()

用 Gomega 的Expect语法对错误做断言:

err = oc.Run("create").Args("-f", stiEnvBuildFixture).Execute() o.Expect(err).NotTo(o.HaveOccurred())

CLI类型本身的字段设计也印证了这一接口语义:从 client.go 中的结构体定义看,CLI分别维护verb(命令动词)、globalArgs、commandArgs、finalArgs(最终拼接参数)、stdin/stdout/stderr(进程标准流)以及adminConfigPath(kubeconfig)等字段,Run()/Args()只是往这些字段累积状态,真正的进程执行发生在Execute()/Output()调用时(源码中对应Run于 L984、Args于 L1032、Output于 L1048、Execute于 L1158 的实现)。此外CLI还提供了KubeFramework()访问 Kubernetes framework 助手、SetupProject()/TeardownProject()管理项目,以及NewCLIWithFramework()、NewHypershiftManagementCLI()等针对不同场景(绑定已有 framework、Hypershift 管理集群)的构造方式,编写特殊场景测试时可按需选用。

七、小结:一个新 Extended 测试的完整流程

综合以上内容,向 origin 仓库提交一个新 extended 测试的标准路径是:

  1. 确认测试归属的功能域,将用例放入对应的 Go 包(如test/extended/builds/),fixture 放入 test/extended/testdata;
  2. 若需要特殊服务端配置,在test/extended/下新增同名 launcher 脚本,复用hack/lib中的环境与服务启动函数,并用 Ginkgo focus 圈定本组用例;
  3. 在顶层Describe中声明 bucket 前缀并创建exutil.NewCLI实例,按Run/Args/Template构造命令,用Execute/Output执行、o.Expect断言;
  4. 按标签规范决定是否加[Serial]、[Slow]、[Conformance]、[local]标签,避免慢测试拖慢并行分区;
  5. 本地用openshift-tests run-test <FULL_TEST_NAME>或正则过滤子集验证通过后再提交。
  • 测试
  • 云原生
  • 质量保障

【免费下载链接】origin

Conformance test suite for OpenShift

项目地址:https://gitcode.com/gh_mirrors/or/origin
点击查看免费下载
上一篇:Wayback Machine 扩展上手指南:3 步装好,找回消失的网页
下一篇:open-vela packages 快应用示例源码导读:Chart图表与Player播放器完整拆解指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询