From 3e203b40c09a2cee799057ef62c1025c221b84ae Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Sun, 18 Dec 2022 11:12:58 -0500 Subject: [PATCH] Added io errors to add_entry. --- src/morethantext/mod.rs | 52 ++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/morethantext/mod.rs b/src/morethantext/mod.rs index 28b8a8c..8d93e17 100644 --- a/src/morethantext/mod.rs +++ b/src/morethantext/mod.rs @@ -66,19 +66,24 @@ impl MoreThanText { }) } - async fn add_entry(&self, entry: CacheEntry) -> String { + async fn add_entry(&self, entry: CacheEntry) -> Result { let mut id: String = "".to_string(); let mut dup = true; while dup { id = thread_rng().sample_iter(&Alphanumeric).take(32).collect(); dup = Path::new(&self.dir).join(&id).as_path().exists().await; } - write(Path::new(&self.dir).join(&id), entry.to_bytes()) - .await - .unwrap(); + match write(Path::new(&self.dir).join(&id), entry.to_bytes()).await { + Ok(_) => (), + Err(err) => { + let mut error = DBError::new("data write"); + error.add_source(err); + return Err(error); + } + }; let mut cache = self.cache.lock().await; cache.insert(id.clone(), entry); - return id; + Ok(id) } async fn get_entry(&self, id: &str) -> Result { @@ -103,6 +108,7 @@ impl MoreThanText { #[cfg(test)] mod setup { use super::*; + use async_std::fs::remove_dir_all; use tempfile::{tempdir, TempDir}; pub struct MTT { @@ -118,6 +124,10 @@ mod setup { .unwrap(); Self { db: db, dir: dir } } + + pub async fn create_io_error(&self) { + remove_dir_all(self.dir.path().join(DATA)).await.unwrap(); + } } } @@ -151,11 +161,14 @@ mod init { #[async_std::test] async fn bad_data_dir() { + let msg = "could not create directory"; match MoreThanText::new("kljsdgfhslkfrh").await { Ok(_) => assert!(false, "This test should fail to create a data directory"), Err(err) => { assert_eq!(err.to_string(), "failed to create data directory"); assert!(err.source().is_some(), "Must include the source error."); + let err_msg = err.source().unwrap().to_string(); + assert!(err_msg.contains(msg), "'{}' not in '{}'", msg, err_msg); } }; } @@ -165,14 +178,15 @@ mod init { mod cache { use super::*; use setup::MTT; + use std::error::Error; #[async_std::test] async fn entry_ids_are_random() { let mtt = MTT::new().await; let data1 = CacheEntry::Raw("one".to_string()); let data2 = CacheEntry::Raw("two".to_string()); - let id1 = mtt.db.add_entry(data1).await; - let id2 = mtt.db.add_entry(data2).await; + let id1 = mtt.db.add_entry(data1).await.unwrap(); + let id2 = mtt.db.add_entry(data2).await.unwrap(); assert_ne!(id1, id2, "Ids should be unique.") } @@ -181,7 +195,7 @@ mod cache { let mtt = MTT::new().await; let data = "something"; let expected = CacheEntry::Raw(data.to_string()); - let id = mtt.db.add_entry(expected.clone()).await; + let id = mtt.db.add_entry(expected.clone()).await.unwrap(); let output = mtt.db.get_entry(&id).await.unwrap(); assert_eq!(output.to_string(), data); let dfile = mtt.dir.path().join(DATA).join(&id); @@ -190,6 +204,22 @@ mod cache { assert_eq!(content, expected.to_bytes()); } + #[async_std::test] + async fn store_bad_file() { + let mtt = MTT::new().await; + let msg = "could not write to file"; + mtt.create_io_error().await; + match mtt.db.add_entry(CacheEntry::Raw("fail".to_string())).await { + Ok(_) => assert!(false, "This test should fail."), + Err(err) => { + assert_eq!(err.to_string(), "data write"); + assert!(err.source().is_some(), "Must include the source error."); + let err_msg = err.source().unwrap().to_string(); + assert!(err_msg.contains(msg), "'{}' not in '{}'", msg, err_msg); + } + } + } + #[async_std::test] async fn retrieve_bad_id() { let mtt = MTT::new().await; @@ -202,7 +232,11 @@ mod cache { #[async_std::test] async fn update_cache_entry() { let mtt = MTT::new().await; - let id = mtt.db.add_entry(CacheEntry::Raw("same".to_string())).await; + let id = mtt + .db + .add_entry(CacheEntry::Raw("same".to_string())) + .await + .unwrap(); let expected = "different"; mtt.db .update_entry(&id, CacheEntry::Raw(expected.to_string()))