127 lines
6.6 KiB
Rust
127 lines
6.6 KiB
Rust
// file: crates/ksp-store-postgres-lib/unit_tests/runtime.rs
|
|
// version: 4
|
|
|
|
fn network() -> ksp_store_api::RawNetworkId {
|
|
return match ksp_store_api::RawNetworkId::new("devnet") {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => panic!("valid backend test network rejected: {error:?}"),
|
|
};
|
|
}
|
|
|
|
fn settings(connection_uri: &str, tls_mode: crate::PostgresBackendTlsMode) -> crate::PostgresBackendSettings {
|
|
return crate::PostgresBackendSettings::new(
|
|
network(),
|
|
connection_uri,
|
|
8,
|
|
std::time::Duration::from_secs(10),
|
|
std::time::Duration::from_secs(5),
|
|
std::time::Duration::from_secs(10),
|
|
std::time::Duration::from_secs(5),
|
|
tls_mode,
|
|
true,
|
|
std::time::Duration::from_secs(30),
|
|
std::time::Duration::from_secs(10),
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn physical_settings_debug_redacts_connection_uri() {
|
|
let secret = "postgresql://secret-user:secret-password@localhost/ksp";
|
|
let value = settings(secret, crate::PostgresBackendTlsMode::VerifyFull);
|
|
let rendered = format!("{value:?}");
|
|
assert!(!rendered.contains("secret-user"));
|
|
assert!(!rendered.contains("secret-password"));
|
|
assert!(rendered.contains("<redacted>"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn malformed_or_oversized_uri_is_rejected_without_retaining_input() {
|
|
let malformed = "not-a-postgresql-uri-secret-canary";
|
|
let malformed_result = super::normalized_config(&settings(malformed, crate::PostgresBackendTlsMode::Disabled));
|
|
let malformed_error = malformed_result.err();
|
|
assert_eq!(malformed_error.as_ref().map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::ConfigInvalid));
|
|
assert!(!format!("{malformed_error:?}").contains("secret-canary"));
|
|
let oversized = "x".repeat(super::MAX_CONNECTION_URI_BYTES + 1);
|
|
let oversized_result = super::normalized_config(&settings(oversized.as_str(), crate::PostgresBackendTlsMode::Disabled));
|
|
assert_eq!(oversized_result.err().map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::ConfigInvalid));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn typed_disabled_policy_overrides_uri_tls_and_connection_controls() {
|
|
let value = settings(
|
|
"postgresql://operator:secret@localhost/ksp?sslmode=require&application_name=hostile&connect_timeout=1&sslnegotiation=direct",
|
|
crate::PostgresBackendTlsMode::Disabled,
|
|
);
|
|
let config = match super::normalized_config(&value) {
|
|
std::result::Result::Ok(config) => config,
|
|
std::result::Result::Err(error) => panic!("valid disabled config rejected: {error:?}"),
|
|
};
|
|
assert_eq!(config.get_ssl_mode(), tokio_postgres::config::SslMode::Disable);
|
|
assert_eq!(config.get_ssl_negotiation(), tokio_postgres::config::SslNegotiation::Postgres);
|
|
assert_eq!(config.get_application_name(), std::option::Option::Some(super::APPLICATION_NAME));
|
|
assert_eq!(config.get_connect_timeout(), std::option::Option::Some(&std::time::Duration::from_secs(10)));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn typed_verify_full_policy_forces_tls_and_rejects_hostaddr_only_identity() {
|
|
let value = settings(
|
|
"postgresql://operator:secret@localhost/ksp?sslmode=disable&application_name=hostile&connect_timeout=1",
|
|
crate::PostgresBackendTlsMode::VerifyFull,
|
|
);
|
|
let config = match super::normalized_config(&value) {
|
|
std::result::Result::Ok(config) => config,
|
|
std::result::Result::Err(error) => panic!("valid verify_full config rejected: {error:?}"),
|
|
};
|
|
assert_eq!(config.get_ssl_mode(), tokio_postgres::config::SslMode::Require);
|
|
assert_eq!(config.get_ssl_negotiation(), tokio_postgres::config::SslNegotiation::Postgres);
|
|
assert_eq!(config.get_application_name(), std::option::Option::Some(super::APPLICATION_NAME));
|
|
assert_eq!(config.get_connect_timeout(), std::option::Option::Some(&std::time::Duration::from_secs(10)));
|
|
let hostaddr_only = settings("hostaddr=127.0.0.1 user=operator dbname=ksp", crate::PostgresBackendTlsMode::VerifyFull);
|
|
let rejected = super::normalized_config(&hostaddr_only);
|
|
assert_eq!(rejected.err().map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::ConfigInvalid));
|
|
#[cfg(unix)]
|
|
{
|
|
let unix_socket = settings("host=/var/run/postgresql user=operator dbname=ksp", crate::PostgresBackendTlsMode::VerifyFull);
|
|
let unix_rejected = super::normalized_config(&unix_socket);
|
|
assert_eq!(unix_rejected.err().map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::ConfigInvalid));
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn libpq_server_options_are_rejected_in_foundation_runtime() {
|
|
let value = settings("host=localhost user=operator dbname=ksp options='-c statement_timeout=0'", crate::PostgresBackendTlsMode::Disabled);
|
|
let rejected = super::normalized_config(&value);
|
|
let error = rejected.err();
|
|
assert_eq!(error.as_ref().map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::ConfigInvalid));
|
|
assert_eq!(error.map(|value| return value.phase()), std::option::Option::Some("server_options"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_008_capability_error_mapping_uses_stable_store_and_store_api_codes() {
|
|
let cases = [
|
|
(crate::PostgresBackendErrorKind::Conflict, ksp_store_api::ERROR_CODE_RAW_CONFLICT),
|
|
(crate::PostgresBackendErrorKind::DataInvalid, ksp_store_api::ErrorCode::new("store", "postgres_data_invalid")),
|
|
(crate::PostgresBackendErrorKind::PageLimitUnsupported, ksp_store_api::ErrorCode::new("store", "postgres_page_limit_unsupported")),
|
|
(crate::PostgresBackendErrorKind::QueryInvalid, ksp_store_api::ERROR_CODE_RAW_QUERY_INVALID),
|
|
(crate::PostgresBackendErrorKind::ReadFailed, ksp_store_api::ErrorCode::new("store", "postgres_read_failed")),
|
|
(crate::PostgresBackendErrorKind::ReferenceNotFound, ksp_store_api::ErrorCode::new("store", "raw_reference_not_found")),
|
|
(crate::PostgresBackendErrorKind::RetentionCompactionUnsupported, crate::ERROR_CODE_POSTGRES_RETENTION_COMPACTION_UNSUPPORTED),
|
|
(crate::PostgresBackendErrorKind::WriteFailed, ksp_store_api::ErrorCode::new("store", "postgres_write_failed")),
|
|
(crate::PostgresBackendErrorKind::WrongNetwork, ksp_store_api::ErrorCode::new("store", "wrong_network")),
|
|
];
|
|
for (kind, expected) in cases {
|
|
let backend = crate::PostgresBackendError::new(kind, "pre_008_canary");
|
|
let mapped = super::map_capability_error(backend);
|
|
assert_eq!(mapped.code(), expected);
|
|
let rendered = std::format!("{mapped:?}");
|
|
assert!(!rendered.contains("postgresql://"));
|
|
assert!(!rendered.contains("SELECT "));
|
|
}
|
|
return;
|
|
}
|