use anyhow::Result; use archivist::{ store::GzStore, tree::{CountingTree, DateTimeDirTree}, Archivist, }; use chrono::Local; use std::{ fs, io::Cursor, path::Path, sync::{Arc, Once}, }; use tempdir::TempDir; const DATA_DIR: &str = "./tests/data"; static INIT: Once = Once::new(); fn setup() { INIT.call_once(|| { tracing_subscriber::fmt::init(); }); } #[tokio::test(flavor = "multi_thread")] async fn add_raw() -> Result<()> { setup(); let image_path = Path::new(DATA_DIR).join("words.txt"); let dir = TempDir::new("archivist").expect("Create tmp dir"); let a = Archivist::new(dir.path().to_str().unwrap(), DateTimeDirTree::default(), 10).await?; let s = fs::read_to_string(image_path.clone()).unwrap(); for _ in 0..100 { let res = a.add("string.txt", &s).await; assert!(res.is_ok(), "{:?}", res); } Ok(()) } #[tokio::test(flavor = "multi_thread")] async fn multitasking() -> Result<()> { setup(); let image_path = Path::new(DATA_DIR).join("words.txt"); let dir = TempDir::new("archivist").expect("Create tmp dir"); let a = Arc::new( Archivist::new(dir.path().to_str().unwrap(), DateTimeDirTree::default(), 10).await?, ); let s = fs::read_to_string(image_path.clone()).unwrap(); let t1 = tokio::spawn({ let a = a.clone(); let s = s.clone(); async move { for _ in 0..100 { let res = a.add("string.txt", &s).await; assert!(res.is_ok(), "{:?}", res); } } }); let t2 = tokio::spawn(async move { for _ in 0..100 { let res = a.add("string.txt", &s).await; assert!(res.is_ok(), "{:?}", res); } }); tokio::try_join!(t1, t2)?; Ok(()) } #[tokio::test(flavor = "multi_thread")] async fn add_raw_same_timestamp() -> Result<()> { setup(); let image_path = Path::new(DATA_DIR).join("words.txt"); let dir = TempDir::new("archivist").expect("Create tmp dir"); let a = Archivist::new(dir.path().to_str().unwrap(), DateTimeDirTree::default(), 10).await?; let s = fs::read_to_string(image_path.clone()).unwrap(); // add 10 groups of files for _ in 0..10 { a.tree().await.set_timestamp(Local::now()); // add 10 files with the same timestamp but different suffix to group files together. for i in 0..10 { let res = a.add(&format!("string_{i}.txt"), &s).await; assert!(res.is_ok(), "{:?}", res); } } Ok(()) } #[tokio::test(flavor = "multi_thread")] async fn add_raw_counting_tree() -> Result<()> { setup(); let image_path = Path::new(DATA_DIR).join("words.txt"); let dir = TempDir::new("archivist").expect("Create tmp dir"); let a = Archivist::new(dir.path().to_str().unwrap(), CountingTree::new(10), 10).await?; let s = fs::read_to_string(image_path.clone()).unwrap(); let ids = &["XXX", "YYY", "ZZZ"]; for (_, id) in (0..100).zip(ids.iter().cycle()) { a.tree().await.id = id.to_string(); let res = a.add("_string.txt", &s).await; assert!(res.is_ok(), "{:?}", res); } Ok(()) } #[tokio::test(flavor = "multi_thread")] async fn add_gz() -> Result<()> { setup(); let image_path = Path::new(DATA_DIR).join("words.txt"); let dir = TempDir::new("archivist").expect("Create tmp dir"); let a = Archivist::new(dir.path().to_str().unwrap(), DateTimeDirTree::default(), 10).await?; let s = fs::read_to_string(image_path.clone()).unwrap(); for _ in 0..100 { let ss = GzStore::new(Cursor::new(s.clone())); let res = a.add("words.txt.gz", &ss).await; assert!(res.is_ok(), "{:?}", res); } Ok(()) } #[tokio::test(flavor = "multi_thread")] async fn add_image() -> Result<()> { setup(); let image_path = Path::new(DATA_DIR).join("lena.tiff"); let dir = TempDir::new("archivist").expect("Create tmp dir"); let a = Archivist::new(dir.path().to_str().unwrap(), DateTimeDirTree::default(), 10).await?; let image = image::open(image_path).unwrap(); for _ in 0..100 { let res = a.add("image.jpg", &image).await; assert!(res.is_ok(), "{:?}", res); } Ok(()) }