kitchen-freezer/tests/sync.rs

359 lines
12 KiB
Rust
Raw Normal View History

mod scenarii;
2021-03-22 23:42:41 +01:00
2021-04-13 23:32:07 +02:00
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
use std::sync::{Arc, Mutex};
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
2021-04-28 23:46:11 +02:00
use kitchen_fridge::mock_behaviour::MockBehaviour;
2021-02-25 00:46:32 +01:00
/// A test that simulates a regular synchronisation between a local cache and a server.
/// Note that this uses a second cache to "mock" a server.
struct TestFlavour {
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
scenarii: Vec<scenarii::ItemScenario>,
2021-04-13 23:32:07 +02:00
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
mock_behaviour: Arc<Mutex<MockBehaviour>>,
}
2021-04-05 23:04:52 +02:00
#[cfg(not(feature = "local_calendar_mocks_remote_calendars"))]
impl TestFlavour {
pub fn normal() -> Self { Self{} }
pub fn first_sync_to_local() -> Self { Self{} }
2021-04-04 00:35:59 +02:00
pub fn first_sync_to_server() -> Self { Self{} }
2021-04-05 22:21:56 +02:00
pub fn transient_task() -> Self { Self{} }
pub fn normal_with_errors1() -> Self { Self{} }
pub fn normal_with_errors2() -> Self { Self{} }
pub fn normal_with_errors3() -> Self { Self{} }
pub fn normal_with_errors4() -> Self { Self{} }
pub fn normal_with_errors5() -> Self { Self{} }
pub fn normal_with_errors6() -> Self { Self{} }
pub fn normal_with_errors7() -> Self { Self{} }
pub fn normal_with_errors8() -> Self { Self{} }
pub fn normal_with_errors9() -> Self { Self{} }
pub fn normal_with_errors10() -> Self { Self{} }
pub fn normal_with_errors11() -> Self { Self{} }
2021-04-18 00:32:13 +02:00
pub fn normal_with_errors12() -> Self { Self{} }
2021-04-13 23:32:07 +02:00
pub async fn run(&self, _max_attempts: u32) {
2021-04-19 08:29:52 +02:00
panic!("WARNING: This test required the \"integration_tests\" Cargo feature");
2021-04-05 23:04:52 +02:00
}
}
#[cfg(feature = "local_calendar_mocks_remote_calendars")]
impl TestFlavour {
pub fn normal() -> Self {
Self {
scenarii: scenarii::scenarii_basic(),
2021-04-13 23:32:07 +02:00
mock_behaviour: Arc::new(Mutex::new(MockBehaviour::new())),
}
}
pub fn first_sync_to_local() -> Self {
Self {
scenarii: scenarii::scenarii_first_sync_to_local(),
2021-04-13 23:32:07 +02:00
mock_behaviour: Arc::new(Mutex::new(MockBehaviour::new())),
}
}
2021-04-04 00:35:59 +02:00
pub fn first_sync_to_server() -> Self {
Self {
scenarii: scenarii::scenarii_first_sync_to_server(),
2021-04-13 23:32:07 +02:00
mock_behaviour: Arc::new(Mutex::new(MockBehaviour::new())),
2021-04-04 00:35:59 +02:00
}
}
2021-04-05 22:21:56 +02:00
pub fn transient_task() -> Self {
Self {
scenarii: scenarii::scenarii_transient_task(),
2021-04-13 23:32:07 +02:00
mock_behaviour: Arc::new(Mutex::new(MockBehaviour::new())),
2021-04-05 22:21:56 +02:00
}
}
pub fn normal_with_errors1() -> Self {
2021-04-13 23:32:07 +02:00
Self {
scenarii: scenarii::scenarii_basic(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour::fail_now(10))),
}
}
pub fn normal_with_errors2() -> Self {
Self {
scenarii: scenarii::scenarii_basic(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
get_calendars_behaviour: (0,1),
create_calendar_behaviour: (2,2),
..MockBehaviour::default()
})),
}
}
pub fn normal_with_errors3() -> Self {
Self {
scenarii: scenarii::scenarii_first_sync_to_server(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
get_calendars_behaviour: (1,6),
create_calendar_behaviour: (0,1),
..MockBehaviour::default()
})),
}
}
pub fn normal_with_errors4() -> Self {
Self {
scenarii: scenarii::scenarii_first_sync_to_server(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
add_item_behaviour: (1,3),
..MockBehaviour::default()
})),
}
}
pub fn normal_with_errors5() -> Self {
Self {
scenarii: scenarii::scenarii_basic(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
get_item_version_tags_behaviour: (0,1),
..MockBehaviour::default()
})),
}
}
pub fn normal_with_errors6() -> Self {
Self {
scenarii: scenarii::scenarii_basic(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
2021-11-16 00:10:47 +01:00
get_item_by_url_behaviour: (3,2),
..MockBehaviour::default()
})),
}
}
pub fn normal_with_errors7() -> Self {
Self {
scenarii: scenarii::scenarii_basic(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
delete_item_behaviour: (0,2),
..MockBehaviour::default()
})),
}
}
pub fn normal_with_errors8() -> Self {
Self {
scenarii: scenarii::scenarii_basic(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
add_item_behaviour: (2,3),
2021-11-16 00:10:47 +01:00
get_item_by_url_behaviour: (1,4),
..MockBehaviour::default()
})),
}
}
pub fn normal_with_errors9() -> Self {
Self {
scenarii: scenarii::scenarii_basic(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
get_calendars_behaviour: (0,8),
delete_item_behaviour: (1,1),
..MockBehaviour::default()
})),
}
}
pub fn normal_with_errors10() -> Self {
Self {
scenarii: scenarii::scenarii_first_sync_to_server(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
get_calendars_behaviour: (0,8),
delete_item_behaviour: (1,1),
create_calendar_behaviour: (1,4),
get_item_version_tags_behaviour: (3,1),
..MockBehaviour::default()
})),
}
}
pub fn normal_with_errors11() -> Self {
Self {
scenarii: scenarii::scenarii_basic(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
get_calendars_behaviour: (0,8),
delete_item_behaviour: (1,1),
create_calendar_behaviour: (1,4),
get_item_version_tags_behaviour: (3,1),
2021-11-16 00:10:47 +01:00
get_item_by_url_behaviour: (0,41),
..MockBehaviour::default()
})),
}
}
2021-04-18 00:32:13 +02:00
pub fn normal_with_errors12() -> Self {
Self {
scenarii: scenarii::scenarii_basic(),
mock_behaviour: Arc::new(Mutex::new(MockBehaviour{
update_item_behaviour: (0,3),
..MockBehaviour::default()
})),
}
}
2021-04-13 23:32:07 +02:00
pub async fn run(&self, max_attempts: u32) {
self.mock_behaviour.lock().unwrap().suspend();
let mut provider = scenarii::populate_test_provider_before_sync(&self.scenarii, Arc::clone(&self.mock_behaviour)).await;
print_provider(&provider, "before sync").await;
2021-04-03 18:04:56 +02:00
2021-04-13 23:32:07 +02:00
self.mock_behaviour.lock().unwrap().resume();
for attempt in 0..max_attempts {
println!("\nSyncing...\n");
if provider.sync().await == true {
println!("Sync complete after {} attempts (multiple attempts are due to forced errors in mocked behaviour)", attempt+1);
break
}
}
self.mock_behaviour.lock().unwrap().suspend();
print_provider(&provider, "after sync").await;
// Check the contents of both sources are the same after sync
2021-04-04 01:02:37 +02:00
assert!(provider.remote().has_same_observable_content_as(provider.local()).await.unwrap());
2021-02-25 00:46:32 +01:00
// But also explicitely check that every item is expected
2021-04-13 23:32:07 +02:00
let expected_provider = scenarii::populate_test_provider_after_sync(&self.scenarii, Arc::clone(&self.mock_behaviour)).await;
2021-03-31 08:40:21 +02:00
2021-04-04 01:02:37 +02:00
assert!(provider.local() .has_same_observable_content_as(expected_provider.local() ).await.unwrap());
assert!(provider.remote().has_same_observable_content_as(expected_provider.remote()).await.unwrap());
2021-04-05 23:20:45 +02:00
// Perform a second sync, even if no change has happened, just to check
println!("Syncing again");
2021-04-13 23:32:07 +02:00
provider.sync().await;
2021-04-05 23:20:45 +02:00
assert!(provider.local() .has_same_observable_content_as(expected_provider.local() ).await.unwrap());
assert!(provider.remote().has_same_observable_content_as(expected_provider.remote()).await.unwrap());
}
}
async fn run_flavour(flavour: TestFlavour, max_attempts: u32) {
let _ = env_logger::builder().is_test(true).try_init();
flavour.run(max_attempts).await;
}
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_regular_sync() {
run_flavour(TestFlavour::normal(), 1).await;
}
2021-02-25 00:46:32 +01:00
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_sync_empty_initial_local() {
run_flavour(TestFlavour::first_sync_to_local(), 1).await;
2021-04-03 18:04:56 +02:00
}
2021-04-04 00:35:59 +02:00
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
2021-04-04 00:35:59 +02:00
async fn test_sync_empty_initial_server() {
run_flavour(TestFlavour::first_sync_to_server(), 1).await;
2021-04-04 00:35:59 +02:00
}
2021-04-05 22:21:56 +02:00
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
2021-04-05 22:21:56 +02:00
async fn test_sync_transient_task() {
run_flavour(TestFlavour::transient_task(), 1).await;
}
2021-04-05 22:21:56 +02:00
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync1() {
run_flavour(TestFlavour::normal_with_errors1(), 100).await;
2021-04-05 22:21:56 +02:00
}
2021-04-13 23:32:07 +02:00
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync2() {
run_flavour(TestFlavour::normal_with_errors2(), 100).await;
}
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync3() {
run_flavour(TestFlavour::normal_with_errors3(), 100).await;
}
2021-04-13 23:32:07 +02:00
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync4() {
run_flavour(TestFlavour::normal_with_errors4(), 100).await;
}
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync5() {
run_flavour(TestFlavour::normal_with_errors5(), 100).await;
}
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync6() {
run_flavour(TestFlavour::normal_with_errors6(), 100).await;
}
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync7() {
run_flavour(TestFlavour::normal_with_errors7(), 100).await;
}
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync8() {
run_flavour(TestFlavour::normal_with_errors8(), 100).await;
}
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync9() {
run_flavour(TestFlavour::normal_with_errors9(), 100).await;
}
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync10() {
run_flavour(TestFlavour::normal_with_errors10(), 100).await;
}
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
async fn test_errors_in_regular_sync11() {
run_flavour(TestFlavour::normal_with_errors11(), 100).await;
2021-04-13 23:32:07 +02:00
}
2021-04-04 00:35:59 +02:00
2021-04-18 00:32:13 +02:00
#[tokio::test]
2021-04-19 08:29:52 +02:00
#[cfg_attr(not(feature="integration_tests"), ignore)]
2021-04-18 00:32:13 +02:00
async fn test_errors_in_regular_sync12() {
run_flavour(TestFlavour::normal_with_errors12(), 100).await;
}
2021-04-04 00:35:59 +02:00
#[cfg(feature = "integration_tests")]
2021-04-28 23:46:11 +02:00
use kitchen_fridge::{traits::CalDavSource,
2021-07-08 16:05:03 +02:00
provider::Provider,
2021-04-04 00:35:59 +02:00
cache::Cache,
calendar::cached_calendar::CachedCalendar,
};
2021-04-03 18:04:56 +02:00
/// Print the contents of the provider. This is usually used for debugging
#[allow(dead_code)]
#[cfg(feature = "integration_tests")]
2021-04-03 18:04:56 +02:00
async fn print_provider(provider: &Provider<Cache, CachedCalendar, Cache, CachedCalendar>, title: &str) {
2021-03-22 22:39:50 +01:00
let cals_server = provider.remote().get_calendars().await.unwrap();
2021-04-03 18:04:56 +02:00
println!("----Server, {}-------", title);
2021-04-28 23:46:11 +02:00
kitchen_fridge::utils::print_calendar_list(&cals_server).await;
2021-02-27 11:58:40 +01:00
let cals_local = provider.local().get_calendars().await.unwrap();
2021-04-03 18:04:56 +02:00
println!("-----Local, {}-------", title);
2021-04-28 23:46:11 +02:00
kitchen_fridge::utils::print_calendar_list(&cals_local).await;
2021-02-25 00:46:32 +01:00
}