arcbox-daemon 0.9.0

ArcBox daemon process
use std::future::pending;

use super::*;

#[tokio::test]
async fn graceful_failure_returns_an_error_without_forcing() {
    let stopped = stop_runtime_with(
        async { anyhow::bail!("recovery cleanup failed") },
        async { panic!("a completed graceful stop must not be forced") },
        pending(),
        None,
    )
    .await;
    let RuntimeStop::Graceful(result) = stopped else {
        panic!("expected a completed graceful stop");
    };
    assert!(
        RuntimeStop::Graceful(result)
            .finish()
            .unwrap_err()
            .to_string()
            .contains("recovery cleanup failed")
    );
}

#[tokio::test(start_paused = true)]
async fn forced_stop_errors_survive_both_signal_and_deadline() {
    for deadline in [false, true] {
        let signal = async move {
            if deadline {
                pending::<()>().await;
            }
        };
        let stopped = stop_runtime_with(
            pending(),
            async { anyhow::bail!("reserved VM stop failed") },
            signal,
            deadline.then_some(Duration::from_secs(10)),
        )
        .await;
        let RuntimeStop::Forced(result) = stopped else {
            panic!("expected a forced stop");
        };
        assert!(
            result
                .unwrap_err()
                .to_string()
                .contains("reserved VM stop failed")
        );
    }
}

#[tokio::test]
async fn graceful_task_panic_survives_successful_or_failed_force_cleanup() {
    for force_fails in [false, true] {
        let stopped = stop_runtime_with(
            async { panic!("graceful worker panicked") },
            async move {
                anyhow::ensure!(!force_fails, "forced cleanup failed");
                Ok(())
            },
            pending(),
            None,
        )
        .await;
        let RuntimeStop::Forced(result) = stopped else {
            panic!("a task panic must force cleanup");
        };
        let error = format!("{:#}", result.unwrap_err());
        assert!(error.contains("graceful worker panicked"));
        assert_eq!(error.contains("forced cleanup failed"), force_fails);
    }
}

#[tokio::test]
async fn forced_task_panic_is_returned_for_daemon_cleanup() {
    let stopped = stop_runtime_with(
        pending(),
        async { panic!("forced worker panicked") },
        async {},
        None,
    )
    .await;
    let RuntimeStop::Forced(result) = stopped else {
        panic!("expected a forced stop");
    };
    assert!(format!("{:#}", result.unwrap_err()).contains("forced worker panicked"));
}