跳到主要内容

测试流程

AxVisor 的测试流程基于 axci 仓库提供的统一测试脚本和 GitHub Actions 工作流。测试分为自动测试(CI)本地测试两种方式。

统一测试脚本(axci)

axci 仓库是整个测试流程的核心,提供了所有测试相关的脚本和工作流配置。

仓库地址:https://github.com/arceos-hypervisor/axci

axci 仓库结构

axci/
├── .github/
│ └── workflows/ # GitHub Actions 工作流
│ ├── check.yml # 代码质量检查
│ ├── test.yml # 集成测试
│ ├── deploy.yml # 文档部署
│ ├── release.yml # 版本发布
│ └── verify-tag.yml # 标签验证
├── check.sh # 本地代码质量检查脚本
├── tests.sh # 本地集成测试脚本
└── README.md # 使用文档

提供的测试工具

类型工具用途
CI 工作流.github/workflows/*.ymlGitHub Actions 自动化测试
本地脚本check.sh代码质量检查(fmt、clippy、build、doc)
本地脚本tests.sh本地集成测试(QEMU + Board)

使用方式

axci 中的测试工具不直接使用,而是在各组件仓库中被调用:

  • 自动测试:通过 GitHub Actions 的 workflow_call 机制引用
  • 本地测试:通过组件仓库的 scripts/check.shscripts/test.sh 调用

自动测试(CI)

自动测试通过 GitHub Actions 实现,在代码提交、创建 Pull Request 或推送标签时自动触发。

重要说明:CI 测试使用完整自建的本地集成测试环境,包括所有测试设备(QEMU 虚拟机和物理开发板),能够执行完整的测试矩阵。

CI 工作流配置

axci 共享工作流

axci 仓库提供了 5 个核心工作流:

工作流功能触发方式
check.yml代码质量检查(fmt、clippy、build、doc)push、pull_request
test.yml集成测试(QEMU + Board)push、pull_request、workflow_dispatch
verify-tag.yml验证版本标签(分支、版本一致性)被其他工作流调用
deploy.yml部署文档到 GitHub Pagespush tag v*..
release.yml创建 Release 并发布到 crates.iopush tag v*..

工作流执行流程:

组件仓库 CI 配置

arm_vcpu 为例,展示如何使用 axci 的共享工作流。

1. Check 工作流配置 (arm_vcpu/.github/workflows/check.yml)

# Quality Check Workflow
# References shared workflow from axci

name: Check

on:
push:
branches: ['**']
tags-ignore: ['**']
pull_request:
workflow_dispatch:

jobs:
check:
uses: arceos-hypervisor/axci/.github/workflows/check.yml@main

这个配置会在以下情况触发:

  • 推送到任何分支(排除标签)
  • 创建 Pull Request
  • 手动触发

2. Test 工作流配置 (arm_vcpu/.github/workflows/test.yml)

# Integration Test Workflow
# References shared workflow from axci

name: Test

on:
push:
branches:
- '**'
tags-ignore:
- '**'
pull_request:
workflow_dispatch:

jobs:
test:
uses: arceos-hypervisor/axci/.github/workflows/test.yml@main

这个配置会在代码提交时自动运行集成测试,测试会在 self-hosted runner 上执行。

3. Release 和 Deploy 工作流配置

# Release Workflow
name: Release

on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-pre.[0-9]+'

jobs:
release:
uses: arceos-hypervisor/axci/.github/workflows/release.yml@main
with:
verify_branch: true
verify_version: true
secrets:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
# Deploy Workflow
name: Deploy

on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'

jobs:
deploy:
uses: arceos-hypervisor/axci/.github/workflows/deploy.yml@main
with:
verify_branch: true
verify_version: true

自定义工作流参数

axci 的工作流支持自定义参数。例如,可以指定编译目标、Rust 组件、测试目标等。详细参数配置请参考 axci 仓库文档

集成测试执行流程

集成测试的核心是 test.yml 工作流,它采用矩阵策略并行执行多个测试任务。

详细步骤说明:

1. Filter test targets(过滤测试目标)

根据 test_targets 输入参数决定是否执行测试:

  • all:运行所有测试
  • axvisor:仅运行 axvisor 测试
  • starry:仅运行 starry 测试
  • 也可以指定具体的测试目标,如 axvisor-qemu-aarch64-arceos

2. Checkout component(检出组件)

将被测组件代码检出到 component/ 目录。

3. Checkout test target(检出测试目标)

检出测试目标仓库到相应目录:

  • Axvisor:https://github.com/arceos-hypervisor/axvisor
  • Starry:https://github.com/Starry-OS/StarryOS

4. Get component crate name(获取 crate 名称)

从组件的 Cargo.toml 中自动检测 crate 名称,或使用输入参数。

5. Apply patch to Cargo.toml(应用补丁)

通过 [patch.crates-io] 覆盖测试目标对组件的依赖:

[patch.crates-io]
arm_vcpu = { path = "../component" }

这样,测试目标在构建时会使用本地检出的组件代码,而不是 crates.io 上的版本。

6. Install dependencies(安装依赖)

安装测试所需的工具,如 ostool

7. Run tests(运行测试)

根据测试类型执行不同的测试命令:

  • QEMU 测试

    cargo xtask qemu \
    --build-config configs/board/qemu-aarch64.toml \
    --qemu-config .github/workflows/qemu-aarch64.toml \
    --vmconfigs configs/vms/arceos-aarch64-qemu-smp1.toml
  • Board 测试

    cargo xtask uboot \
    --build-config configs/board/phytiumpi.toml \
    --uboot-config .github/workflows/uboot.toml \
    --vmconfigs configs/vms/arceos-aarch64-e2000-smp1.toml \
    --bin-dir /home/runner/tftp

测试矩阵配置

Axvisor 测试包含以下测试组合:

QEMU 测试:

架构VM 配置VM 名称测试内容
aarch64arceos-aarch64-qemu-smp1.tomlArceOSArceOS guest
aarch64linux-aarch64-qemu-smp1.tomlLinuxLinux guest
x86_64nimbos-x86_64-qemu-smp1.tomlNimbOSNimbOS guest

Board 测试:

开发板VM 配置VM 名称测试内容
phytiumpiarceos-aarch64-e2000-smp1.tomlArceOSArceOS guest
phytiumpilinux-aarch64-e2000-smp1.tomlLinuxLinux guest
roc-rk3568-pcarceos-aarch64-rk3568-smp1.tomlArceOSArceOS guest
roc-rk3568-pclinux-aarch64-rk3568-smp1.tomlLinuxLinux guest

QEMU 测试配置

QEMU 测试使用 TOML 配置文件定义 QEMU 启动参数和测试成功/失败条件:

# qemu-aarch64.toml
args = [
"-nographic",
"-cpu", "cortex-a72",
"-machine", "virt,virtualization=on,gic-version=3",
"-smp", "4",
"-device", "virtio-blk-device,drive=disk0",
"-drive", "id=disk0,if=none,format=raw,file=${workspaceFolder}/tmp/rootfs.img",
"-append", "root=/dev/vda rw init=/init",
"-m", "8g",
]
fail_regex = []
success_regex = [
"Hello, world!",
"test pass!",
]
to_bin = true
uefi = false

关键配置项:

  • args:QEMU 命令行参数
  • success_regex:匹配成功的正则表达式列表
  • fail_regex:匹配失败的正则表达式列表
  • to_bin:是否将 ELF 转换为二进制
  • uefi:是否使用 UEFI 启动

Board 测试配置

Board 测试使用 U-Boot 通过 TFTP 加载固件:

# uboot.toml
baud_rate = "${env:BOARD_COMM_UART_BAUD}"
board_power_off_cmd = "${env:BOARD_POWER_OFF}"
board_reset_cmd = "${env:BOARD_POWER_RESET}"
dtb_file = "${env:BOARD_DTB}"
fail_regex = [
"panicked at",
]
serial = "${env:BOARD_COMM_UART_DEV}"
success_regex = [
"Welcome to AxVisor Shell!",
"All tests passed!",
"Hello World!",
"root@firefly:~#",
"root@phytium-Ubuntu:~#",
"Set hostname to <phytiumpi>",
"Last login: *",
]

[net]
interface = "${env:BOARD_COMM_NET_IFACE}"
tftp_dir = "${env:TFTP_DIR}"

关键配置项:

  • serial:串口设备路径(从环境变量读取)
  • baud_rate:串口波特率
  • board_reset_cmd:重启开发板的命令
  • board_power_off_cmd:关闭开发板电源的命令
  • success_regex:匹配成功的正则表达式列表
  • fail_regex:匹配失败的正则表达式列表
  • tftp_dir:TFTP 服务器目录

环境变量配置:

Board 测试需要在 self-hosted runner 上配置以下环境变量:

# ~/.bashrc 或 /home/runner/.env
export BOARD_COMM_UART_DEV="/dev/ttyUSB0"
export BOARD_COMM_UART_BAUD="1500000"
export BOARD_POWER_RESET="/home/runner/scripts/reset-board.sh"
export BOARD_POWER_OFF="/home/runner/scripts/power-off.sh"
export BOARD_DTB="/path/to/board.dtb"
export BOARD_COMM_NET_IFACE="eth0"
export TFTP_DIR="/home/runner/tftp"

测试结果分析

测试结果通过正则表达式匹配串口输出来判定:

成功条件:

  • 串口输出匹配 success_regex 中的任意一个模式
  • 未匹配到 fail_regex 中的任何模式
  • 测试超时前完成

失败条件:

  • 串口输出匹配 fail_regex 中的任意一个模式
  • 测试超时
  • QEMU 或开发板启动失败

常见问题排查:

问题可能原因解决方法
构建失败依赖版本不兼容检查 Cargo.lock,更新依赖
QEMU 启动失败QEMU 参数错误检查 qemu-*.toml 配置
测试超时success_regex 未匹配检查正则表达式,查看实际输出
Board 无法连接串口或网络问题检查硬件连接,验证环境变量
镜像加载失败TFTP 服务异常检查 TFTP 服务器状态

GitHub Actions 会为每个测试生成详细的报告,包括:

  • ✅ 成功的测试:显示绿色勾号
  • ❌ 失败的测试:显示红色叉号,可展开查看详细日志
  • ⏭️ 跳过的测试:显示跳过图标

本地测试

本地测试允许开发者在提交代码前进行快速验证。本地测试使用 axci 仓库提供的 check.shtests.sh 脚本。

重要说明:本地测试仅使用开发者本地机器上的 QEMU 和已连接的开发板,测试环境相对有限。完整的集成测试环境仅在 CI 中提供。

测试脚本

axci 提供了两个本地测试脚本:

脚本功能
axci/check.sh代码质量检查(fmt、clippy、build、doc)
axci/tests.sh集成测试(QEMU + Board)

重要:这些脚本不直接使用,而是在组件仓库中被调用。

在组件仓库中使用

每个组件仓库都提供了自己的测试脚本,这些脚本会自动下载并调用 axci 中的测试工具。

代码质量检查

# 在组件仓库根目录运行
./scripts/check.sh

集成测试

# 运行所有测试
./scripts/test.sh

# 仅运行 axvisor QEMU 测试
./scripts/test.sh -t axvisor-qemu

# 详细输出
./scripts/test.sh -v

# 仅显示命令(不执行)
./scripts/test.sh --dry-run

环境准备

基础依赖

# 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 安装 QEMU
sudo apt install qemu-system-arm qemu-system-x86

# 安装 ostool
cargo install ostool --version ^0.8

Board 测试环境(可选)

如果要运行物理开发板测试,需要配置环境变量:

# ~/.bashrc 或 ~/.zshrc
export BOARD_COMM_UART_DEV="/dev/ttyUSB0"
export BOARD_COMM_UART_BAUD="1500000"
export BOARD_POWER_RESET="/home/user/scripts/reset-board.sh"
export BOARD_POWER_OFF="/home/user/scripts/power-off.sh"
export BOARD_DTB="/path/to/board.dtb"
export BOARD_COMM_NET_IFACE="eth0"
export TFTP_DIR="/home/user/tftp"

测试镜像会自动从 GitHub Releases 下载到 /tmp/.axvisor-images/