#![allow(dead_code)]
use std::time::Duration;
use crabka_broker::{Broker, BrokerConfig, BrokerHandle};
use crabka_client_consumer::{AutoOffsetReset, Consumer};
use crabka_client_producer::{Acks, Producer, ProducerRecord};
use tempfile::TempDir;
pub struct TestBroker {
pub handle: BrokerHandle,
pub bootstrap: String,
_dir: TempDir,
}
pub async fn start_broker() -> TestBroker {
let dir = TempDir::new().expect("tempdir");
let handle = Broker::start(BrokerConfig::for_tests(dir.path().to_path_buf()))
.await
.expect("broker start");
let bootstrap = handle.listen_addr().to_string();
TestBroker {
handle,
bootstrap,
_dir: dir,
}
}
pub async fn create_topic(bootstrap: &str, name: &str, partitions: i32) {
crabka_replicator::admin_util::ensure_topic(bootstrap, name, partitions, None)
.await
.expect("ensure_topic");
}
pub async fn produce(bootstrap: &str, topic: &str, key: &[u8], value: &[u8]) {
let producer = Producer::builder()
.bootstrap(bootstrap)
.enable_idempotence(false)
.acks(Acks::All)
.build()
.await
.expect("producer");
producer
.send(ProducerRecord {
topic: topic.to_string(),
partition: None,
key: Some(bytes::Bytes::copy_from_slice(key)),
value: Some(bytes::Bytes::copy_from_slice(value)),
headers: vec![],
timestamp_ms: None,
})
.await
.await
.expect("ack recv")
.expect("produce");
producer.flush().await.expect("flush");
producer.close().await.expect("close");
}
pub async fn count(bootstrap: &str, topic: &str) -> usize {
crabka_replicator::admin_util::read_all(bootstrap, topic, None)
.await
.map_or(0, |v| v.len())
}
pub async fn await_count(bootstrap: &str, topic: &str, n: usize, timeout: Duration) {
let start = std::time::Instant::now();
loop {
if count(bootstrap, topic).await >= n {
return;
}
assert!(
start.elapsed() <= timeout,
"topic `{topic}` did not reach {n} records within {timeout:?}"
);
tokio::time::sleep(Duration::from_millis(300)).await;
}
}
pub async fn consume_and_commit(bootstrap: &str, group: &str, topic: &str) {
let mut consumer = Consumer::builder()
.bootstrap(bootstrap)
.group_id(group)
.subscribe(vec![topic.to_string()])
.auto_offset_reset(AutoOffsetReset::Earliest)
.build()
.await
.expect("consumer");
let mut idle = 0;
while idle < 3 {
let recs = consumer
.poll(Duration::from_millis(500))
.await
.expect("poll");
if recs.is_empty() {
idle += 1;
} else {
idle = 0;
}
}
consumer.commit_sync().await.expect("commit");
consumer.close().await.expect("close");
}