Skip to content
Merged
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
2 changes: 1 addition & 1 deletion e2e/rust/src/harness/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 1 addition & 4 deletions e2e/rust/src/harness/port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
22 changes: 5 additions & 17 deletions e2e/rust/src/harness/sandbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ use super::output::{extract_field, strip_ansi};
/// The CLI prints `Created sandbox: <name>` (current format). Falls back to
/// `Name: <name>` for compatibility with older output formats.
fn extract_sandbox_name(output: &str) -> Option<String> {
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.
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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<Self, String> {
pub async fn create_keep(command: &[&str], ready_marker: &str) -> Result<Self, String> {
Self::create_keep_with_args(&[], command, ready_marker).await
}

Expand Down Expand Up @@ -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}"))?;

Expand Down Expand Up @@ -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<String, String> {
pub async fn download(&self, sandbox_path: &str, local_dest: &str) -> Result<String, String> {
let mut cmd = openshell_cmd();
cmd.arg("sandbox")
.arg("download")
Expand Down
12 changes: 3 additions & 9 deletions e2e/rust/tests/bypass_detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
57 changes: 13 additions & 44 deletions e2e/rust/tests/cf_auth_smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
);
}
Expand Down Expand Up @@ -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 {}",
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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!(
Expand All @@ -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).
Expand All @@ -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!(
Expand Down
8 changes: 1 addition & 7 deletions e2e/rust/tests/cli_smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand Down
13 changes: 4 additions & 9 deletions e2e/rust/tests/custom_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
36 changes: 13 additions & 23 deletions e2e/rust/tests/edge_tunnel_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ use openshell_e2e::harness::output::strip_ansi;
/// Run `openshell <args>` 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();
Expand Down Expand Up @@ -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!(
Expand Down Expand Up @@ -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!(
Expand Down
10 changes: 8 additions & 2 deletions e2e/rust/tests/forward_proxy_jsonrpc_l7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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),
] {
Expand Down
Loading
Loading