use std::path::PathBuf;
use dittolive_ditto::prelude::*;
mod common;
use common::*;
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn recovery_from_duplicated_persistence_dir() {
const COMPONENT_1: &str = "recovery_from_duplicated_persistence_dir_1";
const COMPONENT_2: &str = "recovery_from_duplicated_persistence_dir_2";
let database_id = ::uuid::Uuid::new_v4().to_string();
let root = ::tempfile::tempdir().unwrap();
let mut path_1 = root.path().to_path_buf();
path_1.push(COMPONENT_1);
let mut path_2 = root.path().to_path_buf();
path_2.push(COMPONENT_2);
let ditto_1 = Ditto::open_sync(
DittoConfig::new(
database_id.clone(),
DittoConfigConnect::SmallPeersOnly { private_key: None },
)
.with_persistence_directory(path_1.clone()),
)
.unwrap();
ditto_1.set_license_from_env("DITTO_LICENSE").ok();
ditto_1.close();
for entry in ::walkdir::WalkDir::new(path_1.clone()) {
let entry = entry.unwrap();
if !entry.file_type().is_file() {
continue;
}
let path = entry.path();
let dest = PathBuf::from(
path.as_os_str()
.to_string_lossy()
.replace(COMPONENT_1, COMPONENT_2),
);
#[allow(clippy::disallowed_methods)]
let _ = std::fs::create_dir_all(dest.parent().unwrap());
std::fs::copy(path, dest).unwrap();
}
let ditto_1 = Ditto::open_sync(
DittoConfig::new(
database_id.clone(),
DittoConfigConnect::SmallPeersOnly { private_key: None },
)
.with_persistence_directory(path_1),
)
.unwrap();
{
let mut config = TransportConfig::new();
config.listen.tcp.enabled = true;
config.listen.tcp.interface_ip = "127.0.0.1".to_owned();
config.listen.tcp.port = 30001;
ditto_1.set_transport_config(config);
}
let ditto_2 = Ditto::open_sync(
DittoConfig::new(
database_id.clone(),
DittoConfigConnect::SmallPeersOnly { private_key: None },
)
.with_persistence_directory(path_2),
)
.unwrap();
{
let mut config = TransportConfig::new();
config
.connect
.tcp_servers
.insert("127.0.0.1:30001".to_owned());
ditto_2.set_transport_config(config);
}
ditto_1.set_license_from_env("DITTO_LICENSE").ok();
ditto_2.set_license_from_env("DITTO_LICENSE").ok();
ditto_1.set_device_name("ditto_1");
ditto_2.set_device_name("ditto_2");
let (seen_2_tx, mut seen_2_rx) = ::tokio::sync::mpsc::unbounded_channel();
let presence_observer_1 = ditto_1.presence().register_observer(move |graph| {
if let Some(_seen_ditto_2) = graph
.remote_peers
.iter()
.find(|peer| peer.device_name == "ditto_2")
{
seen_2_tx.send(()).ok();
}
});
let (seen_1_tx, mut seen_1_rx) = ::tokio::sync::mpsc::unbounded_channel();
let presence_observer_2 = ditto_2.presence().register_observer(move |graph| {
if let Some(_seen_ditto_1) = graph
.remote_peers
.iter()
.find(|peer| peer.device_name == "ditto_1")
{
seen_1_tx.send(()).ok();
}
});
ditto_1.sync().start().unwrap();
ditto_2.sync().start().unwrap();
::tokio::time::timeout(::std::time::Duration::from_secs(30), async {
seen_1_rx.recv().await.unwrap();
seen_2_rx.recv().await.unwrap();
})
.await
.unwrap();
ditto_1.sync().stop();
ditto_2.sync().stop();
drop(presence_observer_1);
drop(presence_observer_2);
}