use contextgraph_host::Host;
use contextgraph_types::ContextQuery;
fn fixture() -> String {
env!("CARGO_BIN_EXE_contextgraph-example-docs").to_string()
}
fn query() -> ContextQuery {
ContextQuery {
goal: "how do I configure it".into(),
query_text: Some("configuration".into()),
embedding: None,
kinds: vec![],
anchors: vec![],
max_frames: 8,
max_tokens: 4096,
as_of: None,
representation_preferences: vec![],
}
}
#[tokio::test]
async fn a_host_produces_a_self_consistent_usage_report_for_a_real_provider() {
let mut host = Host::new();
host.add_stdio("docs", &fixture(), &[])
.await
.expect("handshake with the fixture should succeed");
let query = query();
let fanout = host.query_all(&query).await;
let report = fanout.usage_report(&query, "2026-07-21T00:00:00Z");
assert!(
report.is_consistent(),
"usage report totals must re-sum from the served frames: {report:?}"
);
assert!(report.within_budget());
assert_eq!(report.budget_requested, query.max_tokens);
let independent: u64 = fanout.accepted_frames().map(|f| f.token_cost as u64).sum();
assert_eq!(report.budget_consumed, independent);
assert!(independent > 0, "the fixture serves non-zero-cost frames");
assert_eq!(report.providers.len(), 1);
let docs = &report.providers[0];
assert_eq!(docs.provider_id, "docs");
assert_eq!(docs.frames_served as usize, docs.served_frames.len());
assert!(docs.frames_served >= 1);
for served in &docs.served_frames {
assert_eq!(served.frame.provider_id, "docs");
assert!(!served.frame.frame_id.is_empty());
assert!(served.frame.is_verifiable());
}
let shutdown = host.shutdown().await;
assert!(shutdown.iter().all(|(_, result)| result.is_ok()));
}