diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b37465a8..fde6252b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,14 +32,6 @@ jobs: - name: Install nextest run: cargo install cargo-nextest --locked - - name: Build httpjail binary - run: | - cargo build --bin httpjail --target-dir target - export HTTPJAIL_BIN="$(pwd)/target/debug/httpjail" - echo "Binary built at: ${HTTPJAIL_BIN}" - ls -la "${HTTPJAIL_BIN}" - echo "HTTPJAIL_BIN=${HTTPJAIL_BIN}" >> $GITHUB_ENV - - name: Run all tests run: cargo nextest run --profile ci @@ -94,15 +86,6 @@ jobs: sudo chown -R ci:ci target || true fi - - name: Build httpjail binary - run: | - source ~/.cargo/env - cargo build --bin httpjail --target-dir target - export HTTPJAIL_BIN="$(pwd)/target/debug/httpjail" - echo "Binary built at: ${HTTPJAIL_BIN}" - ls -la "${HTTPJAIL_BIN}" - echo "HTTPJAIL_BIN=${HTTPJAIL_BIN}" >> $GITHUB_ENV - - name: Run all tests (non-root) run: | source ~/.cargo/env diff --git a/Cargo.lock b/Cargo.lock index 35d94249..7d1d0f7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -796,6 +796,7 @@ dependencies = [ "rand", "rcgen", "rustls", + "serde_json", "serial_test", "socket2 0.5.10", "tempfile", @@ -1746,6 +1747,12 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + [[package]] name = "scc" version = "2.4.0" @@ -1819,6 +1826,18 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "serde_json" +version = "1.0.143" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + [[package]] name = "serial_test" version = "3.2.0" diff --git a/tests/common/mod.rs b/tests/common/mod.rs index f66b7087..621b312a 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,106 +1,6 @@ #![allow(dead_code)] // These are utility functions used across different test modules use std::process::Command; -use std::sync::OnceLock; - -static BUILD_RESULT: OnceLock> = OnceLock::new(); - -/// Build httpjail binary and return the path -pub fn build_httpjail() -> Result { - BUILD_RESULT - .get_or_init(|| { - // First check if HTTPJAIL_BIN is set (e.g., by CI) - if let Ok(bin_path) = std::env::var("HTTPJAIL_BIN") - && std::path::Path::new(&bin_path).exists() - { - eprintln!("Using httpjail binary from HTTPJAIL_BIN: {}", bin_path); - return Ok(bin_path); - } - - // Determine the target directory - let target_dir = std::env::var("CARGO_TARGET_DIR") - .unwrap_or_else(|_| "target".to_string()); - - // Check if the binary already exists - let binary_path = format!("{}/debug/httpjail", target_dir); - if std::path::Path::new(&binary_path).exists() { - return Ok(binary_path); - } - - // Also check the default location in case CARGO_TARGET_DIR is not set - let default_path = "target/debug/httpjail"; - if std::path::Path::new(default_path).exists() { - return Ok(default_path.to_string()); - } - - // Binary doesn't exist, try to build it - eprintln!("httpjail binary not found at {} or {}, attempting to build...", binary_path, default_path); - - let output = Command::new("cargo") - .args(["build", "--bin", "httpjail"]) - .output() - .map_err(|e| { - format!( - "Failed to execute 'cargo build --bin httpjail': {}. \n\ - Make sure cargo is in PATH or build the binary manually with 'cargo build --bin httpjail'", - e - ) - }); - - match output { - Ok(output) if output.status.success() => { - // Check both possible locations after build - if std::path::Path::new(&binary_path).exists() { - eprintln!("Successfully built httpjail binary at {}", binary_path); - Ok(binary_path) - } else if std::path::Path::new(default_path).exists() { - eprintln!("Successfully built httpjail binary at {}", default_path); - Ok(default_path.to_string()) - } else { - // If still not found, provide diagnostic information - let target_debug = format!("{}/debug", target_dir); - Err(format!( - "Build command succeeded but binary not found at {} or {}. \n\ - Current directory: {:?}\n\ - CARGO_TARGET_DIR: {:?}\n\ - Contents of {}: {:?}\n\ - Contents of target/debug: {:?}", - binary_path, - default_path, - std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("unknown")), - std::env::var("CARGO_TARGET_DIR").ok(), - target_debug, - std::fs::read_dir(&target_debug) - .map(|entries| { - entries - .filter_map(|e| e.ok()) - .filter_map(|e| e.file_name().into_string().ok()) - .collect::>() - }) - .unwrap_or_default(), - std::fs::read_dir("target/debug") - .map(|entries| { - entries - .filter_map(|e| e.ok()) - .filter_map(|e| e.file_name().into_string().ok()) - .collect::>() - }) - .unwrap_or_default() - )) - } - } - Ok(output) => { - let stderr = String::from_utf8_lossy(&output.stderr); - Err(format!( - "Failed to build httpjail binary. Build output:\n{}", - stderr - )) - } - Err(e) => Err(e), - } - }) - .clone() -} /// Construct httpjail command with standard test settings pub struct HttpjailCommand { @@ -163,8 +63,8 @@ impl HttpjailCommand { /// Build and execute the command pub fn execute(mut self) -> Result<(i32, String, String), String> { - // Ensure httpjail is built - let httpjail_path = build_httpjail()?; + // Use the binary path produced by the same Cargo test build + let httpjail_path: &str = env!("CARGO_BIN_EXE_httpjail"); // Always add timeout for tests (15 seconds default for CI environment) self.args.insert(0, "--timeout".to_string()); @@ -185,13 +85,13 @@ impl HttpjailCommand { "SUDO_ASKPASS", format!( "{}/askpass_macos.sh", - std::env::current_dir().unwrap().display() + std::env::current_dir().unwrap().to_string_lossy() ), ); } sudo_cmd.arg("-E"); // Preserve environment - sudo_cmd.arg(&httpjail_path); + sudo_cmd.arg(httpjail_path); for arg in &self.args { sudo_cmd.arg(arg); } @@ -200,7 +100,7 @@ impl HttpjailCommand { } sudo_cmd } else { - let mut cmd = Command::new(&httpjail_path); + let mut cmd = Command::new(httpjail_path); for arg in &self.args { cmd.arg(arg); } diff --git a/tests/weak_integration.rs b/tests/weak_integration.rs index 30e8ada0..c2fe967a 100644 --- a/tests/weak_integration.rs +++ b/tests/weak_integration.rs @@ -1,6 +1,6 @@ mod common; -use common::{HttpjailCommand, build_httpjail, test_https_allow, test_https_blocking}; +use common::{HttpjailCommand, test_https_allow, test_https_blocking}; use std::process::{Command, Stdio}; use std::str::FromStr; use std::thread; @@ -172,9 +172,9 @@ fn test_weak_mode_appends_no_proxy() { // Simple server start function - we know the ports we're setting fn start_server(http_port: u16, https_port: u16) -> Result { - let httpjail_path = build_httpjail()?; + let httpjail_path: &str = env!("CARGO_BIN_EXE_httpjail"); - let mut cmd = Command::new(&httpjail_path); + let mut cmd = Command::new(httpjail_path); cmd.arg("--server") .arg("--js") .arg("true")