diff --git a/Cargo.lock b/Cargo.lock index c6330b8897..0854d0bf41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4264,6 +4264,7 @@ dependencies = [ "serde_json", "tar", "temp-env", + "tempfile", "thiserror 2.0.20", "tokio", "tokio-stream", diff --git a/crates/openshell-driver-podman/Cargo.toml b/crates/openshell-driver-podman/Cargo.toml index c49c309f65..18b1928c33 100644 --- a/crates/openshell-driver-podman/Cargo.toml +++ b/crates/openshell-driver-podman/Cargo.toml @@ -51,6 +51,7 @@ openshell-otel-test-support = { path = "../openshell-otel-test-support" } opentelemetry_sdk = { workspace = true, features = ["testing"] } prost-types = { workspace = true } temp-env = "0.3" +tempfile = "3" tokio = { workspace = true, features = ["test-util"] } [lints] diff --git a/e2e/rust/tests/podman_preflight.rs b/crates/openshell-driver-podman/tests/podman_preflight.rs similarity index 60% rename from e2e/rust/tests/podman_preflight.rs rename to crates/openshell-driver-podman/tests/podman_preflight.rs index afb3bc1c38..439cb95d98 100644 --- a/e2e/rust/tests/podman_preflight.rs +++ b/crates/openshell-driver-podman/tests/podman_preflight.rs @@ -1,51 +1,22 @@ // SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -#![cfg(feature = "e2e-podman")] - -//! Podman driver daemon-unavailable e2e tests. +//! Podman driver daemon-unavailable integration tests. //! //! These tests verify that `openshell-driver-podman` fails fast with an //! actionable error when it cannot reach a Podman API socket, instead of //! hanging or silently serving gRPC against a dead connection. //! -//! The tests do NOT require a running Podman daemon or gateway — they point +//! They do NOT require a running Podman daemon or gateway — they point //! `--podman-socket` at a path that is guaranteed not to exist to simulate -//! the daemon being unavailable. +//! the daemon being unavailable. As a plain Cargo integration test in this +//! crate, this runs via the normal `cargo test -p openshell-driver-podman` +//! lane with no special CI wiring: Cargo provides `CARGO_BIN_EXE_` for +//! this crate's own `[[bin]]` target automatically. -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::time::{Duration, Instant}; -use openshell_e2e::harness::output::strip_ansi; - -/// Locate the workspace root by walking up from this crate's manifest directory. -fn workspace_root() -> PathBuf { - Path::new(env!("CARGO_MANIFEST_DIR")) - .ancestors() - .nth(2) - .expect("failed to resolve workspace root from CARGO_MANIFEST_DIR") - .to_path_buf() -} - -/// Return the path to the `openshell-driver-podman` binary. -/// -/// Uses `OPENSHELL_EXTERNAL_DRIVER_BIN` when set (the same env var the shell -/// e2e harness uses for prebuilt standalone driver artifacts), otherwise -/// expects the binary at `/target/debug/openshell-driver-podman`. -fn driver_podman_bin() -> PathBuf { - let bin = std::env::var_os("OPENSHELL_EXTERNAL_DRIVER_BIN").map_or_else( - || workspace_root().join("target/debug/openshell-driver-podman"), - PathBuf::from, - ); - assert!( - bin.is_file(), - "openshell-driver-podman binary not found at {} — set OPENSHELL_EXTERNAL_DRIVER_BIN \ - or run `cargo build -p openshell-driver-podman` first", - bin.display() - ); - bin -} - /// Run `openshell-driver-podman` pointed at a Podman socket that does not /// exist, and wait for it to exit. /// @@ -53,17 +24,20 @@ fn driver_podman_bin() -> PathBuf { /// socket briefly re-activating), so this can take several seconds. async fn run_with_unreachable_podman_socket() -> (String, i32, Duration, PathBuf) { let tmpdir = tempfile::tempdir().expect("create isolated socket dir"); - let missing_socket = tmpdir.path().join("openshell-e2e-nonexistent-podman.sock"); + // Use a short relative path so miette cannot insert a line-wrap gutter + // inside it on platforms with long temporary-directory paths. + let missing_socket = PathBuf::from("missing-podman.sock"); let start = Instant::now(); - let mut cmd = tokio::process::Command::new(driver_podman_bin()); + let mut cmd = tokio::process::Command::new(env!("CARGO_BIN_EXE_openshell-driver-podman")); cmd.arg("--podman-socket") .arg(&missing_socket) + .current_dir(tmpdir.path()) .kill_on_drop(true) .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()); - let output = tokio::time::timeout(Duration::from_secs(60), cmd.output()) + let output = tokio::time::timeout(Duration::from_mins(1), cmd.output()) .await .expect("openshell-driver-podman should exit instead of hanging") .expect("spawn openshell-driver-podman"); @@ -102,15 +76,14 @@ async fn driver_error_names_unreachable_socket() { let (output, code, _, missing_socket) = run_with_unreachable_podman_socket().await; assert_ne!(code, 0); - let clean = strip_ansi(&output); assert!( - clean.contains("connection error"), - "driver error should describe a connection failure:\n{clean}" + output.contains("connection error"), + "driver error should describe a connection failure:\n{output}" ); assert!( - clean.contains(missing_socket.to_str().expect("socket path is utf-8")), - "driver error should name the unreachable socket path {}:\n{clean}", + output.contains(missing_socket.to_str().expect("socket path is utf-8")), + "driver error should name the unreachable socket path {}:\n{output}", missing_socket.display() ); } diff --git a/e2e/rust/Cargo.toml b/e2e/rust/Cargo.toml index b492c8ac86..6868193431 100644 --- a/e2e/rust/Cargo.toml +++ b/e2e/rust/Cargo.toml @@ -93,11 +93,6 @@ name = "podman_host_gateway" path = "tests/podman_host_gateway.rs" required-features = ["e2e-podman"] -[[test]] -name = "podman_preflight" -path = "tests/podman_preflight.rs" -required-features = ["e2e-podman"] - [[test]] name = "podman_corporate_proxy" path = "tests/podman_corporate_proxy.rs" diff --git a/tests/artifacts.nix b/tests/artifacts.nix index c3017a5da5..c86d8f6d30 100644 --- a/tests/artifacts.nix +++ b/tests/artifacts.nix @@ -116,10 +116,6 @@ let "podman_corporate_proxy" "podman_gateway_start" "podman_oci_identity" - # This validates the standalone driver binary's daemon-unavailable path and - # belongs in the Podman driver crate's integration tests. The E2E archive - # does not contain `openshell-driver-podman`. - "podman_preflight" "provider_auto_create" # The provider-refresh feature suite covers revoked Keycloak grants. This # binary instead covers stable workload handles across repeated rotations