use std::{future::Future, pin::Pin, time::Duration};
use crate::{dev::*, *};
pub fn test_store<F, S>(cfg: Pin<Box<F>>)
where
F: 'static + Future<Output = S>,
S: 'static + Store,
{
let system = actix::System::new();
let store = system.block_on(async { cfg.await });
let storage = Storage::build().store(store).finish();
system.block_on(async move {
let key = "store_key";
let value = "val";
assert!(storage.set_bytes(key, value).await.is_ok());
let get_res = storage.get_bytes(key).await;
assert!(get_res.is_ok());
assert_eq!(get_res.unwrap(), Some(value.as_bytes().into()));
let contains_res = storage.contains_key(key).await;
assert!(contains_res.is_ok());
assert!(contains_res.unwrap());
assert!(storage.delete(key).await.is_ok());
let get_res = storage.get_bytes(key).await;
assert!(get_res.is_ok());
assert!(get_res.unwrap().is_none());
let contains_res = storage.contains_key(key).await;
assert!(contains_res.is_ok());
assert!(!contains_res.unwrap());
});
}
pub async fn test_expiry_basics(storage: Storage, delay_secs: u64) {
let delay = Duration::from_secs(delay_secs);
let key = "expiring_key";
let value = "val";
assert!(storage.expiry(key).await.unwrap().is_none());
assert!(storage.set_bytes(key, value).await.is_ok());
assert!(storage.expire(key, delay).await.is_ok());
assert_eq!(
storage.get_bytes(key).await.unwrap(),
Some(value.as_bytes().into())
);
let exp = storage.expiry(key).await.unwrap().unwrap();
assert!(exp.as_secs() > 0);
assert!(exp.as_secs() <= delay_secs);
actix::clock::sleep(Duration::from_secs(delay_secs + 1)).await;
assert_eq!(storage.get_bytes(key).await.unwrap(), None);
}
pub async fn test_expiry_extend(storage: Storage, delay_secs: u64) {
let delay = Duration::from_secs(delay_secs);
let key = "extended_expiring_key";
let value = "val";
assert!(storage.set_bytes(key, value).await.is_ok());
assert!(storage.expire(key, delay).await.is_ok());
storage.extend(key, delay).await.unwrap();
let exp = storage.expiry(key).await.unwrap().unwrap();
assert!(exp.as_secs() >= delay_secs);
assert!(exp.as_secs() <= delay_secs * 2);
actix::clock::sleep(Duration::from_secs(delay_secs + 1)).await;
assert_eq!(storage.get_bytes(key).await.unwrap(), Some(value.into()));
actix::clock::sleep(Duration::from_secs(delay_secs + 1)).await;
assert_eq!(storage.get_bytes(key).await.unwrap(), None);
}
pub async fn test_expiry_persist(storage: Storage, delay_secs: u64) {
let delay = Duration::from_secs(delay_secs);
let key = "persistant_key";
let value = "val";
assert!(storage.set_bytes(key, value).await.is_ok());
assert!(storage.expire(key, delay).await.is_ok());
assert!(storage.persist(key).await.is_ok());
actix::clock::sleep(Duration::from_secs(delay_secs + 1)).await;
assert_eq!(storage.get_bytes(key).await.unwrap(), Some(value.into()));
}
pub async fn test_expiry_set_clearing(storage: Storage, delay_secs: u64) {
let delay = Duration::from_secs(delay_secs);
let key = "set_after_expire_key";
let value = "val";
assert!(storage.set_bytes(key, value).await.is_ok());
assert!(storage.expire(key, delay).await.is_ok());
assert!(storage.set_bytes(key, value).await.is_ok());
actix::clock::sleep(Duration::from_secs((delay_secs) + 1)).await;
assert_eq!(
storage.get_bytes(key).await.unwrap(),
Some(value.as_bytes().into())
);
}
pub async fn test_expiry_override_shorter(storage: Storage, delay_secs: u64) {
let delay = Duration::from_secs(delay_secs);
let key = "expire_override_shorter_key";
let value = "val";
assert!(storage.set_bytes(key, value).await.is_ok());
assert!(storage.expire(key, delay * 5).await.is_ok());
assert!(storage.expire(key, delay).await.is_ok());
actix::clock::sleep(Duration::from_secs(delay_secs + 1)).await;
assert_eq!(storage.get_bytes(key).await.unwrap(), None);
}
pub async fn test_expiry_override_longer(storage: Storage, delay_secs: u64) {
let delay = Duration::from_secs(delay_secs);
let key = "expire_override_longer_key";
let value = "val";
assert!(storage.set_bytes(key, value).await.is_ok());
assert!(storage.expire(key, delay).await.is_ok());
assert!(storage.expire(key, delay * 5).await.is_ok());
actix::clock::sleep(Duration::from_secs(delay_secs + 1)).await;
assert_eq!(
storage.get_bytes(key).await.unwrap(),
Some(value.as_bytes().into())
);
}
pub fn test_expiry<F, S, E>(cfg: Pin<Box<F>>, delay_secs: u64)
where
F: 'static + Future<Output = (S, E)>,
S: 'static + Store,
E: 'static + Expiry,
{
let system = actix::System::new();
let (store, expiry) = system.block_on(async { cfg.await });
let storage = Storage::build().store(store).expiry(expiry).finish();
let futures: Vec<Pin<Box<dyn Future<Output = ()>>>> = vec![
Box::pin(test_expiry_basics(storage.clone(), delay_secs)),
Box::pin(test_expiry_extend(storage.clone(), delay_secs)),
Box::pin(test_expiry_persist(storage.clone(), delay_secs)),
Box::pin(test_expiry_set_clearing(storage.clone(), delay_secs)),
Box::pin(test_expiry_override_shorter(storage.clone(), delay_secs)),
Box::pin(test_expiry_override_longer(storage, delay_secs)),
];
system.block_on(async {
futures::future::join_all(futures).await;
});
}
pub async fn test_expiry_store_basics(storage: Storage, delay_secs: u64) {
let delay = Duration::from_secs(delay_secs);
let key = "expiry_store_key";
let value = "value";
assert!(storage.set_expiring_bytes(key, value, delay).await.is_ok());
let (v, e) = storage.get_expiring_bytes(key).await.unwrap().unwrap();
assert_eq!(v, value.as_bytes());
assert!(e.unwrap().as_secs() > 0);
assert!(e.unwrap().as_secs() <= delay_secs);
actix::clock::sleep(Duration::from_secs(delay_secs + 1)).await;
assert_eq!(storage.get_expiring_bytes(key).await.unwrap(), None);
}
pub async fn test_expiry_store_override_shorter(storage: Storage, delay_secs: u64) {
let delay = Duration::from_secs(delay_secs);
let key = "expire_store_override_shorter_key";
let value = "value";
assert!(storage.set_expiring_bytes(key, value, delay).await.is_ok());
assert!(storage
.set_expiring_bytes(key, value, delay * 2)
.await
.is_ok());
let exp = storage.expiry(key).await.unwrap().unwrap();
assert!(exp.as_secs() > delay_secs);
assert!(exp.as_secs() <= delay_secs * 2);
actix::clock::sleep(Duration::from_secs(delay_secs + 1)).await;
assert_eq!(storage.get_bytes(key).await.unwrap(), Some(value.into()));
}
pub async fn test_expiry_store_override_longer(storage: Storage, delay_secs: u64) {
let delay = Duration::from_secs(delay_secs);
let key = "expire_store_override_longer_key";
let value = "value";
assert!(storage
.set_expiring_bytes(key, value, delay * 2)
.await
.is_ok());
assert!(storage.set_expiring_bytes(key, value, delay).await.is_ok());
let exp = storage.expiry(key).await.unwrap().unwrap();
assert!(exp.as_secs() > 0);
assert!(exp.as_secs() <= delay_secs);
actix::clock::sleep(Duration::from_secs(delay_secs + 1)).await;
assert_eq!(storage.get_bytes(key).await.unwrap(), None);
}
pub fn test_expiry_store<F, S>(cfg: Pin<Box<F>>, delay_secs: u64)
where
F: 'static + Future<Output = S>,
S: 'static + ExpiryStore,
{
let system = actix::System::new();
let store = system.block_on(async { cfg.await });
let storage = Storage::build().expiry_store(store).finish();
let futures: Vec<Pin<Box<dyn Future<Output = ()>>>> = vec![
Box::pin(test_expiry_store_basics(storage.clone(), delay_secs)),
Box::pin(test_expiry_store_override_shorter(
storage.clone(),
delay_secs,
)),
Box::pin(test_expiry_store_override_longer(storage, delay_secs)),
];
system.block_on(async move {
futures::future::join_all(futures).await;
});
}
#[cfg(any(
feature = "serde-json",
feature = "serde-cbor",
feature = "serde-ron",
feature = "serde-yaml",
feature = "serde-bincode",
feature = "serde-xml"
))]
pub async fn test_format<S: 'static + Store>(store: S, format: Format) {
let storage = Storage::build().store(store).format(format).finish();
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
struct Human {
name: String,
height: u32,
says_hello: bool,
}
fn get_mamad() -> Human {
Human {
name: "Mamad".to_string(),
height: 160,
says_hello: false,
}
}
let value = get_mamad();
let key = format!("key_{:?}", format);
storage.set(key.clone(), &value).await.unwrap();
let v: Option<Human> = storage.get(key).await.unwrap();
assert!(v.is_some());
assert_eq!(v.unwrap(), value);
}
#[cfg(all(
feature = "serde-json",
feature = "serde-cbor",
feature = "serde-ron",
feature = "serde-yaml",
feature = "serde-bincode",
feature = "serde-xml"
))]
fn get_formats() -> Vec<Format> {
vec![
Format::Json,
Format::Cbor,
Format::Ron,
Format::Yaml,
Format::Bincode,
Format::Xml,
]
}
#[cfg(all(
feature = "serde-json",
feature = "serde-cbor",
feature = "serde-ron",
feature = "serde-yaml",
feature = "serde-bincode",
feature = "serde-xml"
))]
pub fn test_all_formats<F, S>(cfg: Pin<Box<F>>)
where
F: 'static + Future<Output = S>,
S: 'static + Store + Clone,
{
let system = actix::System::new();
let store = system.block_on(async { cfg.await });
let formats = get_formats();
for format in formats {
let store = store.clone();
system.block_on(async move {
test_format(store, format).await;
});
}
}