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)
|
||||
.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);
|
||||
}
|
||||
|
||||
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?;
|
||||
info!("shutting down server...");
|
||||
shards.close_all().await?;
|
||||
|
||||
@@ -42,7 +42,8 @@ impl Sha256 {
|
||||
format!("{:x}", self)
|
||||
}
|
||||
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)]
|
||||
mod test {
|
||||
pub mod test {
|
||||
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();
|
||||
super::Shard::open(0, conn).await.unwrap()
|
||||
}
|
||||
|
||||
@@ -5,8 +5,11 @@ use crate::{sha256::Sha256, shard::Shard};
|
||||
#[derive(Clone)]
|
||||
pub struct Shards(Vec<Shard>);
|
||||
impl Shards {
|
||||
pub fn new(shards: Vec<Shard>) -> Self {
|
||||
Self(shards)
|
||||
pub fn new(shards: Vec<Shard>) -> Option<Self> {
|
||||
if shards.is_empty() {
|
||||
return None;
|
||||
}
|
||||
Some(Self(shards))
|
||||
}
|
||||
|
||||
pub fn shard_for(&self, sha256: &Sha256) -> &Shard {
|
||||
|
||||
Reference in New Issue
Block a user