Added io errors to add_entry.

This commit is contained in:
Jeff Baskin 2022-12-18 11:12:58 -05:00
parent 83e3b2ef9e
commit 3e203b40c0

View File

@ -66,19 +66,24 @@ impl MoreThanText {
}) })
} }
async fn add_entry(&self, entry: CacheEntry) -> String { async fn add_entry(&self, entry: CacheEntry) -> Result<String, DBError> {
let mut id: String = "".to_string(); let mut id: String = "".to_string();
let mut dup = true; let mut dup = true;
while dup { while dup {
id = thread_rng().sample_iter(&Alphanumeric).take(32).collect(); id = thread_rng().sample_iter(&Alphanumeric).take(32).collect();
dup = Path::new(&self.dir).join(&id).as_path().exists().await; dup = Path::new(&self.dir).join(&id).as_path().exists().await;
} }
write(Path::new(&self.dir).join(&id), entry.to_bytes()) match write(Path::new(&self.dir).join(&id), entry.to_bytes()).await {
.await Ok(_) => (),
.unwrap(); Err(err) => {
let mut error = DBError::new("data write");
error.add_source(err);
return Err(error);
}
};
let mut cache = self.cache.lock().await; let mut cache = self.cache.lock().await;
cache.insert(id.clone(), entry); cache.insert(id.clone(), entry);
return id; Ok(id)
} }
async fn get_entry(&self, id: &str) -> Result<CacheEntry, DBError> { async fn get_entry(&self, id: &str) -> Result<CacheEntry, DBError> {
@ -103,6 +108,7 @@ impl MoreThanText {
#[cfg(test)] #[cfg(test)]
mod setup { mod setup {
use super::*; use super::*;
use async_std::fs::remove_dir_all;
use tempfile::{tempdir, TempDir}; use tempfile::{tempdir, TempDir};
pub struct MTT { pub struct MTT {
@ -118,6 +124,10 @@ mod setup {
.unwrap(); .unwrap();
Self { db: db, dir: dir } 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_std::test]
async fn bad_data_dir() { async fn bad_data_dir() {
let msg = "could not create directory";
match MoreThanText::new("kljsdgfhslkfrh").await { match MoreThanText::new("kljsdgfhslkfrh").await {
Ok(_) => assert!(false, "This test should fail to create a data directory"), Ok(_) => assert!(false, "This test should fail to create a data directory"),
Err(err) => { Err(err) => {
assert_eq!(err.to_string(), "failed to create data directory"); assert_eq!(err.to_string(), "failed to create data directory");
assert!(err.source().is_some(), "Must include the source error."); 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 { mod cache {
use super::*; use super::*;
use setup::MTT; use setup::MTT;
use std::error::Error;
#[async_std::test] #[async_std::test]
async fn entry_ids_are_random() { async fn entry_ids_are_random() {
let mtt = MTT::new().await; let mtt = MTT::new().await;
let data1 = CacheEntry::Raw("one".to_string()); let data1 = CacheEntry::Raw("one".to_string());
let data2 = CacheEntry::Raw("two".to_string()); let data2 = CacheEntry::Raw("two".to_string());
let id1 = mtt.db.add_entry(data1).await; let id1 = mtt.db.add_entry(data1).await.unwrap();
let id2 = mtt.db.add_entry(data2).await; let id2 = mtt.db.add_entry(data2).await.unwrap();
assert_ne!(id1, id2, "Ids should be unique.") assert_ne!(id1, id2, "Ids should be unique.")
} }
@ -181,7 +195,7 @@ mod cache {
let mtt = MTT::new().await; let mtt = MTT::new().await;
let data = "something"; let data = "something";
let expected = CacheEntry::Raw(data.to_string()); 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(); let output = mtt.db.get_entry(&id).await.unwrap();
assert_eq!(output.to_string(), data); assert_eq!(output.to_string(), data);
let dfile = mtt.dir.path().join(DATA).join(&id); let dfile = mtt.dir.path().join(DATA).join(&id);
@ -190,6 +204,22 @@ mod cache {
assert_eq!(content, expected.to_bytes()); 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_std::test]
async fn retrieve_bad_id() { async fn retrieve_bad_id() {
let mtt = MTT::new().await; let mtt = MTT::new().await;
@ -202,7 +232,11 @@ mod cache {
#[async_std::test] #[async_std::test]
async fn update_cache_entry() { async fn update_cache_entry() {
let mtt = MTT::new().await; 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"; let expected = "different";
mtt.db mtt.db
.update_entry(&id, CacheEntry::Raw(expected.to_string())) .update_entry(&id, CacheEntry::Raw(expected.to_string()))