Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ lifecycle management, output parsing, and cleanup.
Suites:

- Common suite (`--features e2e`) - driver-neutral CLI behavior, sandbox lifecycle, sync, port forwarding, policy, and provider tests.
- CLI conformance (`--features e2e-cli-conformance`) - a curated portable CLI
baseline selected from existing E2E test targets. The profile contains gateway
smoke, sandbox lifecycle, and sandbox label workflows.
- Docker suite (`--features e2e-docker`) - common suite plus Docker-only coverage such as Dockerfile image builds, Docker preflight checks, and managed Docker gateway start.
- Docker GPU suite (`--features e2e-docker-gpu`) - Docker suite plus GPU sandbox smoke coverage.
- VM suite (`--features e2e-vm`) - runs e2e tests on a VM.
Expand All @@ -169,6 +172,24 @@ Run the Docker-backed Rust CLI e2e suite:
mise run e2e:rust
```

Run the minimal portable CLI conformance profile against the gateway selected
in your OpenShell CLI configuration:

```shell
mise run e2e:cli-conformance
```

The gateway must already be installed, reachable, and selected before the task
starts. The task does not provision a gateway or select a compute driver. Set
`OPENSHELL_BIN` to test a prebuilt CLI; otherwise, the task builds the CLI from
the current checkout.

The conformance task selects existing test targets explicitly. Driver suites
provision their own gateways and enable the same profile when they run
overlapping portable targets; the test implementations are shared instead of
duplicated as driver-specific coverage. VM overlay and TLS-key permission
assertions remain in the VM suite instead of the portable smoke workflow.

Run the Podman-backed Rust CLI e2e suite:

```shell
Expand Down
24 changes: 24 additions & 0 deletions e2e/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ publish = false

[features]
e2e = []
# Selects the portable CLI conformance profile. The profile initially reuses
# existing E2E test targets; membership is defined by the e2e:cli-conformance
# task so adding the feature does not remove tests from existing E2E suites.
e2e-cli-conformance = ["e2e"]
# Selects tests that rely on `host.openshell.internal` (the sandbox's stable
# alias to the host running test fixtures). docker, podman, and vm wire the
# alias unconditionally; the kube driver only does so when the chart's
Expand All @@ -41,6 +45,26 @@ name = "oidc_pkce"
path = "tests/oidc_pkce.rs"
required-features = ["e2e-oidc-pkce"]

[[test]]
name = "smoke"
path = "tests/smoke.rs"
required-features = ["e2e-cli-conformance"]

[[test]]
name = "sandbox_lifecycle"
path = "tests/sandbox_lifecycle.rs"
required-features = ["e2e-cli-conformance"]

[[test]]
name = "sandbox_labels"
path = "tests/sandbox_labels.rs"
required-features = ["e2e-cli-conformance"]

[[test]]
name = "vm_overlay"
path = "tests/vm_overlay.rs"
required-features = ["e2e-vm"]

[[test]]
name = "custom_image"
path = "tests/custom_image.rs"
Expand Down
2 changes: 1 addition & 1 deletion e2e/rust/e2e-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
E2E_TEST="${OPENSHELL_E2E_DOCKER_TEST:-smoke}"
E2E_FEATURES="${OPENSHELL_E2E_DOCKER_FEATURES:-e2e,e2e-docker}"
E2E_FEATURES="${OPENSHELL_E2E_DOCKER_FEATURES:-e2e-docker,e2e-cli-conformance}"
DEFAULT_WORKLOAD_MANIFEST="${ROOT}/e2e/gpu/images/.build/workloads.yaml"

if [ "${E2E_TEST}" = "gpu" ] && [ -z "${OPENSHELL_E2E_WORKLOAD_MANIFEST:-}" ] && [ ! -f "${DEFAULT_WORKLOAD_MANIFEST}" ]; then
Expand Down
2 changes: 1 addition & 1 deletion e2e/rust/e2e-kubernetes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"

E2E_FEATURES="${OPENSHELL_E2E_KUBERNETES_FEATURES:-e2e,e2e-host-gateway,e2e-kubernetes}"
E2E_FEATURES="${OPENSHELL_E2E_KUBERNETES_FEATURES:-e2e,e2e-cli-conformance,e2e-host-gateway,e2e-kubernetes}"

# Docker and Podman build their local gateway and CLI together in the shared
# gateway wrapper. Kubernetes consumes published gateway images, so only its
Expand Down
2 changes: 1 addition & 1 deletion e2e/rust/e2e-podman.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
E2E_TEST="${OPENSHELL_E2E_PODMAN_TEST:-}"
E2E_FEATURES="${OPENSHELL_E2E_PODMAN_FEATURES:-e2e-podman}"
E2E_FEATURES="${OPENSHELL_E2E_PODMAN_FEATURES:-e2e-podman,e2e-cli-conformance}"
DEFAULT_WORKLOAD_MANIFEST="${ROOT}/e2e/gpu/images/.build/workloads.yaml"

if [ "${E2E_TEST}" = "gpu" ] && [ -z "${OPENSHELL_E2E_WORKLOAD_MANIFEST:-}" ] && [ ! -f "${DEFAULT_WORKLOAD_MANIFEST}" ]; then
Expand Down
4 changes: 2 additions & 2 deletions e2e/rust/e2e-vm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ GATEWAY_BIN="${OPENSHELL_GATEWAY_BIN:-${ROOT}/target/debug/openshell-gateway}"
DRIVER_BIN="${OPENSHELL_VM_DRIVER_BIN:-${ROOT}/target/debug/openshell-driver-vm}"
CLI_BIN="${OPENSHELL_BIN:-${ROOT}/target/debug/openshell}"
E2E_TEST_OVERRIDE="${OPENSHELL_E2E_VM_TEST:-}"
E2E_FEATURES="${OPENSHELL_E2E_VM_FEATURES:-e2e-vm}"
E2E_FEATURES="${OPENSHELL_E2E_VM_FEATURES:-e2e-vm,e2e-cli-conformance}"
SANDBOX_IMAGE="${OPENSHELL_SANDBOX_IMAGE:-${COMMUNITY_SANDBOX_IMAGE:-ghcr.io/nvidia/openshell-community/sandboxes/base:latest}}"

# The VM driver places `compute-driver.sock` under `[openshell.drivers.vm].state_dir`.
Expand Down Expand Up @@ -371,7 +371,6 @@ fi
# The CLI uses the raw endpoint but still resolves matching metadata so it
# can find the mTLS client bundle.

export OPENSHELL_E2E_EXPECT_VM_OVERLAY=1
export OPENSHELL_E2E_DRIVER="vm"
export OPENSHELL_E2E_VM_STATE_DIR="${RUN_STATE_DIR}"
e2e_export_gateway_restart_metadata \
Expand Down Expand Up @@ -405,5 +404,6 @@ if [ -n "${E2E_TEST_OVERRIDE}" ]; then
else
run_e2e_test smoke
run_e2e_test host_gateway_alias
run_e2e_test vm_overlay
run_e2e_test vm_gateway_start
fi
42 changes: 0 additions & 42 deletions e2e/rust/tests/smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ async fn gateway_smoke() {
sb.create_output,
);

if std::env::var_os("OPENSHELL_E2E_EXPECT_VM_OVERLAY").is_some() {
assert_vm_overlay_root(&sb.name).await;
}

// ── 3. Verify the sandbox appeared in the list ───────────────────
let mut list_cmd = openshell_cmd();
list_cmd
Expand Down Expand Up @@ -99,41 +95,3 @@ async fn gateway_smoke() {
// ── 4. Cleanup ───────────────────────────────────────────────────
sb.cleanup().await;
}

async fn assert_vm_overlay_root(sandbox_name: &str) {
let script = concat!(
"set -eu; ",
"test \"$(stat -f -c %T /)\" = \"overlayfs\"; ",
"printf \"overlay-write\\n\" > /sandbox/overlay-check; ",
"test \"$(cat /sandbox/overlay-check)\" = \"overlay-write\"; ",
"if [ -e /opt/openshell/tls/tls.key ]; then ",
"test \"$(stat -c %a /opt/openshell/tls/tls.key)\" = \"600\"; ",
"fi; ",
"echo vm-overlay-ok",
);

let mut exec_cmd = openshell_cmd();
exec_cmd
.args(["sandbox", "exec", "--name", sandbox_name, "--no-tty", "--"])
.arg("sh")
.arg("-lc")
.arg(script)
.stdout(Stdio::piped())
.stderr(Stdio::piped());

let output = exec_cmd
.output()
.await
.expect("failed to run VM overlay assertion");
let combined = strip_ansi(&format!(
"{}{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
));

assert!(
output.status.success() && combined.contains("vm-overlay-ok"),
"VM overlay assertion failed (status {:?}):\n{combined}",
output.status.code(),
);
}
54 changes: 54 additions & 0 deletions e2e/rust/tests/vm_overlay.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//! VM-driver-specific assertions for the sandbox root filesystem.

use std::process::Stdio;

use openshell_e2e::harness::binary::openshell_cmd;
use openshell_e2e::harness::output::strip_ansi;
use openshell_e2e::harness::sandbox::SandboxGuard;

#[tokio::test]
async fn vm_overlay() {
let mut sandbox = SandboxGuard::create(&["--", "echo", "vm-sandbox-ready"])
.await
.expect("sandbox create should succeed");

let script = concat!(
"set -eu; ",
"test \"$(stat -f -c %T /)\" = \"overlayfs\"; ",
"printf \"overlay-write\\n\" > /sandbox/overlay-check; ",
"test \"$(cat /sandbox/overlay-check)\" = \"overlay-write\"; ",
"if [ -e /opt/openshell/tls/tls.key ]; then ",
"test \"$(stat -c %a /opt/openshell/tls/tls.key)\" = \"600\"; ",
"fi; ",
"echo vm-overlay-ok",
);

let mut exec_cmd = openshell_cmd();
exec_cmd
.args(["sandbox", "exec", "--name", &sandbox.name, "--no-tty", "--"])
.arg("sh")
.arg("-lc")
.arg(script)
.stdout(Stdio::piped())
.stderr(Stdio::piped());

let output = exec_cmd
.output()
.await
.expect("failed to run VM overlay assertion");
let combined = strip_ansi(&format!(
"{}{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
));
assert!(
output.status.success() && combined.contains("vm-overlay-ok"),
"VM overlay assertion failed (status {:?}):\n{combined}",
output.status.code(),
);

sandbox.cleanup().await;
}
9 changes: 8 additions & 1 deletion tasks/test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,14 @@ hide = true
["e2e:rust"]
description = "Run Rust CLI e2e tests against a Docker-backed gateway"
run = [
"e2e/with-docker-gateway.sh cargo test --manifest-path e2e/rust/Cargo.toml --features e2e-docker",
"e2e/with-docker-gateway.sh cargo test --manifest-path e2e/rust/Cargo.toml --features e2e-docker,e2e-cli-conformance",
]

["e2e:cli-conformance"]
description = "Run the portable CLI conformance baseline against the configured gateway"
run = [
"if [ -z \"${OPENSHELL_BIN:-}\" ]; then cargo build -p openshell-cli; fi",
"cargo test --manifest-path e2e/rust/Cargo.toml --features e2e-cli-conformance --test smoke --test sandbox_lifecycle --test sandbox_labels",
]

["e2e:websocket-conformance"]
Expand Down
Loading