use std::{sync::Mutex, time::Duration};
use super::*;
pub fn get_offline_ditto() -> Result<Ditto, DittoError> {
let ditto = Ditto::builder()
.with_temp_dir()
.with_identity(|ditto_root| {
identity::OfflinePlayground::new(ditto_root, AppId::generate())
})?
.with_minimum_log_level(LogLevel::Error)
.build()?;
ditto.set_license_from_env("DITTO_LICENSE").unwrap();
Ok(ditto)
}
pub fn get_offline_ditto_with_root(root: Arc<dyn DittoRoot>) -> Result<Ditto, DittoError> {
let ditto = Ditto::builder()
.with_root(root)
.with_identity(|ditto_root| {
identity::OfflinePlayground::new(ditto_root, AppId::generate())
})?
.with_minimum_log_level(LogLevel::Error)
.build()?;
ditto.set_license_from_env("DITTO_LICENSE").unwrap();
Ok(ditto)
}
#[test]
fn test_observe_peers() {
let ditto = get_offline_ditto().unwrap();
ditto.start_sync().unwrap();
let is_observed = Arc::new(Mutex::new(false));
let is_observed_2 = is_observed.retain();
#[allow(deprecated)]
let _obs = ditto.observe_peers(move |_v2_presence| {
let mut observed = is_observed_2.lock().unwrap();
*observed = true;
});
while !*is_observed.lock().unwrap() {}
}
#[test]
fn test_presence_observe() {
let ditto = get_offline_ditto().unwrap();
ditto.start_sync().unwrap();
let is_observed = Arc::new(Mutex::new(false));
let is_observed_2 = is_observed.retain();
let _obs = ditto.presence().observe(move |_graph| {
let mut observed = is_observed_2.lock().unwrap();
*observed = true;
});
while !*is_observed.lock().unwrap() {}
}
#[test]
fn test_presence_exec() {
let ditto = get_offline_ditto().unwrap();
ditto.start_sync().unwrap();
let graph = ditto.presence().graph();
assert!(graph.local_peer.connections.is_empty());
assert!(graph.remote_peers.is_empty());
}
#[test]
fn test_observe_multiple_peers() {
let ditto = get_offline_ditto().unwrap();
ditto.start_sync().unwrap();
let is_observed_1 = Arc::new(Mutex::new(false));
let is_observed_1_copy = is_observed_1.retain();
let is_observed_2 = Arc::new(Mutex::new(false));
let is_observed_2_copy = is_observed_2.retain();
let _obs_1 = ditto.presence().observe(move |_presence_graph| {
let mut observed = is_observed_1_copy.lock().unwrap();
*observed = true;
});
let _obs_2 = ditto.presence().observe(move |_presence_graph| {
let mut observed = is_observed_2_copy.lock().unwrap();
*observed = true;
});
while !(*is_observed_1.lock().unwrap() && *is_observed_2.lock().unwrap()) {}
}
#[test]
fn test_disk_usage_exec() {
let ditto = get_offline_ditto().unwrap();
let tree = ditto.disk_usage().exec();
assert_eq!(tree.path, "ditto");
}
#[test]
fn test_disk_usage_observe() {
let (tx, rx) = std::sync::mpsc::sync_channel(1);
let ditto = get_offline_ditto().unwrap();
let _observer = ditto.disk_usage().observe(move |_| {
tx.send(()).unwrap();
});
let mut path = ditto.persistence_directory().to_path_buf();
path.push("file.tmp");
std::fs::File::create(path).unwrap();
rx.recv().unwrap();
}
#[test]
fn test_store_disk_usage_exec() {
let ditto = get_offline_ditto().unwrap();
#[allow(deprecated)]
let tree = ditto.store.disk_usage().exec();
assert_eq!(PathBuf::from(tree.path), PathBuf::from("ditto/ditto_store"));
}
#[test]
fn test_store_disk_usage_observe() {
let (tx, rx) = std::sync::mpsc::sync_channel(1);
let ditto = get_offline_ditto().unwrap();
let _observer = ditto.disk_usage().observe(move |_| {
tx.send(()).unwrap();
});
let mut path = ditto.persistence_directory().to_path_buf();
path.push("ditto_store");
path.push("file.tmp");
std::fs::File::create(path).unwrap();
rx.recv().unwrap();
}
#[test]
fn test_multiple_restart() {
let ditto = get_offline_ditto().unwrap();
let tmp_path = ditto.root();
ditto.start_sync().unwrap();
ditto.stop_sync();
ditto.close();
let ditto_to_be_created_rx;
{
let tx;
(tx, ditto_to_be_created_rx) = ::std::sync::mpsc::channel();
::std::thread::spawn(move || {
let ditto = get_offline_ditto_with_root(tmp_path).unwrap();
tx.send(ditto).unwrap();
});
};
let Ok(ditto) = ditto_to_be_created_rx.recv_timeout(Duration::from_secs(5)) else {
panic!("timed out creating new ditto instance");
};
ditto.start_sync().unwrap();
ditto.stop_sync();
}
#[test]
fn test_ditto_data_migration() {
let tmp = Arc::new(TempRoot::new());
let mut path: PathBuf = tmp.root_path().into();
path.push("ditto_data");
path.push("randomDirectory");
std::fs::create_dir_all(&path).unwrap();
path.push("randomFile");
std::fs::File::create(path).unwrap();
let ditto = get_offline_ditto_with_root(tmp).unwrap();
let mut root: PathBuf = ditto.persistence_directory().into();
root.push("randomDirectory");
root.push("randomFile");
assert!(root.exists());
root.pop();
root.push("ditto_data");
assert!(root.exists().not());
}
#[test]
fn test_ditto_deep_data_migration() {
use serde_json::json;
let tmp = Arc::new(TempRoot::new());
let mut path: PathBuf = tmp.root_path().into();
path.push("ditto_data");
let data_root = Arc::new(PersistentRoot::new(path.clone()).unwrap());
let ditto = get_offline_ditto_with_root(data_root).unwrap();
let store = ditto.store();
let collection = store.collection("test").unwrap();
let doc_id = collection.upsert(json!({"Seth": 7})).unwrap();
ditto.close();
let ditto = get_offline_ditto_with_root(tmp).unwrap();
let store = ditto.store();
let collection = store.collection("test").unwrap();
let doc = collection.find_by_id(doc_id.clone()).exec().unwrap();
let value: u32 = doc.get("Seth").unwrap();
assert_eq!(value, 7);
ditto.close();
assert!(path.exists().not());
}