use bashkit::Bash;
use std::sync::atomic::Ordering;
#[tokio::test]
async fn cancel_aborts_execution() {
let mut bash = Bash::new();
let token = bash.cancellation_token();
token.store(true, Ordering::Relaxed);
let result = bash.exec("echo hello").await;
assert!(result.is_err());
let err = result.unwrap_err();
assert_eq!(err.to_string(), "execution cancelled");
}
#[tokio::test]
async fn cancel_resets_manually() {
let mut bash = Bash::new();
let token = bash.cancellation_token();
token.store(true, Ordering::Relaxed);
let result = bash.exec("echo first").await;
assert!(result.is_err());
token.store(false, Ordering::Relaxed);
let result = bash.exec("echo second").await;
assert!(result.is_ok());
assert_eq!(result.unwrap().stdout.trim(), "second");
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn cancel_mid_execution() {
let mut bash = Bash::new();
let token = bash.cancellation_token();
let cancel_token = token.clone();
tokio::spawn(async move {
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
cancel_token.store(true, Ordering::Relaxed);
});
let result = bash.exec("for i in $(seq 1 10000); do echo $i; done").await;
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "execution cancelled");
token.store(false, Ordering::Relaxed);
}
#[tokio::test]
async fn uncancelled_execution_succeeds() {
let mut bash = Bash::new();
let _token = bash.cancellation_token();
let result = bash.exec("echo works").await;
assert!(result.is_ok());
assert_eq!(result.unwrap().stdout.trim(), "works");
}
#[tokio::test]
async fn cancellation_token_is_shared() {
let bash = Bash::new();
let token1 = bash.cancellation_token();
let token2 = bash.cancellation_token();
token1.store(true, Ordering::Relaxed);
assert!(token2.load(Ordering::Relaxed));
}