mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-26 03:55:07 +08:00
Merge #2466
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:
commit
4fc73195e6
@ -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 { .. }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user