diff --git a/e2e/rust/src/harness/output.rs b/e2e/rust/src/harness/output.rs index c1c926e6e1..28022043f0 100644 --- a/e2e/rust/src/harness/output.rs +++ b/e2e/rust/src/harness/output.rs @@ -16,7 +16,7 @@ pub fn strip_ansi(s: &str) -> String { // Consume the `[` and everything up to the terminating letter. if chars.peek() == Some(&'[') { chars.next(); // consume '[' - // Consume parameter bytes (digits, ';') and the final byte. + // Consume parameter bytes (digits, ';') and the final byte. for c in chars.by_ref() { if c.is_ascii_alphabetic() { break; diff --git a/e2e/rust/src/harness/port.rs b/e2e/rust/src/harness/port.rs index 70f4549919..e6c82ceb5b 100644 --- a/e2e/rust/src/harness/port.rs +++ b/e2e/rust/src/harness/port.rs @@ -51,10 +51,7 @@ pub async fn wait_for_port(host: &str, port: u16, max_wait: Duration) -> Result< pub fn find_free_port() -> u16 { let listener = TcpListener::bind(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0)).expect("bind to port 0"); - listener - .local_addr() - .expect("local_addr after bind") - .port() + listener.local_addr().expect("local_addr after bind").port() } #[cfg(test)] diff --git a/e2e/rust/src/harness/sandbox.rs b/e2e/rust/src/harness/sandbox.rs index 43fa4ee396..de3a69c198 100644 --- a/e2e/rust/src/harness/sandbox.rs +++ b/e2e/rust/src/harness/sandbox.rs @@ -20,8 +20,7 @@ use super::output::{extract_field, strip_ansi}; /// The CLI prints `Created sandbox: ` (current format). Falls back to /// `Name: ` for compatibility with older output formats. fn extract_sandbox_name(output: &str) -> Option { - extract_field(output, "Created sandbox") - .or_else(|| extract_field(output, "Name")) + extract_field(output, "Created sandbox").or_else(|| extract_field(output, "Name")) } /// Default timeout for waiting for a sandbox to become ready. @@ -76,9 +75,7 @@ impl SandboxGuard { let output = timeout(SANDBOX_READY_TIMEOUT, cmd.output()) .await - .map_err(|_| { - format!("sandbox create timed out after {SANDBOX_READY_TIMEOUT:?}") - })? + .map_err(|_| format!("sandbox create timed out after {SANDBOX_READY_TIMEOUT:?}"))? .map_err(|e| format!("failed to spawn openshell: {e}"))?; let stdout = String::from_utf8_lossy(&output.stdout).to_string(); @@ -123,10 +120,7 @@ impl SandboxGuard { /// Returns an error if the process exits prematurely, the ready marker is /// not seen within [`SANDBOX_READY_TIMEOUT`], or the sandbox name cannot /// be parsed. - pub async fn create_keep( - command: &[&str], - ready_marker: &str, - ) -> Result { + pub async fn create_keep(command: &[&str], ready_marker: &str) -> Result { Self::create_keep_with_args(&[], command, ready_marker).await } @@ -255,9 +249,7 @@ impl SandboxGuard { let output = timeout(SANDBOX_READY_TIMEOUT, cmd.output()) .await .map_err(|_| { - format!( - "sandbox create --upload timed out after {SANDBOX_READY_TIMEOUT:?}" - ) + format!("sandbox create --upload timed out after {SANDBOX_READY_TIMEOUT:?}") })? .map_err(|e| format!("failed to spawn openshell: {e}"))?; @@ -429,11 +421,7 @@ impl SandboxGuard { /// # Errors /// /// Returns an error if the download command fails. - pub async fn download( - &self, - sandbox_path: &str, - local_dest: &str, - ) -> Result { + pub async fn download(&self, sandbox_path: &str, local_dest: &str) -> Result { let mut cmd = openshell_cmd(); cmd.arg("sandbox") .arg("download") diff --git a/e2e/rust/tests/bypass_detection.rs b/e2e/rust/tests/bypass_detection.rs index 698fd346d6..56415a554b 100644 --- a/e2e/rust/tests/bypass_detection.rs +++ b/e2e/rust/tests/bypass_detection.rs @@ -58,16 +58,10 @@ async fn bypass_attempt_is_rejected_fast() { .create_output .lines() .find(|l| l.contains("bypass_result")) - .unwrap_or_else(|| { - panic!( - "no bypass_result JSON in output:\n{}", - guard.create_output - ) - }); + .unwrap_or_else(|| panic!("no bypass_result JSON in output:\n{}", guard.create_output)); - let parsed: serde_json::Value = serde_json::from_str(json_line.trim()).unwrap_or_else(|e| { - panic!("failed to parse JSON '{json_line}': {e}") - }); + let parsed: serde_json::Value = serde_json::from_str(json_line.trim()) + .unwrap_or_else(|e| panic!("failed to parse JSON '{json_line}': {e}")); let result = parsed["bypass_result"].as_str().unwrap(); let elapsed_ms = parsed["elapsed_ms"].as_u64().unwrap(); diff --git a/e2e/rust/tests/cf_auth_smoke.rs b/e2e/rust/tests/cf_auth_smoke.rs index 29d4362273..34fa1be02c 100644 --- a/e2e/rust/tests/cf_auth_smoke.rs +++ b/e2e/rust/tests/cf_auth_smoke.rs @@ -136,8 +136,10 @@ async fn gateway_login_help_is_recognized() { let clean = strip_ansi(&output); // Should mention authenticating or Cloudflare assert!( - clean.to_lowercase().contains("authenticat") || clean.to_lowercase().contains("cloudflare") - || clean.to_lowercase().contains("login") || clean.to_lowercase().contains("browser"), + clean.to_lowercase().contains("authenticat") + || clean.to_lowercase().contains("cloudflare") + || clean.to_lowercase().contains("login") + || clean.to_lowercase().contains("browser"), "expected auth-related text in gateway login --help:\n{clean}" ); } @@ -210,10 +212,7 @@ async fn gateway_add_creates_cf_metadata() { ); // Verify the gateway was set as active. - let active_path = tmpdir - .path() - .join("openshell") - .join("active_gateway"); + let active_path = tmpdir.path().join("openshell").join("active_gateway"); assert!( active_path.exists(), "active_gateway file should exist at {}", @@ -241,18 +240,11 @@ async fn gateway_add_derives_name_from_hostname() { let (output, code) = run_with_config( tmpdir.path(), - &[ - "gateway", - "add", - "https://my-special-gateway.brevlab.com", - ], + &["gateway", "add", "https://my-special-gateway.brevlab.com"], ) .await; - assert_eq!( - code, 0, - "gateway add should exit 0:\n{output}" - ); + assert_eq!(code, 0, "gateway add should exit 0:\n{output}"); // The derived name should be the hostname. let metadata_path = tmpdir @@ -344,10 +336,7 @@ async fn gateway_add_rejects_duplicate_name() { ], ) .await; - assert_ne!( - code, 0, - "duplicate gateway add should fail:\n{output}" - ); + assert_ne!(code, 0, "duplicate gateway add should fail:\n{output}"); let clean = strip_ansi(&output); assert!( @@ -363,18 +352,9 @@ async fn gateway_add_rejects_duplicate_name() { /// `ssh://` endpoint with `--local` should fail. #[tokio::test] async fn gateway_add_ssh_url_conflicts_with_local() { - let (output, code) = run_isolated(&[ - "gateway", - "add", - "ssh://user@host:8080", - "--local", - ]) - .await; + let (output, code) = run_isolated(&["gateway", "add", "ssh://user@host:8080", "--local"]).await; - assert_ne!( - code, 0, - "ssh:// with --local should fail:\n{output}" - ); + assert_ne!(code, 0, "ssh:// with --local should fail:\n{output}"); } /// `ssh://` endpoint with `--remote` should fail (redundant). @@ -389,26 +369,15 @@ async fn gateway_add_ssh_url_conflicts_with_remote() { ]) .await; - assert_ne!( - code, 0, - "ssh:// with --remote should fail:\n{output}" - ); + assert_ne!(code, 0, "ssh:// with --remote should fail:\n{output}"); } /// `ssh://` endpoint without a port should fail. #[tokio::test] async fn gateway_add_ssh_url_requires_port() { - let (output, code) = run_isolated(&[ - "gateway", - "add", - "ssh://user@host", - ]) - .await; + let (output, code) = run_isolated(&["gateway", "add", "ssh://user@host"]).await; - assert_ne!( - code, 0, - "ssh:// without port should fail:\n{output}" - ); + assert_ne!(code, 0, "ssh:// without port should fail:\n{output}"); let clean = strip_ansi(&output); assert!( diff --git a/e2e/rust/tests/cli_smoke.rs b/e2e/rust/tests/cli_smoke.rs index b88f59af29..fe3d78b146 100644 --- a/e2e/rust/tests/cli_smoke.rs +++ b/e2e/rust/tests/cli_smoke.rs @@ -364,13 +364,7 @@ async fn gateway_add_can_shadow_system_gateway_with_user_registration() { let (add_output, add_code) = run_with_config( config_dir.path(), Some(system_dir.path()), - &[ - "gateway", - "add", - "http://127.0.0.1:17671", - "--name", - "beta", - ], + &["gateway", "add", "http://127.0.0.1:17671", "--name", "beta"], ) .await; assert_eq!( diff --git a/e2e/rust/tests/custom_image.rs b/e2e/rust/tests/custom_image.rs index ff3cda86ae..fa905bbf19 100644 --- a/e2e/rust/tests/custom_image.rs +++ b/e2e/rust/tests/custom_image.rs @@ -52,15 +52,10 @@ async fn sandbox_from_custom_dockerfile() { // Step 2: Create a sandbox from the Dockerfile. let dockerfile_str = dockerfile_path.to_str().expect("Dockerfile path is UTF-8"); - let mut guard = SandboxGuard::create(&[ - "--from", - dockerfile_str, - "--", - "cat", - "/etc/marker.txt", - ]) - .await - .expect("sandbox create from Dockerfile"); + let mut guard = + SandboxGuard::create(&["--from", dockerfile_str, "--", "cat", "/etc/marker.txt"]) + .await + .expect("sandbox create from Dockerfile"); // Step 3: Verify the marker file content appears in the output. let clean_output = strip_ansi(&guard.create_output); diff --git a/e2e/rust/tests/edge_tunnel_e2e.rs b/e2e/rust/tests/edge_tunnel_e2e.rs index e39edc3ea9..80ee4a6ed8 100644 --- a/e2e/rust/tests/edge_tunnel_e2e.rs +++ b/e2e/rust/tests/edge_tunnel_e2e.rs @@ -26,9 +26,7 @@ use openshell_e2e::harness::output::strip_ansi; /// Run `openshell ` using the system's configured gateway. async fn run_cli(args: &[&str]) -> (String, i32) { let mut cmd = openshell_cmd(); - cmd.args(args) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()); + cmd.args(args).stdout(Stdio::piped()).stderr(Stdio::piped()); let output = cmd.output().await.expect("spawn openshell"); let stdout = String::from_utf8_lossy(&output.stdout).to_string(); @@ -164,20 +162,16 @@ async fn ws_tunnel_status_through_edge_proxy() { // Extract the gateway endpoint from the info output. // The format varies, but it should contain a URL-like string. - let endpoint = info_clean - .lines() - .find_map(|line| { - if line.to_lowercase().contains("endpoint") - || line.to_lowercase().contains("gateway") - { - // Try to extract a URL from the line - line.split_whitespace() - .find(|word| word.starts_with("http://") || word.starts_with("https://")) - .map(String::from) - } else { - None - } - }); + let endpoint = info_clean.lines().find_map(|line| { + if line.to_lowercase().contains("endpoint") || line.to_lowercase().contains("gateway") { + // Try to extract a URL from the line + line.split_whitespace() + .find(|word| word.starts_with("http://") || word.starts_with("https://")) + .map(String::from) + } else { + None + } + }); let Some(endpoint) = endpoint else { eprintln!( @@ -208,12 +202,8 @@ async fn ws_tunnel_status_through_edge_proxy() { "dummy-test-jwt", ); - let (output, code) = run_cli_with_config(tmpdir.path(), &[ - "--gateway", - "edge-tunnel-test", - "status", - ]) - .await; + let (output, code) = + run_cli_with_config(tmpdir.path(), &["--gateway", "edge-tunnel-test", "status"]).await; let clean = strip_ansi(&output); assert_eq!( diff --git a/e2e/rust/tests/forward_proxy_jsonrpc_l7.rs b/e2e/rust/tests/forward_proxy_jsonrpc_l7.rs index d5196b3554..174e3b6db9 100644 --- a/e2e/rust/tests/forward_proxy_jsonrpc_l7.rs +++ b/e2e/rust/tests/forward_proxy_jsonrpc_l7.rs @@ -429,7 +429,10 @@ print(json.dumps(results, sort_keys=True)) ("forward_method_initialize_allowed", 200), ("forward_method_tools_list_allowed", 200), ("forward_method_tools_call_allowed", 200), - ("forward_method_tools_call_with_unmatched_params_allowed", 200), + ( + "forward_method_tools_call_with_unmatched_params_allowed", + 200, + ), // forward proxy — method denied ("forward_method_tools_delete_denied", 403), // forward proxy — batch @@ -441,7 +444,10 @@ print(json.dumps(results, sort_keys=True)) ("connect_method_initialize_allowed", 200), ("connect_method_tools_list_allowed", 200), ("connect_method_tools_call_allowed", 200), - ("connect_method_tools_call_with_unmatched_params_allowed", 200), + ( + "connect_method_tools_call_with_unmatched_params_allowed", + 200, + ), // CONNECT path — method denied ("connect_method_tools_delete_denied", 403), ] { diff --git a/e2e/rust/tests/live_policy_update.rs b/e2e/rust/tests/live_policy_update.rs index c3bad7e802..1ee9ea1046 100644 --- a/e2e/rust/tests/live_policy_update.rs +++ b/e2e/rust/tests/live_policy_update.rs @@ -231,8 +231,7 @@ fn extract_version(output: &str) -> Option { /// Extract the policy hash from `policy get` output. fn extract_hash(output: &str) -> Option { - extract_field(output, "Hash") - .or_else(|| extract_field(output, "Policy hash")) + extract_field(output, "Hash").or_else(|| extract_field(output, "Policy hash")) } /// Check that a version number appears in `policy list` output as a @@ -265,8 +264,7 @@ fn list_output_contains_version(output: &str, version: u32) -> bool { async fn live_policy_update_round_trip() { // --- Write two distinct policy files --- let policy_a = write_policy(&["api.anthropic.com"]).expect("write policy A"); - let policy_b = - write_policy(&["api.anthropic.com", "example.com"]).expect("write policy B"); + let policy_b = write_policy(&["api.anthropic.com", "example.com"]).expect("write policy B"); let policy_a_path = policy_a .path() @@ -280,16 +278,21 @@ async fn live_policy_update_round_trip() { .to_string(); // --- Create a long-running sandbox --- - let mut guard = SandboxGuard::create_keep( - &["sh", "-c", "echo Ready && sleep infinity"], - "Ready", - ) - .await - .expect("create keep sandbox"); + let mut guard = + SandboxGuard::create_keep(&["sh", "-c", "echo Ready && sleep infinity"], "Ready") + .await + .expect("create keep sandbox"); // --- Set initial policy A --- let r = run_cli(&[ - "policy", "set", &guard.name, "--policy", &policy_a_path, "--wait", "--timeout", "120", + "policy", + "set", + &guard.name, + "--policy", + &policy_a_path, + "--wait", + "--timeout", + "120", ]) .await; assert!( @@ -306,8 +309,12 @@ async fn live_policy_update_round_trip() { r.exit_code, r.output ); - let initial_version = extract_version(&r.output) - .unwrap_or_else(|| panic!("could not parse version from policy get output:\n{}", r.output)); + let initial_version = extract_version(&r.output).unwrap_or_else(|| { + panic!( + "could not parse version from policy get output:\n{}", + r.output + ) + }); assert!( initial_version >= 1, "initial policy version should be >= 1, got {initial_version}" @@ -317,7 +324,14 @@ async fn live_policy_update_round_trip() { // --- Push same policy A again -> should be idempotent --- let r = run_cli(&[ - "policy", "set", &guard.name, "--policy", &policy_a_path, "--wait", "--timeout", "120", + "policy", + "set", + &guard.name, + "--policy", + &policy_a_path, + "--wait", + "--timeout", + "120", ]) .await; assert!( @@ -327,7 +341,11 @@ async fn live_policy_update_round_trip() { ); let r = run_cli(&["policy", "get", &guard.name]).await; - assert!(r.success, "policy get after repeat should succeed:\n{}", r.output); + assert!( + r.success, + "policy get after repeat should succeed:\n{}", + r.output + ); let repeat_version = extract_version(&r.output) .unwrap_or_else(|| panic!("could not parse version after repeat:\n{}", r.output)); @@ -342,7 +360,14 @@ async fn live_policy_update_round_trip() { // --- Push policy B -> should create new version --- let r = run_cli(&[ - "policy", "set", &guard.name, "--policy", &policy_b_path, "--wait", "--timeout", "120", + "policy", + "set", + &guard.name, + "--policy", + &policy_b_path, + "--wait", + "--timeout", + "120", ]) .await; assert!( @@ -352,7 +377,11 @@ async fn live_policy_update_round_trip() { ); let r = run_cli(&["policy", "get", &guard.name]).await; - assert!(r.success, "policy get after B should succeed:\n{}", r.output); + assert!( + r.success, + "policy get after B should succeed:\n{}", + r.output + ); let new_version = extract_version(&r.output) .unwrap_or_else(|| panic!("could not parse version after B:\n{}", r.output)); @@ -367,7 +396,14 @@ async fn live_policy_update_round_trip() { // --- Push policy B again -> idempotent --- let r = run_cli(&[ - "policy", "set", &guard.name, "--policy", &policy_b_path, "--wait", "--timeout", "120", + "policy", + "set", + &guard.name, + "--policy", + &policy_b_path, + "--wait", + "--timeout", + "120", ]) .await; assert!( @@ -377,7 +413,11 @@ async fn live_policy_update_round_trip() { ); let r = run_cli(&["policy", "get", &guard.name]).await; - assert!(r.success, "policy get after B repeat should succeed:\n{}", r.output); + assert!( + r.success, + "policy get after B repeat should succeed:\n{}", + r.output + ); let repeat_b_version = extract_version(&r.output) .unwrap_or_else(|| panic!("could not parse version after B repeat:\n{}", r.output)); @@ -432,16 +472,21 @@ async fn live_policy_update_from_empty_network_policies() { .to_string(); // Create sandbox with empty network policy. - let mut guard = SandboxGuard::create_keep( - &["sh", "-c", "echo Ready && sleep infinity"], - "Ready", - ) - .await - .expect("create keep sandbox"); + let mut guard = + SandboxGuard::create_keep(&["sh", "-c", "echo Ready && sleep infinity"], "Ready") + .await + .expect("create keep sandbox"); // Set initial empty policy. let r = run_cli(&[ - "policy", "set", &guard.name, "--policy", &empty_path, "--wait", "--timeout", "120", + "policy", + "set", + &guard.name, + "--policy", + &empty_path, + "--wait", + "--timeout", + "120", ]) .await; assert!( @@ -451,14 +496,25 @@ async fn live_policy_update_from_empty_network_policies() { ); let r = run_cli(&["policy", "get", &guard.name]).await; - assert!(r.success, "policy get (empty) should succeed:\n{}", r.output); + assert!( + r.success, + "policy get (empty) should succeed:\n{}", + r.output + ); let initial_version = extract_version(&r.output) .unwrap_or_else(|| panic!("could not parse version from empty policy:\n{}", r.output)); // Push policy with network rules. let r = run_cli(&[ - "policy", "set", &guard.name, "--policy", &full_path, "--wait", "--timeout", "120", + "policy", + "set", + &guard.name, + "--policy", + &full_path, + "--wait", + "--timeout", + "120", ]) .await; assert!( @@ -509,7 +565,13 @@ async fn initial_sparse_policy_is_acknowledged_as_loaded() { ); let mut guard = SandboxGuard::create_keep_with_args( - &["--name", "e2e-2159-sparse-enrich", "--policy", sparse_policy, "--no-tty"], + &[ + "--name", + "e2e-2159-sparse-enrich", + "--policy", + sparse_policy, + "--no-tty", + ], &["sh", "-c", "echo Ready && sleep infinity"], "Ready", ) @@ -565,7 +627,9 @@ async fn initial_sparse_policy_is_acknowledged_as_loaded() { async fn local_policy_override_survives_gateway_policy_polls() { let image_context = write_local_override_image().expect("write local override image"); let dockerfile = image_context.path().join("Dockerfile"); - let dockerfile = dockerfile.to_str().expect("Dockerfile path should be utf-8"); + let dockerfile = dockerfile + .to_str() + .expect("Dockerfile path should be utf-8"); let gateway_policy_a_file = write_policy(&["example.com"]).expect("write gateway policy A"); let gateway_policy_a_path = gateway_policy_a_file @@ -611,7 +675,11 @@ async fn local_policy_override_survives_gateway_policy_polls() { "sandbox", ]) .await; - assert!(initial_logs.success, "fetch initial sandbox logs:\n{}", initial_logs.output); + assert!( + initial_logs.success, + "fetch initial sandbox logs:\n{}", + initial_logs.output + ); assert!( initial_logs .output @@ -633,7 +701,11 @@ async fn local_policy_override_survives_gateway_policy_polls() { &gateway_policy_b_path, ]) .await; - assert!(update.success, "publish gateway policy B:\n{}", update.output); + assert!( + update.success, + "publish gateway policy B:\n{}", + update.output + ); // A later gateway revision must also remain observational in local mode. tokio::time::sleep(std::time::Duration::from_secs(4)).await; @@ -648,7 +720,11 @@ async fn local_policy_override_survives_gateway_policy_polls() { "sandbox", ]) .await; - assert!(updated_logs.success, "fetch updated sandbox logs:\n{}", updated_logs.output); + assert!( + updated_logs.success, + "fetch updated sandbox logs:\n{}", + updated_logs.output + ); assert!( !updated_logs.output.contains("Policy reloaded successfully"), "gateway policy updates must not replace the local override:\n{}", diff --git a/e2e/rust/tests/podman_gateway_resume.rs b/e2e/rust/tests/podman_gateway_resume.rs index fea2fab3e7..2600202537 100644 --- a/e2e/rust/tests/podman_gateway_resume.rs +++ b/e2e/rust/tests/podman_gateway_resume.rs @@ -14,7 +14,9 @@ use std::time::Duration; -use openshell_e2e::harness::cli::{sandbox_names, wait_for_healthy, wait_for_sandbox_exec_contains}; +use openshell_e2e::harness::cli::{ + sandbox_names, wait_for_healthy, wait_for_sandbox_exec_contains, +}; use openshell_e2e::harness::gateway::ManagedGateway; use openshell_e2e::harness::sandbox::SandboxGuard; diff --git a/e2e/rust/tests/port_forward.rs b/e2e/rust/tests/port_forward.rs index b198eeb94a..89d9d86e1c 100644 --- a/e2e/rust/tests/port_forward.rs +++ b/e2e/rust/tests/port_forward.rs @@ -58,17 +58,14 @@ async fn port_forward_echo() { // --------------------------------------------------------------- // Step 1 — Create a sandbox with the echo server running. // --------------------------------------------------------------- - let mut guard = - SandboxGuard::create_keep(&["python3", "-c", &script], "echo-server-ready") - .await - .expect("sandbox create with echo server"); + let mut guard = SandboxGuard::create_keep(&["python3", "-c", &script], "echo-server-ready") + .await + .expect("sandbox create with echo server"); // --------------------------------------------------------------- // Step 2 — Start port forwarding in the background. // --------------------------------------------------------------- - let mut forward_child = guard - .spawn_forward(port) - .expect("spawn port forward"); + let mut forward_child = guard.spawn_forward(port).expect("spawn port forward"); // Wait for the local port to accept connections. wait_for_port("127.0.0.1", port, Duration::from_secs(30)) diff --git a/e2e/rust/tests/sandbox_lifecycle.rs b/e2e/rust/tests/sandbox_lifecycle.rs index 4caad87371..01e89422e0 100644 --- a/e2e/rust/tests/sandbox_lifecycle.rs +++ b/e2e/rust/tests/sandbox_lifecycle.rs @@ -70,8 +70,7 @@ async fn delete_sandbox(name: &str) { #[tokio::test] async fn sandbox_create_keeps_sandbox_after_tty_command_by_default() { let mut cmd = openshell_tty_cmd(&["sandbox", "create", "--", "echo", "OK"]); - cmd.stdout(Stdio::piped()) - .stderr(Stdio::piped()); + cmd.stdout(Stdio::piped()).stderr(Stdio::piped()); let output = cmd.output().await.expect("spawn openshell sandbox create"); let stdout = String::from_utf8_lossy(&output.stdout).to_string(); @@ -83,9 +82,13 @@ async fn sandbox_create_keeps_sandbox_after_tty_command_by_default() { "sandbox create should succeed (exit {:?}):\n{combined}", output.status.code() ); - assert!(combined.contains("OK"), "expected command output in:\n{combined}"); + assert!( + combined.contains("OK"), + "expected command output in:\n{combined}" + ); - let sandbox_name = extract_sandbox_name(&combined).expect("sandbox name should be present in output"); + let sandbox_name = + extract_sandbox_name(&combined).expect("sandbox name should be present in output"); for _ in 0..20 { if sandbox_list_names().await.contains(&sandbox_name) { @@ -113,7 +116,10 @@ async fn sandbox_create_with_no_keep_cleans_up_after_tty_command() { "sandbox create should succeed (exit {:?}):\n{combined}", output.status.code() ); - assert!(combined.contains("OK"), "expected command output in:\n{combined}"); + assert!( + combined.contains("OK"), + "expected command output in:\n{combined}" + ); let sandbox_name = extract_sandbox_name(&combined).expect("sandbox name should be present in output"); diff --git a/e2e/rust/tests/settings_management.rs b/e2e/rust/tests/settings_management.rs index e69269d7d8..a3089590f7 100644 --- a/e2e/rust/tests/settings_management.rs +++ b/e2e/rust/tests/settings_management.rs @@ -44,14 +44,7 @@ impl GlobalSettingCleanup { impl Drop for GlobalSettingCleanup { fn drop(&mut self) { let _ = std::process::Command::new(openshell_bin()) - .args([ - "settings", - "delete", - "--global", - "--key", - self.key, - "--yes", - ]) + .args(["settings", "delete", "--global", "--key", self.key, "--yes"]) .stdout(Stdio::null()) .stderr(Stdio::null()) .status(); @@ -122,20 +115,12 @@ async fn settings_global_override_round_trip() { .unwrap_or_else(std::sync::PoisonError::into_inner); let _global_cleanup = GlobalSettingCleanup::new(TEST_KEY); - let cleanup_before = run_cli(&[ - "settings", - "delete", - "--global", - "--key", - TEST_KEY, - "--yes", - ]) - .await; + let cleanup_before = + run_cli(&["settings", "delete", "--global", "--key", TEST_KEY, "--yes"]).await; assert!( cleanup_before.success, "initial global setting cleanup should succeed (exit {:?}):\n{}", - cleanup_before.exit_code, - cleanup_before.clean_output + cleanup_before.exit_code, cleanup_before.clean_output ); let mut guard = @@ -147,47 +132,52 @@ async fn settings_global_override_round_trip() { assert!( initial.success, "settings get should succeed (exit {:?}):\n{}", - initial.exit_code, - initial.clean_output + initial.exit_code, initial.clean_output ); assert_setting_line_with_scope(&initial.clean_output, TEST_KEY, "", "unset"); let set_sandbox = run_cli(&[ - "settings", "set", &guard.name, "--key", TEST_KEY, "--value", "true", + "settings", + "set", + &guard.name, + "--key", + TEST_KEY, + "--value", + "true", ]) .await; assert!( set_sandbox.success, "sandbox setting set should succeed (exit {:?}):\n{}", - set_sandbox.exit_code, - set_sandbox.clean_output + set_sandbox.exit_code, set_sandbox.clean_output ); // Wait for the gateway to reflect the setting change. The setting is stored // server-side, so `settings get` reads it immediately. Poll to ensure the // config_revision has been updated (visible in the output). - wait_for_setting_value(&guard.name, TEST_KEY, "true", "sandbox", Duration::from_secs(10)) - .await; + wait_for_setting_value( + &guard.name, + TEST_KEY, + "true", + "sandbox", + Duration::from_secs(10), + ) + .await; let after_sandbox_set = run_cli(&["settings", "get", &guard.name]).await; assert!( after_sandbox_set.success, "settings get after sandbox set should succeed (exit {:?}):\n{}", - after_sandbox_set.exit_code, - after_sandbox_set.clean_output + after_sandbox_set.exit_code, after_sandbox_set.clean_output ); assert_setting_line_with_scope(&after_sandbox_set.clean_output, TEST_KEY, "true", "sandbox"); // Sandbox-scoped delete should succeed when not globally managed. - let sandbox_delete = run_cli(&[ - "settings", "delete", &guard.name, "--key", TEST_KEY, - ]) - .await; + let sandbox_delete = run_cli(&["settings", "delete", &guard.name, "--key", TEST_KEY]).await; assert!( sandbox_delete.success, "sandbox setting delete should succeed (exit {:?}):\n{}", - sandbox_delete.exit_code, - sandbox_delete.clean_output + sandbox_delete.exit_code, sandbox_delete.clean_output ); assert!( sandbox_delete @@ -213,10 +203,20 @@ async fn settings_global_override_round_trip() { // Re-set at sandbox scope so we can test global override next. let re_set = run_cli(&[ - "settings", "set", &guard.name, "--key", TEST_KEY, "--value", "true", + "settings", + "set", + &guard.name, + "--key", + TEST_KEY, + "--value", + "true", ]) .await; - assert!(re_set.success, "re-set should succeed:\n{}", re_set.clean_output); + assert!( + re_set.success, + "re-set should succeed:\n{}", + re_set.clean_output + ); let set_global = run_cli(&[ "settings", "set", "--global", "--key", TEST_KEY, "--value", "false", "--yes", @@ -225,8 +225,7 @@ async fn settings_global_override_round_trip() { assert!( set_global.success, "global setting set should succeed (exit {:?}):\n{}", - set_global.exit_code, - set_global.clean_output + set_global.exit_code, set_global.clean_output ); assert!( set_global @@ -237,7 +236,13 @@ async fn settings_global_override_round_trip() { ); let blocked_sandbox_set = run_cli(&[ - "settings", "set", &guard.name, "--key", TEST_KEY, "--value", "true", + "settings", + "set", + &guard.name, + "--key", + TEST_KEY, + "--value", + "true", ]) .await; assert!( @@ -252,10 +257,8 @@ async fn settings_global_override_round_trip() { ); // Sandbox-scoped delete should also be blocked while globally managed. - let blocked_sandbox_delete = run_cli(&[ - "settings", "delete", &guard.name, "--key", TEST_KEY, - ]) - .await; + let blocked_sandbox_delete = + run_cli(&["settings", "delete", &guard.name, "--key", TEST_KEY]).await; assert!( !blocked_sandbox_delete.success, "sandbox delete should fail while key is global-managed:\n{}", @@ -266,25 +269,16 @@ async fn settings_global_override_round_trip() { assert!( global_get.success, "global settings get should succeed (exit {:?}):\n{}", - global_get.exit_code, - global_get.clean_output + global_get.exit_code, global_get.clean_output ); assert_setting_line(&global_get.clean_output, TEST_KEY, "false"); - let delete_global = run_cli(&[ - "settings", - "delete", - "--global", - "--key", - TEST_KEY, - "--yes", - ]) - .await; + let delete_global = + run_cli(&["settings", "delete", "--global", "--key", TEST_KEY, "--yes"]).await; assert!( delete_global.success, "global settings delete should succeed (exit {:?}):\n{}", - delete_global.exit_code, - delete_global.clean_output + delete_global.exit_code, delete_global.clean_output ); assert!( delete_global @@ -298,30 +292,38 @@ async fn settings_global_override_round_trip() { assert!( global_after_delete.success, "global settings get after delete should succeed (exit {:?}):\n{}", - global_after_delete.exit_code, - global_after_delete.clean_output + global_after_delete.exit_code, global_after_delete.clean_output ); assert_setting_line(&global_after_delete.clean_output, TEST_KEY, ""); let sandbox_set_after_delete = run_cli(&[ - "settings", "set", &guard.name, "--key", TEST_KEY, "--value", "false", + "settings", + "set", + &guard.name, + "--key", + TEST_KEY, + "--value", + "false", ]) .await; assert!( sandbox_set_after_delete.success, "sandbox setting set after global delete should succeed (exit {:?}):\n{}", - sandbox_set_after_delete.exit_code, - sandbox_set_after_delete.clean_output + sandbox_set_after_delete.exit_code, sandbox_set_after_delete.clean_output ); let sandbox_after_delete = run_cli(&["settings", "get", &guard.name]).await; assert!( sandbox_after_delete.success, "settings get after global delete should succeed (exit {:?}):\n{}", - sandbox_after_delete.exit_code, - sandbox_after_delete.clean_output + sandbox_after_delete.exit_code, sandbox_after_delete.clean_output + ); + assert_setting_line_with_scope( + &sandbox_after_delete.clean_output, + TEST_KEY, + "false", + "sandbox", ); - assert_setting_line_with_scope(&sandbox_after_delete.clean_output, TEST_KEY, "false", "sandbox"); guard.cleanup().await; } diff --git a/e2e/rust/tests/upload_create.rs b/e2e/rust/tests/upload_create.rs index b1284cc15f..5cc3964841 100644 --- a/e2e/rust/tests/upload_create.rs +++ b/e2e/rust/tests/upload_create.rs @@ -35,13 +35,10 @@ async fn create_with_upload_directory_preserves_source_basename() { // The command reads the marker file — if upload worked, its content // appears in the output. - let mut guard = SandboxGuard::create_with_upload( - upload_str, - "/sandbox/data", - &["cat", remote_marker], - ) - .await - .expect("sandbox create --upload"); + let mut guard = + SandboxGuard::create_with_upload(upload_str, "/sandbox/data", &["cat", remote_marker]) + .await + .expect("sandbox create --upload"); let clean = strip_ansi(&guard.create_output); assert!( @@ -70,7 +67,11 @@ async fn create_with_multiple_uploads() { let mut guard = SandboxGuard::create_with_uploads( &[(spec_a, "/sandbox/alpha"), (spec_b, "/sandbox/beta")], - &["sh", "-c", "cat /sandbox/alpha/alpha/a.txt /sandbox/beta/beta/b.txt"], + &[ + "sh", + "-c", + "cat /sandbox/alpha/alpha/a.txt /sandbox/beta/beta/b.txt", + ], ) .await .expect("sandbox create with multiple --upload flags"); @@ -97,13 +98,10 @@ async fn create_with_upload_single_file() { let file_str = file_path.to_str().expect("file path is UTF-8"); - let mut guard = SandboxGuard::create_with_upload( - file_str, - "/sandbox", - &["cat", "/sandbox/config.txt"], - ) - .await - .expect("sandbox create --upload single file"); + let mut guard = + SandboxGuard::create_with_upload(file_str, "/sandbox", &["cat", "/sandbox/config.txt"]) + .await + .expect("sandbox create --upload single file"); let clean = strip_ansi(&guard.create_output); assert!( diff --git a/e2e/rust/tests/user_namespaces.rs b/e2e/rust/tests/user_namespaces.rs index 5e9996817f..53f2c6ec1f 100644 --- a/e2e/rust/tests/user_namespaces.rs +++ b/e2e/rust/tests/user_namespaces.rs @@ -48,14 +48,24 @@ async fn set_user_namespaces(enable: bool) -> Result<(), String> { }; kubectl(&[ - "set", "env", "statefulset/openshell", - "-n", "openshell", env_arg, - ]).await?; + "set", + "env", + "statefulset/openshell", + "-n", + "openshell", + env_arg, + ]) + .await?; kubectl(&[ - "rollout", "status", "statefulset/openshell", - "-n", "openshell", "--timeout=120s", - ]).await?; + "rollout", + "status", + "statefulset/openshell", + "-n", + "openshell", + "--timeout=120s", + ]) + .await?; // Give the gateway time to fully initialize after rollout. tokio::time::sleep(Duration::from_secs(5)).await; @@ -84,16 +94,25 @@ async fn wait_for_sandbox(name: &str, timeout_secs: u64) -> Result<(), String> { let deadline = tokio::time::Instant::now() + Duration::from_secs(timeout_secs); while tokio::time::Instant::now() < deadline { if let Ok(n) = kubectl(&[ - "get", "sandbox", name, "-n", "openshell", - "-o", "jsonpath={.metadata.name}", - ]).await { + "get", + "sandbox", + name, + "-n", + "openshell", + "-o", + "jsonpath={.metadata.name}", + ]) + .await + { if !n.trim().is_empty() { return Ok(()); } } tokio::time::sleep(Duration::from_secs(2)).await; } - Err(format!("sandbox {name} did not appear within {timeout_secs}s")) + Err(format!( + "sandbox {name} did not appear within {timeout_secs}s" + )) } /// Find a sandbox pod by its sandbox CRD name. The CRD controller creates a @@ -102,16 +121,25 @@ async fn wait_for_sandbox_pod(name: &str, timeout_secs: u64) -> Result<(), Strin let deadline = tokio::time::Instant::now() + Duration::from_secs(timeout_secs); while tokio::time::Instant::now() < deadline { if let Ok(n) = kubectl(&[ - "get", "pod", name, "-n", "openshell", - "-o", "jsonpath={.metadata.name}", - ]).await { + "get", + "pod", + name, + "-n", + "openshell", + "-o", + "jsonpath={.metadata.name}", + ]) + .await + { if !n.trim().is_empty() { return Ok(()); } } tokio::time::sleep(Duration::from_secs(2)).await; } - Err(format!("sandbox pod {name} did not appear within {timeout_secs}s")) + Err(format!( + "sandbox pod {name} did not appear within {timeout_secs}s" + )) } // Disabled by default — not reachable from any project-controlled cluster @@ -144,9 +172,13 @@ async fn sandbox_pod_spec_has_user_namespace_fields() { // ready in DinD environments, so we spawn the CLI and inspect the pod // spec independently. let mut cmd = openshell_cmd(); - cmd.arg("sandbox").arg("create") - .arg("--name").arg(&sandbox_name) - .arg("--").arg("sleep").arg("infinity"); + cmd.arg("sandbox") + .arg("create") + .arg("--name") + .arg(&sandbox_name) + .arg("--") + .arg("sleep") + .arg("infinity"); cmd.stdout(Stdio::piped()).stderr(Stdio::piped()); let mut child = cmd.spawn().expect("failed to spawn openshell create"); @@ -168,15 +200,27 @@ async fn sandbox_pod_spec_has_user_namespace_fields() { // Inspect the pod spec for hostUsers. let host_users = kubectl(&[ - "get", "pod", &sandbox_name, "-n", "openshell", - "-o", "jsonpath={.spec.hostUsers}", - ]).await; + "get", + "pod", + &sandbox_name, + "-n", + "openshell", + "-o", + "jsonpath={.spec.hostUsers}", + ]) + .await; // Inspect capabilities on the agent container. let caps = kubectl(&[ - "get", "pod", &sandbox_name, "-n", "openshell", - "-o", "jsonpath={.spec.containers[?(@.name=='agent')].securityContext.capabilities.add}", - ]).await; + "get", + "pod", + &sandbox_name, + "-n", + "openshell", + "-o", + "jsonpath={.spec.containers[?(@.name=='agent')].securityContext.capabilities.add}", + ]) + .await; // Clean up. stop_child(&mut child).await; @@ -186,7 +230,8 @@ async fn sandbox_pod_spec_has_user_namespace_fields() { // Assert hostUsers is false. let host_users_val = host_users.expect("failed to get hostUsers from pod spec"); assert_eq!( - host_users_val.trim(), "false", + host_users_val.trim(), + "false", "sandbox pod must have spec.hostUsers=false when user namespaces are enabled" ); diff --git a/e2e/rust/tests/vm_gateway_resume.rs b/e2e/rust/tests/vm_gateway_resume.rs index 3bff91df74..b2ec6c8b57 100644 --- a/e2e/rust/tests/vm_gateway_resume.rs +++ b/e2e/rust/tests/vm_gateway_resume.rs @@ -11,7 +11,9 @@ use std::time::Duration; -use openshell_e2e::harness::cli::{sandbox_names, wait_for_healthy, wait_for_sandbox_exec_contains}; +use openshell_e2e::harness::cli::{ + sandbox_names, wait_for_healthy, wait_for_sandbox_exec_contains, +}; use openshell_e2e::harness::gateway::ManagedGateway; use openshell_e2e::harness::sandbox::SandboxGuard; diff --git a/tasks/rust.toml b/tasks/rust.toml index a8856377fe..f035193fd8 100644 --- a/tasks/rust.toml +++ b/tasks/rust.toml @@ -18,12 +18,18 @@ hide = true ["rust:format"] description = "Format Rust code" -run = "cargo fmt --all" +run = [ + "cargo fmt --all", + "cargo fmt --manifest-path e2e/rust/Cargo.toml --all", +] hide = true ["rust:format:check"] description = "Check Rust formatting" -run = "cargo fmt --all -- --check" +run = [ + "cargo fmt --all -- --check", + "cargo fmt --manifest-path e2e/rust/Cargo.toml --all -- --check", +] hide = true ["rust:verify:telemetry-off"]