use acton_reactive::prelude::AgentRuntime;
use std::time::Duration;
use tokio::sync::oneshot;
pub struct AgentTestRuntime {
runtime: AgentRuntime,
}
impl AgentTestRuntime {
#[must_use]
pub fn new() -> Self {
Self {
runtime: acton_reactive::prelude::ActonApp::launch(),
}
}
#[must_use]
pub fn runtime_mut(&mut self) -> &mut AgentRuntime {
&mut self.runtime
}
#[must_use]
pub const fn runtime(&self) -> &AgentRuntime {
&self.runtime
}
pub async fn shutdown(mut self) -> Result<(), anyhow::Error> {
self.runtime.shutdown_all().await
}
}
impl Default for AgentTestRuntime {
fn default() -> Self {
Self::new()
}
}
impl Drop for AgentTestRuntime {
fn drop(&mut self) {
if let Ok(handle) = tokio::runtime::Handle::try_current() {
let mut runtime = std::mem::take(&mut self.runtime);
handle.spawn(async move {
let _ = runtime.shutdown_all().await;
});
}
}
}
pub async fn await_response<T>(rx: oneshot::Receiver<T>) -> T {
await_response_with_timeout(rx, Duration::from_secs(1)).await
}
pub async fn await_response_with_timeout<T>(rx: oneshot::Receiver<T>, timeout: Duration) -> T {
tokio::time::timeout(timeout, rx)
.await
.expect("Timeout waiting for agent response")
.expect("Agent response channel closed")
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test(flavor = "multi_thread")]
async fn test_agent_test_runtime_creation() {
let runtime = AgentTestRuntime::new();
drop(runtime); }
#[tokio::test(flavor = "multi_thread")]
async fn test_agent_test_runtime_default() {
let runtime = AgentTestRuntime::default();
drop(runtime);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_await_response_success() {
let (tx, rx) = oneshot::channel::<String>();
tx.send("test".to_string()).unwrap();
let result = await_response(rx).await;
assert_eq!(result, "test");
}
#[tokio::test(flavor = "multi_thread")]
async fn test_await_response_with_custom_timeout() {
let (tx, rx) = oneshot::channel::<i32>();
tx.send(42).unwrap();
let result = await_response_with_timeout(rx, Duration::from_millis(100)).await;
assert_eq!(result, 42);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_runtime_mut_returns_mutable_ref() {
let mut runtime = AgentTestRuntime::new();
let _runtime_ref = runtime.runtime_mut();
}
#[tokio::test(flavor = "multi_thread")]
async fn test_runtime_returns_ref() {
let runtime = AgentTestRuntime::new();
let _runtime_ref = runtime.runtime();
}
#[tokio::test(flavor = "multi_thread")]
async fn test_explicit_shutdown() {
let runtime = AgentTestRuntime::new();
let result = runtime.shutdown().await;
assert!(result.is_ok());
}
}