Windmill 集成测试体系深度解析:基于 docker-compose 的升级兼容性与端到端回归方案 Windmill 集成测试体系深度解析基于 docker-compose 的升级兼容性与端到端回归方案【免费下载链接】windmillOpen-source developer platform to power your entire infra and turn scripts into webhooks, workflows and UIs. Fastest workflow engine (13x vs Airflow). Open-source alternative to Retool and Temporal.项目地址: https://gitcode.com/GitHub_Trending/wi/windmillWindmill 集成测试integration tests是该开源工作流引擎为保障每次提交到 main 分支后的端到端质量而设计的自动化测试体系先部署最新发布的稳定镜像再升级到本次提交构建的 dev 镜像并借助WMILL_RUNNING_DEV环境变量验证旧数据 新版本的升级兼容性。读完本文你将掌握该测试套件的完整执行流程、docker-compose 测试基础设施、各测试用例的断言逻辑以及如何在本地复现这套端到端回归方案。测试定位与核心设计思想集成测试位于仓库的 integration_tests 目录其设计目标非常明确在每次 push 到 main 分支时排除 tag 提交自动运行验证 Windmill 全链路功能在真实部署环境下的可用性。该体系最核心的设计思想是升级兼容性验证。传统集成测试往往只在单一版本上运行而 Windmill 的这套测试采用先跑稳定版、再跑 dev 版的双轮模式第一轮拉取[version.txt](https://link.gitcode.com/i/8a71e67f94201581555595ad68a4c777)中记录的最新已发布镜像部署完整的 Windmill 栈运行全部测试第二轮将栈升级到本次提交构建的 dev 镜像tag 为dev再次运行全部测试。两轮之间脚本、Flow、Schedule 等实体对象不会被删除而是带着第一轮部署的数据直接进入第二轮。此时WMILL_RUNNING_DEV环境变量被置为1测试代码据此切换行为——这正是验证在旧版本 Windmill 上部署的 scripts/flows/schedules升级后不会损坏的关键机制。部分测试只有在WMILL_RUNNING_DEV 1时才跳过或才运行从而将升级回归与纯 dev 新功能验证两类场景清晰隔离。测试流水线的四个阶段整个流程由 run.sh 脚本驱动set -euo pipefail保证任何一步失败即中止阶段操作说明1. 准备 Python 环境python -m venv .venv/并pip install -r requirements.txt创建独立虚拟环境避免污染系统 Python2. 启动稳定版栈WM_IMAGE... WM_VERSION... docker compose up -d部署[docker-compose.yml](https://link.gitcode.com/i/9c908a919323cb4999ba606daf37bc0c)定义的完整服务3. 第一轮测试.venv/bin/python -m unittest -v test针对已发布稳定版本运行全部测试类4. 升级并重测WM_VERSIONdev docker compose up -d然后WMILL_RUNNING_DEV1 python -m unittest -v test升级到 dev 镜像后重跑并同步收集日志到./logs/docker-compose.log其中docker compose logs --no-color --follow会将容器日志重定向到integration_tests/logs目录便于 CI 失败时归档排查。依赖清单见 requirements.txt核心为httpxHTTP 客户端、docker容器管理用于 agent worker 测试与gitpython。测试基础设施docker-compose 服务拓扑docker-compose.yml 定义了测试所需的完整服务栈共 5 个服务dbpostgres:14暴露5432端口通过 healthcheckpg_isready等待就绪数据持久化到db_data卷。注释指出如需外部数据库可将 replicas 设为 0 并在.env中指定DATABASE_URLwindmill_server${WM_IMAGE}:${WM_VERSION}暴露8000端口设置DATABASE_URL、MODEserverhealthcheck 用curl -f http://localhost:8000/api/version探测 API 可用性并依赖 db 健康windmill_worker同样使用${WM_IMAGE}:${WM_VERSION}MODEworker、WORKER_GROUPdefault限制 1 CPU / 2048M 内存挂载 Docker socket允许 worker 内部运行 Docker 容器及worker_dependency_cache卷注释提示调试时可KEEP_JOB_DIRtrue并挂载/tmp/windmillnpm_registryverdaccio/verdaccio端口4873为 SDK 测试提供私有 NPM registry配置见 verdaccio/config.yaml——监听localhost:4873与npm_registry:4873包默认代理到官方 npmjspypi_serverpypiserver/pypiserver:latest端口8080为 Python SDK 测试提供私有 PyPI 服务。镜像与版本由 common.sh 统一注入export WM_VERSION$(cat ${root_dirpath}/version.txt) export WM_VERSION_DEVdev export WM_IMAGEghcr.io/windmill-labs/windmill-ee即稳定版版本号取自 version.txt当前仓库为1.809.0dev 版固定为dev标签镜像统一使用 Enterprise 版镜像windmill-ee。测试用例集从多语言脚本到 Agent Worker所有测试类通过 test/init.py 聚合导出python -m unittest -v test会自动发现并运行它们。多语言脚本回归测试test/identity_script_test.py 验证 Windmill 支持的 6 种脚本语言bash、bun、deno、go、python3、php能否正确执行恒等函数并回传结果第一轮非 dev创建脚本create_script(pathu/admin/{lang}_identity_script, content..., languagelang)每个语言一个独立测试方法断言run_sync返回原值。有趣的是 bash 断言为字符串5注释说明bash only knows strings——体现了对不同语言类型系统的差异化处理dev 轮WMILL_RUNNING_DEV1则删除脚本完成对旧版本部署脚本的清理验证。跨语言 Flow 流水线测试test/increment_flow_test.py 是测试套件中最具代表性的用例构建一个 5 模块的 Flowdeno → bun → python3 → go → bash每个模块对输入x执行1并通过input_transforms串联{ id: b, value: { type: rawscript, content: export async function main(x: number) {\\n return x 1\\n}\\n, language: bun, input_transforms: { x: { expr: results.a, type: javascript } } } }最终断言输入x5经过5第一个模块的flow_input.x 5再加 4 次1后bash 输出字符串15。这同时验证了跨语言数据传递、results.{id}引用语法与 Flow 调度引擎的正确性。Schedule 定时调度测试test/schedule_test.py 创建基于脚本u/admin/scheduled_script和基于 Flowu/admin/scheduled_flow的两个 Schedulecron 表达式为*/5 * * * * *每 5 秒时区Europe/Paris。测试轮询jobs/list?script_path_exact...接口等待 30 秒内出现created_at晚于测试开始时间的运行记录从而证明调度器在稳定版与升级后的 dev 版上都能持续触发任务。Agent Worker 测试test/agent_workers.py 是套件中依赖 Docker SDK 的特殊用例覆盖 Windmill 的 Agent 模式通过/api/agent_workers/create_agent_token生成jwt_agent_前缀的 JWT token并解析 payload 断言worker_group、tags、exp字段用 Docker SDK 启动一个MODEagentAGENT_TOKEN...的容器通过get_workers_list轮询确认 Agent 成功连接创建一个带agent_test自定义标签的 bash 脚本并同步运行验证标签路由让任务落到 Agent worker 上。容器清理通过atexit.register(cleanup_docker_container)兜底防止测试崩溃后残留容器。WindmillClient测试与后端 API 的桥梁所有测试都复用 test/wmill_integration_test_utils.py 中的WindmillClient它封装了完整的 API 交互是理解测试原理的关键登录与会话向/api/auth/loginPOSTadminwindmill.dev / changeme与 docker-compose 的默认管理员一致换取 Bearer tokenclient 超时设为 60 秒——注释说明Go/Rust 首次编译可能耗时 10 秒以上License 注入_set_license_key读取LICENSE_KEY环境变量并 POST 到/api/settings/global/license_key这就是 README 中WM_LICENSE_KEY_CI的落地方式——Enterprise 版本必须携带有效 license key全部测试才能运行Workspace 管理自动创建integration-tests工作区已存在则跳过对应真实用户按 workspace 隔离资源的模型核心执行方法run_sync(path, args, type)POST 到/api/w/{workspace}/jobs/run_wait_result/{type}/{path}typep运行脚本、typef运行 Flow。该端点在后端实现于 jobs.rs 的run_wait_result_script_by_path会先校验 license keycheck_license_key_valid、校验 scopejobs:run:scripts:{path}、执行参数预处理再调用内部实现排队执行并等待结果部署状态轮询create_script提交后轮询/scripts/deployment_status/h/{hash}直至lock字段非空部署成功或出现lock_error_logs部署失败并带有 60 秒超时此外还封装了 Flow、Schedule、Variable、Resource、Git Sync 配置、fork workspace、Gitea 客户端等大量辅助方法。本地运行指南免镜像的轻量调试README 明确指出本地直接跑测试并不轻松——因为需要一份包含最新代码的 Docker 镜像。但测试本质上只是向http://localhost:8000发起 API 调用因此可以绕过容器直接用本地编译的二进制运行。前置条件WindmillEnterprise 版本需要 license key设置为环境变量WM_LICENSE_KEY_CI。以运行identity_script_test.py为例终端 1 启动本地服务cargo run --features enterprise终端 2 运行测试python -m unittest -v test.TestIdentityScript这种真实后端 Python 测试客户端的模式让开发者无需构建 Docker 镜像即可快速验证单点功能。注意部分测试需要额外准备详见下文 SDK 测试。SDK 测试的特殊准备私有 registry 发布README 特别提示SDK 相关测试需要 Windmill SDK 包先发布到私有 NPM registry 或 PyPI 服务器自定义准备逻辑封装在 build.sh 中。该脚本的完整流程为source common.sh读取镜像与版本变量docker pull稳定版与 dev 版镜像调用.github/change-versions.sh将版本号临时改为${WM_VERSION}-dev启动npm_registry服务通过 curl 向 Verdaccio 注册windmill用户密码changeme再用npm-cli-login完成登录执行 typescript-client/publish.sh 将 TypeScript SDK 发布到http://localhost:4873docker compose down清理并通过change-versions.sh恢复原版本号。脚本末尾的注释# TODO: publish Python SDK to private PyPI registry表明 Python SDK 的发布逻辑尚未实现——这也解释了 README TODO 列表中Test Python SDK的由来。CI 集成与镜像构建流水线的联动这套测试并非孤立运行而是作为 Docker 镜像发布流水线的质量关卡。在 .github/workflows/docker-image.yml 中run_integration_testjob 依赖build_eeEnterprise 镜像构建运行在ubicloud上步骤为- name: Prepare test run run: cd integration_tests ./build.sh - name: Test run timeout-minutes: 15 env: LICENSE_KEY: ${{ secrets.WM_LICENSE_KEY_CI }} run: cd integration_tests ./run.sh - name: Archive logs uses: actions/upload-artifactv4 with: path: integration_tests/logs两个步骤都带有条件! startsWith(github.ref, refs/tags/v)与 README 所述每次 push 到 main排除 tags一致测试失败时日志会作为 artifact 归档tag_latestjob 又依赖run_integration_test集成测试通过后才允许打latesttag可见该套件是发布门禁的重要一环。已知缺口待补充的测试场景README 的 TODO 列表清晰标注了当前套件尚未覆盖的领域对希望贡献测试代码的开发者是很好的切入点测试 Python SDK测试 job 失败场景当前主要验证成功路径测试专用 workerdedicated workersSchedule 的 Error handlers 与 Recovery handlers并发限制Concurrency limits小结Windmill 的集成测试体系提供了一套可复用的升级兼容性 端到端回归参考范式以 docker-compose 构建接近生产的服务拓扑用轻量 Python 客户端直连真实 API通过环境变量切换旧数据跑新版本的验证模式并让该套件嵌入 CI 作为发布门禁。对于需要保障数据库与已部署实体跨版本不破坏的开发者这套方案的思路稳定版播种 → dev 版回归 → 差异化断言可以直接借鉴。【免费下载链接】windmillOpen-source developer platform to power your entire infra and turn scripts into webhooks, workflows and UIs. Fastest workflow engine (13x vs Airflow). Open-source alternative to Retool and Temporal.项目地址: https://gitcode.com/GitHub_Trending/wi/windmill创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考