测试环境虚拟机
Forge testenv引擎,为基础设施测试提供虚拟机、网络和SSH密钥。
“我针对从网络而不是容器启动的真实VM测试PXE启动服务器。 testenv-vm允许我在forge.yaml中声明vm、具有DHCP/TFTP的网络和SSH密钥。 该引擎自动处理依赖关系排序、并行执行和清理。" --基础设施工程师
testenv vm解决了什么问题?
基础设施测试(PXE引导、裸机配置、网络服务)需要真实的虚拟机,而不是容器。 每个项目都构建自定义VM生命周期管理:域XML、QCOW2覆盖、云初始化ISO、网桥网络、DHCP/TFTP、SSH密钥分发、清理。 如何获得具有自动依赖解析功能的声明性、与提供者无关的VM测试环境? testenv vm通过以下方式处理它 forge.yaml 配置。 它管理3种资源类型(密钥、网络、VM),支持3种网络类型(网桥、libvirt、dnsmasq)、3种密钥类型(rsa、ed25519、ecdsa),并为每个提供者提供13个模型上下文协议(MCP)工具。
快速开始
# Install forge
go install github.com/alexandremahdhaoui/forge/cmd/forge@latest# forge.yaml
engines:
- alias: e2e-testenv
type: testenv
testenv:
- engine: go://github.com/alexandremahdhaoui/testenv-vm/cmd/testenv-vm
spec:
providers:
- name: libvirt
engine: go://github.com/alexandremahdhaoui/testenv-vm/cmd/providers/testenv-vm-provider-libvirt
keys:
- name: vm-ssh
spec: { type: ed25519 }
networks:
- name: test-net
kind: bridge
spec: { cidr: "192.168.100.1/24" }
vms:
- name: test-vm
spec:
memory: 2048
vcpus: 2
network: "{{ .Networks.test-net.Name }}"
cloudInit:
users:
- name: ubuntu
sshAuthorizedKeys: ["{{ .Keys.vm-ssh.PublicKey }}"]# Run tests with VM infrastructure
forge test e2e它是如何工作的?
+-------------------------------------------------------------------+
| Forge Test Runner |
+-------------------------------------------------------------------+
|
| MCP: "create" / "delete"
v
+-------------------------------------------------------------------+
| testenv-vm MCP Server |
| |
| +----------------+ +-------------+ +------------------------+ |
| | Spec Parser | | DAG Builder | | Executor | |
| | - Validate | | - Deps graph| | - Parallel phases | |
| | - Template | | - Topo sort | | - Rollback on failure | |
| +----------------+ +-------------+ +------------------------+ |
| |
| +--------------------------------------------------------------+ |
| | Provider Manager | |
| | - Start/stop provider MCP servers | |
| | - Route operations to providers | |
| +--------------------------------------------------------------+ |
+-------------------------------------------------------------------+
| |
| MCP | MCP
v v
+------------------+ +------------------+
| Libvirt Provider | | Stub Provider |
| - vm, network | | - In-memory mock |
| - key | | - E2E testing |
+------------------+ +------------------+Forge调用testenv虚拟机 create 带有规范的MCP工具。编排器解析规范,从模板引用构建有向无环图(DAG),并在并行阶段执行资源。每个提供程序都作为单独的MCP服务器进程运行,实现了进程隔离和独立的版本控制。看 设计.md 对于完整的技术设计。
目录
如何配置?
配置存在于 forge.yaml 在...之下 testenv 部分。
资源类型:
- 钥匙 --三种类型:rsa、ed25519、ecdsa。生成用于VM访问的SSH密钥对。
- 网络 --3种:网桥(Linux网桥)、libvirt(virsh-net-define)、dnsmasq(DHCP/TFTP)。
- 虚拟机 --定义内存、vCPU、磁盘、云初始化、启动顺序和就绪检查。
模板引用(例如。, {{ .Keys.vm-ssh.PublicKey }})链接资源和驱动依赖性解决方案。
看 Libvirt提供商 用于特定于提供商的配置选项。
如何构建和测试?
4个构建目标: testenv-vm, testenv-vm-provider-stub, testenv-vm-provider-libvirt, generate-testenv-vm.
8个测试阶段:3个皮棉(lint-tags, lint-licenses, lint),1个单元,1个集成,3个e2e(e2e, e2e_libvirt, e2e_libvirt_delete).
forge build # Build all artifacts
forge test-all # Run all test stages
forge test run unit # Run a specific stage
forge test run e2e # Run stub-based E2E tests
forge test run e2e_libvirt # Run libvirt E2E tests (requires libvirt)依赖解析是如何工作的?
模板引用(例如。, {{ .Keys.vm-ssh.PublicKey }})在DAG中定义边。拓扑排序产生执行阶段。一个阶段内的资源并行执行。阶段按顺序执行。
模板实时呈现:在资源创建之前,使用已完成资源中的值。这可以防止前向引用,并确保确定性的执行顺序。
如何在运行时创建虚拟机?
使用 client.NewClient 随着 WithProvisioner 在测试执行期间创建虚拟机:
result, _ := orchestrator.Create(ctx, input)
c, _ := client.NewClient(result.Provisioner, "control-plane",
client.WithProvisioner(result.Provisioner))
worker, _ := c.CreateVM(ctx, "worker-1", v1.VMSpec{
Memory: 2048, VCPUs: 2, Network: "test-net",
})
worker.WaitReady(ctx, 2*time.Minute)运行时虚拟机通过模板与现有资源集成,并自动清理。看 运行时虚拟机创建 了解详情。
如何测试PXE启动方案?
使用DHCP/TFTP配置dnsmasq网络:
networks:
- name: pxe-services
kind: dnsmasq
spec:
dhcp:
enabled: true
rangeStart: "192.168.200.50"
rangeEnd: "192.168.200.100"
tftp:
enabled: true
root: "./tftp"
bootFile: "undionly.kpxe"
vms:
- name: pxe-client
spec:
boot: { order: [network, hd], firmware: bios }常见问题解答
有哪些供应商? Libvirt(功能齐全的本地虚拟化)和存根(用于E2E测试的内存模拟)。每个提供者公开13个MCP工具,涵盖3种资源类型。
支持哪些准备状态检查? SSH(等待SSH服务器)、TCP(等待端口)和CloudInit(通过SSH等待云初始化完成)。SSH确认网络连接和客户操作系统就绪。
如果VM创建失败会发生什么? 当 cleanupOnFailure 是 true (默认),testenv vm以相反的依赖顺序销毁创建的资源。尽力删除会在单个失败后继续进行。
国家是如何管理的? JSON文件 stateDir (默认值 .forge/testenv-vm).状态持久性允许在进程重新启动时进行可靠的清理。
我可以使用多个提供商吗? 对。每个资源都指定其提供者。同一环境中的不同资源可以使用不同的提供者。
系统要求是什么? Linux、libvirt 6.0+、QEMU/KVM、用于创建网桥的sudo访问。存根提供程序没有系统要求。
为什么选择MCP进行供应商沟通? Forge使用MCP进行发动机通信。对提供者使用相同的协议可以保持一致性,实现进程隔离,并允许独立的版本控制。
文档
用户指南:
- Libvirt提供商 --配置、网络类型、云初始化、故障排除
- 运行时虚拟机创建 --测试期间的动态VM配置
设计:
- 设计.md --架构、数据模型、协议细节
API
- 提供者接口 --供应商MCP工具规格
贡献
欢迎捐款。打开问题或拉取请求。
许可证
Apache 2.0
