use std::path::PathBuf;
use std::sync::Arc;
use cc_lb_plugin_api::SlotKey;
use cc_lb_plugin_wire::{FilterRequest, Principal, UpstreamCandidate};
use cc_lb_runtime_wasmtime::WasmtimeRuntime;
use metrics_exporter_prometheus::PrometheusBuilder;
use rkyv::rancor::Error;
fn cache_aware_wasm() -> Option<Vec<u8>> {
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("crates/")
.parent()
.expect("workspace root")
.join("target/wasm32-unknown-unknown/release/cache_aware_wasmtime.wasm");
std::fs::read(path).ok()
}
fn tiny_filter_request() -> FilterRequest {
use cc_lb_plugin_wire::Claim;
FilterRequest {
request_id: Box::from("metrics-probe"),
method: Box::from("POST"),
path: Box::from("/v1/messages"),
query: None,
headers: Box::new([]),
body: Box::from(&[][..]),
principal: Principal {
id: Box::from("tenant"),
kind: Box::from("api_key"),
claims: Box::new([Claim {
key: Box::from("keep_k"),
value: Box::from(&b"1"[..]),
}]),
},
candidates: Box::new([UpstreamCandidate {
upstream_id: Box::from("a"),
name: Box::from("upstream-a"),
kind: Box::from("anthropic_api_key"),
observed_at_unix_secs: 0,
predicted_cache_read_tokens: 10,
}]),
}
}
#[test]
fn successful_filter_call_emits_three_metric_families() {
let Some(wasm) = cache_aware_wasm() else {
return;
};
let recorder = PrometheusBuilder::new().build_recorder();
let handle = recorder.handle();
let plugin_name = "cache-aware-wasmtime";
let key = SlotKey::global("metrics-probe");
metrics::with_local_recorder(&recorder, || {
let rt = Arc::new(WasmtimeRuntime::with_defaults().expect("engine"));
rt.register_filter(key.clone(), plugin_name, &wasm)
.expect("register");
let req = tiny_filter_request();
let in_bytes = rkyv::to_bytes::<Error>(&req).expect("encode");
let _out = rt.call_filter(&key, in_bytes.as_slice()).expect("call");
});
let rendered = handle.render();
assert!(
rendered.contains("cc_lb_plugin_call_duration_seconds"),
"duration histogram must be emitted; rendered=\n{rendered}",
);
assert!(
rendered.contains(&format!("plugin=\"{plugin_name}\"")),
"labels must include plugin=\"{plugin_name}\"; rendered=\n{rendered}",
);
assert!(
rendered.contains("hook=\"filter\""),
"labels must include hook=\"filter\"; rendered=\n{rendered}",
);
}