#![allow(clippy::unwrap_used, clippy::expect_used)]
use std::collections::BTreeMap;
use chronix::prelude::*;
use chronix::Chronix;
const BASE: i64 = 1_700_000_000_000_000_000;
const SEC: i64 = 1_000_000_000;
fn seeded() -> (tempfile::TempDir, Chronix) {
let dir = tempfile::tempdir().unwrap();
let db = Chronix::open(
ChronixConfig::builder()
.data_dir(dir.path())
.build()
.unwrap(),
)
.unwrap();
let points: Vec<Point> = (0..20_000i64)
.map(|i| {
let tags: BTreeMap<String, String> = [("host".to_string(), format!("h{}", i % 4))]
.into_iter()
.collect();
let key = SeriesKey::new("m", tags).unwrap();
let fields: BTreeMap<String, FieldValue> =
[("v".to_string(), FieldValue::F64(i as f64))]
.into_iter()
.collect();
Point::new(key, fields, BASE + i * SEC).unwrap()
})
.collect();
let _ = db.insert_batch(&points).unwrap();
db.flush().unwrap();
(dir, db)
}
fn timestamps(batch: &arrow::record_batch::RecordBatch) -> Vec<i64> {
batch
.column_by_name(chronix_core::TIME_COLUMN)
.unwrap()
.as_any()
.downcast_ref::<arrow::array::Int64Array>()
.unwrap()
.iter()
.flatten()
.collect()
}
#[test]
fn a_range_without_tag_filters_returns_only_rows_in_range() {
let (_dir, db) = seeded();
let start = BASE + 10_000 * SEC;
let end = start + 100 * SEC;
let plan = db
.query()
.measurement("m")
.range(start, end)
.build()
.unwrap();
let ts = timestamps(&db.execute(&plan).unwrap());
assert!(
ts.iter().all(|t| *t >= start && *t <= end),
"rows outside [{start}, {end}] were returned"
);
assert_eq!(ts.len(), 101, "inclusive range over 1s points");
}
#[test]
fn a_range_with_tag_filters_returns_only_rows_in_range() {
let (_dir, db) = seeded();
let start = BASE + 10_000 * SEC;
let end = start + 100 * SEC;
let plan = db
.query()
.measurement("m")
.tag("host", "h0")
.range(start, end)
.build()
.unwrap();
let ts = timestamps(&db.execute(&plan).unwrap());
assert!(
ts.iter().all(|t| *t >= start && *t <= end),
"rows outside [{start}, {end}] were returned"
);
assert_eq!(ts.len(), 26);
}
#[test]
fn the_streaming_path_agrees_with_the_collecting_one() {
let (_dir, db) = seeded();
let start = BASE + 10_000 * SEC;
let end = start + 100 * SEC;
let plan = db
.query()
.measurement("m")
.range(start, end)
.build()
.unwrap();
let collected = timestamps(&db.execute(&plan).unwrap());
let mut streamed: Vec<i64> = Vec::new();
for batch in db.execute_iter(&plan).unwrap() {
streamed.extend(timestamps(&batch.unwrap()));
}
let mut a = collected;
let mut b = streamed;
a.sort_unstable();
b.sort_unstable();
assert_eq!(a, b, "execute and execute_iter disagreed on the same plan");
}