test(oci): accept existing workspace rejection diagnostics

Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
Matthew Grossman
2026-10-08 12:04:51 +02:00
committed by Evan Lezar
parent 27bfea80ab
commit 9ebe52b37e
@@ -21,9 +21,6 @@ const BASE_IMAGE: &str = "nvcr.io/nvidia/base/ubuntu:24.04";
const ENGINE_ENV: &str = "OPENSHELL_TEST_CONTAINER_ENGINE";
const CREATE_TIMEOUT: Duration = Duration::from_mins(10);
const COMMAND_TIMEOUT: Duration = Duration::from_mins(2);
/// Sandbox condition reason for an image `WORKDIR` the sandbox identity
/// cannot use.
const WORKSPACE_VALIDATION_FAILED: &str = "WorkspaceValidationFailed";
/// A complete sandbox policy without a `process` section, so the sandbox
/// identity falls back to the image `USER`.
const IMAGE_IDENTITY_POLICY: &str = "version: 1
@@ -117,8 +114,9 @@ async fn default_workdir_uses_managed_workspace() {
}
/// OpenShell rejects a custom `WORKDIR` that the image user cannot write
/// instead of granting the user new access to it, and reports that reason
/// rather than a generic startup failure.
/// instead of granting the user new access to it. Drivers may surface the
/// rejection through different startup diagnostics rather than one condition
/// reason.
#[tokio::test]
async fn unwritable_custom_workdir_is_rejected() {
run("oci-image/unwritable-workdir", async |runner| {
@@ -156,18 +154,58 @@ USER app
if create.success() || create.stdout().contains("should-not-run") {
return Err(create.failure_diagnostic("sandbox creation fails before the command runs"));
}
if !create.stdout().contains(WORKSPACE_VALIDATION_FAILED)
&& !create.stderr().contains(WORKSPACE_VALIDATION_FAILED)
{
return Err(create.failure_diagnostic(&format!(
"sandbox creation fails with {WORKSPACE_VALIDATION_FAILED}"
)));
let diagnostic = format!("{}\n{}", create.stdout(), create.stderr());
if !has_workspace_rejection_diagnostic(&diagnostic) {
return Err(create.failure_diagnostic(
"sandbox creation reports a workspace, permission, or workload startup rejection",
));
}
Ok(())
})
.await;
}
fn has_workspace_rejection_diagnostic(diagnostic: &str) -> bool {
let diagnostic = diagnostic.to_ascii_lowercase();
// The CLI may wrap the human message across lines with diagnostic gutters.
// Match the existing startup reason and exit detail independently.
if diagnostic.contains("containerexited") && diagnostic.contains("exited with code") {
return true;
}
[
"workspace",
"workingdir",
"permission denied",
// Some drivers expose the rejected workload launch through SSH rather
// than propagating the runtime's workspace validation text.
"subsystem request failed",
]
.iter()
.any(|message| diagnostic.contains(message))
}
#[test]
fn workspace_rejection_diagnostics_do_not_require_one_condition_reason() {
for diagnostic in [
"image workspace validation failed",
"WorkingDir /workspace/project is not writable",
"Permission denied (os error 13)",
"ContainerExited: Container exited with code 1",
"Error: × sandbox entered error phase while provisioning: ContainerExited: Container\n │ exited with code 1",
"subsystem request failed",
] {
assert!(has_workspace_rejection_diagnostic(diagnostic));
}
for diagnostic in [
"",
"gateway connection refused",
"image pull failed",
"ContainerExited",
] {
assert!(!has_workspace_rejection_diagnostic(diagnostic));
}
}
async fn run(scenario: &str, test: impl AsyncFnOnce(&mut OpenShellRunner) -> Result<(), String>) {
let mut runner =
OpenShellRunner::from_env(scenario).expect("candidate openshell CLI is available");