unit tests for store handler
This commit is contained in:
@@ -30,3 +30,56 @@ pub async fn store_handler(
|
|||||||
.store(sha256, request.content_type, request.data.contents)
|
.store(sha256, request.content_type, request.data.contents)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use crate::shard::test::make_shard;
|
||||||
|
use axum::body::Bytes;
|
||||||
|
use axum_typed_multipart::FieldData;
|
||||||
|
|
||||||
|
async fn make_shards() -> Shards {
|
||||||
|
Shards::new(vec![make_shard().await]).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_request(sha256: Option<Sha256>, data: Bytes) -> StoreResult {
|
||||||
|
store_handler(
|
||||||
|
Extension(make_shards().await),
|
||||||
|
TypedMultipart(StoreRequest {
|
||||||
|
sha256: sha256.map(|s| s.hex_string()),
|
||||||
|
content_type: "text/plain".to_string(),
|
||||||
|
data: FieldData {
|
||||||
|
metadata: Default::default(),
|
||||||
|
contents: data,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_store_handler() {
|
||||||
|
let result = send_request(None, "hello, world!".as_bytes().into()).await;
|
||||||
|
assert!(matches!(result, StoreResult::Created { .. }));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_store_handler_mismatched_sha256() {
|
||||||
|
let not_hello_world = Sha256::from_bytes("not hello, world!".as_bytes());
|
||||||
|
let hello_world = Sha256::from_bytes("hello, world!".as_bytes());
|
||||||
|
let result = send_request(Some(not_hello_world), "hello, world!".as_bytes().into()).await;
|
||||||
|
assert_eq!(
|
||||||
|
result,
|
||||||
|
StoreResult::Sha256Mismatch {
|
||||||
|
sha256: hello_world.hex_string()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_store_handler_matching_sha256() {
|
||||||
|
let hello_world = Sha256::from_bytes("hello, world!".as_bytes());
|
||||||
|
let result = send_request(Some(hello_world), "hello, world!".as_bytes().into()).await;
|
||||||
|
assert!(matches!(result, StoreResult::Created { .. }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
shards_vec.push(shard);
|
shards_vec.push(shard);
|
||||||
}
|
}
|
||||||
|
|
||||||
let shards = Shards::new(shards_vec);
|
let shards = Shards::new(shards_vec).ok_or("num shards must be > 0")?;
|
||||||
server_loop(server, shards.clone()).await?;
|
server_loop(server, shards.clone()).await?;
|
||||||
info!("shutting down server...");
|
info!("shutting down server...");
|
||||||
shards.close_all().await?;
|
shards.close_all().await?;
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ impl Sha256 {
|
|||||||
format!("{:x}", self)
|
format!("{:x}", self)
|
||||||
}
|
}
|
||||||
pub fn modulo(&self, num: usize) -> usize {
|
pub fn modulo(&self, num: usize) -> usize {
|
||||||
self.0[0] as usize % num
|
let sum: usize = self.0.iter().map(|v| *v as usize).sum();
|
||||||
|
sum % num
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,10 +154,10 @@ async fn get_num_entries(conn: &Connection) -> Result<usize, tokio_rusqlite::Err
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
pub mod test {
|
||||||
use crate::sha256::Sha256;
|
use crate::sha256::Sha256;
|
||||||
|
|
||||||
async fn make_shard() -> super::Shard {
|
pub async fn make_shard() -> super::Shard {
|
||||||
let conn = tokio_rusqlite::Connection::open_in_memory().await.unwrap();
|
let conn = tokio_rusqlite::Connection::open_in_memory().await.unwrap();
|
||||||
super::Shard::open(0, conn).await.unwrap()
|
super::Shard::open(0, conn).await.unwrap()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ use crate::{sha256::Sha256, shard::Shard};
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Shards(Vec<Shard>);
|
pub struct Shards(Vec<Shard>);
|
||||||
impl Shards {
|
impl Shards {
|
||||||
pub fn new(shards: Vec<Shard>) -> Self {
|
pub fn new(shards: Vec<Shard>) -> Option<Self> {
|
||||||
Self(shards)
|
if shards.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(Self(shards))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shard_for(&self, sha256: &Sha256) -> &Shard {
|
pub fn shard_for(&self, sha256: &Sha256) -> &Shard {
|
||||||
|
|||||||
Reference in New Issue
Block a user