use std::{sync::mpsc, time::Duration}; use nu_test_support::nu_with_plugins; fn ensure_stress_env_vars_unset() { for (key, _) in std::env::vars_os() { if key.to_string_lossy().starts_with("STRESS_") { panic!("Test is running in a dirty environment: {key:?} is set"); } } } #[test] fn test_stdio() { ensure_stress_env_vars_unset(); let result = nu_with_plugins!( cwd: ".", plugin: ("nu_plugin_stress_internals"), "stress_internals" ); assert!(result.status.success()); assert!(result.out.contains("local_socket_path: None")); } #[test] fn test_local_socket() { ensure_stress_env_vars_unset(); let result = nu_with_plugins!( cwd: ".", envs: vec![ ("STRESS_ADVERTISE_LOCAL_SOCKET", "1"), ], plugin: ("nu_plugin_stress_internals"), "stress_internals" ); assert!(result.status.success()); // Should be run once in stdio mode assert!(result.err.contains("--stdio")); // And then in local socket mode assert!(result.err.contains("--local-socket")); assert!(result.out.contains("local_socket_path: Some")); } #[test] fn test_failing_local_socket_fallback() { ensure_stress_env_vars_unset(); let result = nu_with_plugins!( cwd: ".", envs: vec![ ("STRESS_ADVERTISE_LOCAL_SOCKET", "1"), ("STRESS_REFUSE_LOCAL_SOCKET", "1"), ], plugin: ("nu_plugin_stress_internals"), "stress_internals" ); assert!(result.status.success()); // Count the number of times we do stdio/local socket let mut count_stdio = 0; let mut count_local_socket = 0; for line in result.err.split('\n') { if line.contains("--stdio") { count_stdio += 1; } if line.contains("--local-socket") { count_local_socket += 1; } } // Should be run once in local socket mode assert_eq!(1, count_local_socket, "count of --local-socket"); // Should be run twice in stdio mode, due to the fallback assert_eq!(2, count_stdio, "count of --stdio"); // In the end it should not be running in local socket mode, but should succeed assert!(result.out.contains("local_socket_path: None")); } #[test] fn test_exit_before_hello_stdio() { ensure_stress_env_vars_unset(); // This can deadlock if not handled properly, so we try several times and timeout for _ in 0..5 { let (tx, rx) = mpsc::channel(); std::thread::spawn(move || { let result = nu_with_plugins!( cwd: ".", envs: vec![ ("STRESS_EXIT_BEFORE_HELLO", "1"), ], plugin: ("nu_plugin_stress_internals"), "stress_internals" ); let _ = tx.send(result); }); let result = rx .recv_timeout(Duration::from_secs(15)) .expect("timed out. probably a deadlock"); assert!(!result.status.success()); } } #[test] fn test_exit_early_stdio() { ensure_stress_env_vars_unset(); let result = nu_with_plugins!( cwd: ".", envs: vec![ ("STRESS_EXIT_EARLY", "1"), ], plugin: ("nu_plugin_stress_internals"), "stress_internals" ); assert!(!result.status.success()); assert!(result.err.contains("--stdio")); } #[test] fn test_exit_early_local_socket() { ensure_stress_env_vars_unset(); let result = nu_with_plugins!( cwd: ".", envs: vec![ ("STRESS_ADVERTISE_LOCAL_SOCKET", "1"), ("STRESS_EXIT_EARLY", "1"), ], plugin: ("nu_plugin_stress_internals"), "stress_internals" ); assert!(!result.status.success()); assert!(result.err.contains("--local-socket")); } #[test] fn test_wrong_version() { ensure_stress_env_vars_unset(); let result = nu_with_plugins!( cwd: ".", envs: vec![ ("STRESS_WRONG_VERSION", "1"), ], plugin: ("nu_plugin_stress_internals"), "stress_internals" ); assert!(!result.status.success()); assert!(result.err.contains("version")); assert!(result.err.contains("0.0.0")); }