Build and Testing

Relevant source files

This document covers the automated build system, continuous integration pipeline, testing procedures, and documentation generation for the AxVM hypervisor project. It explains the multi-architecture build matrix, CI/CD workflow stages, and quality assurance processes that ensure code reliability across supported platforms.

For information about development dependencies and integration with the ArceOS ecosystem, see Dependencies and Integration.

Build System Overview

The AxVM project uses a GitHub Actions-based continuous integration system that validates code quality, builds across multiple architectures, and generates documentation. The build system supports three primary target architectures (x86_64, RISC-V, and AArch64) with different execution environments ranging from hosted Linux to bare-metal embedded targets.

CI Pipeline Architecture

flowchart TD
subgraph subGraph3["Documentation Pipeline"]
    doc_build["cargo doc --no-deps"]
    index_redirect["index.html redirect"]
    gh_pages_deploy["GitHub Pages deploy"]
end
subgraph subGraph2["Build Stages"]
    format_check["cargo fmt --check"]
    clippy_lint["cargo clippy"]
    cargo_build["cargo build"]
    unit_tests["cargo test"]
end
subgraph subGraph1["CI Job Matrix"]
    matrix_strategy["strategy.matrix"]
    toolchain_variants["rust-toolchain variants"]
    target_variants["targets variants"]
    nightly_2024["nightly-2024-12-25"]
    nightly_latest["nightly"]
    x86_linux["x86_64-unknown-linux-gnu"]
    x86_none["x86_64-unknown-none"]
    riscv_none["riscv64gc-unknown-none-elf"]
    aarch64_none["aarch64-unknown-none-softfloat"]
end
subgraph subGraph0["GitHub Actions Workflow"]
    trigger["push/pull_request triggers"]
    ci_job["ci job"]
    doc_job["doc job"]
end

cargo_build --> unit_tests
ci_job --> format_check
ci_job --> matrix_strategy
clippy_lint --> cargo_build
doc_build --> index_redirect
doc_job --> doc_build
format_check --> clippy_lint
index_redirect --> gh_pages_deploy
matrix_strategy --> target_variants
matrix_strategy --> toolchain_variants
target_variants --> aarch64_none
target_variants --> riscv_none
target_variants --> x86_linux
target_variants --> x86_none
toolchain_variants --> nightly_2024
toolchain_variants --> nightly_latest
trigger --> ci_job
trigger --> doc_job

Sources: .github/workflows/ci.yml(L1 - L61) 

Supported Architecture Targets

The build system validates AxVM across multiple target architectures that align with the hypervisor's multi-architecture support design. Each target represents a different execution environment and use case.

Target TripleArchitectureEnvironmentUse Case
x86_64-unknown-linux-gnux86_64Hosted LinuxDevelopment, unit testing
x86_64-unknown-nonex86_64Bare metalHypervisor deployment
riscv64gc-unknown-none-elfRISC-V 64-bitBare metal ELFRISC-V hypervisor
aarch64-unknown-none-softfloatAArch64Bare metal, soft FPARM hypervisor

Build Matrix Configuration

flowchart TD
subgraph Components["Components"]
    rust_src["rust-src"]
    clippy_comp["clippy"]
    rustfmt_comp["rustfmt"]
end
subgraph subGraph1["Target Matrix"]
    x86_linux["x86_64-unknown-linux-gnu"]
    x86_bare["x86_64-unknown-none"]
    riscv_bare["riscv64gc-unknown-none-elf"]
    arm_bare["aarch64-unknown-none-softfloat"]
end
subgraph subGraph0["Toolchain Matrix"]
    stable_toolchain["nightly-2024-12-25"]
    latest_toolchain["nightly"]
end

latest_toolchain --> arm_bare
latest_toolchain --> riscv_bare
latest_toolchain --> x86_bare
latest_toolchain --> x86_linux
stable_toolchain --> arm_bare
stable_toolchain --> clippy_comp
stable_toolchain --> riscv_bare
stable_toolchain --> rust_src
stable_toolchain --> rustfmt_comp
stable_toolchain --> x86_bare
stable_toolchain --> x86_linux

Sources: .github/workflows/ci.yml(L10 - L19) 

CI Pipeline Stages

The continuous integration pipeline consists of multiple validation stages that run sequentially for each target in the build matrix. The pipeline uses a fail-fast: false strategy to ensure all combinations are tested even if some fail.

Code Quality Validation

The first stage validates code formatting and style consistency:

sequenceDiagram
    participant GitHubActions as "GitHub Actions"
    participant RustToolchain as "Rust Toolchain"
    participant cargofmt as "cargo fmt"
    participant cargoclippy as "cargo clippy"

    GitHubActions ->> RustToolchain: "Setup nightly toolchain"
    GitHubActions ->> RustToolchain: "Install components: rust-src, clippy, rustfmt"
    GitHubActions ->> RustToolchain: "Add target: ${{ matrix.targets }}"
    GitHubActions ->> cargofmt: "cargo fmt --all -- --check"
    cargofmt ->> GitHubActions: "Format validation result"
    GitHubActions ->> cargoclippy: "cargo clippy --target ${{ matrix.targets }} --all-features"
    Note over cargoclippy: "Allows clippy::new_without_default"
    cargoclippy ->> GitHubActions: "Lint validation result"

The clippy stage includes specific configuration to suppress the new_without_default warning, allowing constructors without Default implementation.

Sources: .github/workflows/ci.yml(L22 - L26) 

Build Validation

Each target architecture undergoes compilation validation with full feature enablement:

cargo build --target ${{ matrix.targets }} --all-features

The build stage uses continue-on-error for the latest nightly toolchain to prevent pipeline failures from upstream Rust changes while maintaining stability with the pinned nightly version.

Sources: .github/workflows/ci.yml(L27 - L29) 

Unit Testing

Unit tests execute only on the x86_64-unknown-linux-gnu target, which provides the hosted environment necessary for test execution:

cargo test --target x86_64-unknown-linux-gnu -- --nocapture

This restriction reflects the practical limitation that bare-metal targets cannot execute standard Rust test harnesses without additional infrastructure.

Sources: .github/workflows/ci.yml(L30 - L33) 

Documentation Generation

The documentation pipeline operates independently from the main CI job and includes automated deployment to GitHub Pages for the default branch.

Documentation Build Process

flowchart TD
subgraph subGraph2["Deployment Conditions"]
    default_branch_check["github.ref == default-branch"]
    single_commit["single-commit: true"]
    target_folder["folder: target/doc"]
end
subgraph subGraph1["RUSTDOCFLAGS Environment"]
    broken_links["-D rustdoc::broken_intra_doc_links"]
    missing_docs["-D missing-docs"]
end
subgraph subGraph0["Documentation Job"]
    doc_trigger["GitHub trigger"]
    doc_checkout["Checkout repository"]
    doc_toolchain["Setup nightly-2024-12-25"]
    doc_build["cargo doc --no-deps --all-features"]
    doc_index["Generate index.html redirect"]
    doc_deploy["Deploy to gh-pages branch"]
end

broken_links --> doc_build
default_branch_check --> doc_deploy
doc_build --> doc_index
doc_checkout --> doc_toolchain
doc_index --> doc_deploy
doc_toolchain --> doc_build
doc_trigger --> doc_checkout
missing_docs --> doc_build
single_commit --> doc_deploy
target_folder --> doc_deploy

The documentation build enforces strict documentation standards through RUSTDOCFLAGS that treat broken intra-doc links and missing documentation as compilation errors.

Sources: .github/workflows/ci.yml(L35 - L61) 

Index Page Generation

The pipeline automatically generates a redirect index page that points to the main crate documentation:

printf '<meta http-equiv="refresh" content="0;url=%s/index.html">' $(cargo tree | head -1 | cut -d' ' -f1) > target/doc/index.html

This command extracts the crate name from cargo tree output and creates an HTML redirect to the appropriate documentation entry point.

Sources: .github/workflows/ci.yml(L52 - L53) 

Error Handling and Resilience

The CI configuration includes several resilience mechanisms to handle different failure scenarios:

ConditionBehaviorPurpose
continue-on-error: ${{ matrix.rust-toolchain == 'nightly' }}Allow latest nightly failuresPrevent upstream breakage
fail-fast: falseContinue other matrix jobs on failureComplete validation coverage
Documentation error handlingAllow non-default branch doc failuresPrevent blocking on doc issues

The pipeline distinguishes between the stable nightly toolchain (nightly-2024-12-25) and the latest nightly, allowing experimentation with newer compiler versions while maintaining build stability.

Sources: .github/workflows/ci.yml(L8 - L9)  .github/workflows/ci.yml(L25)  .github/workflows/ci.yml(L28)  .github/workflows/ci.yml(L32)  .github/workflows/ci.yml(L50) 

Quality Assurance Standards

The CI pipeline enforces several quality standards across the codebase:

  • Code Formatting: Uniform formatting via rustfmt with --check flag
  • Linting: Comprehensive linting through clippy with minimal suppressions
  • Documentation: Complete documentation coverage with broken link detection
  • Multi-architecture Compatibility: Build validation across all supported targets
  • Feature Completeness: All builds use --all-features to ensure complete validation

These standards ensure that AxVM maintains high code quality and reliability across its supported platforms and use cases.

Sources: .github/workflows/ci.yml(L22 - L33)  .github/workflows/ci.yml(L43)  .github/workflows/ci.yml(L49 - L53)