diff --git a/Cargo.lock b/Cargo.lock index 1c2289e..82cc174 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,21 +198,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - [[package]] name = "futures-channel" version = "0.3.30" @@ -220,7 +205,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", - "futures-sink", ] [[package]] @@ -229,23 +213,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - [[package]] name = "futures-sink" version = "0.3.30" @@ -264,15 +231,10 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ - "futures-channel", "futures-core", - "futures-io", - "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", - "slab", ] [[package]] @@ -726,8 +688,8 @@ dependencies = [ "openapi", "regex", "serde_json", - "serial_test", "snafu", + "temp-env", "tokio", ] @@ -913,15 +875,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "scc" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ad2bbb0ae5100a07b7a6f2ed7ab5fd0045551a4c507989b7a620046ea3efdc" -dependencies = [ - "sdd", -] - [[package]] name = "schannel" version = "0.1.23" @@ -937,12 +890,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sdd" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84345e4c9bd703274a082fb80caaa99b7612be48dfaa1dd9266577ec412309d" - [[package]] name = "security-framework" version = "2.11.0" @@ -1009,31 +956,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serial_test" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b4b487fe2acf240a021cf57c6b2b4903b1e78ca0ecd862a71b71d2a51fed77d" -dependencies = [ - "futures", - "log", - "once_cell", - "parking_lot", - "scc", - "serial_test_derive", -] - -[[package]] -name = "serial_test_derive" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -1127,6 +1049,15 @@ dependencies = [ "libc", ] +[[package]] +name = "temp-env" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96374855068f47402c3121c6eed88d29cb1de8f3ab27090e273e420bdabcf050" +dependencies = [ + "parking_lot", +] + [[package]] name = "tempfile" version = "3.10.1" diff --git a/pinecone_sdk/Cargo.toml b/pinecone_sdk/Cargo.toml index 3bdebc4..9d2768b 100644 --- a/pinecone_sdk/Cargo.toml +++ b/pinecone_sdk/Cargo.toml @@ -14,4 +14,4 @@ snafu = "0.8.3" [dev-dependencies] mockito = "0.30" -serial_test = "3.1.1" +temp-env = "0.3.6" diff --git a/pinecone_sdk/src/control/list_indexes.rs b/pinecone_sdk/src/control/list_indexes.rs index 8ff707f..2b3c8b7 100644 --- a/pinecone_sdk/src/control/list_indexes.rs +++ b/pinecone_sdk/src/control/list_indexes.rs @@ -15,17 +15,15 @@ impl Pinecone { #[cfg(test)] mod tests { use super::*; - use crate::config::Config; use crate::control::list_indexes::models::index_model::Metric; + use crate::utils::errors::PineconeError; use mockito::mock; - use openapi::apis::configuration::ApiKey; - use openapi::apis::configuration::Configuration; use openapi::models::IndexList; use openapi::models::IndexModel; use tokio; #[tokio::test] - async fn test_list_indexes() { + async fn test_list_indexes() -> Result<(), PineconeError> { // Create a mock server let _m = mock("GET", "/indexes") .with_status(200) @@ -68,34 +66,34 @@ mod tests { .expect("Failed to create Pinecone instance"); // Call list_indexes and verify the result - let result = pinecone.list_indexes().await; + let index_list = pinecone + .list_indexes() + .await + .expect("Failed to list indexes"); - match result { - Ok(index_list) => { - let expected = IndexList { - // name: String, dimension: i32, metric: Metric, host: String, spec: models::IndexModelSpec, status: models::IndexModelStatus) - indexes: Some(vec![ - IndexModel::new( - "index1".to_string(), - 1536, - Metric::Cosine, - "host1".to_string(), - models::IndexModelSpec::default(), - models::IndexModelStatus::default(), - ), - IndexModel::new( - "index2".to_string(), - 1536, - Metric::Cosine, - "host2".to_string(), - models::IndexModelSpec::default(), - models::IndexModelStatus::default(), - ), - ]), - }; - assert_eq!(index_list, expected); - } - Err(err) => panic!("Expected Ok, got Err: {:?}", err), - } + let expected = IndexList { + // name: String, dimension: i32, metric: Metric, host: String, spec: models::IndexModelSpec, status: models::IndexModelStatus) + indexes: Some(vec![ + IndexModel::new( + "index1".to_string(), + 1536, + Metric::Cosine, + "host1".to_string(), + models::IndexModelSpec::default(), + models::IndexModelStatus::default(), + ), + IndexModel::new( + "index2".to_string(), + 1536, + Metric::Cosine, + "host2".to_string(), + models::IndexModelSpec::default(), + models::IndexModelStatus::default(), + ), + ]), + }; + assert_eq!(index_list, expected); + + Ok(()) } -} \ No newline at end of file +} diff --git a/pinecone_sdk/src/control/mod.rs b/pinecone_sdk/src/control/mod.rs index 61b19f0..bc5d416 100644 --- a/pinecone_sdk/src/control/mod.rs +++ b/pinecone_sdk/src/control/mod.rs @@ -1,3 +1 @@ mod list_indexes; - -pub use list_indexes::*; \ No newline at end of file diff --git a/pinecone_sdk/src/pinecone.rs b/pinecone_sdk/src/pinecone.rs index 0305931..32c0938 100644 --- a/pinecone_sdk/src/pinecone.rs +++ b/pinecone_sdk/src/pinecone.rs @@ -80,25 +80,11 @@ impl Pinecone { #[cfg(test)] mod tests { - use std::env; - use super::*; - use serial_test::serial; use tokio; - fn set_env_var(key: &str, value: &str) { - env::set_var(key, value); - assert!(env::var(key).is_ok()); - assert!(env::var(key).unwrap() == value); - } - - fn remove_env_var(key: &str) { - env::remove_var(key); - assert!(env::var(key).is_err()); - } - #[tokio::test] - async fn test_arg_api_key() { + async fn test_arg_api_key() -> Result<(), PineconeError> { let mock_api_key = "mock-arg-api-key".to_string(); let mock_controller_host = "mock-arg-controller-host".to_string(); @@ -107,54 +93,55 @@ mod tests { Some(mock_controller_host.clone()), Some(HashMap::new()), None, - ); + ) + .expect("Expected to successfully create Pinecone instance"); + + assert_eq!(pinecone.config.api_key, mock_api_key.clone()); - assert!(pinecone.is_ok()); - assert_eq!(pinecone.unwrap().config.api_key, mock_api_key.clone()); + Ok(()) } #[tokio::test] - #[serial] - async fn test_env_api_key() { + async fn test_env_api_key() -> Result<(), PineconeError> { let mock_api_key = "mock-env-api-key".to_string(); let mock_controller_host = "mock-arg-controller-host".to_string(); - set_env_var("PINECONE_API_KEY", mock_api_key.as_str()); + temp_env::with_var("PINECONE_API_KEY", Some(mock_api_key.as_str()), || { + let pinecone = Pinecone::new( + None, + Some(mock_controller_host.clone()), + Some(HashMap::new()), + None, + ) + .expect("Expected to successfully create Pinecone instance"); - let pinecone = Pinecone::new( - None, - Some(mock_controller_host.clone()), - Some(HashMap::new()), - None, - ); + assert_eq!(pinecone.config.api_key, mock_api_key.clone()); + }); - assert!(pinecone.is_ok()); - assert_eq!(pinecone.unwrap().config.api_key, mock_api_key.clone()); + Ok(()) } #[tokio::test] - #[serial] - async fn test_no_api_key() { + async fn test_no_api_key() -> Result<(), PineconeError> { let mock_controller_host = "mock-arg-controller-host".to_string(); - remove_env_var("PINECONE_API_KEY"); + temp_env::with_var_unset("PINECONE_API_KEY", || { + let pinecone = Pinecone::new( + None, + Some(mock_controller_host.clone()), + Some(HashMap::new()), + None, + ) + .expect_err("Expected to fail creating Pinecone instance due to missing API key"); - let pinecone = Pinecone::new( - None, - Some(mock_controller_host.clone()), - Some(HashMap::new()), - None, - ); + assert!(matches!(pinecone, PineconeError::APIKeyMissingError)); + }); - assert!(pinecone.is_err()); - assert!(matches!( - pinecone.err().unwrap(), - PineconeError::APIKeyMissingError - )); + Ok(()) } #[tokio::test] - async fn test_arg_host() { + async fn test_arg_host() -> Result<(), PineconeError> { let mock_api_key = "mock-arg-api-key".to_string(); let mock_controller_host = "mock-arg-controller-host".to_string(); let pinecone = Pinecone::new( @@ -162,50 +149,60 @@ mod tests { Some(mock_controller_host.clone()), Some(HashMap::new()), None, - ); + ) + .expect("Expected to successfully create Pinecone instance"); - assert!(pinecone.is_ok()); - assert_eq!( - pinecone.unwrap().config.controller_url, - mock_controller_host.clone() - ); + assert_eq!(pinecone.config.controller_url, mock_controller_host.clone()); + + Ok(()) } #[tokio::test] - #[serial] - async fn test_env_host() { + async fn test_env_host() -> Result<(), PineconeError> { let mock_api_key = "mock-arg-api-key".to_string(); let mock_controller_host = "mock-env-controller-host".to_string(); - set_env_var("PINECONE_CONTROLLER_HOST", mock_controller_host.as_str()); - - let pinecone = Pinecone::new(Some(mock_api_key.clone()), None, Some(HashMap::new()), None); + temp_env::with_var( + "PINECONE_CONTROLLER_HOST", + Some(mock_controller_host.as_str()), + || { + let pinecone = + Pinecone::new(Some(mock_api_key.clone()), None, Some(HashMap::new()), None) + .expect("Expected to successfully create Pinecone instance with env host"); - assert!(pinecone.is_ok()); - assert_eq!( - pinecone.unwrap().config.controller_url, - mock_controller_host.clone() + assert_eq!(pinecone.config.controller_url, mock_controller_host.clone()); + }, ); + + Ok(()) } #[tokio::test] - #[serial] - async fn test_default_host() { + async fn test_default_host() -> Result<(), PineconeError> { let mock_api_key = "mock-arg-api-key".to_string(); - remove_env_var("PINECONE_CONTROLLER_HOST"); - - let pinecone = Pinecone::new(Some(mock_api_key.clone()), None, Some(HashMap::new()), None); - - assert!(pinecone.is_ok()); - assert_eq!( - pinecone.unwrap().config.controller_url, - "https://api.pinecone.io".to_string() - ); + temp_env::with_var_unset("PINECONE_CONTROLLER_HOST", || { + let pinecone = Pinecone::new( + Some(mock_api_key.clone()), + None, + Some(HashMap::new()), + None, + ) + .expect( + "Expected to successfully create Pinecone instance with default controller host", + ); + + assert_eq!( + pinecone.config.controller_url, + "https://api.pinecone.io".to_string() + ); + }); + + Ok(()) } #[tokio::test] - async fn test_arg_headers() { + async fn test_arg_headers() -> Result<(), PineconeError> { let mock_api_key = "mock-arg-api-key".to_string(); let mock_controller_host = "mock-arg-controller-host".to_string(); let mock_headers = HashMap::from([ @@ -218,18 +215,16 @@ mod tests { Some(mock_controller_host.clone()), Some(mock_headers.clone()), None, - ); + ) + .expect("Expected to successfully create Pinecone instance"); - assert!(pinecone.is_ok()); - assert_eq!( - pinecone.unwrap().config.additional_headers, - mock_headers.clone() - ); + assert_eq!(pinecone.config.additional_headers, mock_headers.clone()); + + Ok(()) } #[tokio::test] - #[serial] - async fn test_env_headers() { + async fn test_env_headers() -> Result<(), PineconeError> { let mock_api_key = "mock-arg-api-key".to_string(); let mock_controller_host = "mock-arg-controller-host".to_string(); let mock_headers = HashMap::from([ @@ -237,69 +232,70 @@ mod tests { ("envheader2".to_string(), "value2".to_string()), ]); - set_env_var( + temp_env::with_var( "PINECONE_ADDITIONAL_HEADERS", - serde_json::to_string(&mock_headers).unwrap().as_str(), - ); - - let pinecone = Pinecone::new( - Some(mock_api_key.clone()), - Some(mock_controller_host.clone()), - None, - None, + Some(serde_json::to_string(&mock_headers).unwrap().as_str()), + || { + let pinecone = Pinecone::new( + Some(mock_api_key.clone()), + Some(mock_controller_host.clone()), + None, + None, + ) + .expect("Expected to successfully create Pinecone instance with env headers"); + + assert_eq!(pinecone.config.additional_headers, mock_headers.clone()); + }, ); - assert!(pinecone.is_ok()); - assert_eq!( - pinecone.unwrap().config.additional_headers, - mock_headers.clone() - ); + Ok(()) } #[tokio::test] - #[serial] - async fn test_invalid_env_headers() { + async fn test_invalid_env_headers() -> Result<(), PineconeError> { let mock_api_key = "mock-arg-api-key".to_string(); let mock_controller_host = "mock-arg-controller-host".to_string(); - set_env_var("PINECONE_ADDITIONAL_HEADERS", "invalid-json"); - - let pinecone = Pinecone::new( - Some(mock_api_key.clone()), - Some(mock_controller_host.clone()), - None, - None, - ); - - assert!(pinecone.is_err()); - assert!(matches!( - pinecone.err().unwrap(), - PineconeError::InvalidHeadersError { .. } - )); + temp_env::with_var("PINECONE_ADDITIONAL_HEADERS", Some("invalid-json"), || { + let pinecone = Pinecone::new( + Some(mock_api_key.clone()), + Some(mock_controller_host.clone()), + None, + None, + ) + .expect_err("Expected to fail creating Pinecone instance due to invalid headers"); + + assert!(matches!( + pinecone, + PineconeError::InvalidHeadersError { .. } + )); + }); + + Ok(()) } #[tokio::test] - #[serial] - async fn test_default_headers() { + async fn test_default_headers() -> Result<(), PineconeError> { let mock_api_key = "mock-arg-api-key".to_string(); let mock_controller_host = "mock-arg-controller-host".to_string(); - remove_env_var("PINECONE_ADDITIONAL_HEADERS"); + temp_env::with_var_unset("PINECONE_ADDITIONAL_HEADERS", || { + let pinecone = Pinecone::new( + Some(mock_api_key.clone()), + Some(mock_controller_host.clone()), + Some(HashMap::new()), + None, + ) + .expect("Expected to successfully create Pinecone instance"); - let pinecone = Pinecone::new( - Some(mock_api_key.clone()), - Some(mock_controller_host.clone()), - Some(HashMap::new()), - None, - ); + assert_eq!(pinecone.config.additional_headers, HashMap::new()); + }); - assert!(pinecone.is_ok()); - assert_eq!(pinecone.unwrap().config.additional_headers, HashMap::new()); + Ok(()) } #[tokio::test] - #[serial] - async fn test_arg_overrides_env() { + async fn test_arg_overrides_env() -> Result<(), PineconeError> { let mock_arg_api_key = "mock-arg-api-key".to_string(); let mock_arg_controller_host = "mock-arg-controller-host".to_string(); let mock_arg_headers = HashMap::from([ @@ -313,35 +309,36 @@ mod tests { ("envheader2".to_string(), "value2".to_string()), ]); - set_env_var("PINECONE_API_KEY", mock_env_api_key.as_str()); - set_env_var( - "PINECONE_CONTROLLER_HOST", - mock_env_controller_host.as_str(), - ); - env::set_var( - "PINECONE_ADDITIONAL_HEADERS", - serde_json::to_string(&mock_env_headers).unwrap(), - ); - - let pinecone = Pinecone::new( - Some(mock_arg_api_key.clone()), - Some(mock_arg_controller_host.clone()), - Some(mock_arg_headers.clone()), - None, + temp_env::with_vars( + [ + ("PINECONE_API_KEY", Some(mock_env_api_key.as_str())), + ( + "PINECONE_CONTROLLER_HOST", + Some(mock_env_controller_host.as_str()), + ), + ( + "PINECONE_ADDITIONAL_HEADERS", + Some(serde_json::to_string(&mock_env_headers).unwrap().as_str()), + ), + ], + || { + let pinecone = Pinecone::new( + Some(mock_arg_api_key.clone()), + Some(mock_arg_controller_host.clone()), + Some(mock_arg_headers.clone()), + None, + ) + .expect("Expected to successfully create Pinecone instance"); + + assert_eq!(pinecone.config.api_key, mock_arg_api_key.clone()); + assert_eq!( + pinecone.config.controller_url, + mock_arg_controller_host.clone() + ); + assert_eq!(pinecone.config.additional_headers, mock_arg_headers.clone()); + }, ); - assert!(pinecone.is_ok()); - assert_eq!( - pinecone.as_ref().unwrap().config.api_key, - mock_arg_api_key.clone() - ); - assert_eq!( - pinecone.as_ref().unwrap().config.controller_url, - mock_arg_controller_host.clone() - ); - assert_eq!( - pinecone.as_ref().unwrap().config.additional_headers, - mock_arg_headers.clone() - ); + Ok(()) } } \ No newline at end of file diff --git a/pinecone_sdk/tests/integration_test.rs b/pinecone_sdk/tests/integration_test.rs index ae970a9..e539b81 100644 --- a/pinecone_sdk/tests/integration_test.rs +++ b/pinecone_sdk/tests/integration_test.rs @@ -1,9 +1,13 @@ use pinecone_sdk::pinecone::Pinecone; +use pinecone_sdk::utils::errors::PineconeError; #[tokio::test] -async fn test_list_serverless_index_env() { +async fn test_list_index_env() -> Result<(), PineconeError> { let pinecone = Pinecone::new(None, None, None, None).unwrap(); - let list_response = pinecone.list_indexes().await; + let _ = pinecone + .list_indexes() + .await + .expect("Failed to list indexes"); - assert!(list_response.is_ok()); -} \ No newline at end of file + Ok(()) +}