Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
0b8cd5f
test(conformance): add SDK-driven testkit and sandbox-lifecycle suite
elezar Oct 15, 2026
f4259eb
test(tmachine): add session API, test targets, and environment defini…
elezar Oct 15, 2026
898ca46
test(runner): run test plans in tmachine environments
elezar Oct 15, 2026
a37ebe9
build(cargo): keep conformance lockfile aligned with the root
elezar Oct 15, 2026
d3d315c
fix(tests): build tmachine on x86 and keep results paths absolute
elezar Oct 16, 2026
1e1a587
refactor(tests): move testkit out of the conformance workspace
elezar Oct 16, 2026
6919ab4
fix(tests): wait for the gateway before running an environment's tests
elezar Oct 16, 2026
cf72f11
ci(tests): run the e2e suites and test infrastructure checks in CI
elezar Oct 16, 2026
e78fa79
test(conformance): add run_to_completion_exit_delete
elezar Oct 16, 2026
342f261
test(testkit): require a stable random ID for every test
elezar Oct 16, 2026
6efaa24
docs(tests): state what a conformance test may assert
elezar Oct 16, 2026
56bdba4
test(runner): derive the expected test matrix and add waivers
elezar Oct 16, 2026
b0b4626
docs(tests): put new end-to-end tests under tests/
elezar Oct 16, 2026
fca3500
test(conformance): run the CLI conformance tests as testkit suites
elezar Oct 16, 2026
a29ce0f
test(tests): define k3s and Podman environments for the test plans
elezar Oct 16, 2026
bd8184a
ci(tests): run the conformance lanes through the test runner
elezar Oct 16, 2026
2e91679
test(tests): define arm64 Podman environments
elezar Oct 16, 2026
6739288
fix(tests): install git in every tmachine environment
elezar Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/branch-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ jobs:
cargo fmt --manifest-path e2e/rust/Cargo.toml --all -- --check
cargo fmt --manifest-path examples/governance-interceptor/Cargo.toml --all -- --check
cargo fmt --manifest-path examples/supervisor-middleware-content-guard/Cargo.toml --all -- --check
cargo fmt --manifest-path tests/testkit/Cargo.toml --all -- --check
cargo fmt --manifest-path tests/runner/Cargo.toml --all -- --check
cargo fmt --manifest-path tests/tmachine/Cargo.toml --all -- --check

cargo-lockfiles:
name: Cargo lockfiles
Expand All @@ -239,6 +242,10 @@ jobs:
shell: nix develop -c bash -euo pipefail {0}
run: tasks/scripts/check-cargo-lockfiles.sh

- name: Verify Cargo lockfile alignment
shell: nix develop -c bash -euo pipefail {0}
run: uv run tasks/scripts/check_cargo_lockfile_alignment.py

rust-lint:
name: Rust lint (${{ matrix.system }})
needs: pr_metadata
Expand Down Expand Up @@ -275,6 +282,9 @@ jobs:
cargo clippy --locked --manifest-path e2e/rust/Cargo.toml --all-targets -- -D warnings
cargo clippy --locked --manifest-path examples/governance-interceptor/Cargo.toml --all-targets -- -D warnings
cargo clippy --locked --manifest-path examples/supervisor-middleware-content-guard/Cargo.toml --all-targets -- -D warnings
cargo clippy --locked --manifest-path tests/testkit/Cargo.toml --all-targets -- -D warnings
cargo clippy --locked --manifest-path tests/runner/Cargo.toml --all-targets -- -D warnings
cargo clippy --locked --manifest-path tests/tmachine/Cargo.toml --all-targets -- -D warnings

rust-test:
name: Rust test (${{ matrix.system }})
Expand Down Expand Up @@ -312,6 +322,9 @@ jobs:
run: |
cargo nextest run --locked --profile ci --workspace --features openshell-server/test-support
cargo nextest run --locked --config-file .config/nextest.toml --profile ci --manifest-path examples/supervisor-middleware-content-guard/Cargo.toml
cargo nextest run --locked --config-file .config/nextest.toml --profile ci --manifest-path tests/testkit/Cargo.toml
cargo nextest run --locked --config-file .config/nextest.toml --profile ci --manifest-path tests/runner/Cargo.toml
cargo nextest run --locked --config-file .config/nextest.toml --profile ci --manifest-path tests/tmachine/Cargo.toml

rust-postgres-test:
name: Rust PostgreSQL tests
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/branch-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -240,25 +240,25 @@ jobs:
deb-artifact-name: deb-linux-amd64
rpm-artifact-name: rpm-linux-x86_64

# Run driver-independent conformance tests.
# Run the conformance suites the cpu-tests plan selects, one job per amd64
# environment.
conformance-integration:
needs: prepare-integration
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/integration-runner.yml
uses: ./.github/workflows/e2e-suites.yml
with:
category: conformance
source-sha: ${{ needs.prepare-integration.outputs.source_sha }}
integration-inputs-artifact-id: ${{ needs.prepare-integration.outputs.integration_inputs_artifact_id }}
test-matrix: >-
matrix: >-
[
{"environment":"ubuntu-docker-rootful","installer":"deb","testsuite":"conformance"},
{"environment":"ubuntu-k3s","installer":"k3s","testsuite":"conformance"},
{"environment":"ubuntu-k3s","installer":"k3s-ha","testsuite":"conformance"},
{"environment":"fedora-podman-rootful","installer":"rpm","testsuite":"conformance"},
{"environment":"fedora-podman-rootless","installer":"rpm","testsuite":"conformance"}
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.ubuntu2404-amd64.docker-rootful.deb"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.ubuntu2404-amd64.k3s.k3s"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list is copied by hand from cpu-tests.yaml (5 of its 10 environments) and repeated in release-dev and release-qualification, with no check between them. The arm64 environments are planned but never run, and nothing reports it, which is the failure mode that hid Kubernetes coverage. I'd generate this from the plan, or check it against the plan, before cutover.

{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.ubuntu2404-amd64.k3s.k3s-ha"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.fedora44-amd64.podman-rootful.rpm"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.fedora44-amd64.podman-rootless.rpm"}
]

# Run feature-specific integration tests:
Expand Down
98 changes: 98 additions & 0 deletions .github/workflows/e2e-suites.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

name: E2E Suites

on:
workflow_call:
inputs:
source-sha:
description: Source revision of the prepared candidate artifacts
required: true
type: string
integration-inputs-artifact-id:
description: Immutable ID of the prepared integration inputs artifact
required: true
type: string
matrix:
description: >-
JSON array of {"plan", "runner"} entries, each with an optional
"environment". A plan is a file stem in tests/plans/ that selects
the suites and environments to run; "environment" narrows an entry
to one of them, so environments run as parallel jobs.
required: true
type: string

permissions:
actions: read
contents: read
packages: read

# github.workflow is the caller's name here, so scope the group to this job
# to avoid colliding with (and cancelling) the calling workflow.
concurrency:
group: ${{ github.workflow }}-e2e-suites-${{ github.ref }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old runner keyed concurrency on category. Without a discriminator, a second e2e-suites.yml lane in the same caller (GPU, features) would cancel this one.

cancel-in-progress: true

jobs:
e2e-suites:
name: E2E suites (${{ matrix.plan }}, ${{ matrix.environment || matrix.runner }})
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(inputs.matrix) }}
runs-on: ${{ matrix.runner }}
timeout-minutes: 90
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs['source-sha'] }}
persist-credentials: false

- name: Enable KVM access
run: |
set -euo pipefail
if [[ ! -c /dev/kvm ]]; then
echo "::error::The runner did not expose /dev/kvm"
exit 1
fi
sudo chmod 0666 /dev/kvm
exec 3<>/dev/kvm
exec 3>&-

- uses: ./.github/actions/setup-nix

- name: Cache tmachine disks
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5.1.0
with:
path: ~/.cache/tmachine
key: tmachine-${{ runner.os }}-${{ runner.arch }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

integration-runner.yml deliberately skipped this cache for ubuntu-k3s (#3848), and now every environment shares one key. Intentional? Also, each job now cross-compiles the testkit/SDK workspace with no cargo cache, where prepared archives came from prepare-integration before, so expect a CI time increase.


- name: Download integration inputs
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
artifact-ids: ${{ inputs['integration-inputs-artifact-id'] }}
path: artifacts

- name: Run suites
env:
PLAN: ${{ matrix.plan }}
ENVIRONMENT: ${{ matrix.environment || '' }}
run: |
# Retry dependency preparation, then run the plan once. The runner
# builds the suites for the guest, so it needs no prepared archives.
nix build --no-link .#test-runner || nix build --no-link .#test-runner
args=(test --plan "tests/plans/${PLAN}.yaml" --results artifacts/test-results)
if [[ -n "${ENVIRONMENT}" ]]; then
args+=(--env "${ENVIRONMENT}")
fi
nix run .#test-runner -- "${args[@]}"

- name: Upload results
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: e2e-results-${{ matrix.plan }}-${{ matrix.environment || matrix.runner }}
path: artifacts/test-results
if-no-files-found: ignore
retention-days: 7
17 changes: 9 additions & 8 deletions .github/workflows/release-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,24 +112,25 @@ jobs:
deb-artifact-name: deb-linux-amd64
rpm-artifact-name: rpm-linux-x86_64

# Run the conformance suites the cpu-tests plan selects, one job per amd64
# environment.
conformance-integration:
needs: prepare-integration
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/integration-runner.yml
uses: ./.github/workflows/e2e-suites.yml
with:
category: conformance
source-sha: ${{ needs.prepare-integration.outputs.source_sha }}
integration-inputs-artifact-id: ${{ needs.prepare-integration.outputs.integration_inputs_artifact_id }}
test-matrix: >-
matrix: >-
[
{"environment":"ubuntu-docker-rootful","installer":"deb","testsuite":"conformance"},
{"environment":"ubuntu-k3s","installer":"k3s","testsuite":"conformance"},
{"environment":"ubuntu-k3s","installer":"k3s-ha","testsuite":"conformance"},
{"environment":"fedora-podman-rootful","installer":"rpm","testsuite":"conformance"},
{"environment":"fedora-podman-rootless","installer":"rpm","testsuite":"conformance"}
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.ubuntu2404-amd64.docker-rootful.deb"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.ubuntu2404-amd64.k3s.k3s"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.ubuntu2404-amd64.k3s.k3s-ha"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.fedora44-amd64.podman-rootful.rpm"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.fedora44-amd64.podman-rootless.rpm"}
]

feature-specific-integration:
Expand Down
17 changes: 9 additions & 8 deletions .github/workflows/release-qualification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,24 +65,25 @@ jobs:
deb-artifact-name: deb-linux-amd64
rpm-artifact-name: rpm-linux-x86_64

# Run the conformance suites the cpu-tests plan selects, one job per amd64
# environment.
conformance-integration:
needs: prepare-integration
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/integration-runner.yml
uses: ./.github/workflows/e2e-suites.yml
with:
category: conformance
source-sha: ${{ needs.prepare-integration.outputs.source_sha }}
integration-inputs-artifact-id: ${{ needs.prepare-integration.outputs.integration_inputs_artifact_id }}
test-matrix: >-
matrix: >-
[
{"environment":"ubuntu-docker-rootful","installer":"deb","testsuite":"conformance"},
{"environment":"ubuntu-k3s","installer":"k3s","testsuite":"conformance"},
{"environment":"ubuntu-k3s","installer":"k3s-ha","testsuite":"conformance"},
{"environment":"fedora-podman-rootful","installer":"rpm","testsuite":"conformance"},
{"environment":"fedora-podman-rootless","installer":"rpm","testsuite":"conformance"}
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.ubuntu2404-amd64.docker-rootful.deb"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.ubuntu2404-amd64.k3s.k3s"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.ubuntu2404-amd64.k3s.k3s-ha"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.fedora44-amd64.podman-rootful.rpm"},
{"plan":"cpu-tests","runner":"ubuntu-24.04","environment":"tmachine.fedora44-amd64.podman-rootless.rpm"}
]

feature-specific-integration:
Expand Down
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ ocsf_emit!(event);

- If you change sandbox infrastructure, ensure the relevant sandbox e2e path succeeds.

## End-to-End Tests

- Add new end-to-end tests under `tests/suites/`, following [TESTING.md](TESTING.md). `e2e/` is being migrated to `tests/` and only takes fixes.

## Network Sockets

- On latency-sensitive TCP streams, disable Nagle's algorithm so small
Expand Down
12 changes: 12 additions & 0 deletions CI.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,17 @@ retain the binary installer because their fixtures configure its system service,
local HTTP gateway, and CLI path. The manual Integration Tests workflow defaults
to the package installers and downloads the packages selected by its matrix.

The conformance lanes (`conformance-integration`) run the e2e suites through
`e2e-suites.yml` on the same prepared inputs. Each matrix entry pairs a plan
from `tests/plans/`, which selects the suites and environments, with a runner,
and optionally narrows it to one environment so environments run as parallel
jobs. The test runner builds the suites for the guest itself, and each entry
uploads JUnit reports and failure diagnostics as
`e2e-results-<plan>-<environment>`. Branch E2E, Release Dev, and Release
Qualification run the `cpu-tests` plan on the five amd64 environments: Ubuntu
with Docker (deb), K3s and HA K3s, and Fedora with rootful and rootless Podman
(rpm).

Three opt-in labels enable the long-running E2E suites:

- `test:e2e` runs the Docker, rootless Podman, Kubernetes, and VM E2E suites
Expand Down Expand Up @@ -554,6 +565,7 @@ The bot's full administrator documentation is internal to NVIDIA. The only comma
|---|---|
| `.github/workflows/branch-checks.yml` | Required non-E2E checks. Triggers on `push: pull-request/[0-9]+` for PR mirrors and `merge_group` for queued merges. |
| `.github/workflows/branch-e2e.yml` | Standard, GPU, Kubernetes HA, and Kubernetes credential-driver E2E. PR mirror pushes use `test:e2e`, `test:e2e-gpu`, and `test:e2e-kubernetes` labels; merge groups do not run E2E. |
| `.github/workflows/e2e-suites.yml` | Reusable matrix job that runs the e2e suites selected by plans in `tests/plans/` on the given runners, optionally one environment per job, and uploads `e2e-results-<plan>-<environment or runner>`. Used by the conformance lanes. |
| `.github/workflows/build-binaries.yml`, `build-vm-driver.yml` | Shared binary matrices used by branch and release workflows. The VM driver remains separate because its build consumes the runtime binaries. |
| `.github/workflows/build-images.yml` | Builds and pushes multi-platform images, then uploads the same OCI images as workflow artifacts. |
| `.github/workflows/package-release-binaries.yml` | Packages raw build artifacts into release tarballs without rebuilding them. |
Expand Down
Loading
Loading