#![cfg(feature = "builtin-kernels")]
use lmflow::{Graph, Packet, State, Timestamp};
fn init() {
lmflow::register_builtin_kernels();
}
const BATCH3: &str = r#"
nodes:
- name: b
kernel: BatchSumKernel
input_ports: ["in"]
output_ports: ["out"]
input_policy: { type: batch, capacity: 3 }
input_ports: ["in"]
output_ports: ["out"]
"#;
#[test]
fn batch_sums_and_flushes_partial_on_close() {
init();
let graph = Graph::from_yaml(BATCH3).unwrap();
let poller = graph.add_poller("out").unwrap();
graph.start().unwrap();
let input = graph.input("in").unwrap();
for i in 1..=10i64 {
input
.send(Packet::from_i64(i).at(Timestamp(i - 1)))
.unwrap();
}
graph.close_all_inputs();
graph.wait_done().unwrap();
assert_eq!(graph.state(), State::Terminated);
let got: Vec<i64> = std::iter::from_fn(|| poller.next().map(|p| p.as_i64().unwrap())).collect();
assert_eq!(
got,
vec![6, 15, 24, 10],
"three full batches then the partial batch flushed on close"
);
}
#[test]
fn batch_on_thread_pool() {
init();
let graph = Graph::from_yaml(
r#"
executors:
- { name: cpu, type: ThreadPoolExecutor, num_threads: 2 }
nodes:
- name: b
kernel: BatchSumKernel
executor: cpu
input_ports: ["in"]
output_ports: ["out"]
input_policy: { type: batch, capacity: 4 }
input_ports: ["in"]
output_ports: ["out"]
"#,
)
.unwrap();
let poller = graph.add_poller("out").unwrap();
graph.start().unwrap();
let input = graph.input("in").unwrap();
for i in 0..8i64 {
input.send(Packet::from_i64(1).at(Timestamp(i))).unwrap();
}
graph.close_all_inputs();
graph.wait_done().unwrap();
assert_eq!(graph.state(), State::Terminated);
let got: Vec<i64> = std::iter::from_fn(|| poller.next().map(|p| p.as_i64().unwrap())).collect();
assert_eq!(got, vec![4, 4], "two full batches of four 1s");
}
#[test]
fn batch_rejects_zero_capacity() {
init();
let err = Graph::from_yaml(
r#"
nodes:
- name: b
kernel: BatchSumKernel
input_ports: ["in"]
output_ports: ["out"]
input_policy: { type: batch, capacity: 0 }
input_ports: ["in"]
output_ports: ["out"]
"#,
)
.unwrap_err();
assert!(err.to_string().contains("batch size"), "{err}");
}
#[test]
fn batch_accepts_multi_input() {
init();
let graph = Graph::from_yaml(
r#"
nodes:
- name: b
kernel: ZipKernel
input_ports: ["x", "y"]
output_ports: ["out"]
input_policy: { type: batch, capacity: 2 }
input_ports: ["x", "y"]
output_ports: ["out"]
"#,
);
assert!(graph.is_ok(), "多输入口 batch 应可建图:{:?}", graph.err());
}