use crate::collection::Collection;
use crate::distance::DistanceMetric;
use crate::point::Point;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use tempfile::TempDir;
pub fn setup_collection(dim: usize) -> (TempDir, Collection) {
let dir = tempfile::tempdir().expect("test: tempdir creation");
let col = Collection::create(PathBuf::from(dir.path()), dim, DistanceMetric::Cosine)
.expect("test: collection creation");
(dir, col)
}
#[allow(dead_code)] pub fn setup_collection_with_points(dim: usize, points: Vec<Point>) -> (TempDir, Collection) {
let (dir, col) = setup_collection(dim);
col.upsert(points).expect("test: upsert");
(dir, col)
}
#[allow(dead_code)] pub fn make_point(id: u64, vector: Vec<f32>) -> Point {
Point {
id,
vector,
payload: None,
sparse_vectors: None,
}
}
pub fn make_point_with_payload(id: u64, vector: Vec<f32>, payload: serde_json::Value) -> Point {
Point {
id,
vector,
payload: Some(payload),
sparse_vectors: None,
}
}
#[derive(Default)]
struct WarnSink {
events: Mutex<Vec<String>>,
}
struct FlattenVisitor<'a>(&'a mut String);
impl tracing::field::Visit for FlattenVisitor<'_> {
fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) {
use std::fmt::Write;
let _ = write!(self.0, "{}={:?} ", field.name(), value);
}
}
struct WarnCapture {
sink: Arc<WarnSink>,
}
impl tracing::Subscriber for WarnCapture {
fn enabled(&self, metadata: &tracing::Metadata<'_>) -> bool {
*metadata.level() <= tracing::Level::WARN
}
fn new_span(&self, _: &tracing::span::Attributes<'_>) -> tracing::span::Id {
tracing::span::Id::from_u64(1)
}
fn record(&self, _: &tracing::span::Id, _: &tracing::span::Record<'_>) {}
fn record_follows_from(&self, _: &tracing::span::Id, _: &tracing::span::Id) {}
fn event(&self, event: &tracing::Event<'_>) {
let mut line = String::new();
event.record(&mut FlattenVisitor(&mut line));
self.sink
.events
.lock()
.expect("test: warn sink lock")
.push(line);
}
fn enter(&self, _: &tracing::span::Id) {}
fn exit(&self, _: &tracing::span::Id) {}
}
#[allow(dead_code)] pub fn capture_warns<T>(f: impl FnOnce() -> T) -> (T, Vec<String>) {
let sink = Arc::new(WarnSink::default());
let subscriber = WarnCapture { sink: sink.clone() };
let out = tracing::subscriber::with_default(subscriber, f);
let events = sink.events.lock().expect("test: warn sink lock").clone();
(out, events)
}