2466: index resolver tests r=MarinPostma a=MarinPostma

add more index resolver tests


depends on #2455 

followup #2453 

Co-authored-by: ad hoc <postma.marin@protonmail.com>
This commit is contained in:
bors[bot] 2022-06-09 17:50:01 +00:00 committed by GitHub
commit 4fc73195e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -386,8 +386,14 @@ mod real {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::index::IndexStats;
use super::index_store::MockIndexStore;
use super::meta_store::MockIndexMetaStore;
use super::*; use super::*;
use futures::future::ok;
use milli::FieldDistribution;
use nelson::Mocker; use nelson::Mocker;
pub enum MockIndexResolver<U, I> { pub enum MockIndexResolver<U, I> {
@ -493,174 +499,178 @@ mod test {
} }
} }
// TODO: ignoring this test, it has become too complex to maintain, and rather implement #[actix_rt::test]
// handler logic test. async fn test_remove_unknown_index() {
// proptest! { let mut meta_store = MockIndexMetaStore::new();
// #[test] meta_store
// #[ignore] .expect_delete()
// fn test_process_task( .once()
// task in any::<Task>().prop_filter("IndexUid should be Some", |s| s.index_uid.is_some()), .returning(|_| Box::pin(ok(None)));
// index_exists in any::<bool>(),
// index_op_fails in any::<bool>(), let index_store = MockIndexStore::new();
// any_int in any::<u64>(),
// ) { let mocker = Mocker::default();
// actix_rt::System::new().block_on(async move { let file_store = UpdateFileStore::mock(mocker);
// let uuid = Uuid::new_v4();
// let mut index_store = MockIndexStore::new(); let index_resolver = IndexResolver::new(meta_store, index_store, file_store);
//
// let mocker = Mocker::default(); let mut task = Task {
// id: 1,
// // Return arbitrary data from index call. content: TaskContent::IndexDeletion {
// match &task.content { index_uid: IndexUid::new_unchecked("test"),
// TaskContent::DocumentAddition{primary_key, ..} => { },
// let result = move || if !index_op_fails { events: Vec::new(),
// Ok(DocumentAdditionResult { indexed_documents: any_int, number_of_documents: any_int }) };
// } else {
// // return this error because it's easy to generate... index_resolver.process_task(&mut task).await;
// Err(IndexError::DocumentNotFound("a doc".into()))
// }; assert!(matches!(task.events[0], TaskEvent::Failed { .. }));
// if primary_key.is_some() { }
// mocker.when::<String, IndexResult<IndexMeta>>("update_primary_key")
// .then(move |_| Ok(IndexMeta{ created_at: OffsetDateTime::now_utc(), updated_at: OffsetDateTime::now_utc(), primary_key: None })); #[actix_rt::test]
// } async fn test_remove_index() {
// mocker.when::<(IndexDocumentsMethod, Option<String>, UpdateFileStore, IntoIter<Uuid>), IndexResult<DocumentAdditionResult>>("update_documents") let mut meta_store = MockIndexMetaStore::new();
// .then(move |(_, _, _, _)| result()); meta_store.expect_delete().once().returning(|_| {
// } Box::pin(ok(Some(IndexMeta {
// TaskContent::SettingsUpdate{..} => { uuid: Uuid::new_v4(),
// let result = move || if !index_op_fails { creation_task_id: 1,
// Ok(()) })))
// } else { });
// // return this error because it's easy to generate...
// Err(IndexError::DocumentNotFound("a doc".into())) let mut index_store = MockIndexStore::new();
// }; index_store.expect_delete().once().returning(|_| {
// mocker.when::<&Settings<Checked>, IndexResult<()>>("update_settings") let mocker = Mocker::default();
// .then(move |_| result()); mocker.when::<(), ()>("close").then(|_| ());
// } mocker
// TaskContent::DocumentDeletion(DocumentDeletion::Ids(_ids)) => { .when::<(), IndexResult<IndexStats>>("stats")
// let result = move || if !index_op_fails { .then(|_| {
// Ok(DocumentDeletionResult { deleted_documents: any_int as u64, remaining_documents: any_int as u64 }) Ok(IndexStats {
// } else { size: 10,
// // return this error because it's easy to generate... number_of_documents: 10,
// Err(IndexError::DocumentNotFound("a doc".into())) is_indexing: None,
// }; field_distribution: FieldDistribution::default(),
// })
// mocker.when::<&[String], IndexResult<DocumentDeletionResult>>("delete_documents") });
// .then(move |_| result()); Box::pin(ok(Some(Index::mock(mocker))))
// }, });
// TaskContent::DocumentDeletion(DocumentDeletion::Clear) => {
// let result = move || if !index_op_fails { let mocker = Mocker::default();
// Ok(()) let file_store = UpdateFileStore::mock(mocker);
// } else {
// // return this error because it's easy to generate... let index_resolver = IndexResolver::new(meta_store, index_store, file_store);
// Err(IndexError::DocumentNotFound("a doc".into()))
// }; let mut task = Task {
// mocker.when::<(), IndexResult<()>>("clear_documents") id: 1,
// .then(move |_| result()); content: TaskContent::IndexDeletion {
// }, index_uid: IndexUid::new_unchecked("test"),
// TaskContent::IndexDeletion => { },
// mocker.when::<(), ()>("close") events: Vec::new(),
// .times(index_exists as usize) };
// .then(move |_| ());
// } index_resolver.process_task(&mut task).await;
// TaskContent::IndexUpdate { primary_key }
// | TaskContent::IndexCreation { primary_key } => { assert!(matches!(task.events[0], TaskEvent::Succeeded { .. }));
// if primary_key.is_some() { }
// let result = move || if !index_op_fails {
// Ok(IndexMeta{ created_at: OffsetDateTime::now_utc(), updated_at: OffsetDateTime::now_utc(), primary_key: None }) #[actix_rt::test]
// } else { async fn test_delete_documents() {
// // return this error because it's easy to generate... let mut meta_store = MockIndexMetaStore::new();
// Err(IndexError::DocumentNotFound("a doc".into())) meta_store.expect_get().once().returning(|_| {
// }; Box::pin(ok((
// mocker.when::<String, IndexResult<IndexMeta>>("update_primary_key") "test".to_string(),
// .then(move |_| result()); Some(IndexMeta {
// } uuid: Uuid::new_v4(),
// } creation_task_id: 1,
// TaskContent::Dump { .. } => { } }),
// } )))
// });
// mocker.when::<(), IndexResult<IndexStats>>("stats")
// .then(|()| Ok(IndexStats { size: 0, number_of_documents: 0, is_indexing: Some(false), field_distribution: BTreeMap::new() })); let mut index_store = MockIndexStore::new();
// index_store.expect_get().once().returning(|_| {
// let index = Index::mock(mocker); let mocker = Mocker::default();
// mocker
// match &task.content { .when::<(), IndexResult<()>>("clear_documents")
// // an unexisting index should trigger an index creation in the folllowing cases: .once()
// TaskContent::DocumentAddition { allow_index_creation: true, .. } .then(|_| Ok(()));
// | TaskContent::SettingsUpdate { allow_index_creation: true, is_deletion: false, .. } mocker
// | TaskContent::IndexCreation { .. } if !index_exists => { .when::<(), IndexResult<IndexStats>>("stats")
// index_store .once()
// .expect_create() .then(|_| {
// .once() Ok(IndexStats {
// .withf(move |&found| !index_exists || found == uuid) size: 10,
// .returning(move |_| Box::pin(ok(index.clone()))); number_of_documents: 10,
// }, is_indexing: None,
// TaskContent::IndexDeletion => { field_distribution: FieldDistribution::default(),
// index_store })
// .expect_delete() });
// // this is called only if the index.exists Box::pin(ok(Some(Index::mock(mocker))))
// .times(index_exists as usize) });
// .withf(move |&found| !index_exists || found == uuid)
// .returning(move |_| Box::pin(ok(Some(index.clone())))); let mocker = Mocker::default();
// } let file_store = UpdateFileStore::mock(mocker);
// // if index already exists, create index will return an error
// TaskContent::IndexCreation { .. } if index_exists => (), let index_resolver = IndexResolver::new(meta_store, index_store, file_store);
// TaskContent::Dump { .. } => (),
// // The index exists and get should be called let mut task = Task {
// _ if index_exists => { id: 1,
// index_store content: TaskContent::DocumentDeletion {
// .expect_get() deletion: DocumentDeletion::Clear,
// .once() index_uid: IndexUid::new_unchecked("test"),
// .withf(move |&found| found == uuid) },
// .returning(move |_| Box::pin(ok(Some(index.clone())))); events: Vec::new(),
// }, };
// // the index doesn't exist and shouldn't be created, the uuidstore will return an error, and get_index will never be called.
// _ => (), index_resolver.process_task(&mut task).await;
// }
// assert!(matches!(task.events[0], TaskEvent::Succeeded { .. }));
// let mut uuid_store = MockIndexMetaStore::new(); }
// uuid_store
// .expect_get() #[actix_rt::test]
// .returning(move |uid| { async fn test_index_update() {
// Box::pin(ok((uid, index_exists.then(|| crate::index_resolver::meta_store::IndexMeta {uuid, creation_task_id: 0 })))) let mut meta_store = MockIndexMetaStore::new();
// }); meta_store.expect_get().once().returning(|_| {
// Box::pin(ok((
// // we sould only be creating an index if the index doesn't alredy exist "test".to_string(),
// uuid_store Some(IndexMeta {
// .expect_insert() uuid: Uuid::new_v4(),
// .withf(move |_, _| !index_exists) creation_task_id: 1,
// .returning(|_, _| Box::pin(ok(()))); }),
// )))
// uuid_store });
// .expect_delete()
// .times(matches!(task.content, TaskContent::IndexDeletion) as usize) let mut index_store = MockIndexStore::new();
// .returning(move |_| Box::pin(ok(index_exists.then(|| crate::index_resolver::meta_store::IndexMeta { uuid, creation_task_id: 0})))); index_store.expect_get().once().returning(|_| {
// let mocker = Mocker::default();
// let mocker = Mocker::default();
// let update_file_store = UpdateFileStore::mock(mocker); mocker
// let index_resolver = IndexResolver::new(uuid_store, index_store, update_file_store); .when::<String, IndexResult<crate::index::IndexMeta>>("update_primary_key")
// .once()
// let batch = Batch { id: Some(1), created_at: OffsetDateTime::now_utc(), content: crate::tasks::batch::BatchContent::IndexUpdate(task.clone()) }; .then(|_| {
// if index_resolver.accept(&batch) { Ok(crate::index::IndexMeta {
// let result = index_resolver.process_batch(batch).await; created_at: OffsetDateTime::now_utc(),
// updated_at: OffsetDateTime::now_utc(),
// // Test for some expected output scenarios: primary_key: Some("key".to_string()),
// // Index creation and deletion cannot fail because of a failed index op, since they })
// // don't perform index ops. });
// if index_op_fails && !matches!(task.content, TaskContent::IndexDeletion | TaskContent::IndexCreation { primary_key: None } | TaskContent::IndexUpdate { primary_key: None } | TaskContent::Dump { .. }) Box::pin(ok(Some(Index::mock(mocker))))
// || (index_exists && matches!(task.content, TaskContent::IndexCreation { .. })) });
// || (!index_exists && matches!(task.content, TaskContent::IndexDeletion
// | TaskContent::DocumentDeletion(_) let mocker = Mocker::default();
// | TaskContent::SettingsUpdate { is_deletion: true, ..} let file_store = UpdateFileStore::mock(mocker);
// | TaskContent::SettingsUpdate { allow_index_creation: false, ..}
// | TaskContent::DocumentAddition { allow_index_creation: false, ..} let index_resolver = IndexResolver::new(meta_store, index_store, file_store);
// | TaskContent::IndexUpdate { .. } ))
// { let mut task = Task {
// assert!(matches!(result.content.first().unwrap().events.last().unwrap(), TaskEvent::Failed { .. }), "{:?}", result); id: 1,
// } else { content: TaskContent::IndexUpdate {
// assert!(matches!(result.content.first().unwrap().events.last().unwrap(), TaskEvent::Succeeded { .. }), "{:?}", result); primary_key: Some("key".to_string()),
// } index_uid: IndexUid::new_unchecked("test"),
// } },
// }); events: Vec::new(),
// } };
// }
index_resolver.process_task(&mut task).await;
assert!(matches!(task.events[0], TaskEvent::Succeeded { .. }));
}
} }