Merge pull request #2803 from zeroclaw-labs/issue-2746-capability-aware-tests-dev
test(infra): add capability-aware handling for sandbox-restricted test environments
This commit is contained in:
commit
bd2beb3e16
@ -69,6 +69,7 @@ pub mod runtime;
|
||||
pub(crate) mod security;
|
||||
pub(crate) mod service;
|
||||
pub(crate) mod skills;
|
||||
pub mod test_capabilities;
|
||||
pub mod tools;
|
||||
pub(crate) mod tunnel;
|
||||
pub mod update;
|
||||
|
||||
@ -1287,7 +1287,15 @@ mod tests {
|
||||
}),
|
||||
);
|
||||
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
if let Err(err) = std::net::TcpListener::bind("127.0.0.1:0") {
|
||||
let reason = format!("loopback bind unavailable: {err}");
|
||||
eprintln!("Skipping loopback-dependent Anthropic test: {reason}");
|
||||
return;
|
||||
}
|
||||
|
||||
let listener = TcpListener::bind("127.0.0.1:0")
|
||||
.await
|
||||
.expect("loopback bind should be available after capability check");
|
||||
let addr = listener.local_addr().unwrap();
|
||||
let server_handle = tokio::spawn(async move {
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
|
||||
56
src/test_capabilities.rs
Normal file
56
src/test_capabilities.rs
Normal file
@ -0,0 +1,56 @@
|
||||
//! Lightweight capability probes used by tests in constrained environments.
|
||||
//!
|
||||
//! These helpers let tests skip gracefully when sandbox restrictions prevent
|
||||
//! operations like loopback binds or writable-home access.
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::net::TcpListener;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
/// Return the configured home directory from environment variables.
|
||||
pub fn home_dir_from_env() -> Option<PathBuf> {
|
||||
env::var_os("HOME")
|
||||
.or_else(|| env::var_os("USERPROFILE"))
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(PathBuf::from)
|
||||
}
|
||||
|
||||
/// Check that a directory is writable by creating and deleting a tiny probe file.
|
||||
pub fn check_writable_dir(path: &Path) -> Result<(), String> {
|
||||
fs::create_dir_all(path).map_err(|err| {
|
||||
format!(
|
||||
"failed to create directory {} for capability probe: {err}",
|
||||
path.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
let nanos = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.map(|duration| duration.as_nanos())
|
||||
.unwrap_or(0);
|
||||
let probe_name = format!(".zeroclaw-capability-probe-{}-{nanos}", std::process::id());
|
||||
let probe_path = path.join(probe_name);
|
||||
|
||||
fs::write(&probe_path, b"probe")
|
||||
.map_err(|err| format!("failed to write probe file {}: {err}", probe_path.display()))?;
|
||||
|
||||
if let Err(err) = fs::remove_file(&probe_path) {
|
||||
return Err(format!(
|
||||
"failed to clean up probe file {}: {err}",
|
||||
probe_path.display()
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Verify loopback bind capability for local mock servers used in tests.
|
||||
pub fn check_loopback_bind() -> Result<(), String> {
|
||||
TcpListener::bind("127.0.0.1:0")
|
||||
.map(|listener| {
|
||||
drop(listener);
|
||||
})
|
||||
.map_err(|err| format!("loopback bind unavailable: {err}"))
|
||||
}
|
||||
@ -35,7 +35,16 @@ use std::path::PathBuf;
|
||||
#[ignore = "requires live Gemini OAuth credentials with refresh_token"]
|
||||
async fn gemini_warmup_refreshes_expired_oauth_token() -> Result<()> {
|
||||
// Find ~/.zeroclaw/auth-profiles.json
|
||||
let home = env::var("HOME").expect("HOME env var not set");
|
||||
let Some(home) = zeroclaw::test_capabilities::home_dir_from_env() else {
|
||||
eprintln!("⚠️ Skipping test: neither HOME nor USERPROFILE is set");
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if let Err(reason) = zeroclaw::test_capabilities::check_writable_dir(&home) {
|
||||
eprintln!("⚠️ Skipping test: home directory is not writable ({reason})");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let zeroclaw_dir = PathBuf::from(home).join(".zeroclaw");
|
||||
let auth_profiles_path = zeroclaw_dir.join("auth-profiles.json");
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user