From 48968b403b7250c9f4ccd18e5cc22e2fe3612a8e Mon Sep 17 00:00:00 2001 From: Vika Date: Wed, 5 May 2021 17:33:44 +0300 Subject: Refactored the Redis instance spawning in tests to automatically kill Redis --- src/database/mod.rs | 16 ++++++---------- src/database/redis/mod.rs | 25 ++++++++++++++++++++++--- src/lib.rs | 42 +++++++++++++++--------------------------- 3 files changed, 43 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/database/mod.rs b/src/database/mod.rs index d6b7dd6..943a1ad 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -6,7 +6,7 @@ use crate::indieauth::User; mod redis; pub use crate::database::redis::RedisStorage; #[cfg(test)] -pub use redis::tests::get_redis_instance; +pub use redis::tests::{RedisInstance, get_redis_instance}; #[derive(Serialize, Deserialize, PartialEq, Debug)] pub struct MicropubChannel { @@ -222,18 +222,14 @@ mod tests { #[async_std::test] async fn test_redis_storage_basic_operations() { - let (tempdir, mut redis, uri) = get_redis_instance().await; - let backend = super::RedisStorage::new(uri).await.unwrap(); + let redis_instance = get_redis_instance().await; + let backend = super::RedisStorage::new(redis_instance.uri().to_string()).await.unwrap(); test_backend_basic_operations(backend).await; - redis.kill().expect("Redis wasn't running"); - drop(tempdir); } #[async_std::test] - async fn test_redis_storage_channel_support() { - let (tempdir, mut redis, uri) = get_redis_instance().await; - let backend = super::RedisStorage::new(uri).await.unwrap(); + async fn test_redis_storage_channel_list() { + let redis_instance = get_redis_instance().await; + let backend = super::RedisStorage::new(redis_instance.uri().to_string()).await.unwrap(); test_backend_get_channel_list(backend).await; - redis.kill().expect("Redis wasn't running"); - drop(tempdir); } } diff --git a/src/database/redis/mod.rs b/src/database/redis/mod.rs index ccbf831..a3b4bf8 100644 --- a/src/database/redis/mod.rs +++ b/src/database/redis/mod.rs @@ -249,11 +249,28 @@ impl RedisStorage { #[cfg(test)] pub mod tests { - use std::{process}; + use std::process; use std::time::Duration; use mobc_redis::redis; - pub async fn get_redis_instance() -> (tempdir::TempDir, process::Child, String) { + pub struct RedisInstance { + // We just need to hold on to it so it won't get dropped and remove the socket + _tempdir: tempdir::TempDir, + uri: String, + child: std::process::Child + } + impl Drop for RedisInstance { + fn drop(&mut self) { + self.child.kill().expect("Failed to kill the child!"); + } + } + impl RedisInstance { + pub fn uri(&self) -> &str { + &self.uri + } + } + + pub async fn get_redis_instance() -> RedisInstance { let tempdir = tempdir::TempDir::new("redis").expect("failed to create tempdir"); let socket = tempdir.path().join("redis.sock"); let redis_child = process::Command::new("redis-server") @@ -282,6 +299,8 @@ pub mod tests { } } - return (tempdir, redis_child, uri) + return RedisInstance { + uri, child: redis_child, _tempdir: tempdir + } } } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 2fe87f4..d834aed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,31 +82,31 @@ pub async fn get_app_with_redis(token_endpoint: surf::Url, redis_uri: String, me } #[cfg(test)] -pub async fn get_app_with_test_redis(token_endpoint: surf::Url) -> (tempdir::TempDir, std::process::Child, database::RedisStorage, App) { - let (tempdir, child, uri) = crate::database::get_redis_instance().await; - let backend = database::RedisStorage::new(uri).await.unwrap(); +pub async fn get_app_with_test_redis(token_endpoint: surf::Url) -> (database::RedisInstance, database::RedisStorage, App) { + let redis_instance = database::get_redis_instance().await; + let backend = database::RedisStorage::new(redis_instance.uri().to_string()).await.unwrap(); let app = tide::with_state(ApplicationState { token_endpoint, media_endpoint: None, storage: backend.clone(), http_client: surf::Client::new(), }); - return (tempdir, child, backend, equip_app(app)) + return (redis_instance, backend, equip_app(app)) } #[cfg(test)] -#[allow(unused_variables,unused_imports)] +#[allow(unused_variables)] mod tests { use super::*; use serde_json::json; use tide_testing::TideTestingExt; - use crate::database::Storage; use mockito::mock; + use database::Storage; // Helpers - async fn create_app() -> (database::RedisStorage, App, tempdir::TempDir, std::process::Child) { + async fn create_app() -> (database::RedisStorage, App, database::RedisInstance) { //get_app_with_memory_for_testing(surf::Url::parse(&*mockito::server_url()).unwrap()).await - let (t, c, b, a) = get_app_with_test_redis(surf::Url::parse(&*mockito::server_url()).unwrap()).await; - (b, a, t, c) + let (r, b, a) = get_app_with_test_redis(surf::Url::parse(&*mockito::server_url()).unwrap()).await; + (b, a, r) } async fn post_json(app: &App, json: serde_json::Value) -> surf::Response { @@ -125,7 +125,7 @@ mod tests { .with_body(r#"{"me": "https://fireburn.ru", "client_id": "https://quill.p3k.io/", "scope": "create update media"}"#) .create(); - let (db, app, tempdir, mut child) = create_app().await; + let (db, app, _r) = create_app().await; let response = post_json(&app, json!({ "type": ["h-entry"], @@ -153,8 +153,6 @@ mod tests { } })).await; assert_eq!(response.status(), 403); - - child.kill().expect("Couldn't kill Redis"); } #[async_std::test] @@ -165,14 +163,12 @@ mod tests { .with_body(r#"{"me": "https://fireburn.ru", "client_id": "https://quill.p3k.io/", "scope": "create update media"}"#) .create(); - let (db, app, tempdir, mut child) = create_app().await; + let (db, app, _r) = create_app().await; let response: serde_json::Value = app.get("/micropub?q=config") .header("Authorization", "test") .recv_json().await.unwrap(); assert!(!response["q"].as_array().unwrap().is_empty()); - - child.kill().expect("Couldn't kill Redis"); } #[async_std::test] @@ -183,25 +179,21 @@ mod tests { .with_body(r#"{"error":"unauthorized","error_description":"A valid access token is required."}"#) .create(); - let (db, app, tempdir, mut child) = create_app().await; + let (db, app, _r) = create_app().await; let response: surf::Response = app.get("/micropub?q=config") .header("Authorization", "test") .send().await.unwrap(); assert_eq!(response.status(), 401); - - child.kill().expect("Couldn't kill Redis"); } #[async_std::test] async fn test_no_auth_header() { - let (db, app, tempdir, mut child) = create_app().await; + let (db, app, _r) = create_app().await; let request: surf::RequestBuilder = app.get("/micropub?q=config"); let response: surf::Response = request.send().await.unwrap(); assert_eq!(response.status(), 401); - - child.kill().expect("Couldn't kill Redis"); } #[async_std::test] @@ -212,7 +204,7 @@ mod tests { .with_body(r#"{"me": "https://fireburn.ru", "client_id": "https://quill.p3k.io/", "scope": "create update media"}"#) .create(); - let (storage, app, tempdir, mut child) = create_app().await; + let (storage, app, _r) = create_app().await; let request: surf::RequestBuilder = app.post("/micropub") .header("Authorization", "Bearer test") @@ -225,8 +217,6 @@ mod tests { // Assume the post is in the database at this point. let post = storage.get_post(&uid).await.unwrap().unwrap(); assert_eq!(post["properties"]["content"][0]["html"].as_str().unwrap().trim(), "

something interesting

"); - - child.kill().expect("Couldn't kill Redis"); } #[async_std::test] @@ -237,7 +227,7 @@ mod tests { .with_body(r#"{"me": "https://fireburn.ru", "client_id": "https://quill.p3k.io/", "scope": "create update media"}"#) .create(); - let (storage, app, tempdir, mut child) = create_app().await; + let (storage, app, _r) = create_app().await; let mut response = post_json(&app, json!({ "type": ["h-entry"], @@ -272,7 +262,5 @@ mod tests { assert_eq!(new_feed["children"].as_array().unwrap().len(), 2); assert_eq!(new_feed["children"][0].as_str().unwrap(), uid); assert_eq!(new_feed["children"][1].as_str().unwrap(), first_uid); - - child.kill().expect("Couldn't kill Redis"); } } -- cgit 1.4.1