十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Cog 项目测试利器:test-registry-util 本地镜像仓库的创建、检查与测试集成指南

Cog 项目测试利器:test-registry-util 本地镜像仓库的创建、检查与测试集成指南 Cog 项目测试利器test-registry-util 本地镜像仓库的创建、检查与测试集成指南【免费下载链接】cogContainers for machine learning项目地址: https://gitcode.com/GitHub_Trending/co/cogtest-registry-util是 CogContainers for machine learning仓库中专门用于创建和检查本地测试用镜像仓库的命令行工具。它面向拥有大量复杂镜像操作代码需要测试的场景——mock 无法保证代码在真实数据下工作因此该工具负责在测试中启动一个真实、随机的本地 registry并以真实镜像数据填充。读完本文你将掌握如何用catalog/init/run三个子命令管理测试镜像数据如何用pkg/registry_testhelpers在 Go 测试中一键拉起带真实数据的 registry以及这些工具背后的容器与 OCI 镜像索引原理。为什么测试需要真实的镜像仓库Cog 项目涉及大量细碎的镜像操作代码推送、拉取、解析 manifest、处理多平台索引等。其工具说明tools/test-registry-util/README.md直言Mocks arent great for this because we need to make sure the code works with actual data.也就是说mock 无法验证代码与真实数据的交互是否符合预期所以项目维护了一套真实的镜像数据供测试使用。这套数据以distribution/distributionDocker Registry 服务端期望的磁盘布局存放在仓库中测试期间会在随机本地端口拉起一个临时 registry用这些数据填充测试结束自动关闭。test-registry-util就是这套机制的数据生产与检查工具。工具定位与数据存储布局工具入口位于 tools/test-registry-util/main.go基于spf13/cobra构建提供三个子命令init、catalog、run。所有命令都支持一个持久化 flag--storage-dir registry 数据存储目录默认 pkg/registry_testhelpers/testdata镜像数据存储在pkg/registry_testhelpers/testdata目录下其结构匹配distribution/distribution的存储布局。从仓库实际内容看pkg/registry_testhelpers/testdata/docker/registry/v2/典型的目录组织为registry/ v2/ blobs/sha256/前两位/完整sha256/data # 内容寻址的 blob 数据 repositories/alpine/ _layers/sha256/sha256/link # 层引用 _manifests/ revisions/sha256/... # manifest 修订记录 tags/latest/current/link # 标签指向的 manifest digest例如pkg/registry_testhelpers/testdata/docker/registry/v2/repositories/alpine/_manifests/tags/latest/current/link的内容即是指向 index manifest 的 digestsha256:9a0ff41dccad7a96f324a4655a715c623ed3511c7336361ffa9dadcecbdb99e5为什么把镜像数据提交进 git从 main.go 中的注释可以看到约束Keep the images sizes small since theyre stored in git. For reference, thealpine:latestimage forlinux/amd64~3.5MB compressed.——即选用的镜像必须足够小以便随仓库版本管理。三个子命令的实战用法catalog检查 registry 中的镜像在仓库根目录执行go run ./tools/test-registry-util catalog工具会启动一个临时 registry 容器挂载--storage-dir指定的数据目录然后遍历其中的仓库与标签打印类似如下的目录树alpine:latest application/vnd.oci.image.index.v1json index - sha256:9a0ff41dccad7a96f324a4655a715c623ed3511c7336361ffa9dadcecbdb99e5 linux/amd64 - sha256:1c4eef651f65e2f7daee7ee785882ac164b02b78fb74503052a26dc061c90474 linux/arm64 - sha256:757d680068d77be46fd1ea20fb21db16f150468c5e7079a08a2e4705aec096ac python:3.10 application/vnd.oci.image.manifest.v1json single platform image - sha256:f33bb19d5a518ba7e0353b6da48d58a04ef674de0bab0810e4751230ea1d4b19输出揭示了两种镜像形态多平台 indexapplication/vnd.oci.image.index.v1jsonalpine:latest是一个 index下面分别列出linux/amd64与linux/arm64各自的 manifest digest单平台镜像application/vnd.oci.image.manifest.v1jsonpython:3.10直接是单个 manifest。基于此测试代码中就可以使用多种引用方式localhost:port/alpine:latest—— 拿到多平台 indexlocalhost:port/alpine:latest 平台linux/amd64—— 从多平台 index 中取单个镜像localhost:port/alpine:latestsha256:1c4eef651f65e2f7daee7ee785882ac164b02b78fb74503052a26dc061c90474—— 按 digest 精确取特定镜像localhost:port/python:3.10—— 拿单平台镜像。init重新生成 registry 存储当需要重建/更新测试镜像数据时go run ./tools/test-registry-util init它会下载main.go中images变量指定的全部镜像推送到临时 registry最后把完整数据复制到pkg/registry_testhelpers/testdata。注意一个保护性检查如果目标目录非空init 会直接报错退出源码见 main.go避免意外覆盖现有数据。当前images列表只包含一个镜像定义var images []struct { Image string Platforms []string SinglePlatform string }{ { Image: alpine:latest, Platforms: []string{ linux/amd64, linux/arm64, }, }, }从结构体字段可以看出两种推送模式Platforms列表用于构建多平台 indexSinglePlatform则直接把单平台镜像按标签推送。run在测试之外查看 registryrun是一个便利命令用于在测试环境之外启动 registry 以便人工检查go run ./tools/test-registry-util run它会以当前--storage-dir为数据目录启动 registry 容器并打印监听地址例如Registry running at localhost:port按下 CtrlC 后自动终止容器源码基于signal.NotifyContext监听中断信号main.go。在测试代码中启动真实 registry这是该工具链最核心的用途。仓库提供了pkg/registry_testhelpers包pkg/registry_testhelpers/registry_container.goREADME 中给出的最小示例import github.com/replicate/cog/pkg/registry_testhelpers func TestMyFunction(t *testing.T) { registryContainer : registry_testhelpers.StartTestRegistry(ctx) image : registryContainer.ImageRef(alpine:latest) // use image as a real image reference }实际项目中完整用法为StartTestRegistry(t)其工作流程见 registry_container.go读取当前源码目录下的testdata/docker作为测试镜像数据在 10249999 的 insecure 端口范围内挑选一个空闲端口Docker 将 localhost 的 1-9999 视为 insecure 端口无需 TLS通过 testcontainers 启动registry:3容器将数据目录拷贝进容器的/var/lib/registry/并绑定宿主端口等待/的 HTTP 探活成功10 秒超时通过t.Cleanup注册清理函数测试结束自动销毁容器无需手动关闭。StartTestRegistry在并发测试中是安全的源码注释明确 This is safe to run concurrently across multiple tests因为每个测试实例使用独立的随机端口。RegistryContainer 的辅助 API拿到*RegistryContainer后常用方法包括见 registry_container.goImageRef(ref string) string把alpine:latest拼成localhost:port/alpine:latest形式的完整引用ImageRefForTest(t, label)生成以测试名称为仓库名、以 label缺省为时间戳为标签的引用避免测试间仓库名冲突CloneRepo(t, existingRepo, newRepo)用crane.CopyRepository复制整个仓库适合需要从既有数据派生新仓库的场景CloneRepoForTest(t, repo)把既有仓库复制为以测试名命名的仓库ImageExists(t, ref) error通过remote.Head检查镜像是否已存在RegistryHost()返回localhost:port地址。带认证的 registry如果需要验证认证逻辑可以用WithAuth(username, password)选项authReg : registry_testhelpers.StartTestRegistry(t, registry_testhelpers.WithAuth(testuser, testpass))其实现会生成 bcrypt 加密的 htpasswd 并通过registry.WithHtpasswd配置容器见 registry_container.go。启用后ImageExists等操作会自动携带对应凭据模拟真实带鉴权的镜像仓库。源码级原理init 如何组装多平台 indexmain.go 中的runAndInit完整展示了拉取-重推-组装的流程核心步骤值得细读校验目标目录为空随后在临时目录启动 registry 容器对每个源镜像、每个平台用remote.Image(srcRef, remote.WithPlatform(plat))按平台拉取 manifest先按 digest 推入新 registrydestReposha256:...确保 blob 与 manifest 全部落盘通过mutate.AppendManifests把该平台的 manifest 及其v1.Descriptor{Platform: plat}追加进 index全部平台追加完毕后把 index 的 media type 设为 OCI 标准mutate.IndexMediaType(empty.Index, types.OCIImageIndex)并以标签形式推送remote.WriteIndex将临时 registry 的完整数据目录用os.CopyFS复制到--storage-dir最后调用catalog打印结果便于人工核对。这套按 digest 推 组 index 打标签的顺序保证了仓库中 blob 去重、index 引用关系完整也是离线分发 OCI 制品时的标准做法。源码级原理catalog 如何枚举镜像树catalog函数main.go使用google/go-containerregistry分三层遍历remote.Catalog列出全部仓库对每个仓库remote.List列出全部标签对每个标签remote.Get取 manifest按 media type 分支输出types.OCIImageIndex/types.DockerManifestList打印 index digest 及其中每个平台的 manifest digest其他类型当作单平台镜像打印 manifest digest。这套枚举逻辑与distribution/distribution的存储结构一一对应repositories/repo/_manifests/tags/tag/下的 link 文件即指向 manifest 的 digest可以作为理解 Docker Registry 内部布局的活教材。项目中的实际使用案例在仓库中可以找到大量消费这套基础设施的集成测试可作为编写测试的参考模板pkg/registry/push_test.goTestPushOperations中StartTestRegistry(t)后用empty.Image构造镜像验证PushImage/PushIndex与Exists还特别验证了PushIndex不会递归推送子 manifest需要先推子镜像再推 indexpkg/model/weight_pipeline_e2e_test.go重量级权重制品.safetensors、.nemo的 Pack → WeightPusher 端到端测试推入真实 registry 后再逐层拉回并逐字节比对覆盖v1 制品解包后磁盘形态正确这一关键性质pkg/docker/docker_client_test.go常规启动与带WithAuth认证的启动两种模式pkg/registry/client_test.goregistry 客户端行为的集成验证。这些测试共同说明了一个实践准则凡是涉及镜像引用解析、推送、拉取、manifest 类型分支的逻辑都应优先使用真实 registry 而非 mock 验证。注意事项与使用前提需要 Docker 环境无论catalog/init/run还是测试中的StartTestRegistry都依赖 testcontainers 启动registry:3容器因此运行环境必须可用 Docker镜像体积约束由于镜像数据随仓库提交新增测试镜像时应遵循 main.go 注释的约束选择体积小的镜像如 alpine避免撑爆仓库init 是幂等重建init会拒绝写入非空目录更新数据前需先清空目标目录端口选择测试 registry 使用 10249999 的 insecure 端口范围无需 TLS适合本地集成测试若测试需要 https 场景需另行扩展run命令的定位它只是测试外查看 registry的便利手段常规测试流程应始终走StartTestRegistry让容器生命周期由t.Cleanup自动管理。小结test-registry-util与pkg/registry_testhelpers构成了 Cog 项目以真实数据验证镜像代码的完整测试基础设施init负责从上游拉取并生成随仓库分发的 registry 数据catalog负责可视化检查镜像树run提供测试外的人工排查入口而StartTestRegistry则把这一切无缝接入 Go 测试生命周期。对任何需要处理 OCI 镜像、多平台索引或容器注册表交互的 Go 项目而言这套模式都值得直接借鉴。【免费下载链接】cogContainers for machine learning项目地址: https://gitcode.com/GitHub_Trending/co/cog创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表