From 164dbe76c6842245c34ea67b084b2a99aa056b85 Mon Sep 17 00:00:00 2001 From: Vika Date: Tue, 19 Jul 2022 06:16:27 +0300 Subject: media: fix small files not being saved to disk properly It turns out that BufWriter requires calling `flush()` manually and doesn't do it on `drop()`. I forgot about that. --- kittybox-rs/src/media/storage/file.rs | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'kittybox-rs/src/media/storage') diff --git a/kittybox-rs/src/media/storage/file.rs b/kittybox-rs/src/media/storage/file.rs index 84edb84..b46cdb2 100644 --- a/kittybox-rs/src/media/storage/file.rs +++ b/kittybox-rs/src/media/storage/file.rs @@ -113,7 +113,8 @@ impl MediaStore for FileStore { } hasher = _hasher; } - + tempfile.flush().await?; + tempfile.into_inner().sync_all().await?; let hash = hasher.finalize(); debug!("Pending upload hash: {}", hex::encode(&hash)); let filename = format!( @@ -193,39 +194,48 @@ mod tests { use tokio::io::AsyncReadExt; #[tokio::test] + #[tracing_test::traced_test] async fn test_streaming_read_write() { let tempdir = tempdir::TempDir::new("file").expect("Failed to create tempdir"); let store = FileStore::new(tempdir.path()); + let tempdir_path = tempdir.into_path(); + - let file: &[u8] = include_bytes!("../../../../README.md"); + let file: &[u8] = include_bytes!("../../../companion-lite/style.css"); let stream = tokio_stream::iter(file.chunks(100).map(|i| Ok(bytes::Bytes::copy_from_slice(i)))); let metadata = Metadata { - filename: Some("README.md".to_string()), - content_type: "text/markdown".to_string(), + filename: Some("style.css".to_string()), + content_type: "text/css".to_string(), length: None }; + // write through the interface let filename = store.write_streaming( "fireburn.ru", metadata, stream ).await.unwrap(); - + println!("{}, {}", filename, tempdir_path + .join("fireburn.ru") + .join(&filename) + .display()); let content = tokio::fs::read( - tempdir.path() + tempdir_path .join("fireburn.ru") .join(&filename) ).await.unwrap(); assert_eq!(content, file); + // check internal metadata format let meta: Metadata = serde_json::from_slice(&tokio::fs::read( - tempdir.path() + tempdir_path .join("fireburn.ru") .join(filename.clone() + ".json") ).await.unwrap()).unwrap(); - assert_eq!(&meta.content_type, "text/markdown"); - assert_eq!(meta.filename.as_deref(), Some("README.md")); + assert_eq!(&meta.content_type, "text/css"); + assert_eq!(meta.filename.as_deref(), Some("style.css")); assert_eq!(meta.length, Some(file.len())); + // read back the data using the interface let (metadata, read_back) = { let (metadata, stream) = store.read_streaming( "fireburn.ru", @@ -240,8 +250,8 @@ mod tests { }; assert_eq!(read_back, file); - assert_eq!(&metadata.content_type, "text/markdown"); - assert_eq!(meta.filename.as_deref(), Some("README.md")); + assert_eq!(&metadata.content_type, "text/css"); + assert_eq!(meta.filename.as_deref(), Some("style.css")); assert_eq!(meta.length, Some(file.len())); } -- cgit 1.4.1