From 18a1abf771e6681c029bc48aab301438d2ff6771 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sat, 23 Mar 2024 11:40:06 +0000 Subject: [PATCH] Run tests in isolated directory This prevents tests from conflicting with eachother if they don't clean up after themselves correctly. --- Cargo.lock | 16 +++++----- Cargo.toml | 1 + src/paste.rs | 83 ++++++++++++++++++++------------------------------- src/server.rs | 49 ++++++++++++++++++------------ src/util.rs | 18 +++++------ 5 files changed, 80 insertions(+), 87 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6c470a2..3c2c01cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1525,9 +1525,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "linked-hash-map" @@ -2354,9 +2354,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.26" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ "bitflags 2.4.1", "errno", @@ -2440,6 +2440,7 @@ dependencies = [ "serde_regex", "shuttle-actix-web", "shuttle-runtime", + "tempfile", "tokio", "tracing", "tracing-subscriber", @@ -2895,15 +2896,14 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.1" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.4.1", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5b0ae548..13db9c18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ default-features = false [dev-dependencies] actix-rt = "2.9.0" +tempfile = "3.10.1" [profile.dev] opt-level = 0 diff --git a/src/paste.rs b/src/paste.rs index 7ae5bb96..b602fb21 100644 --- a/src/paste.rs +++ b/src/paste.rs @@ -286,15 +286,16 @@ mod tests { use actix_web::web::Data; use awc::ClientBuilder; use byte_unit::Byte; - use std::env; use std::str::FromStr; use std::time::Duration; + use tempfile::tempdir; #[actix_rt::test] #[allow(deprecated)] async fn test_paste() -> Result<(), Error> { + let temp_upload_path = tempdir()?; let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = temp_upload_path.path().to_path_buf(); config.paste.random_url = Some(RandomURLConfig { enabled: Some(true), words: Some(3), @@ -307,14 +308,9 @@ mod tests { type_: PasteType::File, }; let file_name = paste.store_file("test.txt", None, None, &config).await?; - assert_eq!("ABC", fs::read_to_string(&file_name).await?); - assert_eq!( - Some("txt"), - PathBuf::from(&file_name) - .extension() - .and_then(|v| v.to_str()) - ); - fs::remove_file(file_name).await?; + let file_path = temp_upload_path.path().join(file_name); + assert_eq!("ABC", fs::read_to_string(&file_path).await?); + assert_eq!(Some("txt"), file_path.extension().and_then(|v| v.to_str())); Ok(()) } @@ -322,8 +318,9 @@ mod tests { #[actix_rt::test] #[allow(deprecated)] async fn test_paste_random() -> Result<(), Error> { + let temp_upload_path = tempdir()?; let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = temp_upload_path.path().to_path_buf(); config.paste.random_url = Some(RandomURLConfig { length: Some(4), type_: RandomURLType::Alphanumeric, @@ -335,10 +332,10 @@ mod tests { type_: PasteType::File, }; let file_name = paste.store_file("foo.tar.gz", None, None, &config).await?; - assert_eq!("tessus", fs::read_to_string(&file_name).await?); + let file_path = temp_upload_path.path().join(&file_name); + assert_eq!("tessus", fs::read_to_string(&file_path).await?); assert!(file_name.ends_with(".tar.gz")); assert!(file_name.starts_with("foo.")); - fs::remove_file(file_name).await?; config.paste.random_url = Some(RandomURLConfig { length: Some(4), @@ -351,10 +348,10 @@ mod tests { type_: PasteType::File, }; let file_name = paste.store_file(".foo.tar.gz", None, None, &config).await?; - assert_eq!("tessus", fs::read_to_string(&file_name).await?); + let file_path = temp_upload_path.path().join(&file_name); + assert_eq!("tessus", fs::read_to_string(&file_path).await?); assert!(file_name.ends_with(".tar.gz")); assert!(file_name.starts_with(".foo.")); - fs::remove_file(file_name).await?; config.paste.random_url = Some(RandomURLConfig { length: Some(4), @@ -367,9 +364,9 @@ mod tests { type_: PasteType::File, }; let file_name = paste.store_file("foo.tar.gz", None, None, &config).await?; - assert_eq!("tessus", fs::read_to_string(&file_name).await?); + let file_path = temp_upload_path.path().join(&file_name); + assert_eq!("tessus", fs::read_to_string(&file_path).await?); assert!(file_name.ends_with(".tar.gz")); - fs::remove_file(file_name).await?; Ok(()) } @@ -377,8 +374,9 @@ mod tests { #[actix_rt::test] #[allow(deprecated)] async fn test_paste_with_extension() -> Result<(), Error> { + let temp_upload_path = tempdir()?; let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = temp_upload_path.path().to_path_buf(); config.paste.default_extension = String::from("txt"); config.paste.random_url = None; let paste = Paste { @@ -386,9 +384,9 @@ mod tests { type_: PasteType::File, }; let file_name = paste.store_file(".foo", None, None, &config).await?; - assert_eq!("xyz", fs::read_to_string(&file_name).await?); + let file_path = temp_upload_path.path().join(&file_name); + assert_eq!("xyz", fs::read_to_string(&file_path).await?); assert_eq!(".foo.txt", file_name); - fs::remove_file(file_name).await?; config.paste.default_extension = String::from("bin"); config.paste.random_url = Some(RandomURLConfig { @@ -401,14 +399,9 @@ mod tests { type_: PasteType::File, }; let file_name = paste.store_file("random", None, None, &config).await?; - assert_eq!("xyz", fs::read_to_string(&file_name).await?); - assert_eq!( - Some("bin"), - PathBuf::from(&file_name) - .extension() - .and_then(|v| v.to_str()) - ); - fs::remove_file(file_name).await?; + let file_path = temp_upload_path.path().join(&file_name); + assert_eq!(Some("bin"), file_path.extension().and_then(|v| v.to_str())); + assert_eq!("xyz", fs::read_to_string(&file_path).await?); Ok(()) } @@ -416,8 +409,9 @@ mod tests { #[actix_rt::test] #[allow(deprecated)] async fn test_paste_filename_from_header() -> Result<(), Error> { + let temp_upload_path = tempdir()?; let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = temp_upload_path.path().to_path_buf(); config.paste.random_url = Some(RandomURLConfig { length: Some(4), type_: RandomURLType::Alphanumeric, @@ -436,9 +430,9 @@ mod tests { &config, ) .await?; - assert_eq!("tessus", fs::read_to_string(&file_name).await?); assert_eq!("fn_from_header.txt", file_name); - fs::remove_file(file_name).await?; + let file_path = temp_upload_path.path().join(&file_name); + assert_eq!("tessus", fs::read_to_string(&file_path).await?); config.paste.random_url = Some(RandomURLConfig { length: Some(4), @@ -458,9 +452,9 @@ mod tests { &config, ) .await?; - assert_eq!("tessus", fs::read_to_string(&file_name).await?); + let file_path = temp_upload_path.path().join(&file_name); + assert_eq!("tessus", fs::read_to_string(&file_path).await?); assert_eq!("fn_from_header", file_name); - fs::remove_file(file_name).await?; Ok(()) } @@ -469,7 +463,7 @@ mod tests { #[allow(deprecated)] async fn test_paste_oneshot() -> Result<(), Error> { let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = tempdir()?.path().to_path_buf(); config.paste.random_url = None; fs::create_dir_all( @@ -501,7 +495,7 @@ mod tests { #[allow(deprecated)] async fn test_paste_url() -> Result<(), Error> { let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = tempdir()?.path().to_path_buf(); config.paste.random_url = Some(RandomURLConfig { enabled: Some(true), ..RandomURLConfig::default() @@ -541,7 +535,7 @@ mod tests { #[allow(deprecated)] async fn test_paste_remote_url() -> Result<(), Error> { let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = tempdir()?.path().to_path_buf(); config.server.max_content_length = Byte::from_str("30k").expect("cannot parse byte"); fs::create_dir_all( @@ -561,25 +555,12 @@ mod tests { .timeout(Duration::from_secs(30)) .finish(), ); - let file_name = paste.store_remote_file(None, &client_data, &config).await?; - let file_path = PasteType::RemoteFile - .get_path(&config.server.upload_path) - .expect("Bad upload path") - .join(file_name); + let _ = paste.store_remote_file(None, &client_data, &config).await?; + assert_eq!( "70ff72a2f7651b5fae3aa9834e03d2a2233c52036610562f7fa04e089e8198ed", util::sha256_digest(&*paste.data)? ); - fs::remove_file(file_path).await?; - - for paste_type in &[PasteType::Url, PasteType::Oneshot] { - fs::remove_dir( - paste_type - .get_path(&config.server.upload_path) - .expect("Bad upload path"), - ) - .await?; - } Ok(()) } diff --git a/src/server.rs b/src/server.rs index da35657c..db5b82df 100644 --- a/src/server.rs +++ b/src/server.rs @@ -398,6 +398,7 @@ mod tests { use std::str; use std::thread; use std::time::Duration; + use tempfile::tempdir; fn get_multipart_request(data: &str, name: &str, filename: &str) -> TestRequest { let multipart_data = format!( @@ -730,9 +731,10 @@ mod tests { #[actix_web::test] async fn test_delete_file() -> Result<(), Error> { + let temp_upload_path = tempdir()?; let mut config = Config::default(); config.server.delete_tokens = Some(["test".to_string()].into()); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = temp_upload_path.path().to_path_buf(); let app = test::init_service( App::new() @@ -759,8 +761,7 @@ mod tests { assert_eq!(StatusCode::OK, response.status()); assert_body(response.into_body(), "file deleted\n").await?; - let path = PathBuf::from(file_name); - assert!(!path.exists()); + assert!(!temp_upload_path.path().join(file_name).exists()); Ok(()) } @@ -768,7 +769,7 @@ mod tests { #[actix_web::test] async fn test_delete_file_without_token_in_config() -> Result<(), Error> { let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = tempdir()?.path().to_path_buf(); let app = test::init_service( App::new() @@ -793,8 +794,9 @@ mod tests { #[actix_web::test] async fn test_upload_file() -> Result<(), Error> { + let test_delete_file = tempdir()?; let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = test_delete_file.path().to_path_buf(); let app = test::init_service( App::new() @@ -825,7 +827,7 @@ mod tests { assert_eq!(StatusCode::OK, response.status()); assert_body(response.into_body(), ×tamp).await?; - fs::remove_file(file_name).await?; + fs::remove_file(test_delete_file.path().join(file_name)).await?; let serve_request = TestRequest::get() .uri(&format!("/{file_name}")) .to_request(); @@ -837,8 +839,9 @@ mod tests { #[actix_web::test] async fn test_upload_file_override_filename() -> Result<(), Error> { + let test_delete_file = tempdir()?; let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = test_delete_file.path().to_path_buf(); let app = test::init_service( App::new() @@ -875,7 +878,7 @@ mod tests { assert_eq!(StatusCode::OK, response.status()); assert_body(response.into_body(), ×tamp).await?; - fs::remove_file(header_filename).await?; + fs::remove_file(test_delete_file.path().join(header_filename)).await?; let serve_request = TestRequest::get() .uri(&format!("/{header_filename}")) .to_request(); @@ -887,8 +890,9 @@ mod tests { #[actix_web::test] async fn test_upload_same_filename() -> Result<(), Error> { + let temp_upload_dir = tempdir()?; let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = temp_upload_dir.path().to_path_buf(); let app = test::init_service( App::new() @@ -932,7 +936,7 @@ mod tests { assert_eq!(StatusCode::CONFLICT, response.status()); assert_body(response.into_body(), "file already exists\n").await?; - fs::remove_file(header_filename).await?; + fs::remove_file(temp_upload_dir.path().join(header_filename)).await?; Ok(()) } @@ -987,8 +991,9 @@ mod tests { #[actix_web::test] async fn test_upload_expiring_file() -> Result<(), Error> { + let temp_upload_path = tempdir()?; let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = temp_upload_path.path().to_path_buf(); let app = test::init_service( App::new() @@ -1032,9 +1037,14 @@ mod tests { let response = test::call_service(&app, serve_request).await; assert_eq!(StatusCode::NOT_FOUND, response.status()); - if let Some(glob_path) = glob(&format!("{file_name}.[0-9]*")) - .map_err(error::ErrorInternalServerError)? - .next() + if let Some(glob_path) = glob( + &temp_upload_path + .path() + .join(format!("{file_name}.[0-9]*")) + .to_string_lossy(), + ) + .map_err(error::ErrorInternalServerError)? + .next() { fs::remove_file(glob_path.map_err(error::ErrorInternalServerError)?).await?; } @@ -1044,8 +1054,9 @@ mod tests { #[actix_web::test] async fn test_upload_remote_file() -> Result<(), Error> { + let temp_upload_dir = tempdir()?; let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = temp_upload_dir.path().to_path_buf(); config.server.max_content_length = Byte::from_u128(30000).unwrap_or_default(); let app = test::init_service( @@ -1091,7 +1102,7 @@ mod tests { util::sha256_digest(&*body_bytes)? ); - fs::remove_file(file_name).await?; + fs::remove_file(temp_upload_dir.path().join(file_name)).await?; let serve_request = TestRequest::get() .uri(&format!("/{file_name}")) @@ -1105,7 +1116,7 @@ mod tests { #[actix_web::test] async fn test_upload_url() -> Result<(), Error> { let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = tempdir()?.path().to_path_buf(); let app = test::init_service( App::new() @@ -1145,7 +1156,7 @@ mod tests { #[actix_web::test] async fn test_upload_oneshot() -> Result<(), Error> { let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = tempdir()?.path().to_path_buf(); let app = test::init_service( App::new() @@ -1205,7 +1216,7 @@ mod tests { #[actix_web::test] async fn test_upload_oneshot_url() -> Result<(), Error> { let mut config = Config::default(); - config.server.upload_path = env::current_dir()?; + config.server.upload_path = tempdir()?.path().to_path_buf(); let oneshot_url_suffix = "oneshot_url"; diff --git a/src/util.rs b/src/util.rs index 1e491102..1752c214 100644 --- a/src/util.rs +++ b/src/util.rs @@ -143,6 +143,8 @@ mod tests { use std::env; use std::fs; use std::thread; + use tempfile::tempdir; + #[test] fn test_system_time() -> Result<(), ActixError> { let system_time = get_system_time()?.as_millis(); @@ -185,18 +187,16 @@ mod tests { #[test] fn test_get_expired_files() -> Result<(), ActixError> { - let current_dir = env::current_dir()?; + let test_temp_dir = tempdir()?; + let test_dir = test_temp_dir.path(); let expiration_time = get_system_time()?.as_millis() + 50; - let path = PathBuf::from(format!("expired.file2.{expiration_time}")); + let path = test_dir.join(format!("expired.file2.{expiration_time}")); fs::write(&path, String::new())?; - assert_eq!(Vec::::new(), get_expired_files(¤t_dir)); + assert_eq!(Vec::::new(), get_expired_files(test_dir)); thread::sleep(Duration::from_millis(75)); - assert_eq!( - vec![current_dir.join(&path)], - get_expired_files(¤t_dir) - ); - fs::remove_file(path)?; - assert_eq!(Vec::::new(), get_expired_files(¤t_dir)); + assert_eq!(vec![path.clone()], get_expired_files(test_dir)); + fs::remove_file(&path)?; + assert_eq!(Vec::::new(), get_expired_files(test_dir)); Ok(()) }