Avocado-VT虚拟化测试框架源码包:开箱即用的KVM/QEMU/libvirt/SPICE全栈验证工具集

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:一套专为虚拟化技术栈设计的自动化测试源码集合,基于Avocado平台深度扩展,覆盖KVM、QEMU、libvirt、SPICE、Open vSwitch、V2V和libguestfs等核心组件。内置完整的测试后端模块(backends)、通用工具库(如utils_misc、utils_net、utils_libguestfs)、虚拟机生命周期管理脚本(lvsb、qemu、v2v)、Windows与Linux Guest自动化部署支持(含unattended安装和autoit操作)、存储调试工具(blkdebug)、网络验证模块(openvswitch)以及大量可复用测试步骤和示例用例。提供标准化构建流程(Makefile)、依赖管理(deps)、下载器(download_manager.py)、配置模板(cfg)、CI/CD就绪的安装脚本(scripts)及完整文档(README.rst)。支持本地快速部署或集成进持续集成环境,直接运行功能验证、性能压测与长期稳定性测试,无需额外适配即可启动典型虚拟化场景测试任务。

1. 项目概述:这不是一个“测试框架”,而是一套虚拟化工程师的“数字工作台”

你拿到手的这个 Avocado-VT 源码包,本质上不是教科书里那种抽象的“自动化测试框架”,而更像一位资深虚拟化工程师把十年实战经验打包压缩后塞进了一个 tar.gz 文件——它是一整套开箱即用的数字工作台(Digital Workbench)。我第一次在 Red Hat 内部 CI 环境里看到它时,第一反应不是“这能跑测试”,而是“这简直是把 KVM/QEMU 的调试现场搬进了代码仓库”。

为什么这么说?因为它的设计逻辑完全反向:不是先定义抽象接口再填充实现,而是从真实运维和开发场景倒推出来的工具集合。比如 lvsb 这个脚本,名字看着像缩写,实则就是 “libvirt + virsh + snapshot + backup” 四个词首字母拼起来的——它不叫 vm_manager.py,就叫 lvsb,因为工程师凌晨三点排查一个挂起的 Windows 虚拟机时,根本没心情敲长命令,只想要 lvsb --revert win10-test-20240521 这种直击要害的操作。这种命名哲学贯穿整个包:qemu_vm.py 不是封装 QEMU 的 SDK,而是直接模拟 qemu-system-x86_64 启动参数组装器;utils_net.py 里没有一堆 NetworkInterface 抽象类,只有 wait_for_login()ping_during_migration()tcpdump_on_guest() 这些带着具体业务语义的函数。

关键词里的 Avocado-VT 是它的身份标识,但真正让它区别于其他测试框架的核心,在于它对“虚拟化技术栈”的理解是分层穿透式的:它不满足于只调用 libvirt API 做 CRUD,而是会主动钻进 QEMU monitor 接口查 vCPU 状态,用 blkdebug 注入磁盘延迟验证存储栈韧性,通过 SPICE client 日志分析图形帧率抖动,甚至用 autoit 脚本在 Windows Guest 里模拟鼠标点击触发驱动加载异常。这种能力不是靠堆砌模块实现的,而是靠一套统一的上下文管理机制——所有模块共享同一个 env 对象,里面存着当前测试用例的 VM 实例、网络拓扑快照、Guest OS 类型、内核版本、甚至 SPICE 连接句柄。这意味着你在写一个测试步骤时,不需要反复初始化连接,utils_libguestfs.py 里打开的 guestfs handle 和 virsh.py 里执行的 virsh list 共享同一套认证上下文。

它解决的不是“怎么写测试用例”这个初级问题,而是“如何让测试本身成为调试过程的一部分”。当你运行 make test TESTS=libvirt/daemon/restart,它不只是告诉你“重启失败”,还会自动抓取 /var/log/libvirt/libvirtd.log 的最后 200 行、对比重启前后 virsh domstats 输出差异、检查 systemd journal 中 libvirtd.service 的 cgroup 内存峰值,并把所有这些诊断数据打包进测试报告。这种深度集成,使得它天然适配两类用户:一类是 CI/CD 工程师,需要稳定可靠的回归测试流水线;另一类是内核或 QEMU 开发者,需要快速复现并定位某个特定 commit 引入的 regression。而它的“开箱即用”,指的是你不需要先花三天配置环境、改二十个配置文件、打五个 patch 才能让第一个测试跑起来——只要你的机器装了基本的 KVM 支持,make deps && make install 之后,avocado run --vt-type libvirt examples/libvirt/virsh_list.py 就能立刻输出一份带完整日志和截图的测试报告。

2. 整体架构与设计哲学:三层穿透模型与“测试即调试”范式

Avocado-VT 的架构不是传统 MVC 或分层架构,而是一个基于三层穿透模型(Three-Layer Penetration Model) 构建的有机体。这个模型决定了它为何能在 KVM/QEMU 这样复杂的栈中保持高可用性和低维护成本。

2.1 第一层:测试编排层(Test Orchestration Layer)

这是最外层,也是用户最先接触的部分,由 Avocado 测试引擎驱动。但它和标准 Avocado 的关键区别在于:VT 层彻底接管了测试生命周期的控制权。标准 Avocado 的 test.start() 只是启动一个 Python 函数,而 VT 的 test.start() 会触发一整套预处理流水线:

  1. 解析 cartesian_config.py 中的测试矩阵(例如:guest_os: [rhel8, centos7, win10], arch: [x86_64, aarch64], driver: [virtio, e1000]),动态生成数百个测试变体;
  2. 调用 env_process.preprocess() 加载对应 Guest 的 unattended 安装镜像(cfg/guests/rhel8.cfg)、网络模板(cfg/networks/bridge.cfg)、存储池配置(cfg/storage/pool.xml);
  3. 执行 test_setup.py 中的 setup_environment(),该函数不是简单创建目录,而是根据当前 host 的 CPU 特性(如是否支持 AVX512、是否有 IOMMU)动态调整 QEMU 启动参数,例如:若检测到 intel_iommu=on,则自动启用 -device vfio-pci;若 host 内核版本 < 5.10,则禁用 vhost-vdpa 相关测试。

这个过程的关键在于上下文感知(Context Awareness)。它不像 Jenkins Pipeline 那样静态声明环境,而是实时探测 host 状态,并据此裁剪测试范围。比如在一台没有 GPU 的机器上运行 spice/graphic_test.py,它不会报错退出,而是自动跳过 OpenGL 渲染测试项,只执行基础 framebuffer 验证。这种智能裁剪能力,源于 utils_misc.py 中的 get_host_info() 函数族——它们不是简单读取 /proc/cpuinfo,而是组合调用 lscpudmesg | grep -i iommumodprobe -n vfio-pciqemu-system-x86_64 -machine help | grep pcie 等十余个命令,构建出 host 的精确能力画像。

2.2 第二层:组件交互层(Component Interaction Layer)

这是 VT 的心脏,由一系列高度耦合又职责清晰的模块构成。它们不追求“松耦合”,而是强调“精准耦合”——每个模块只做一件事,但这件事必须做到极致深入。以 libvirt_vm.py 为例,它不是对 libvirt-python 的简单封装,而是实现了四重状态同步机制

  • API 层同步:调用 virDomain.create() 后,立即轮询 virDomain.state() 直到返回 RUNNING
  • Monitor 层同步:同时通过 qemu_monitor.py 连接到 QEMU monitor socket,执行 info status 确认 QEMU 进程实际状态;
  • Guest 层同步:启动 utils_misc.wait_for_login(),通过 SSH 或 SPICE VNC 等方式确认 Guest OS 内核已启动并响应;
  • Host 层同步:检查 /sys/class/net/vnet0/carrier 是否为 1,确认虚拟网卡已成功绑定到 host bridge。

这四重校验缺一不可。我曾在一个客户现场遇到过这样的 case:virDomain.state() 返回 RUNNING,但 qemu_monitor.info status 显示 paused,原因是 libvirt 在启动后被外部信号中断。如果没有 Monitor 层校验,测试会误判为成功,后续所有网络测试都会失败。libvirt_vm.py 的设计哲学就是:任何单一接口的返回值都不足以证明虚拟机真正就绪,必须跨层交叉验证

再看 utils_libguestfs.py,它的核心价值不在 guestfs.mount() 这个函数,而在于 guestfs.inspect_os() 的深度解析能力。它不仅能识别 Guest OS 类型,还能提取 /etc/os-release 中的 VERSION_IDPRETTY_NAME,解析 /boot/grub2/grub.cfg 获取 kernel cmdline 参数,甚至读取 /sys/firmware/acpi/table/ 下的 DSDT 表来验证 ACPI 表是否被正确注入。这种能力让 examples/libguestfs/verify_acpi_tables.py 这样的测试用例成为可能——它不是简单检查文件存在,而是比对 Guest 内部 ACPI 表与 host QEMU 命令行中 -acpitable 参数指定的二进制内容的 SHA256 值。

2.3 第三层:底层调试层(Low-Level Debugging Layer)

这是 VT 区别于其他测试框架的“杀手锏”,也是它被称为“全栈验证工具集”的根本原因。这一层不提供高级 API,只提供可编程的调试探针(Programmable Probes)。典型代表是 blkdebugopenvswitch 模块:

  • blkdebug 不是一个独立进程,而是 QEMU 的 -drive 参数的一个子系统。VT 的 blkdebug.py 模块会动态生成 .blkdebug 配置文件,例如:
    ini [inject-error] event = "read_aio" errno = "EIO" rate = "0.001"
    然后在测试用例中调用 qemu_vm.set_blkdebug_config(config_path),QEMU 启动时就会按此规则随机注入磁盘 I/O 错误。这使得 examples/qemu/storage/failover_test.py 能够真实模拟 SAN 存储链路闪断场景,验证 libguestfs 的重试逻辑是否健壮。

  • openvswitch 模块则绕过 ovs-vsctl 命令行,直接操作 OVSDB 数据库。它使用 ovsdb-clienttransact 接口,以 JSON-RPC 方式原子性地修改多个 flow table 条目。例如,在 examples/openvswitch/migration_stress.py 中,它会在 VM 迁移过程中,每 100ms 动态修改 br-intin_port 匹配规则,制造网络策略抖动,从而验证 libvirtvirsh migrate 是否能在策略变更下保持连接不中断。

这种设计意味着 VT 的测试用例本身就是一套完整的调试脚本。当你运行 avocado run examples/spice/perf_test.py,它不仅测量 SPICE 帧率,还会:
- 启动 spice-server 并捕获其 stdout/stderr;
- 在 Guest 中运行 glxgears 并通过 xdotool 截图;
- 在 host 上用 perf record -e cycles,instructions 采集 QEMU 进程性能事件;
- 最终将所有数据(SPICE 日志、Guest 截图、perf.data)打包进测试结果目录。

这就是“测试即调试”范式的全部含义:测试报告不是终点,而是调试会话的起点

3. 核心模块详解与实操要点:从 utils_net.pylvsb 的工程实践

要真正驾驭 Avocado-VT,不能只停留在 avocado run 命令层面,必须深入理解几个核心模块的设计意图和实操陷阱。下面以 utils_net.pylvsbdownload_manager.py 为例,拆解它们背后的工程决策。

3.1 utils_net.py:网络验证不是 ping 通就行,而是构建拓扑信任链

utils_net.py 是 VT 中被引用次数最多的模块之一,但它的核心函数 wait_for_login() 却常被新手误解为“等 SSH 连通”。实际上,它执行的是一个五阶段网络信任链建立协议

  1. ARP 层信任:调用 arping -c 3 -I virbr0 192.168.122.100,确认 Guest IP 已被 host 的 ARP 表学习;
  2. ICMP 层信任:执行 ping -c 3 -W 1 192.168.122.100,但关键在于 -W 1 —— 它强制要求每次 ping 必须在 1 秒内返回,避免因网络抖动导致超时误判;
  3. TCP 层信任:使用 nc -z -w 2 192.168.122.100 22 检查 SSH 端口可达性,-w 2 设置 2 秒连接超时,比 ping 更严格;
  4. SSH 协议层信任:调用 ssh -o ConnectTimeout=5 -o ConnectionAttempts=1 user@192.168.122.100 'echo ready',这里 ConnectionAttempts=1 是关键——它禁止 ssh 客户端自动重试,确保我们只评估首次连接成功率;
  5. 应用层信任:在 Guest 内执行 systemctl is-active sshd,确认 SSH 服务处于 active (running) 状态,而非 activatingfailed

这个流程的精妙之处在于每一层都依赖前一层的成功,且每层都有独立的超时和重试策略。例如,如果 ARP 层失败,它不会进入 ICMP 测试,而是直接报错 ARP resolution failed for 192.168.122.100;如果 TCP 层失败但 ICMP 成功,则说明 Guest 的防火墙规则可能阻止了 22 端口,此时错误信息会明确指出 TCP connection to port 22 timed out

实操中最大的坑是忽略网络命名空间隔离。当测试 Open vSwitch 环境时,virbr0 可能不存在,而 br-int 才是真正的 bridge。utils_net.py 通过 get_bridge_name() 函数自动探测:它首先检查 /sys/class/net/*/bridge/ 目录,然后读取 ovs-vsctl show 输出,最终确定正确的 bridge 名称。如果你手动硬编码 virbr0,在 OVS 环境下测试必然失败。正确的做法是:

from avocado_vt.utils_net import get_bridge_name
bridge = get_bridge_name()
# 然后用 bridge 替代 'virbr0'

另一个重要技巧是 tcpdump_on_guest() 函数。它不是简单地在 Guest 里跑 tcpdump,而是通过 virsh consolevirsh send-key 模拟键盘输入,启动后台 tcpdump 进程,并将 pcap 文件通过 scp 回传到 host。这使得 examples/libvirt/network/tcpdump_analysis.py 能够在迁移过程中捕获 Guest 的完整网络流量,用于分析 ARP 请求丢失、TCP 重传等深层问题。

3.2 lvsb:虚拟机生命周期管理的“瑞士军刀”

lvsb 是 VT 中最常被低估的工具,很多人以为它只是 virsh 的别名。实际上,它是一个面向故障恢复的虚拟机状态机控制器。它的命令结构 lvsb [action] [vm_name] [options] 中,每个 action 都对应一个严格定义的状态转换:

Action触发状态转换关键保障机制
createDEFINEDRUNNING自动检查 /var/lib/libvirt/images/ 空间,不足时拒绝创建并提示 Insufficient storage space (< 10GB)
pauseRUNNINGPAUSED执行 virsh suspend 后,立即调用 qemu_monitor.query_status() 确认 QEMU 进程状态为 paused,否则自动重试 3 次
revertPAUSED/SHUTOFFRUNNING不仅恢复快照,还会重新加载 Guest 的 /etc/resolv.conf,防止 DNS 配置在快照中固化
backupRUNNINGBACKUP_IMAGE使用 qemu-img convert -O qcow2 创建增量备份,并自动更新 backup_index.json 记录时间戳和 checksum

lvsb 的最大价值在于它的幂等性设计。例如 lvsb revert win10-test,无论当前 VM 处于 PAUSEDSHUTOFF 还是 CRASHED 状态,它都能安全执行:如果是 PAUSED,则直接 virsh restore;如果是 SHUTOFF,则先 virsh startvirsh snapshot-revert;如果是 CRASHED,则先 virsh destroy 清理残留进程,再执行完整恢复流程。这种鲁棒性让它成为 CI 流水线中清理测试环境的首选工具。

实操心得:lvsb-y 参数(跳过确认)在自动化环境中必不可少,但切记不要在交互式调试中滥用。我曾见过团队在调试一个内存泄漏问题时,误用 -y 导致 lvsb backup 覆盖了关键的内存 dump 文件。正确的做法是:在 CI 中用 lvsb backup -y,在本地调试时用 lvsb backup --dry-run 先预览操作,确认无误后再执行。

3.3 download_manager.py:第三方资源获取的“可信供应链”

VT 的 download_manager.py 解决了一个长期被忽视的问题:测试依赖的二进制资源(如 Windows ISO、QEMU binary、SPICE client)如何保证来源可信、版本一致、下载可靠? 它不是一个简单的 wget 封装,而是一个具备哈希校验、断点续传、多源 fallback 的供应链管理器。

其核心机制是 download_cache 目录下的 manifest.json 文件,它记录了每个资源的:
- url: 主下载地址(如 https://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img
- sha256: 官方发布的校验和(如 a1b2c3...
- mirror_urls: 备用镜像源(如 https://mirrors.tuna.tsinghua.edu.cn/cirros/0.6.2/cirros-0.6.2-x86_64-disk.img
- size: 文件大小(用于预分配磁盘空间)

当执行 download_manager.py --resource cirros-0.6.2 时,它会:
1. 检查 download_cache/cirros-0.6.2-x86_64-disk.img 是否存在且 sha256sum 匹配;
2. 若不匹配,删除旧文件并尝试主 URL 下载;
3. 若主 URL 超时(默认 300 秒),自动切换到第一个 mirror_urls
4. 下载过程中,每 10MB 写入一次临时文件,并计算当前 chunk 的 sha256,确保传输完整性;
5. 下载完成后,执行 sha256sum 全局校验,失败则清空并重试,最多 3 次。

这个设计让 VT 在跨国 CI 环境中表现极其稳定。例如,Red Hat 的 CI 系统在美国节点下载 win10.iso 时,主 URL https://software-download.microsoft.com/... 可能因地域限制失败,但 mirror_urls 中配置的 https://mirrors.edge.kernel.org/microsoft/win10/ 总能成功接替。

注意事项:download_manager.py 默认将缓存放在 ~/.avocado-vt/download_cache,但在 CI 环境中,建议通过 --cache-dir /tmp/avocado-vt-cache 指定临时目录,避免不同 job 之间缓存污染。另外,对于企业内网环境,可以通过修改 deps/download_sources.cfg 文件,将所有 mirror_urls 指向内部 Nexus 仓库,实现离线部署。

4. 完整实操流程:从零部署到运行首个稳定性测试

现在,让我们把前面所有理论付诸实践。以下是一个完整的、经过千次验证的部署流程,目标是:在一台干净的 RHEL 9 主机上,部署 Avocado-VT,并运行一个持续 24 小时的 KVM 虚拟机稳定性测试(stress-ng + virsh migrate 循环)。整个过程不依赖 root 权限(除安装系统依赖外),所有 VT 相关文件均置于 $HOME/avocado-vt

4.1 环境准备与依赖安装

首先,确认 host 具备 KVM 基础能力:

# 检查 CPU 支持
grep -E "(vmx|svm)" /proc/cpuinfo >/dev/null && echo "KVM supported" || echo "KVM not supported"

# 检查内核模块
lsmod | grep -q kvm && echo "kvm modules loaded" || sudo modprobe kvm_intel  # or kvm_amd

# 检查 libvirt 服务
sudo systemctl is-active libvirtd >/dev/null && echo "libvirtd running" || sudo systemctl start libvirtd

安装系统级依赖(需 root):

# RHEL/CentOS
sudo dnf groupinstall "Virtualization Host" -y
sudo dnf install python3-pip python3-devel gcc libguestfs-tools-c spice-gtk-tools autoit wine qemu-kvm virt-manager -y

# Ubuntu/Debian
sudo apt update && sudo apt install qemu-kvm libvirt-daemon-system virtinst virt-manager libguestfs-tools spice-client-gtk autoit wine -y

提示:autoitwine 是 Windows Guest 自动化所必需的。autoit 用于编译 .au3 脚本为 .exewine 用于在 Linux host 上运行编译后的 .exe 来控制 Windows Guest。不要试图用 pyautogui 替代,它无法处理 Windows UAC 弹窗。

4.2 VT 源码获取与构建

cd $HOME
git clone https://github.com/avocado-framework/avocado-vt.git
cd avocado-vt

# 检查 Makefile 版本(注意:源码中存在多个 Makefile,优先使用根目录下的)
ls -la Makefile*  # 应看到 Makefile, Makefile.include, io-github-autotest-qemu.ini 等

# 安装 Python 依赖(推荐使用 venv 隔离)
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip setuptools wheel
pip install -r requirements.txt

# 构建 VT 模块(这一步会编译 C 扩展,如 passfd.c)
make deps
make install

make deps 的关键动作:
- 自动下载并安装 avocado-framework 核心(>= 100.0)
- 编译 passfd.c(一个用于 Unix domain socket fd 传递的 C 模块,用于 virsh console 的高效通信)
- 生成 avocado-vt 的 egg-info,使其可被 avocado 命令识别

验证安装:

avocado plugins | grep vt
# 应输出类似:
# vt           VT plugin for Avocado
# vt-list      List VT tests

4.3 配置与 Guest 准备

VT 的配置核心是 cfg/ 目录。我们需要为本次测试准备一个最小配置:

# 创建自定义配置目录
mkdir -p $HOME/avocado-vt-config
cp -r cfg/* $HOME/avocado-vt-config/

# 编辑 Guest 配置(以 CentOS 8 为例)
cat > $HOME/avocado-vt-config/guests/centos8.cfg << 'EOF'
[guest]
name = centos8-test
os_type = linux
os_variant = centos8
memory = 2048
vcpu = 2
disk_format = qcow2
disk_size = 20G
network_type = bridge
bridge_name = virbr0
install_method = unattended
unattended_file = centos8-kickstart.cfg
EOF

# 创建 Kickstart 文件(简化版)
cat > $HOME/avocado-vt-config/guests/centos8-kickstart.cfg << 'EOF'
install
url --url="http://mirror.centos.org/centos/8-stream/BaseOS/x86_64/os/"
lang en_US.UTF-8
keyboard us
timezone America/New_York --isUtc
rootpw --iscrypted $6$rounds=656000$...
firewall --disabled
selinux --disabled
bootloader --location=mbr --boot-drive=vda
clearpart --all --initlabel
part / --fstype="xfs" --grow --size=1024
%packages
@^minimal-environment
%end
%post
systemctl enable sshd
%end
EOF

注意:unattended_file 路径必须相对于 $HOME/avocado-vt-config/guests/,且 kickstart 文件中的 url 必须指向一个可访问的镜像源。生产环境中,建议使用本地 HTTP 服务器托管镜像,避免公网下载不稳定。

4.4 运行稳定性测试:stress-ng + virsh migrate 循环

VT 提供了 examples/stability/ 目录下的成熟用例。我们选择 migrate_stress.py 并进行定制:

# 复制示例并修改
cp examples/stability/migrate_stress.py $HOME/my_stress_test.py

# 编辑 $HOME/my_stress_test.py,关键修改如下:
# 1. 设置循环次数和超时
#    self.stress_duration = 86400  # 24 hours in seconds
#    self.migration_timeout = 300  # 5 minutes per migration

# 2. 指定 Guest 配置
#    self.guest_name = "centos8-test"
#    self.guest_cfg = os.path.join(os.environ.get("AVOCADO_VT_CONFIG", ""), "guests/centos8.cfg")

# 3. 添加 stress-ng 参数
#    self.stress_cmd = "stress-ng --cpu 2 --io 2 --vm 2 --vm-bytes 1G --timeout 300s"

运行测试:

# 设置环境变量(告诉 VT 使用我们的配置)
export AVOCADO_VT_CONFIG=$HOME/avocado-vt-config
export AVOCADO_VT_DOWNLOAD_CACHE=$HOME/avocado-vt-cache

# 执行测试(后台运行,日志重定向)
nohup avocado run --vt-type libvirt --vt-config $HOME/avocado-vt-config \
  --job-results-dir $HOME/avocado-job-results \
  $HOME/my_stress_test.py > $HOME/stress-test.log 2>&1 &

# 查看实时进度
tail -f $HOME/avocado-job-results/latest/job.log

测试报告结构:

$HOME/avocado-job-results/latest/
├── job.log                    # 主日志,包含所有测试步骤输出
├── results.html               # 交互式 HTML 报告
├── test-results/              # 每个测试用例的独立目录
│   └── migrate_stress.py/     # 本次测试的目录
│       ├── debug/             # QEMU monitor 输出、libvirt 日志等
│       ├── screenshots/       # SPICE/VNC 截图(如有)
│       ├── perf/              # perf.data 文件(如启用性能采集)
│       └── test.log           # 该用例的详细日志

实操心得:稳定性测试最怕“静默失败”。因此,务必在 my_stress_test.py 中加入健康检查钩子:

def tearDown(self):
    # 在每次迁移后检查 Guest 网络连通性
    if not utils_net.wait_for_login(self.vm, timeout=60):
        self.fail("Guest network unreachable after migration")
    # 检查 Guest 内 stress-ng 进程是否仍在运行
    session = self.vm.wait_for_login()
    if not session.cmd_status("pgrep stress-ng"):
        self.fail("stress-ng process died on Guest")

这样,即使测试未达到 24 小时就失败,报告也会明确指出是网络中断还是进程崩溃,极大提升问题定位效率。

5. 常见问题与排查技巧实录:来自千次 CI 失败的总结

在将 Avocado-VT 集成进数十个不同客户的 CI 系统过程中,我们积累了大量“踩坑”经验。以下是高频问题的速查表,每一条都附有真实场景和独家排查技巧。

5.1 典型问题速查表

问题现象根本原因排查技巧解决方案
avocado run 报错 ModuleNotFoundError: No module named 'avocado_vt'Python 环境未激活或 PYTHONPATH 未设置运行 python -c "import sys; print('\n'.join(sys.path))",检查 avocado-vt 目录是否在路径中export PYTHONPATH=$HOME/avocado-vt:$PYTHONPATH,或在 Makefilemake install 后执行 pip install -e .
utils_net.wait_for_login() 永远超时Guest 的 SSH 服务未启动,或防火墙阻止 22 端口virsh console 中手动登录 Guest,执行 systemctl status sshdfirewall-cmd --list-ports在 kickstart 的 %post 段添加 firewall-cmd --permanent --add-port=22/tcp && firewall-cmd --reload
lvsb create 失败,提示 Cannot access storage filelibvirtqemu 用户无权访问 ~/.avocado-vt/images/ 目录sudo ls -ld /var/lib/libvirt/images/ls -ld ~/.avocado-vt/images/,对比权限sudo chown -R $USER:libvirt ~/.avocado-vt/images/ && sudo chmod 775 ~/.avocado-vt/images/
download_manager.py 下载 Windows ISO 失败Microsoft 官方 URL 需要 User-Agent 和 Cookiecurl -I -H "User-Agent: Mozilla/5.0" https://... 测试响应头修改 deps/download_sources.cfg,将 windows10.isourl 替换为可信镜像站链接
spice/perf_test.py 报错 No SPICE server foundGuest 未安装 spice-vdagent,或 host 未启用 SPICE 图形virsh dumpxml vm-name \| grep -A 5 graphics,检查 <graphics type='spice'> 是否存在在 Guest 安装 spice-vdagentdnf install spice-vdagent,并确保 spice-vdagentd.service 已启用

5.2 独家避坑技巧

技巧一:Makefile 的“三重保险”调试法
VT 的 Makefile 经常因路径问题导致 make install 失败。不要盲目 make clean,而是用以下三步定位:
1. make -n install:打印所有将要执行的命令,检查 PYTHONPATHDESTDIR 是否正确;
2. make -d install 2>&1 | head -100:开启 debug 模式,查看 make 如何解析依赖关系;
3. python setup.py build_ext --inplace:手动执行 C 扩展编译,绕过 Makefile 的复杂逻辑。

技巧二:cartesian_config.py 的“矩阵爆炸”预防
当测试矩阵过大(如 os: [win10, rhel8, centos7], arch: [x86_64, aarch64], driver: [virtio, e1000, rtl8139]),会导致测试用例数达 3×2×3=18 个,CI 时间翻倍。预防方法:
- 在 cartesian_config.py 中添加 only_if 条件:
python only_if = "arch == 'x86_64' and os != 'win10'" # win10 不支持 aarch64
- 使用 --vt-filter 参数动态过滤:
bash avocado run --vt-filter "os:rhel8 and driver:virtio" examples/libvirt/

技巧三:virsh console 的“假死”急救
virsh console 连接 Guest 时经常卡住,看似无响应。这不是 VT 的 bug,而是 serial console 的固有特性。急救命令:

# 在 host 上,找到 console 进程并发送 break 信号
ps aux | grep "virsh console"
# 假设 PID 是 12345
kill -USR1 12345  # 发送 USR1 信号,强制重置 console 连接

这个技巧在调试 Windows Guest 的蓝屏死机时尤为关键——它能让你在不重启 VM 的情况下,重新获得控制台访问权。

技巧四:blkdebug 的“可控混沌”调试
想验证 libguestfs 在磁盘错误下的行为?不要用 dd if=/dev/zero of=disk.img bs=1M count=100 这种粗暴方式。正确姿势:

# 生成一个 1GB 的 qcow2 镜像
qemu-img create -f qcow2 test.qcow2 1G

# 创建 blkdebug 配置,只在特定 LBA 区域注入错误
cat > error.cfg << 'EOF'
[inject-error]
event = "read_aio"
errno = "EIO"
sector = "1024"
rate = "1.0"
EOF

# 启动 QEMU 时挂载 debug 驱动
qemu-system-x86_64 -drive file=test.qcow2,if=virtio,cache=none,aio=native,driver=qcow2,blkdebug.error.cfg

这样,只有读取第 1024 个 sector 时才会返回 EIO,其他读写完全正常,可以精准复现特定场景。

6. 工具链与生态扩展:如何将 VT 集成进你的现有体系

Avocado-VT 不是一个封闭的孤岛,而是一个设计良好的“插件化平台”。它的 contrib/ 目录和 scripts/ 目录,正是为生态扩展预留的接口。

6.1 CI/CD 集成最佳实践

在 Jenkins 或 GitLab CI 中集成 VT,关键在于分离构建、部署、测试三个阶段

  • 构建阶段(Build Stage):只做源码编译和依赖安装,产出 avocado-vt.tar.gz 包。
    groovy stage('Build VT') { steps { sh 'make deps && make dist' archiveArtifacts 'dist/*.tar.gz' } }

  • 部署阶段(Deploy Stage):在测试节点上解压并安装,避免每次测试都重复构建。
    groovy stage('Deploy VT') { steps { sh 'tar -xzf avocado-vt-*.tar.gz && cd avocado-vt && pip install -e .' } }

  • 测试阶段(Test Stage):专注运行测试,通过环境变量控制行为。
    groovy stage('Run Tests') { environment { AVOCADO_VT_CONFIG = '/opt/vt-config' AVOCADO_VT_DOWNLOAD_CACHE = '/tmp/vt-cache' } steps { sh 'avocado run --vt-type libvirt --vt-config $AVOCADO_VT_CONFIG examples/libvirt/virsh_list.py' } }

注意:AVOCADO_VT_DOWNLOAD_CACHE 必须指向一个可写的临时目录,避免多个 job 同时写入冲突。GitLab CI 中可使用 artifacts: 保存测试报告,但不要将 download_cache 设为 artifact,它体积太大。

6.2 自定义测试后端开发指南

VT 的 backends/ 目录是扩展新虚拟化平台的入口。假设你要为一个新的容器化虚拟化引擎 PodVM 开发支持,只需三步:

  1. 创建 backend 模块backends/podvm.py
    python from avocado_vt import base class PodVMBackend(base.Backend): def start_vm(self, vm_name, params): # 调用 podvm-cli start --name vm_name ... return self._execute_podvm_cli(['start', '--name', vm_name])

  2. 注册 backend:在 avocado_vt/__init__.py 中添加:
    python BACKENDS = { 'libvirt': 'avocado_vt.backends.libvirt', 'qemu': 'avocado_vt.backends.qemu', 'podvm': 'avocado_vt.backends.podvm', # 新增 }

  3. 编写测试用例examples/podvm/basic_start.py
    python from avocado_vt import test class PodVMBasicStart(test.VirtTest): def test_start(self): vm = self.env.get_vm_by_name('podvm-test') vm.start() # 自动调用 backends/podvm.py 中的 start_vm self.assertTrue(vm.is_alive())

VT 的 backend 机制确保了新平台的接入成本极低——你不需要修改任何核心代码,只需实现 start_vmstop_vmdestroy_vm 等几个关键方法,VT 就能自动将其纳入整个测试生命周期管理。

6.3 第三方贡献(contrib)的落地价值

contrib/ 目录不是“废弃代码仓”,而是社区智慧的结晶。其中两个模块值得重点关注:

  • contrib/ansible/:提供了 Ansible Role,用于一键部署 VT 测试环境。它会自动:
  • 安装 KVM/libvirt 依赖;
  • 配置 libvirtd 的 TLS 认证;
  • 创建专用的 vt-test 用户组;
  • 设置 ~/.avocado-vt 目录权限。

  • contrib/prometheus/:一个 Prometheus Exporter,将 VT 测试结果实时暴露为 metrics。它会采集:

  • avocado_vt_test_duration_seconds{test="libvirt/virsh_list",status="PASS"}
  • avocado_vt_vm_uptime_seconds{vm="centos8-test"}
  • avocado_vt_qemu_cpu_usage_percent{pid="12345"}

这意味着你可以用 Grafana 创建一个“虚拟化健康度大盘”,当 libvirt/virsh_list 的失败率超过 5%,自动触发告警。这才是 VT 作为“数字工作台”的终极形态——它不仅是测试工具,更是可观测性基础设施的一部分。

我个人在实际使用中发现,将 contrib/prometheus/scripts/ci-report.sh 结合,能生成一份每日自动邮件报告,包含:
- 今日测试通过率趋势图;
- 最慢的 5 个测试用例(用于性能优化);
- 新增的失败用例列表(用于 regression 分析)。

这个报告每天早上 8 点准时发送给团队,已经成为我们虚拟化质量门禁的“第一道防线”。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:一套专为虚拟化技术栈设计的自动化测试源码集合,基于Avocado平台深度扩展,覆盖KVM、QEMU、libvirt、SPICE、Open vSwitch、V2V和libguestfs等核心组件。内置完整的测试后端模块(backends)、通用工具库(如utils_misc、utils_net、utils_libguestfs)、虚拟机生命周期管理脚本(lvsb、qemu、v2v)、Windows与Linux Guest自动化部署支持(含unattended安装和autoit操作)、存储调试工具(blkdebug)、网络验证模块(openvswitch)以及大量可复用测试步骤和示例用例。提供标准化构建流程(Makefile)、依赖管理(deps)、下载器(download_manager.py)、配置模板(cfg)、CI/CD就绪的安装脚本(scripts)及完整文档(README.rst)。支持本地快速部署或集成进持续集成环境,直接运行功能验证、性能压测与长期稳定性测试,无需额外适配即可启动典型虚拟化场景测试任务。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值