#![allow(missing_docs)]
use crate::supervisor::{Status, Supervisor, SupervisorEvent};
use crate::types::{AgentId, AgentMeta, KillReason, KillTrigger, RuntimeState};
use futures::StreamExt;
use std::time::Duration;
pub async fn run_supervisor_conformance<S: Supervisor>(s: S) {
let agent = AgentId("test-agent".into());
let meta = AgentMeta {
id: agent.clone(),
role: "test".into(),
version: "0.0.0".into(),
identity_pubkey: [0u8; 32],
expected_step_p99: None,
};
let err = s.heartbeat(agent.clone()).await.expect_err("must reject");
assert!(matches!(
err,
crate::supervisor::SupervisorError::UnknownAgent(_)
));
let mut stream = s.watch().await;
s.register(agent.clone(), meta).await.expect("register ok");
s.heartbeat(agent.clone()).await.expect("heartbeat ok");
s.report(agent.clone(), Status::Idle)
.await
.expect("report ok");
let mut seen_heartbeat = false;
for _ in 0..4u8 {
let next = tokio::time::timeout(Duration::from_millis(200), stream.next()).await;
if let Ok(Some(SupervisorEvent::Heartbeat(_))) = next {
seen_heartbeat = true;
}
if seen_heartbeat {
break;
}
}
assert!(seen_heartbeat, "Heartbeat event must be emitted");
assert_eq!(s.runtime_state().await, RuntimeState::Running);
s.trip_kill_switch(
KillReason("integration test".into()),
KillTrigger::Programmatic,
)
.await
.expect("kill ok");
assert_eq!(s.runtime_state().await, RuntimeState::Halted);
}
pub async fn run_governor_conformance<G: crate::governor::Governor>(g: G) {
use crate::governor::Permit;
use crate::types::ProviderId;
let provider = ProviderId("anthropic".into());
{
let _p: Permit = g
.acquire_llm(provider.clone(), 100)
.await
.expect("first acquire succeeds");
}
let mut held: Vec<Permit> = Vec::new();
for _ in 0..6u8 {
match g.acquire_llm(provider.clone(), 100).await {
Ok(p) => held.push(p),
Err(_) => break,
}
}
drop(held);
}