#![forbid(unsafe_code)] use secrecy::Secret; use xand_secrets::{CheckHealthError, SecretKeyValueStore}; use xand_secrets_vault::{VaultConfiguration, VaultSecretKeyValueStore}; const TEST_TOKEN: &str = "token123"; const TOKEN_HEADER: &str = "X-Vault-Token"; fn create_basic_kv_store() -> VaultSecretKeyValueStore { VaultSecretKeyValueStore::create_from_config(VaultConfiguration { http_endpoint: mockito::server_url(), token: Secret::new(String::from(TEST_TOKEN)), additional_https_root_certificate_files: None, }) .unwrap() } #[tokio::test] async fn test_healthy() { let kv_store = create_basic_kv_store(); let mock_health = mockito::mock("GET", "/v1/sys/health") .with_status(200) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect(1) .create(); let mock_auth = mockito::mock("GET", "/v1/sys/auth") .with_status(200) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect(1) .create(); let result = kv_store.check_health().await; mock_health.assert(); mock_auth.assert(); result.unwrap(); } #[tokio::test] async fn test_both_failing() { let kv_store = create_basic_kv_store(); let mock_health = mockito::mock("GET", "/v1/sys/health") .with_status(500) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect(1) .create(); let mock_auth = mockito::mock("GET", "/v1/sys/auth") .with_status(401) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect_at_most(1) .create(); let result = kv_store.check_health().await; mock_health.assert(); mock_auth.assert(); if let Err(CheckHealthError::RemoteInternal { internal_error: e }) = result { assert_eq!( "An error code was returned while making an HTTP request to path \"/v1/sys/health\". Status code: 500.", format!("{}", e) ); } else { panic!("Expected RemoteInternal error, got {:?}", result); } } #[tokio::test] async fn test_only_health_failing() { let kv_store = create_basic_kv_store(); let mock_health = mockito::mock("GET", "/v1/sys/health") .with_status(500) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect(1) .create(); let mock_auth = mockito::mock("GET", "/v1/sys/auth") .with_status(200) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect_at_most(1) .create(); let result = kv_store.check_health().await; mock_health.assert(); mock_auth.assert(); if let Err(CheckHealthError::RemoteInternal { internal_error: e }) = result { assert_eq!( "An error code was returned while making an HTTP request to path \"/v1/sys/health\". Status code: 500.", format!("{}", e) ); } else { panic!("Expected RemoteInternal error, got {:?}", result); } } #[tokio::test] async fn test_only_auth_failing() { let kv_store = create_basic_kv_store(); let mock_health = mockito::mock("GET", "/v1/sys/health") .with_status(200) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect(1) .create(); let mock_auth = mockito::mock("GET", "/v1/sys/auth") .with_status(403) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect(1) .create(); let result = kv_store.check_health().await; mock_health.assert(); mock_auth.assert(); if let Err(CheckHealthError::Authentication { internal_error: e }) = result { assert_eq!( "An error code was returned while making an HTTP request to path \"/v1/sys/auth\". Status code: 403.", format!("{}", e) ); } else { panic!("Expected Authentication error, got {:?}", result); } } #[tokio::test] async fn test_health_standby() { let kv_store = create_basic_kv_store(); let mock_health = mockito::mock("GET", "/v1/sys/health") .with_status(429) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect(1) .create(); let mock_auth = mockito::mock("GET", "/v1/sys/auth") .with_status(200) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect(1) .create(); let result = kv_store.check_health().await; mock_health.assert(); mock_auth.assert(); result.unwrap(); } #[tokio::test] async fn test_health_perf_standby() { let kv_store = create_basic_kv_store(); let mock_health = mockito::mock("GET", "/v1/sys/health") .with_status(473) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect(1) .create(); let mock_auth = mockito::mock("GET", "/v1/sys/auth") .with_status(200) .match_header(TOKEN_HEADER, TEST_TOKEN) .expect(1) .create(); let result = kv_store.check_health().await; mock_health.assert(); mock_auth.assert(); result.unwrap(); }