Archiving and reusing builds

In some cases, it can be useful to separate out building tests from running them. Nextest supports archiving builds on one machine, and then extracting the archive to run tests on another machine.

Terms

  • Build machine: The computer that builds tests.
  • Target machine: The computer that runs tests.

Use cases

  • Cross-compilation. The build machine has a different architecture, or runs a different operating system, from the target machine.
  • Test partitioning. Build once on the build machine, then partition test execution across multiple target machines.
  • Saving execution time on more valuable machines. For example, build tests on a regular machine, then run them on a machine with a GPU attached to it.

Requirements

  • The project source must be checked out to the same revision on the target machine. This might be needed for test fixtures and other assets, and nextest sets the right working directory relative to the workspace root when executing tests.
  • It is your responsibility to transfer over the archive. Use the examples below as a template.
  • Nextest must be installed on the target machine. For best results, use the same version of nextest on both machines.

Non-requirements

  • Cargo does not need to be installed on the target machine. If cargo is unavailable, replace cargo nextest with cargo-nextest nextest in the following examples.

Creating archives

cargo nextest archive --archive-file <name-of-archive.tar.zst> creates an archive with the following contents:

  • Cargo-related metadata, at the location target/nextest/cargo-metadata.json.
  • Metadata about test binaries, at the location target/nextest/binaries-metadata.json.
  • All test binaries
  • Other relevant files:
    • Dynamic libraries that test binaries might link to
    • Non-test binaries used by integration tests

Note that archives do not include the source code for your project. It is your responsibility to ensure that the source code for your workspace is transferred over to the target machine and has the same contents.

Currently, the only format supported is a Zstandard-compressed tarball (.tar.zst).

Running tests from archives

cargo nextest list and run support a new --archive-file option. This option accepts archives created by cargo nextest archive as above.

By default, archives are extracted to a temporary directory, and nextest remaps paths to use the new target directory. To specify the directory archives should be extracted to, use the --extract-to option.

Specifying a new location for the source code

By default, nextest expects the workspace's source code to be in the same location on both the build and target machines. To specify a new location for the workspace, use the --workspace-remap <path-to-workspace-root> option with the list or run commands.

Example: Simple build/run split

  1. Build and archive tests:
    cargo nextest archive --archive-file my-archive.tar.zst
    
  2. Run the tests:
    cargo nextest run --archive-file my-archive.tar.zst
    

Example: Use in GitHub Actions

See this working example for how to reuse builds and partition test runs on GitHub Actions.

Example: Cross-compilation

While cross-compiling code, some tests may need to be run on the host platform. (See the note about Filtering by build platform for more.)

On the build machine

  1. Build and run host-only tests:
    cargo nextest run --target <TARGET> -E 'platform(host)'
    
  2. Archive tests:
    cargo nextest archive --target <TARGET> --archive-file my-archive.tar.zst
    
  3. Copy my-archive.tar.zst to the target machine.

On the target machine

  1. Check out the project repository to a path <REPO-PATH>, to the same revision as the build machine.
  2. List target-only tests:
    cargo nextest list -E 'platform(target)' \
        --archive-file my-archive.tar.zst \
        --workspace-remap <REPO-PATH>
    
  3. Run target-only tests:
    cargo nextest run -E 'platform(target)' \
        --archive-file my-archive.tar.zst \
        --workspace-remap <REPO-PATH>
    

Manually creating your own archives

You can also create and manage your own archives, with the following options to cargo nextest list and run:

  • --binaries-metadata: The path to JSON metadata generated by cargo nextest list --list-type binaries-only --message-format json.
  • --target-dir-remap: A possible new location for the target directory. Requires --binaries-metadata.
  • --cargo-metadata: The path to JSON metadata generated by cargo metadata --format-version 1.

Making tests relocatable

Some tests may need to be modified to handle changes in the workspace and target directories. Some common situations:

  • To obtain the path to the source directory, Cargo provides the CARGO_MANIFEST_DIR option at both build time and runtime. For relocatable tests, use the value of CARGO_MANIFEST_DIR at runtime. This means std::env::var("CARGO_MANIFEST_DIR"), not env!("CARGO_MANIFEST_DIR").

    If the workspace is remapped, nextest automatically sets CARGO_MANIFEST_DIR to the new location.

  • To obtain the path to a crate's executables, Cargo provides the CARGO_BIN_EXE_<name> option to integration tests at build time. To handle target directory remapping, use the value of NEXTEST_BIN_EXE_<name> at runtime.

    To retain compatibility with cargo test, you can fall back to the value of CARGO_BIN_EXE_<name> at build time.

Options and arguments for cargo nextest archive

Build and archive tests

Usage: cargo nextest archive [OPTIONS] --archive-file <PATH>

Options:
      --manifest-path <PATH>  Path to Cargo.toml
  -v, --verbose               Verbose output [env: NEXTEST_VERBOSE=]
      --color <WHEN>          Produce color output: auto, always, never [env: CARGO_TERM_COLOR=] [default: auto]
  -h, --help                  Print help information (use `--help` for more detail)

Cargo options:
      --lib                     Test only this package's library unit tests
      --bin <BIN>               Test only the specified binary
      --bins                    Test all binaries
      --test <TEST>             Test only the specified test target
      --tests                   Test all targets
      --bench <BENCH>           Test only the specified bench target
      --benches                 Test all benches
      --all-targets             Test all targets
  -p, --package <PACKAGES>      Package to test
      --workspace               Build all packages in the workspace
      --exclude <EXCLUDE>       Exclude packages from the test
      --all                     Alias for workspace (deprecated)
  -r, --release                 Build artifacts in release mode, with optimizations
      --cargo-profile <NAME>    Build artifacts with the specified Cargo profile
      --build-jobs <JOBS>       Number of build jobs to run
  -F, --features <FEATURES>     Space or comma separated list of features to activate
      --all-features            Activate all available features
      --no-default-features     Do not activate the `default` feature
      --target <TRIPLE>         Build for the target triple
      --target-dir <DIR>        Directory for all generated artifacts
      --ignore-rust-version     Ignore `rust-version` specification in packages
      --unit-graph              Output build graph in JSON (unstable)
      --future-incompat-report  Outputs a future incompatibility report at the end of the build
      --frozen                  Require Cargo.lock and cache are up to date
      --locked                  Require Cargo.lock is up to date
      --offline                 Run without accessing the network
      --config <KEY=VALUE>      Override a configuration value
  -Z <FLAG>                     Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details

Archive options:
      --archive-file <PATH>      File to write archive to
      --archive-format <FORMAT>  Archive format [default: auto] [possible values: auto, tar-zst]
      --zstd-level <LEVEL>       Zstandard compression level (-7 to 22, higher is more compressed + slower) [default: 0]

Config options:
      --config-file <PATH>
          Config file [default: workspace-root/.config/nextest.toml]
      --tool-config-file <TOOL:ABS_PATH>
          Tool-specific config files