#![cfg(feature = "test-util")]
use crate::SimpleRow;
use clickhouse::{Client, test};
use std::time::Duration;
async fn test_provide() {
let mock = test::Mock::new();
let client = Client::default().with_mock(&mock);
let expected = vec![SimpleRow::new(1, "one"), SimpleRow::new(2, "two")];
mock.add(test::handlers::provide(expected.clone()));
let actual = crate::fetch_rows::<SimpleRow>(&client, "doesn't matter").await;
assert_eq!(actual, expected);
}
#[tokio::test]
async fn provide() {
test_provide().await;
tokio::time::pause();
tokio::time::advance(Duration::from_secs(100_000)).await;
test_provide().await;
}
#[tokio::test]
async fn summary_header() {
let mock = test::Mock::new();
let client = Client::default().with_mock(&mock);
let rows = vec![SimpleRow::new(1, "one"), SimpleRow::new(2, "two")];
let summary_json = r#"{"read_rows":"2","read_bytes":"16","written_rows":"0","written_bytes":"0","total_rows_to_read":"2","result_rows":"3","result_bytes":"24","elapsed_ns":"12345","memory_usage":"1024"}"#;
mock.add(test::handlers::provide_with_summary(
rows.clone(),
summary_json,
));
let mut cursor = client.query("doesn't matter").fetch::<SimpleRow>().unwrap();
assert!(cursor.summary().is_none());
let mut actual = Vec::new();
while let Some(row) = cursor.next().await.unwrap() {
actual.push(row);
}
assert_eq!(actual, rows);
let summary = cursor.summary().expect("summary should be present");
assert_eq!(summary.read_rows(), Some(2));
assert_eq!(summary.read_bytes(), Some(16));
assert_eq!(summary.written_rows(), Some(0));
assert_eq!(summary.written_bytes(), Some(0));
assert_eq!(summary.total_rows_to_read(), Some(2));
assert_eq!(summary.result_rows(), Some(3));
assert_eq!(summary.result_bytes(), Some(24));
assert_eq!(summary.elapsed_ns(), Some(12345));
assert_eq!(summary.memory_usage(), Some(1024));
}
#[tokio::test]
async fn summary_header_absent() {
let mock = test::Mock::new();
let client = Client::default().with_mock(&mock);
let rows = vec![SimpleRow::new(1, "one")];
mock.add(test::handlers::provide(rows.clone()));
let mut cursor = client.query("doesn't matter").fetch::<SimpleRow>().unwrap();
while cursor.next().await.unwrap().is_some() {}
assert!(cursor.summary().is_none());
}
#[tokio::test]
async fn summary_header_malformed() {
let mock = test::Mock::new();
let client = Client::default().with_mock(&mock);
let rows = vec![SimpleRow::new(1, "one")];
mock.add(test::handlers::provide_with_summary(
rows.clone(),
"not valid json",
));
let mut cursor = client.query("doesn't matter").fetch::<SimpleRow>().unwrap();
while cursor.next().await.unwrap().is_some() {}
assert!(cursor.summary().is_none());
}
#[tokio::test]
async fn summary_header_unknown_fields() {
let mock = test::Mock::new();
let client = Client::default().with_mock(&mock);
let rows = vec![SimpleRow::new(1, "one")];
let summary_json = r#"{"read_rows":"42","some_future_field":"hello"}"#;
mock.add(test::handlers::provide_with_summary(
rows.clone(),
summary_json,
));
let mut cursor = client.query("doesn't matter").fetch::<SimpleRow>().unwrap();
while cursor.next().await.unwrap().is_some() {}
let summary = cursor.summary().expect("summary should be present");
assert_eq!(summary.read_rows(), Some(42));
assert_eq!(summary.written_rows(), None);
assert_eq!(summary.get("some_future_field"), Some("hello"));
assert_eq!(summary.get("nonexistent"), None);
}
#[tokio::test]
async fn client_with_url() {
let mock = test::Mock::new();
let client = Client::default().with_url(mock.url());
let expected = vec![SimpleRow::new(1, "one"), SimpleRow::new(2, "two")];
mock.add(test::handlers::provide(expected.clone()));
let actual = crate::fetch_rows::<SimpleRow>(&client, "doesn't matter").await;
assert_eq!(actual, expected);
}