119 lines
4.7 KiB
Rust
119 lines
4.7 KiB
Rust
use sdk_storage::{StorageService, unix_to_system_time, create_app};
|
|
use tempfile::TempDir;
|
|
use surf::Client;
|
|
|
|
#[async_std::test]
|
|
async fn store_and_retrieve_hex_in_tempdir() {
|
|
let td = TempDir::new().unwrap();
|
|
let dir_path = td.path().to_string_lossy().to_string();
|
|
let svc = StorageService::new(dir_path);
|
|
|
|
let key = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
let value = b"hello";
|
|
let expires = Some(unix_to_system_time(60 + sdk_storage::system_time_to_unix(std::time::SystemTime::now())));
|
|
|
|
svc.store_data(key, value, expires).await.unwrap();
|
|
let got = svc.retrieve_data(key).await.unwrap();
|
|
assert_eq!(got, value);
|
|
}
|
|
|
|
#[async_std::test]
|
|
async fn conflict_on_duplicate_key() {
|
|
let td = TempDir::new().unwrap();
|
|
let dir_path = td.path().to_string_lossy().to_string();
|
|
let svc = StorageService::new(dir_path);
|
|
|
|
let key = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
|
let value = b"data";
|
|
|
|
svc.store_data(key, value, None).await.unwrap();
|
|
let err = svc.store_data(key, value, None).await.err().expect("should error");
|
|
assert_eq!(err.status(), tide::StatusCode::Conflict);
|
|
}
|
|
|
|
#[async_std::test]
|
|
async fn cleanup_removes_expired() {
|
|
let td = TempDir::new().unwrap();
|
|
let dir_path = td.path().to_string_lossy().to_string();
|
|
let svc = StorageService::new(dir_path.clone());
|
|
|
|
let key = "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";
|
|
let value = b"x";
|
|
// expiration très proche: maintenant - 1s
|
|
let past = sdk_storage::system_time_to_unix(std::time::SystemTime::now()).saturating_sub(1);
|
|
let expires = Some(unix_to_system_time(past));
|
|
|
|
svc.store_data(key, value, expires).await.unwrap();
|
|
// cleanup one-shot
|
|
svc.cleanup_expired_files_once().await.unwrap();
|
|
let res = svc.retrieve_data(key).await;
|
|
assert!(res.is_err(), "expired key should be removed");
|
|
}
|
|
|
|
#[async_std::test]
|
|
async fn http_store_success_and_conflicts_and_invalids() {
|
|
// app with permanent=false so default TTL applies when missing
|
|
let td = TempDir::new().unwrap();
|
|
let storage = td.path().to_string_lossy().to_string();
|
|
let mut app = create_app(false, storage);
|
|
let listener = async_std::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
|
|
let addr = listener.local_addr().unwrap();
|
|
async_std::task::spawn(async move { app.listen(listener).await.unwrap() });
|
|
|
|
let client = Client::new();
|
|
let base = format!("http://{}", addr);
|
|
|
|
// success
|
|
let key = "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";
|
|
let body = serde_json::json!({"key": key, "value": "01aa", "ttl": 120});
|
|
let res = client.post(format!("{}/store", base)).body_json(&body).unwrap().await.unwrap();
|
|
assert!(res.status().is_success());
|
|
|
|
// conflict
|
|
let res2 = client.post(format!("{}/store", base)).body_json(&body).unwrap().await.unwrap();
|
|
assert_eq!(res2.status(), 409);
|
|
|
|
// invalid key
|
|
let bad = serde_json::json!({"key": "xyz", "value": "01"});
|
|
let res3 = client.post(format!("{}/store", base)).body_json(&bad).unwrap().await.unwrap();
|
|
assert_eq!(res3.status(), 400);
|
|
|
|
// invalid value
|
|
let badv = serde_json::json!({"key": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "value": "zz"});
|
|
let res4 = client.post(format!("{}/store", base)).body_json(&badv).unwrap().await.unwrap();
|
|
assert_eq!(res4.status(), 400);
|
|
}
|
|
|
|
#[async_std::test]
|
|
async fn http_retrieve_success_and_invalid_and_notfound() {
|
|
let td = TempDir::new().unwrap();
|
|
let storage = td.path().to_string_lossy().to_string();
|
|
let mut app = create_app(true, storage.clone());
|
|
let listener = async_std::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
|
|
let addr = listener.local_addr().unwrap();
|
|
async_std::task::spawn(async move { app.listen(listener).await.unwrap() });
|
|
|
|
let client = Client::new();
|
|
let base = format!("http://{}", addr);
|
|
|
|
// prepare stored value (permanent mode)
|
|
let svc = StorageService::new(storage);
|
|
let key = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
|
|
svc.store_data(key, b"hi", None).await.unwrap();
|
|
|
|
// success
|
|
let mut res = client.get(format!("{}/retrieve/{}", base, key)).await.unwrap();
|
|
assert!(res.status().is_success());
|
|
let v: serde_json::Value = res.body_json().await.unwrap();
|
|
assert_eq!(v["value"].as_str().unwrap(), hex::encode("hi"));
|
|
|
|
// invalid key
|
|
let res2 = client.get(format!("{}/retrieve/{}", base, "bad")).await.unwrap();
|
|
assert_eq!(res2.status(), 400);
|
|
|
|
// not found
|
|
let k2 = "1111111111111111111111111111111111111111111111111111111111111111";
|
|
let res3 = client.get(format!("{}/retrieve/{}", base, k2)).await.unwrap();
|
|
assert_eq!(res3.status(), 404);
|
|
}
|