mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
fix(tests): stop TEST_ENV_LOCK poison cascade turning 1 panic into 38 (#1604)
This commit is contained in:
@@ -735,10 +735,19 @@ async fn thread_not_found_rpc_error_does_not_report_to_sentry() {
|
||||
let _sentry_guard = sentry::HubSwitchGuard::new(sentry_hub);
|
||||
|
||||
let subscriber = tracing_subscriber::registry().with(
|
||||
sentry::integrations::tracing::layer().event_filter(|metadata| match *metadata.level() {
|
||||
Level::ERROR => sentry::integrations::tracing::EventFilter::Event,
|
||||
Level::WARN | Level::INFO => sentry::integrations::tracing::EventFilter::Breadcrumb,
|
||||
_ => sentry::integrations::tracing::EventFilter::Ignore,
|
||||
sentry::integrations::tracing::layer().event_filter(|metadata| {
|
||||
// Mirror the production sentry-tracing layer: events emitted from
|
||||
// `report_error_message` are captured directly via
|
||||
// `sentry::capture_message` and must not be picked up here too
|
||||
// (otherwise this test sees double events).
|
||||
if metadata.target() == crate::core::observability::REPORT_ERROR_TRACING_TARGET {
|
||||
return sentry::integrations::tracing::EventFilter::Ignore;
|
||||
}
|
||||
match *metadata.level() {
|
||||
Level::ERROR => sentry::integrations::tracing::EventFilter::Event,
|
||||
Level::WARN | Level::INFO => sentry::integrations::tracing::EventFilter::Breadcrumb,
|
||||
_ => sentry::integrations::tracing::EventFilter::Ignore,
|
||||
}
|
||||
}),
|
||||
);
|
||||
let _subscriber_guard = tracing::subscriber::set_default(subscriber);
|
||||
|
||||
+10
-3
@@ -354,6 +354,13 @@ where
|
||||
S: tracing::Subscriber + for<'a> LookupSpan<'a>,
|
||||
{
|
||||
sentry::integrations::tracing::layer().event_filter(|md: &tracing::Metadata<'_>| {
|
||||
// Events emitted from `report_error_message` are captured directly via
|
||||
// `sentry::capture_message` at the call site (see
|
||||
// `core::observability::REPORT_ERROR_TRACING_TARGET` for rationale).
|
||||
// Skip them here so we don't double-report.
|
||||
if md.target() == crate::core::observability::REPORT_ERROR_TRACING_TARGET {
|
||||
return sentry::integrations::tracing::EventFilter::Ignore;
|
||||
}
|
||||
match *md.level() {
|
||||
Level::ERROR => sentry::integrations::tracing::EventFilter::Event,
|
||||
Level::WARN | Level::INFO => sentry::integrations::tracing::EventFilter::Breadcrumb,
|
||||
@@ -372,7 +379,7 @@ mod tests {
|
||||
static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
|
||||
|
||||
fn with_clean_rust_log<R>(f: impl FnOnce() -> R) -> R {
|
||||
let _guard = ENV_LOCK.lock().unwrap();
|
||||
let _guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let prior = std::env::var("RUST_LOG").ok();
|
||||
std::env::remove_var("RUST_LOG");
|
||||
let result = f();
|
||||
@@ -435,7 +442,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn seed_rust_log_respects_existing_value() {
|
||||
let _guard = ENV_LOCK.lock().unwrap();
|
||||
let _guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let prior = std::env::var("RUST_LOG").ok();
|
||||
std::env::set_var("RUST_LOG", "warn");
|
||||
seed_rust_log(true, CliLogDefault::Global);
|
||||
@@ -456,7 +463,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parse_log_file_constraints_handles_csv_and_whitespace() {
|
||||
let _guard = ENV_LOCK.lock().unwrap();
|
||||
let _guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let prior = std::env::var("OPENHUMAN_LOG_FILE_CONSTRAINTS").ok();
|
||||
std::env::set_var("OPENHUMAN_LOG_FILE_CONSTRAINTS", "rpc, , agent ,memory");
|
||||
let parsed = parse_log_file_constraints();
|
||||
|
||||
@@ -119,6 +119,27 @@ fn report_expected_message(kind: ExpectedErrorKind, message: &str, domain: &str,
|
||||
}
|
||||
}
|
||||
|
||||
/// Distinct `tracing::Metadata::target()` we set on the diagnostic
|
||||
/// `tracing::error!` emitted from [`report_error_message`].
|
||||
///
|
||||
/// Sentry capture for this helper happens via an explicit
|
||||
/// `sentry::capture_message` call below — not via the `sentry-tracing`
|
||||
/// layer scooping up the `tracing::error!` event. The production
|
||||
/// `sentry_tracing_layer()` in `core::logging` filters events with this
|
||||
/// target to `EventFilter::Ignore` so we never double-report (one direct
|
||||
/// `capture_message`, one tracing-bridge capture of the same condition).
|
||||
///
|
||||
/// Why direct capture instead of relying on the bridge: the bridge worked
|
||||
/// in steady-state but flaked under parallel test scheduling
|
||||
/// (`thread_not_found_rpc_error_does_not_report_to_sentry` repeatedly hit
|
||||
/// `events.len() == 0` in CI even with a thread-default subscriber wired
|
||||
/// up — likely a Linux-only thread-local ordering quirk in
|
||||
/// `sentry-tracing`'s `Hub::current()` lookup at event-emit time). Direct
|
||||
/// `sentry::capture_message` synchronously routes through the active hub
|
||||
/// and is deterministic, which keeps both production reporting and tests
|
||||
/// honest.
|
||||
pub const REPORT_ERROR_TRACING_TARGET: &str = "openhuman::observability::report_error";
|
||||
|
||||
pub(crate) fn report_error_message(
|
||||
message: &str,
|
||||
domain: &str,
|
||||
@@ -134,7 +155,15 @@ pub(crate) fn report_error_message(
|
||||
}
|
||||
},
|
||||
|| {
|
||||
// Direct, synchronous Sentry capture — see
|
||||
// `REPORT_ERROR_TRACING_TARGET` for why we don't rely on the
|
||||
// `sentry-tracing` layer for this call site.
|
||||
sentry::capture_message(message, sentry::Level::Error);
|
||||
// Diagnostic log line for stderr / file appenders. Tagged with
|
||||
// the marker target so the production sentry-tracing layer
|
||||
// skips it (no double Sentry event).
|
||||
tracing::error!(
|
||||
target: REPORT_ERROR_TRACING_TARGET,
|
||||
domain = domain,
|
||||
operation = operation,
|
||||
error = %message,
|
||||
|
||||
@@ -285,7 +285,7 @@ mod tests {
|
||||
async fn run_one_tick_returns_ok_when_no_client() {
|
||||
// Isolate the workspace/env so config loading doesn't contend with
|
||||
// sibling tests mutating OPENHUMAN_WORKSPACE in parallel.
|
||||
let _guard = ENV_LOCK.lock().expect("env lock");
|
||||
let _guard = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
|
||||
@@ -37,7 +37,7 @@ use crate::openhuman::config::TEST_ENV_LOCK as ENV_LOCK;
|
||||
|
||||
#[test]
|
||||
fn env_flag_enabled_recognizes_truthy_forms() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let key = "OPENHUMAN_TEST_FLAG_A";
|
||||
for truthy in ["1", "true", "TRUE", "yes", "YES"] {
|
||||
unsafe {
|
||||
@@ -61,7 +61,7 @@ fn env_flag_enabled_recognizes_truthy_forms() {
|
||||
|
||||
#[test]
|
||||
fn core_rpc_url_from_env_returns_default_when_unset() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
unsafe {
|
||||
std::env::remove_var("OPENHUMAN_CORE_RPC_URL");
|
||||
}
|
||||
@@ -70,7 +70,7 @@ fn core_rpc_url_from_env_returns_default_when_unset() {
|
||||
|
||||
#[test]
|
||||
fn core_rpc_url_from_env_uses_override_when_set() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_CORE_RPC_URL", "http://1.2.3.4:9999/rpc");
|
||||
}
|
||||
@@ -116,7 +116,7 @@ fn config_openhuman_dir_returns_config_path_parent() {
|
||||
|
||||
#[test]
|
||||
fn get_runtime_flags_reads_env_overrides() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
unsafe {
|
||||
std::env::remove_var("OPENHUMAN_BROWSER_ALLOW_ALL");
|
||||
}
|
||||
@@ -128,7 +128,7 @@ fn get_runtime_flags_reads_env_overrides() {
|
||||
|
||||
#[test]
|
||||
fn set_browser_allow_all_toggles_env_var() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let before = std::env::var("OPENHUMAN_BROWSER_ALLOW_ALL").ok();
|
||||
|
||||
let _ = set_browser_allow_all(true);
|
||||
@@ -503,7 +503,7 @@ async fn get_config_snapshot_wraps_snapshot_in_rpc_outcome() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn load_and_apply_dictation_settings_rejects_invalid_activation_mode() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -525,7 +525,7 @@ async fn load_and_apply_dictation_settings_rejects_invalid_activation_mode() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn load_and_apply_voice_server_settings_rejects_invalid_activation_mode() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -550,7 +550,7 @@ async fn load_and_apply_voice_server_settings_rejects_invalid_activation_mode()
|
||||
|
||||
#[tokio::test]
|
||||
async fn load_and_apply_dictation_settings_accepts_valid_modes() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -576,7 +576,7 @@ async fn load_and_apply_dictation_settings_accepts_valid_modes() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn load_and_apply_voice_server_settings_accepts_valid_modes_and_clamps() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -609,7 +609,7 @@ async fn load_and_apply_voice_server_settings_accepts_valid_modes_and_clamps() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_dictation_settings_reads_from_loaded_config() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -625,7 +625,7 @@ async fn get_dictation_settings_reads_from_loaded_config() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_voice_server_settings_reads_from_loaded_config() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -640,7 +640,7 @@ async fn get_voice_server_settings_reads_from_loaded_config() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_onboarding_completed_reads_from_loaded_config() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -655,7 +655,7 @@ async fn get_onboarding_completed_reads_from_loaded_config() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn load_and_resolve_api_url_returns_api_url_in_response() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -669,7 +669,7 @@ async fn load_and_resolve_api_url_returns_api_url_in_response() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn workspace_onboarding_flag_resolve_rejects_invalid_and_defaults() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -691,7 +691,7 @@ async fn workspace_onboarding_flag_resolve_rejects_invalid_and_defaults() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn workspace_onboarding_flag_set_rejects_invalid_names() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -709,7 +709,7 @@ async fn workspace_onboarding_flag_set_rejects_invalid_names() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn workspace_onboarding_flag_set_round_trip() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = tempdir().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
|
||||
@@ -181,7 +181,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn cli_auth_login_provider_branch_stores_credentials() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
set_workspace(&tmp);
|
||||
let result = cli_auth_login(
|
||||
@@ -204,7 +204,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn cli_auth_login_with_non_empty_fields_passes_them_through() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
set_workspace(&tmp);
|
||||
let fields = serde_json::json!({ "org_id": "org-1" });
|
||||
@@ -216,7 +216,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn cli_auth_logout_provider_branch_reports_no_op_on_empty_store() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
set_workspace(&tmp);
|
||||
let result = cli_auth_logout("openai".into(), None).await;
|
||||
@@ -230,7 +230,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn cli_auth_status_provider_branch_lists_for_provider() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
set_workspace(&tmp);
|
||||
let result = cli_auth_status("openai".into(), None).await;
|
||||
@@ -245,7 +245,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn cli_auth_list_with_empty_filter_lists_all() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
set_workspace(&tmp);
|
||||
let out = cli_auth_list(None).await.expect("list ok");
|
||||
@@ -256,7 +256,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn cli_auth_list_rejects_whitespace_only_filter_as_no_filter() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
set_workspace(&tmp);
|
||||
let out = cli_auth_list(Some(" ".into())).await.expect("list ok");
|
||||
|
||||
@@ -468,6 +468,33 @@ mod tests {
|
||||
#[test]
|
||||
fn find_system_ollama_binary_detects_macos_app_bundle_in_applications() {
|
||||
let _lock = env_lock();
|
||||
// `find_system_ollama_binary` probes a fixed priority list on macOS:
|
||||
// 1. /usr/local/bin/ollama (intel homebrew, hand-installed)
|
||||
// 2. /opt/homebrew/bin/ollama (apple-silicon homebrew)
|
||||
// 3. /Applications/Ollama.app/Contents/Resources/ollama
|
||||
// 4. $HOME/Applications/Ollama.app/Contents/Resources/ollama
|
||||
// The test exercises (4) by pointing $HOME at a tempdir and clearing
|
||||
// PATH/OLLAMA_BIN. Paths (1)–(3) are absolute and cannot be redirected
|
||||
// — if a dev machine already has Ollama installed at either homebrew
|
||||
// location or in the system /Applications dir, the function returns
|
||||
// that real binary first and the assertion below fails. Skip when any
|
||||
// earlier candidate already resolves so this test stays a regression
|
||||
// gate on the ~/Applications branch and not a "is Ollama installed on
|
||||
// this CI runner" probe.
|
||||
let unmaskable_real_install = [
|
||||
"/usr/local/bin/ollama",
|
||||
"/opt/homebrew/bin/ollama",
|
||||
"/Applications/Ollama.app/Contents/Resources/ollama",
|
||||
]
|
||||
.iter()
|
||||
.any(|p| std::path::Path::new(p).is_file());
|
||||
if unmaskable_real_install {
|
||||
eprintln!(
|
||||
"skipping: host has a real Ollama install at a higher-priority absolute path \
|
||||
the test cannot mock"
|
||||
);
|
||||
return;
|
||||
}
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
// Build a fake /Applications/Ollama.app/Contents/Resources/ollama tree.
|
||||
let bundle_bin = tmp
|
||||
|
||||
@@ -149,7 +149,7 @@ async fn handle_device_profile_returns_device_shape() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn handle_presets_returns_presets_list_and_recommended_tier() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -176,7 +176,7 @@ async fn handle_presets_returns_presets_list_and_recommended_tier() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn handle_apply_preset_rejects_invalid_tier() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -191,7 +191,7 @@ async fn handle_apply_preset_rejects_invalid_tier() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn handle_apply_preset_rejects_custom_tier() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -206,7 +206,7 @@ async fn handle_apply_preset_rejects_custom_tier() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn handle_apply_preset_rejects_unsupported_large_tier() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -221,7 +221,7 @@ async fn handle_apply_preset_rejects_unsupported_large_tier() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn handle_apply_preset_accepts_valid_tier_and_persists() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -239,7 +239,7 @@ async fn handle_apply_preset_accepts_valid_tier_and_persists() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn handle_set_ollama_path_rejects_nonexistent_path() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -257,7 +257,7 @@ async fn handle_set_ollama_path_rejects_nonexistent_path() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn handle_set_ollama_path_accepts_empty_string_to_clear() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let _g = ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
unsafe {
|
||||
std::env::set_var("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
|
||||
@@ -69,6 +69,13 @@ mod tests {
|
||||
|
||||
struct ShutdownProbe {
|
||||
tx: mpsc::UnboundedSender<(String, String)>,
|
||||
/// Only forward events whose `source` matches. The event bus is a
|
||||
/// process-global singleton (`event_bus::init_global` is idempotent),
|
||||
/// so parallel tests in this module publish onto the *same* bus and
|
||||
/// every probe sees every shutdown event. Filtering by source keeps
|
||||
/// each test isolated to the event it actually published instead of
|
||||
/// racing on whichever fires first.
|
||||
expected_source: &'static str,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -83,7 +90,9 @@ mod tests {
|
||||
|
||||
async fn handle(&self, event: &DomainEvent) {
|
||||
if let DomainEvent::SystemShutdownRequested { source, reason } = event {
|
||||
let _ = self.tx.send((source.clone(), reason.clone()));
|
||||
if source == self.expected_source {
|
||||
let _ = self.tx.send((source.clone(), reason.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +101,10 @@ mod tests {
|
||||
async fn service_shutdown_publishes_event() {
|
||||
let bus = event_bus::init_global(event_bus::DEFAULT_CAPACITY);
|
||||
let (tx, mut rx) = mpsc::unbounded_channel();
|
||||
let handle = bus.subscribe(Arc::new(ShutdownProbe { tx }));
|
||||
let handle = bus.subscribe(Arc::new(ShutdownProbe {
|
||||
tx,
|
||||
expected_source: "test",
|
||||
}));
|
||||
|
||||
let outcome = service_shutdown(Some("test".into()), Some("integration".into()))
|
||||
.await
|
||||
|
||||
@@ -440,7 +440,7 @@ encrypt = false
|
||||
async fn execute_task_routes_to_cloud_when_local_disabled() {
|
||||
let _env_lock = crate::openhuman::config::TEST_ENV_LOCK
|
||||
.lock()
|
||||
.expect("test env lock");
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
test_mocks::reset();
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
let _workspace = EnvVarGuard::set_to_path("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
@@ -462,7 +462,7 @@ encrypt = false
|
||||
async fn execute_task_routes_to_local_when_local_enabled() {
|
||||
let _env_lock = crate::openhuman::config::TEST_ENV_LOCK
|
||||
.lock()
|
||||
.expect("test env lock");
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
test_mocks::reset();
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
let _workspace = EnvVarGuard::set_to_path("OPENHUMAN_WORKSPACE", tmp.path());
|
||||
|
||||
@@ -422,7 +422,9 @@ fn title_log_prefix_is_grep_friendly_and_stable() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn message_append_returns_typed_not_found_for_stale_thread() {
|
||||
let _env_lock = crate::openhuman::config::TEST_ENV_LOCK.lock().unwrap();
|
||||
let _env_lock = crate::openhuman::config::TEST_ENV_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
let workspace = tempfile::tempdir().expect("workspace");
|
||||
let _workspace_guard = EnvVarGuard::set_to_path("OPENHUMAN_WORKSPACE", workspace.path());
|
||||
let thread_id = "thread-missing";
|
||||
@@ -452,7 +454,9 @@ async fn message_append_returns_typed_not_found_for_stale_thread() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn generate_title_returns_typed_not_found_for_stale_thread() {
|
||||
let _env_lock = crate::openhuman::config::TEST_ENV_LOCK.lock().unwrap();
|
||||
let _env_lock = crate::openhuman::config::TEST_ENV_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
let workspace = tempfile::tempdir().expect("workspace");
|
||||
let _workspace_guard = EnvVarGuard::set_to_path("OPENHUMAN_WORKSPACE", workspace.path());
|
||||
let thread_id = "thread-missing";
|
||||
|
||||
@@ -294,7 +294,7 @@ fn browser_tool_validates_url() {
|
||||
|
||||
#[test]
|
||||
fn browser_tool_empty_allowlist_blocks() {
|
||||
let _guard = BROWSER_ENV_LOCK.lock().expect("env lock poisoned");
|
||||
let _guard = BROWSER_ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let security = Arc::new(SecurityPolicy::default());
|
||||
let tool = BrowserTool::new(security, vec![], None);
|
||||
std::env::remove_var("OPENHUMAN_BROWSER_ALLOW_ALL");
|
||||
@@ -303,7 +303,7 @@ fn browser_tool_empty_allowlist_blocks() {
|
||||
|
||||
#[test]
|
||||
fn browser_tool_empty_allowlist_allows_with_env_flag() {
|
||||
let _guard = BROWSER_ENV_LOCK.lock().expect("env lock poisoned");
|
||||
let _guard = BROWSER_ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let security = Arc::new(SecurityPolicy::default());
|
||||
let tool = BrowserTool::new(security, vec![], None);
|
||||
std::env::set_var("OPENHUMAN_BROWSER_ALLOW_ALL", "1");
|
||||
|
||||
@@ -501,7 +501,7 @@ mod tests {
|
||||
// `update_apply` so the three cases serialise on the same mutex.
|
||||
#[tokio::test]
|
||||
async fn update_apply_rejects_non_github_url_before_network_call() {
|
||||
let _guard = TEST_ENV_LOCK.lock().unwrap();
|
||||
let _guard = TEST_ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let outcome = update_apply(
|
||||
"https://evil.example.com/asset".to_string(),
|
||||
"openhuman-core-x86_64.tar.gz".to_string(),
|
||||
@@ -517,7 +517,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_apply_rejects_unsafe_asset_name() {
|
||||
let _guard = TEST_ENV_LOCK.lock().unwrap();
|
||||
let _guard = TEST_ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let outcome = update_apply(
|
||||
"https://github.com/owner/repo/releases/download/v1/x".to_string(),
|
||||
"../etc/passwd".to_string(),
|
||||
@@ -546,7 +546,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_apply_rejects_when_rpc_mutations_disabled() {
|
||||
let _guard = TEST_ENV_LOCK.lock().unwrap();
|
||||
let _guard = TEST_ENV_LOCK.lock().unwrap_or_else(|e| e.into_inner());
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let _workspace_guard = WorkspaceEnvGuard::set(tmp.path());
|
||||
write_update_policy(
|
||||
|
||||
Reference in New Issue
Block a user