use std::path::PathBuf;
use eyre::{Result, ensure};
use tantivy::{Directory, Index, ReloadPolicy, directory::RamDirectory};
use super::{
dir::FailingDirectory,
utils::{create_multi_segment_index, redis_pool},
};
use crate::CachingDirectory;
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn warmer_clamps_concurrency_to_at_least_one() -> Result<()> {
let pool = redis_pool().await?;
let dir = CachingDirectory::new(RamDirectory::create(), pool);
assert_eq!(dir.warmer().with_concurrency(0).concurrency(), 1);
assert_eq!(dir.warmer().with_concurrency(4).concurrency(), 4);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn warm_index_populates_cache() -> Result<()> {
let pool = redis_pool().await?;
let (index, ram, dir) = create_multi_segment_index(pool.clone())?;
let metas = index.searchable_segment_metas()?;
ensure!(
metas.len() >= 4,
"expected several segments, got {}",
metas.len(),
);
dir.warmer().with_concurrency(8).index(&index).await?;
let dir2 = CachingDirectory::new(FailingDirectory(ram), pool.clone());
let index2 = Index::open(dir2)?;
let _reader: tantivy::IndexReader = index2
.reader_builder()
.reload_policy(ReloadPolicy::Manual)
.try_into()?;
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn warm_index_loads_in_memory_footers() -> Result<()> {
let pool = redis_pool().await?;
let (index, _ram, dir) = create_multi_segment_index(pool.clone())?;
dir.warmer().with_concurrency(4).index(&index).await?;
let metas = index.searchable_segment_metas()?;
let mut checked = 0usize;
for meta in &metas {
for path in meta.list_files() {
if !dir.exists(&path).unwrap_or(false) {
continue;
}
let cached = dir
.cache
.get_async(&path)
.await
.ok_or_else(|| eyre::eyre!("{path:?} missing from the in-memory cache"))?;
ensure!(
cached.get().data().is_some(),
"footer data should be loaded in memory for {path:?}",
);
checked += 1;
}
}
ensure!(
checked >= metas.len() * 5,
"expected to check several files per segment, only checked {checked}",
);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn warm_files_ignores_missing_files() -> Result<()> {
let pool = redis_pool().await?;
let (_index, _ram, dir) = create_multi_segment_index(pool.clone())?;
let missing = [
PathBuf::from("does-not-exist.idx"),
PathBuf::from("also-missing.store"),
];
dir.warmer().with_concurrency(2).files(missing).await?;
Ok(())
}