ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Woodpecker 测试体系与 dummy 后端:无容器环境的流水线集成测试指南

Woodpecker 测试体系与 dummy 后端:无容器环境的流水线集成测试指南 CI/CDDevOps【免费下载链接】woodpeckerWoodpecker is a simple, yet powerful CI/CD engine with great extensibility.项目地址https://gitcode.com/gh_mirrors/wo/woodpecker点击查看免费下载导读本文基于 Woodpecker 开发文档中的 Testing 章节系统梳理该 CI/CD 引擎的测试策略重点剖析其独特的dummy 后端一个不执行任何真实命令、却能完整模拟典型后端生命周期SetupWorkflow → StartStep → TailStep → WaitStep → DestroyStep → DestroyWorkflow的测试专用后端。读者读完本文后将掌握如何用test构建标签编译带 dummy 后端的 agent 与 CLI、如何编写可离线运行的流水线测试配置、如何利用六类环境变量模拟各种步骤失败场景以及如何从源码层面理解 dummy 后端的内部状态机与取消语义。后端测试总览单元测试 集成测试双层策略Woodpecker 的后端backend承担着与具体执行环境Docker、Kubernetes、本地进程等交互的职责因此其测试策略分为两层单元测试Unit Tests采用 Go 语言默认的go test测试框架并借助github.com/stretchr/testify/assert就完整覆盖了步骤成功、步骤失败、日志读取失败、启动失败、取消等路径。集成测试Integration Tests验证流水线引擎pipeline runtime与后端之间的完整调用链。这里的关键问题是真实容器后端依赖 Docker/Kubernetes 环境无法在 CI 或本地任意复现于是 Woodpecker 提供了dummy 后端作为集成测试的执行载体。dummy 后端是什么为什么需要dummy 后端是一个不执行任何命令的特殊后端它模拟的是一个典型后端应有的行为。它的价值在于无需任何容器运行时Docker、Podman 等即可运行完整流水线让流水线引擎pipeline/runtime 等与后端之间的协议交互创建环境、启动步骤、拉取日志、等待结束、销毁得到端到端验证可以精确控制步骤的睡眠时长、退出码、失败时机从而把难以稳定复现的故障变成确定性测试。从源码结构看dummy 后端位于 pipeline/backend/dummy/dummy.go它实现了backend_types.Backend接口pipeline/backend/types 定义其内部用sync.Map作为键值存储来追踪工作流workflow与步骤step的状态状态流转为started → done。如何启用test构建标签dummy 后端默认不参与正式构建整个文件顶部带有//go:build test构建约束见 dummy.go。要在 agent 或 CLI 中启用它需要用test标签重新编译# 编译带 dummy 后端的 CLI可用于本地 exec 调试 go build -tags test -o woodpecker-cli go.woodpecker-ci.org/woodpecker/v3/cmd/cli # 编译带 dummy 后端的 agent go build -tags test -o woodpecker-agent go.woodpecker-ci.org/woodpecker/v3/cmd/agent为什么需要test标签而不是直接内置因为注册逻辑放在独立的init()文件中agent 的 cmd/agent/dummy.go 与 CLI 的 cli/exec/dummy.go 都带有//go:build test约束仅在带该标签构建时通过backends append(backends, dummy.New())将 dummy 注册进后端列表。这样正式发布产物不含测试代码而测试与调试构建可以无缝获得该能力。这也与 Makefile 中的测试目标一致——make test-agent、make test-cli等均通过-tags test $(TAGS)注入该标签。实战一用 dummy 后端运行一个示例流水线编写流水线配置文档给出了一个同时包含步骤step与服务service的示例配置。注意其中image: dummy是关键流水线引擎据此把该步骤路由给 dummy 后端执行when: event: manual steps: - name: echo image: dummy commands: echo hello woodpecker environment: SLEEP: 1s services: echo: image: dummy commands: echo i am a service该配置演示了两个典型场景stepsimage: dummy的普通命令步骤通过environment.SLEEP: 1s让步骤模拟运行 1 秒真实后端中该时间用于容器启动与命令执行services同名的echo服务同样是 dummy 镜像——dummy 后端对 service 类型步骤的处理与命令步骤不同详见下文源码解读部分。执行命令与完整日志解读使用带test标签编译出的 CLI通过--backend-engine dummy指定执行引擎配合--log-level trace观察完整生命周期woodpecker-cli --log-level trace exec --backend-engine dummy example.yaml文档给出了执行后的 trace 级别日志日志中的行号对应源码位置可对照下文源码解读验证调用链9:18PM DBG pipeline/pipeline.go:94 executing 2 stages, in order of: CLIexec 9:18PM DBG pipeline/pipeline.go:104 stage CLIexec StagePos0 Stepsecho 9:18PM DBG pipeline/pipeline.go:104 stage CLIexec StagePos1 Stepsecho 9:18PM TRC pipeline/backend/dummy/dummy.go:75 create workflow environment taskUUID01J10P578JQE6E25VV1EQF0745 9:18PM DBG pipeline/pipeline.go:176 prepare CLIexec stepecho 9:18PM DBG pipeline/pipeline.go:203 executing CLIexec stepecho 9:18PM TRC pipeline/backend/dummy/dummy.go:81 start step echo taskUUID01J10P578JQE6E25VV1EQF0745 9:18PM TRC pipeline/backend/dummy/dummy.go:167 tail logs of step echo taskUUID01J10P578JQE6E25VV1EQF0745 9:18PM DBG pipeline/pipeline.go:209 complete CLIexec stepecho [echo:L0:0s] StepName: echo [echo:L1:0s] StepType: service [echo:L2:0s] StepUUID: 01J10P578JQE6E25VV1A2DNQN9 [echo:L3:0s] StepCommands: [echo:L4:0s] ------------------ [echo:L5:0s] echo ja [echo:L6:0s] ------------------ [echo:L7:0s] 9:18PM DBG pipeline/pipeline.go:176 prepare CLIexec stepecho 9:18PM DBG pipeline/pipeline.go:203 executing CLIexec stepecho 9:18PM TRC pipeline/backend/dummy/dummy.go:81 start step echo taskUUID01J10P578JQE6E25VV1EQF0745 9:18PM TRC pipeline/backend/dummy/dummy.go:167 tail logs of step echo taskUUID01J10P578JQE6E25VV1EQF0745 [echo:L0:0s] StepName: echo [echo:L1:0s] StepType: commands [echo:L2:0s] StepUUID: 01J10P578JQE6E25VV1DFSXX1Y [echo:L3:0s] StepCommands: [echo:L4:0s] ------------------ [echo:L5:0s] echo ja [echo:L6:0s] ------------------ [echo:L7:0s] 9:18PM TRC pipeline/backend/dummy/dummy.go:108 wait for step echo taskUUID01J10P578JQE6E25VV1EQF0745 9:18PM TRC pipeline/backend/dummy/dummy.go:187 stop step echo taskUUID01J10P578JQE6E25VV1EQF0745 9:18PM DBG pipeline/pipeline.go:209 complete CLIexec stepecho 9:18PM TRC pipeline/backend/dummy/dummy.go:208 delete workflow environment taskUUID01J10P578JQE6E25VV1EQF0745这段日志本身就是一个可观测的生命周期时序图你可以据此验证引擎先创建 workflow 环境create workflow environment随后对每个阶段中的步骤依次执行prepare → executing → start → tail logs → complete每个步骤的模拟日志以[echo:Ln:0s]前缀输出内容是dummyExecStepOutput生成的格式化信息StepName、StepType、StepUUID、StepCommandsservice 类型步骤先于 commands 步骤被调度最后统一销毁stop step、delete workflow environment。实战二通过环境变量注入故障场景dummy 后端最强大的能力在于用环境变量精确控制步骤行为从而在无容器环境下确定性模拟各类故障。文档列举了六类控制项结合 dummy.go 源码 中的常量定义整理如下环境变量作用源码常量触发位置SLEEP: 10让步骤运行并等待 10 秒接受 Go duration 格式如1sEnvKeyStepSleepWaitStep中通过time.ParseDuration解析EXPECT_TYPE校验步骤类型是否为clone、service、plugin或commands不匹配则启动失败EnvKeyStepTypeStartStep中与step.Type比对STEP_START_FAIL: true模拟步骤在真正启动前失败例如容器镜像拉取失败EnvKeyStepStartFailStartStep中直接返回错误STEP_TAIL_FAIL: true模拟读取 stdout 日志时出错EnvKeyStepTailFailTailStep中返回错误STEP_EXIT_CODE: 2指定步骤退出码默认 0EnvKeyStepExitCodeWaitStep中作为返回的ExitCodeSTEP_OOM_KILLED: true模拟步骤因内存限制被 OOM 杀死EnvKeyStepOOMKilledWaitStep中设置返回状态的OOMKilled字段此外还有一个工作流级故障注入手段将整个工作流的 UUID 设置为WorkflowSetupShouldFail即可让SetupWorkflow直接返回错误模拟工作流环境创建失败的场景例如后端无法准备执行环境。这一点在源码中由常量WorkflowSetupFailUUID WorkflowSetupShouldFail定义dummy.goSetupWorkflow中通过if taskUUID WorkflowSetupFailUUID直接返回 expected fail to setup workflow 错误。例如要测试步骤启动失败路径只需在步骤的 environment 中写入steps: - name: start-fail-demo image: dummy commands: echo should not really run environment: STEP_START_FAIL: true而模拟 OOM 被杀则是steps: - name: oom-demo image: dummy commands: echo oom demo environment: STEP_OOM_KILLED: true STEP_EXIT_CODE: 137源码解读dummy 后端的状态机与取消语义生命周期与状态校验dummy 后端严格遵循后端接口的标准生命周期并对每一步做状态校验这本身就是在测试引擎是否按协议调用后端SetupWorkflow为工作流在sync.Map中创建停止信号 channel若 UUID 等于WorkflowSetupShouldFail则返回错误StartStep校验工作流环境存在、校验步骤未被重复启动源码注释中甚至提到这是为了回归检测 issue #3494 一类的已启动步骤被再次启动缺陷、校验EXPECT_TYPE与STEP_START_FAIL然后写入started状态TailStep校验步骤已started若设置了STEP_TAIL_FAIL则报错否则返回dummyExecStepOutput生成的伪日志见 dummy.go输出包含 StepName / StepType / StepUUID / StepCommandsWaitStep根据SLEEP睡眠指定时长若未设置 SLEEP则 service 类型步骤固定等待 1 秒常量testServiceTimeout超时未结束即报错普通命令步骤仅time.Sleep(time.Nanosecond)即返回随后依据STEP_EXIT_CODE默认 0与STEP_OOM_KILLED组装返回状态DestroyStep / DestroyWorkflow清理sync.Map中的键其中DestroyWorkflow会关闭停止 channel通知所有正在睡眠的步骤退出。步骤类型常量定义在 pipeline/backend/types/step.goclone、service、plugin、commands与EXPECT_TYPE的校验取值一一对应。取消语义退出码 130dummy 后端对步骤被取消的处理值得特别说明在WaitStep的睡眠过程中一旦上下文context被取消sleepWithContext会返回 canceled 状态此时WaitStep返回ExitCodeCanceled其值为130对应 shell 约定的 SIGINT 退出码 128 2与真实容器运行时的取消语义保持一致dummy.go。这一行为在 dummy_test.go 的TestWaitStepCanceledBySleep中有确定性测试先启动一个SLEEP: 30s的步骤再取消上下文断言WaitStep不报错、步骤标记为 exited、退出码为 130且DestroyStep依然可以成功执行——这正是工作流上下文在 WaitStep 完成前被取消的边界场景。测试即文档dummy_test.go 的覆盖矩阵dummy_test.go 是理解 dummy 后端行为最直接的可执行文档TestSmalPipelineDummyRun包含四个子场景对不存在的工作流调用 StartStep/TailStep/WaitStep 均应报错正常步骤完整走通生命周期且退出码为 0EXPECT_TYPE STEP_EXIT_CODE: 1的 plugin 步骤返回退出码 1STEP_TAIL_FAIL使 TailStep 报错STEP_START_FAIL的 service 步骤使 StartStep 报错、TailStep 与 WaitStep 均报错TestWaitStepCanceledBySleep验证取消路径与退出码 130。这些测试全部使用 testify 的assert/require编写与文档使用默认 golang 单元测试 testify/assert 简化断言的说明完全一致也为后续新增故障注入能力提供了范式。适用场景与注意事项何时使用本地快速调试流水线编排逻辑、为 CLIexec命令做离线验证、在 CI 中跑不需要真实容器的集成测试Makefile 的测试目标即通过-tags test注入。限制dummy 后端不执行真实命令因此无法验证命令本身的正确性、镜像构建、网络等真实行为它验证的是引擎与后端之间的协议与生命周期。版本说明dummy 后端的核心机制在各版本文档中保持一致当前仓库源码v3模块路径与本文引用的实现一致本文命令示例基于woodpecker-cli exec子命令该命令的完整参数可参考 cli/exec 与 cli/common/pipeline.go。延伸阅读后端接口定义与各真实实现pipeline/backenddocker、kubernetes、local、dummy流水线运行时如何驱动后端pipeline/runtime后端类型定义含 StepType 常量pipeline/backend/types/step.goCLI exec 子命令实现cli/exec/exec.go本仓库测试目标与test标签注入方式Makefile赞分享CI/CDDevOps【免费下载链接】woodpeckerWoodpecker is a simple, yet powerful CI/CD engine with great extensibility.项目地址https://gitcode.com/gh_mirrors/wo/woodpecker点击查看免费下载相关推荐Woodpecker 测试体系全解析单元测试、Dummy 后端与集成测试实战Woodpecker 测试体系全解析单元测试、Dummy 后端与集成测试实战 本篇技术指南聚焦 Woodpecker CI/CD 引擎的开发测试体系系统讲解CI/CDDevOpsbRPC集成测试端到端测试与持续集成流水线bRPC集成测试端到端测试与持续集成流水线 在分布式系统开发中服务间的通信可靠性直接影响系统稳定性。你是否曾遇到过单元测试通过但服务联调时出现超时、数据不一后端RPC框架通信网络Data Formulator集成测试端到端测试与CI/CD流水线Data Formulator集成测试端到端测试与CI/CD流水线 痛点AI数据可视化工具的测试挑战 你还在为复杂的AI驱动数据可视化工具编写繁琐的端到端测数据可视化人工智能AI 应用数据分析前端后端AI Agent上一篇GitHub_Trending/tmu/tmux文档翻译规范术语表与风格指南下一篇Hermes Agent 启动脚本排错指南依赖检查、错误处理与 30 秒验证怎么做创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表