Skip to content

Commit 46b129c

Browse files
committed
test(e2e): add Docker GPU smoke test
Signed-off-by: Evan Lezar <elezar@nvidia.com>
1 parent 9f1cb28 commit 46b129c

3 files changed

Lines changed: 67 additions & 9 deletions

File tree

e2e/rust/e2e-docker.sh

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
33
# SPDX-License-Identifier: Apache-2.0
44

5-
# Run the Rust e2e smoke test against a standalone gateway running the
5+
# Run a Rust e2e test against a standalone gateway running the
66
# bundled Docker compute driver.
77
#
88
# Unlike the Kubernetes driver (which deploys a k3s cluster) or the VM
@@ -20,10 +20,12 @@
2020
# 4. Starts openshell-gateway with --drivers=docker, binding to a
2121
# random free host port.
2222
# 5. Installs the client cert into the CLI gateway config dir and
23-
# runs the Rust smoke test.
23+
# runs the selected Rust e2e test.
2424
# 6. Tears the gateway process down on exit.
2525
#
26-
# Usage: mise run e2e:docker
26+
# Usage:
27+
# mise run e2e:docker
28+
# mise run e2e:docker:gpu
2729

2830
set -euo pipefail
2931

@@ -35,6 +37,8 @@ STATE_DIR=""
3537
GATEWAY_CONFIG_DIR=""
3638
GATEWAY_PID=""
3739
GATEWAY_LOG="${WORKDIR}/gateway.log"
40+
E2E_TEST="${OPENSHELL_E2E_DOCKER_TEST:-smoke}"
41+
GPU_MODE="${OPENSHELL_E2E_DOCKER_GPU:-0}"
3842
# Unique sandbox namespace for this test run. Set just before the gateway
3943
# is started so cleanup can filter Docker containers strictly to ones
4044
# this run created, even when other OpenShell sandboxes are present on
@@ -119,6 +123,17 @@ if ! command -v openssl >/dev/null 2>&1; then
119123
echo "ERROR: openssl is required to generate ephemeral PKI" >&2
120124
exit 2
121125
fi
126+
if [ "${GPU_MODE}" = "1" ]; then
127+
DOCKER_CDI_SPEC_DIRS="$(docker info --format '{{json .CDISpecDirs}}' 2>/dev/null || true)"
128+
if [ -z "${DOCKER_CDI_SPEC_DIRS}" ] \
129+
|| [ "${DOCKER_CDI_SPEC_DIRS}" = "null" ] \
130+
|| [ "${DOCKER_CDI_SPEC_DIRS}" = "[]" ] \
131+
|| [ "${DOCKER_CDI_SPEC_DIRS}" = "<no value>" ]; then
132+
echo "ERROR: e2e:docker:gpu requires Docker CDI support." >&2
133+
echo " Generate CDI specs and restart Docker, then verify docker info reports CDISpecDirs." >&2
134+
exit 2
135+
fi
136+
fi
122137

123138
normalize_arch() {
124139
case "$1" in
@@ -186,8 +201,10 @@ chmod +x "${SUPERVISOR_BIN}"
186201
# in the image. Use the community sandbox base image (also what real
187202
# deployments default to). Callers can override with
188203
# OPENSHELL_E2E_DOCKER_SANDBOX_IMAGE if they have a smaller local image
189-
# with the required 'sandbox' user.
190-
SANDBOX_IMAGE="${OPENSHELL_E2E_DOCKER_SANDBOX_IMAGE:-ghcr.io/nvidia/openshell-community/sandboxes/base:latest}"
204+
# with the required 'sandbox' user. CDI injects the NVIDIA userspace
205+
# stack at runtime, so the GPU lane uses the same base image.
206+
DEFAULT_SANDBOX_IMAGE="ghcr.io/nvidia/openshell-community/sandboxes/base:latest"
207+
SANDBOX_IMAGE="${OPENSHELL_E2E_DOCKER_SANDBOX_IMAGE:-${DEFAULT_SANDBOX_IMAGE}}"
191208
if ! docker image inspect "${SANDBOX_IMAGE}" >/dev/null 2>&1; then
192209
echo "Pulling ${SANDBOX_IMAGE}..."
193210
docker pull "${SANDBOX_IMAGE}"
@@ -313,8 +330,8 @@ if [ "${elapsed}" -ge "${timeout}" ]; then
313330
exit 1
314331
fi
315332

316-
# ── Run the smoke test ───────────────────────────────────────────────
317-
echo "Running e2e smoke test (gateway: ${OPENSHELL_GATEWAY}, endpoint: ${CLI_GATEWAY_ENDPOINT})..."
318-
cargo test --manifest-path e2e/rust/Cargo.toml --features e2e --test smoke -- --nocapture
333+
# ── Run the selected test ────────────────────────────────────────────
334+
echo "Running e2e ${E2E_TEST} test (gateway: ${OPENSHELL_GATEWAY}, endpoint: ${CLI_GATEWAY_ENDPOINT})..."
335+
cargo test --manifest-path e2e/rust/Cargo.toml --features e2e --test "${E2E_TEST}" -- --nocapture
319336

320-
echo "Smoke test passed."
337+
echo "${E2E_TEST} test passed."

e2e/rust/tests/docker_gpu.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#![cfg(feature = "e2e")]
5+
6+
//! Docker GPU e2e test.
7+
//!
8+
//! Requires a Docker-backed gateway started with Docker CDI support. The
9+
//! `e2e:docker:gpu` mise task starts that gateway with the default sandbox image
10+
//! unless OPENSHELL_E2E_DOCKER_SANDBOX_IMAGE is set.
11+
12+
use openshell_e2e::harness::output::strip_ansi;
13+
use openshell_e2e::harness::sandbox::SandboxGuard;
14+
15+
#[tokio::test]
16+
async fn docker_gpu_sandbox_runs_nvidia_smi() {
17+
let mut guard = SandboxGuard::create(&[
18+
"--gpu",
19+
"--",
20+
"sh",
21+
"-lc",
22+
"gpu_name=$(nvidia-smi --query-gpu=name --format=csv,noheader | head -n 1); \
23+
test -n \"$gpu_name\"; \
24+
printf 'gpu-ok:%s\n' \"$gpu_name\"",
25+
])
26+
.await
27+
.expect("GPU sandbox create should succeed");
28+
29+
let output = strip_ansi(&guard.create_output);
30+
assert!(
31+
output.contains("gpu-ok:"),
32+
"expected GPU smoke marker in sandbox output:\n{output}"
33+
);
34+
35+
guard.cleanup().await;
36+
}

tasks/test.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,8 @@ run = "e2e/rust/e2e-vm.sh"
6060
["e2e:docker"]
6161
description = "Run smoke e2e against a standalone gateway with the Docker compute driver"
6262
run = "e2e/rust/e2e-docker.sh"
63+
64+
["e2e:docker:gpu"]
65+
description = "Run GPU e2e against a standalone gateway with the Docker compute driver"
66+
env = { OPENSHELL_E2E_DOCKER_GPU = "1", OPENSHELL_E2E_DOCKER_TEST = "docker_gpu" }
67+
run = "e2e/rust/e2e-docker.sh"

0 commit comments

Comments
 (0)