ARTICLE DETAIL

资讯详情

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

Osmedeus 云功能 E2E 与集成测试指南:多提供商分布式扫描的完整验证体系

Osmedeus 云功能 E2E 与集成测试指南:多提供商分布式扫描的完整验证体系 Osmedeus 云功能 E2E 与集成测试指南多提供商分布式扫描的完整验证体系【免费下载链接】osmedeusA Modern Orchestration Engine for Security项目地址: https://gitcode.com/GitHub_Trending/os/osmedeus本篇技术指南围绕 OsmedeusA Modern Orchestration Engine for Security的云功能测试体系展开系统讲解test/e2e/CLOUD_TESTS_README.md所定义的端到端E2E测试与集成测试的组织方式、运行命令、覆盖范围与底层实现。读完本文你将掌握如何运行云测试套件make test-e2e-cloud与make test-cloud、理解 E2E CLI 测试与内部包集成测试的分工边界、读懂cloud-settings.yaml配置结构对应的源码校验逻辑并能用相同的测试模式为云功能新增测试用例。云测试体系概览两层验证架构Osmedeus 的云功能cloud feature用于在多个云厂商DigitalOcean、AWS、GCP、Linode、Azure以及源码中同样支持的 Hetzner上拉起分布式安全扫描集群。围绕这一功能测试被刻意划分为两层各自解决不同层面的验证问题E2E 测试test/e2e/cloud_test.go——以真实 CLI 命令为被测对象验证osmedeus cloud ...子命令的完整行为链配置写入、帮助输出、参数校验、错误处理等。它编译并运行真实二进制属于黑盒验证。集成测试test/integration/cloud_integration_test.go——直接调用internal/cloud与internal/config包内的函数验证配置持久化、环境变量解析、校验规则、成本追踪与基础设施状态管理等内部逻辑属于白盒验证。从源码结构看E2E 测试依赖pkg/cli/cloud.go中由 Cobra 定义的cloud命令树config set/list/clean、create、list、destroy、run而集成测试直接依赖 internal/cloud/config.go、internal/cloud/state.go 与 internal/cloud/cost.go 中的导出函数。两层测试共同覆盖了CLI 入口正确 → 内部实现正确的完整链路。快速开始三种运行方式方式一Makefile 目标推荐Makefile 中定义了专门的云测试目标test-e2e-cloud会先执行build编译二进制再运行匹配TestCloud前缀的 E2E 测试test-cloud直接运行云集成测试文件# 运行全部云 E2E 测试自动编译二进制并安装 gotestsum make test-e2e-cloud # 运行云集成测试internal/cloud 包内部逻辑 make test-cloud # 两者一起跑 make test-e2e-cloud test-cloud两个 Makefile 目标的实现分别对应# Makefile 中的定义 test-e2e-cloud: build install-gotestsum $(TESTCMD) $(TESTFLAGS) -run TestCloud ./test/e2e/... test-cloud: install-gotestsum $(TESTCMD) $(TESTFLAGS) ./test/integration/cloud_integration_test.go注意Makefile 默认优先使用gotestsum若已安装以 testdox 格式输出未安装时自动回退到原生go test -v。test-e2e-cloud中的build依赖意味着首次运行会先编译cmd/osmedeus主程序。方式二go test 直接运行# 运行单个 E2E 测试 go test -v -run TestCloud_ConfigSet ./test/e2e/ go test -v -run TestCloud_ConfigShow ./test/e2e/ # 运行全部云 E2E需要显式列出 e2e_test.go因为它提供了二进制构建与日志工具 go test -v ./test/e2e/cloud_test.go ./test/e2e/e2e_test.go # 运行集成测试 go test -v ./test/integration/cloud_integration_test.go # 短模式跳过耗时长测 go test -v -short ./test/e2e/cloud_test.go ./test/e2e/e2e_test.goE2E 测试的关键前提getBinaryPath定义于 test/e2e/e2e_test.go会在首次调用时通过go build -o build/bin/osmedeus ./cmd/osmedeus自动编译二进制并用sync.Once保证整个测试进程只构建一次。方式三短模式快速验证-short标志对云测试尤为重要——云 E2E 测试全部以if testing.Short() { t.Skip(...) }开头因此短模式会跳过所有云 E2E 用例集成测试中的TestInfrastructureState等不涉及长时间等待的用例仍会执行。适合在 CI 快速冒烟或本地快速验证编译正确性时使用。测试覆盖全景E2E CLI 测试cloud_test.go所有用例都通过runCLIWithLog/runCLIWithLogAndBase执行真实 CLI按功能域可归纳为六组配置管理TestCloud_ConfigSet——设置providers.digitalocean.token等键值断言输出包含 Configuration updated successfullyTestCloud_ConfigShow——先写defaults.provider与defaults.max_instances再show并断言输出含provider:与digitaloceanTestCloud_ConfigSetInvalidKey——验证invalid.nested.key.that.does.not.exist这类非法键的错误处理TestCloud_ConfigEnvironmentVariables——写入${TEST_DIGITALOCEAN_TOKEN}引用并验证环境变量解析TestCloud_ConfigFileCreation——用--base-folder指定独立目录验证cloud-settings.yaml文件确实落盘且内容包含目标值TestCloud_MultipleProviderConfigs——同时配置 DigitalOcean 与 AWS 两组凭据TestCloud_CostLimitConfiguration——配置limits.max_hourly_spend/limits.max_total_spend/limits.max_instancesTestCloud_SSHKeyConfiguration——配置ssh.private_key_path与ssh.userTestCloud_ProviderRegions——为全部 5 个提供商写入区域nyc3/us-east-1/us-central1/us-east/eastus基础设施管理TestCloud_CreateHelp——断言create --help输出包含--provider、--mode、--instances、--forceTestCloud_CreateWithoutConfig——无凭据创建时验证错误提示包含token或输出 not yet fully implemented 占位信息TestCloud_CreateDryRun——预配置 token 与 region 后执行创建检查输出是否包含cost/hourly成本估算信息TestCloud_List——验证cloud list在无基础设施时给出友好提示、有基础设施时输出表格含ID列TestCloud_DestroyHelp——验证destroy --help输出包含destroy与infrastructureTestCloud_DestroyNonExistent——销毁不存在的 ID 时验证not found错误处理工作流执行TestCloud_RunHelp——断言run --help输出包含--provider、--instances、--flowTestCloud_RunWithoutTarget——不带-t目标运行时验证错误提示包含targetTestCloud_RunWithDistributed——在临时 base 目录中组合-m test-bash、-F workflow.yaml、-t example.com、--instances 2、--provider digitalocean的完整云运行命令序列验证与错误处理TestCloud_ProviderValidation——--provider invalid-provider-name应被拒绝TestCloud_InstanceCountValidation——--instances 0与--instances -1均应报错TestCloud_StateDirectory——配置state.backend为local验证cloud-state目录路径约定TestCloud_WithTimeout——配置defaults.timeout为5mTestCloud_Cleanup_OnFailure——配置defaults.cleanup_on_failuretrue与无效 token创建失败后检查cloud-state/infrastructure目录中不残留状态文件高级测试TestCloud_Integration_FullLifecycle——串行执行配置提供商 → create → list → destroy --all完整命令序列长时测试短模式跳过TestCloud_Distributed_WorkerRegistration——占位测试规划了 Redis master worker 注册的完整验证步骤TestCloud_CostTracking——占位测试规划了小时成本计算、实时成本更新、限额执行与完成摘要TestCloud_ParallelOperations——用两个 goroutine 在不同 base 目录并发执行配置操作配合 30 秒超时验证操作隔离TestCloud_SpotInstanceConfiguration——配置providers.aws.use_spot、providers.gcp.use_preemptible、defaults.use_spotTestCloud_CustomSetupCommands——验证setup.commands数组配置路径的可用性这些测试与 pkg/cli/cloud.go 中的真实命令实现一一对应。例如TestCloud_ConfigSet实际触发cloudConfigSetCmd的RunE加载或自动创建cloud-settings.yaml→ 通过点分键路径setCloudConfigValue写入 →SaveCloudConfig落盘TestCloud_CreateDryRun则对应cloudCreateCmd中的provider.EstimateCost(mode, instanceCount)调用这也是输出中Est. cost: $x.xx/hour ($x.xx/day)的来源。集成测试cloud_integration_test.go配置管理TestCloudConfig_LoadAndSave——构造完整CloudConfigs含 DigitalOcean 凭据、Defaults、Limits、State经SaveCloudConfig写出再LoadCloudConfig读回逐字段断言一致TestCloudConfig_EnvironmentVariableResolution——token 写成${TEST_DO_TOKEN}加载后断言已解析为环境变量实际值TestCloudConfig_Validation——表驱动测试覆盖四类场景合法配置、缺 token、非法 provider、defaults.max_instances0错误信息分别包含token/provider/instancesTestCloudConfigMultipleProviders——同时配置 DO / AWS / GCP 三组凭据并验证往返一致TestDefaultCloudConfig——验证 internal/config/cloud_config.go 中DefaultCloudConfigs()的默认值state.backendlocal、defaults.modevm、defaults.providerdigitalocean、limits.max_instances0且各提供商凭据为${...}占位符TestCloudConfigValidation_AWS/TestCloudConfigValidation_GCP——提供商特定校验AWS 缺access_key_id报 AWS credentialsGCP 缺project_id报 GCP credentials成本追踪TestCostTracking——以 DigitalOceans-2vcpu-4gb的小时费率0.02232美元构造CostTracker验证初始成本≈0、随时间增长、CheckLimits通过、GetCostSummary包含 Elapsed/Cost/Hourly Rate、1 小时预估成本精确等于小时费率TestCostLimitCheck——用$100k/小时费率与$0.01上限强制触发超限断言错误信息包含 exceeds maximum total spendTestCostEstimation——表驱动验证 1h / 24h / 168h 的预估成本分别等于0.02232/0.53568/3.74976美元状态管理TestInfrastructureState——完整 CRUD保存含 PulumiStackID 与 Resource公网/私网 IP的Infrastructure→ 断言cloud-state/infrastructure/id.json落盘 →InfrastructureExists→LoadInfrastructureState逐字段比对 →ListInfrastructures→RemoveInfrastructureState→ 验证文件删除TestMultipleInfrastructureStates——同时管理infra-1/2/3三个状态删除其一后仅剩两个TestInfrastructureStateEmpty——不存在的状态目录返回空列表、InfrastructureExists返回 false、加载不存在状态返回错误TestInfrastructureMetadata——验证Metadata中嵌套结构数组、map、数字经 JSON 序列化后完整保留这些集成测试直接对应 internal/cloud/state.go 的实现状态文件统一存放在statePath/infrastructure/id.jsonListInfrastructures对目录中每个.json文件逐个加载并跳过损坏项。测试架构日志工具与三种测试模式共享测试工具来自 e2e_test.goE2E 测试复用了 test/e2e/e2e_test.go 中的基础设施// 带颜色的步骤日志与 internal/logger 风格一致 log : NewTestLogger(t) log.Step(Testing cloud config set command) log.Info(Setting provider token...) log.Success(Configuration updated successfully) // CLI 执行辅助自动注入 --base-folder 与 OSM_SKIP_PATH_SETUP1 stdout, stderr, err : runCLIWithLog(t, log, cloud, config, set, key, value) // 需要拿到独立 base 目录的变体用于验证配置文件落盘 baseDir, stdout, stderr, err : runCLIWithLogAndBase(t, log, cloud, create, ...) // 在既有 base 目录内执行多步测试共享同一份配置 stdout, stderr, err : runCLIInBase(t, log, baseDir, cloud, list)runCLIWithLog的实现要点每个测试调用都会创建独立的t.TempDir()作为 base 目录并通过环境变量OSM_SKIP_PATH_SETUP1与OSM_WORKSPACESbaseDir/workspaces隔离工作区保证测试互不干扰。TestLogger的Command/Result方法会把执行的命令行与截断后的 stdout/stderr 写入测试日志便于失败定位。三种测试模式Pattern 1简单 CLI 测试——适合验证命令输出与无状态行为func TestCloud_ConfigShow(t *testing.T) { log : NewTestLogger(t) log.Step(Testing cloud config show command) stdout, _, err : runCLIWithLog(t, log, cloud, config, show) require.NoError(t, err) assert.Contains(t, stdout, provider:) log.Success(Cloud config show works correctly) }Pattern 2带状态的集成测试——直接构造领域对象并验证持久化往返func TestInfrastructureState(t *testing.T) { tempDir : t.TempDir() stateDir : filepath.Join(tempDir, cloud-state) infra : cloud.Infrastructure{ID: test-infra-12345, Provider: digitalocean, Mode: vm} err : cloud.SaveInfrastructureState(infra, stateDir) require.NoError(t, err) loaded, err : cloud.LoadInfrastructureState(infra.ID, stateDir) require.NoError(t, err) assert.Equal(t, infra.ID, loaded.ID) }Pattern 3长时测试跳过——所有云 E2E 测试统一采用func TestCloud_Integration_FullLifecycle(t *testing.T) { if testing.Short() { t.Skip(skipping full lifecycle integration test in short mode) } // 长时运行的测试序列... }配置结构详解cloud-settings.yaml 与源码校验逻辑测试的核心被测对象之一是云配置文件 public/presets/cloud-settings.example.yaml其结构在 internal/config/cloud_config.go 中定义包含六大区块区块关键字段测试覆盖的取值示例providers6 个提供商的凭据与机型DO:nyc3/s-2vcpu-4gbAWS:us-east-1/t3.mediumdefaultsprovider、mode、max_instances、use_spot、timeout、cleanup_on_failuredigitalocean、vm、10、30mlimitsmax_hourly_spend、max_total_spend、max_instances10.0、100.0、20statebackend、pathlocal、{{base_folder}}/cloud-statesshprivate_key_path、public_key_path、user、password、port~/.ssh/id_rsa、rootsetupcommands、post_commands、ansible安装命令、osmedeus worker join注册命令配置加载链路由 internal/cloud/config.go 实现其中三个关键环节直接对应测试断言~展开——LoadCloudConfig/SaveCloudConfig对~/开头的路径先展开用户主目录环境变量解析——resolveEnvVars使用os.ExpandEnv对全部提供商的凭据字段、SSH 密钥路径与 state 路径做${VAR}替换这正是TestCloudConfig_EnvironmentVariableResolution断言的基础校验规则——ValidateCloudConfig按defaults.provider分派DO 必须含token、AWS 必须含access_key_id与secret_access_key、GCP 必须含project_id与credentials_file同时强制max_hourly_spend/max_total_spend非负、limits.max_instances与defaults.max_instances至少为 1。此外ResolveTemplatePaths会把配置中的{{base_folder}}占位符替换为真实 base 目录——这也是cloud create命令在pkg/cli/cloud.go中加载配置后立即调用它的原因。测试数据与环境变量约定文件布局所有临时目录均由t.TempDir()生成测试结束后自动清理保证并行安全配置文件cloud-settings.yaml位于 base 目录下状态文件cloud-state/infrastructure/id.jsonAnsible 预设cloud-infra/setup-playbook.yaml与cloud-infra/inventory.ini由ensureCloudConfig一并复制对应 public/presets/cloud-infra 中的模板。Mock 数据// 测试令牌/凭据 test-token-12345 env-resolved-token-67890 do-token-12345 // 测试基础设施 ID test-infra-12345 infra-1, infra-2, infra-3 // 测试区域 DigitalOcean: nyc3 AWS: us-east-1 GCP: us-central1 Linode: us-east Azure: eastus环境变量TEST_DO_TOKEN——环境变量解析测试集成测试中作为${TEST_DO_TOKEN}的取值来源TEST_DIGITALOCEAN_TOKEN——E2E 测试中通过os.Setenv注入、defer os.Unsetenv清理默认配置中的${VAR}占位符——DefaultCloudConfigs()为各提供商预设的凭据占位符如${AWS_ACCESS_KEY_ID}。云提供商测试覆盖矩阵原文档给出的覆盖矩阵如下反映了各提供商在配置、校验、成本估算三个维度的完成度ProviderConfigurationValidationCost EstimationDigitalOcean✅✅✅AWS✅✅⏳GCP✅✅⏳Linode✅⏳⏳Azure✅⏳⏳图例✅ 完全覆盖⏳ 部分实现/占位❌ 未覆盖。从源码看Provider接口internal/cloud/provider.go为所有提供商统一定义了Validate/EstimateCost/CreateInfrastructure/DestroyInfrastructure/GetStatus五个方法各提供商实现位于 internal/cloud 目录如 aws.go、gcp.go、digitalocean.go、hetzner.go 等。矩阵中 ⏳ 的含义是接口与配置校验已就绪但对应的真实云 API 集成测试仍待补充。故障排查与调试测试失败时# 检查是否有残留云配置干扰 rm -rf ~/.osmedeus-base/cloud-settings.yaml # 带详细输出运行单个测试 go test -v -run TestCloud_ConfigSet ./test/e2e/ # 检查临时目录残留 ls /tmp | grep -i osmedeus调试技巧# 详细输出全部云 E2E go test -v ./test/e2e/cloud_test.go ./test/e2e/e2e_test.go # 单独运行一个用例 go test -v -run TestCloud_ConfigShow ./test/e2e/ # 生成集成测试覆盖率报告 go test -coverprofilecoverage.out ./test/integration/cloud_integration_test.go go tool cover -htmlcoverage.out由于每个 E2E 用例都使用独立的t.TempDir()base 目录测试间的配置污染基本不会发生若出现偶发失败优先检查~/.osmedeus-base/下是否残留了上次手工操作写入的cloud-settings.yaml。CI/CD 集成云测试被设计为可直接嵌入 CI 流水线# GitHub Actions 示例 - name: Run cloud tests run: | make test-e2e-cloud make test-cloud设计上保证了并行安全所有测试使用临时目录并在结束后自动清理t.TempDir()的自动回收机制避免了测试数据交叉污染。若在 CI 中希望缩短耗时可在 E2E 步骤追加-short跳过长时用例仅保留配置与校验相关的快速用例。未来测试扩展规划文档明确列出了云功能完整落地后计划补充的测试方向当前多为占位测试真实提供商测试携带凭据——真实资源供给、worker 注册与监控、分布式工作流执行、经 SSH 收集结果成本追踪——实时成本累积、最大花费限额强制、成本摘要报表Worker 管理——cloud-init 脚本执行、worker 自动注册、worker 健康监控快照支持——预装工具的定制 VM 快照启动时间从约 5 分钟优化到约 30 秒对应 DigitalOcean 配置中的snapshot_id字段错误恢复——网络故障处理、部分基础设施清理、状态损坏恢复。贡献指南向云功能新增特性时文档要求遵循以下步骤在 cloud_test.go 中补充对应的 E2E 测试在 cloud_integration_test.go 中补充集成测试同步更新本 README 的测试覆盖清单遵循既有测试模式TestLogger日志、require/assert断言、临时目录清理支持-short模式以保障快速验证。关联文档云使用指南 ——面向用户的云功能使用文档云配置示例 ——配置文件模板含 6 个提供商、SSH、成本限额、Ansible 设置的完整注释云速查表 ——常用命令速查架构总览 ——项目整体架构说明API 端点测试 ——REST API 相关 E2E 测试分布式工作流测试 ——分布式扫描相关 E2E 测试【免费下载链接】osmedeusA Modern Orchestration Engine for Security项目地址: https://gitcode.com/GitHub_Trending/os/osmedeus创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表